-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathhinawa-config-rom-printer
executable file
·168 lines (127 loc) · 5.15 KB
/
hinawa-config-rom-printer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (C) 2018 Takashi Sakamoto
import sys
import errno
from pprint import PrettyPrinter
from struct import unpack
from hinawa_utils.ieee1212.config_rom_lexer import Ieee1212ConfigRomLexer
from hinawa_utils.ieee1394.config_rom_parser import Ieee1394ConfigRomParser
import gi
gi.require_version('Hinawa', '4.0')
from gi.repository import Hinawa
if len(sys.argv) < 2:
print('At least one argument is required for firewire character device.')
sys.exit(errno.EINVAL)
path = sys.argv[1]
ops = ('parse', 'lex')
if len(sys.argv) < 3:
op = 'parse'
elif sys.argv[2] in ops:
op = sys.argv[2]
else:
print('Invalid operation: {0}'.format(sys.argv[2]))
sys.exit()
# For Echo Audio Fireworks series.
def handle_echoaudio_keys(key_id, type_name, data):
OUI_COMPANIES = {
0x000ff2: 'Loud Technologies Inc.',
0x001486: 'Echo Digital Audio Corporation',
}
if key_id == 0x08 and type_name == 'IMMEDIATE':
if data in OUI_COMPANIES:
name = OUI_COMPANIES[data]
else:
name = data
return ['MANUFACTURER', name]
return None
# For Apple iSight.
def handle_iidc_v1_30_keys(key_id, type_name, data):
if key_id == 0x00 and type_name == 'CSR_OFFSET':
return ['IIDC_COMMAND_REGS_BASE', data]
return None
def handle_isight_audio_keys(key_id, type_name, data):
if key_id == 0x00 and type_name == 'CSR_OFFSET':
return ['ISIGHT_AUDIO_REG_BASE', data]
return None
def handle_isight_factory_keys(key_id, type_name, data):
LABELS = {
0x01: 'ISIGHT_FACTORY_REG_A',
0x02: 'ISIGHT_FACTORY_REG_B',
0x04: 'ISIGHT_FACTORY_REG_C',
0x05: 'ISIGHT_FACTORY_REG_D',
}
if type_name == 'CSR_OFFSET' and key_id in LABELS:
return [LABELS[key_id], data]
elif key_id == 0x38 and type_name == 'IMMEDIATE':
return ['ISIGHT_FACTORY_DATA', data]
return None
def handle_isight_iris_keys(key_id, type_name, data):
if key_id == 0x3c and type_name == 'IMMEDIATE':
return ['ISIGHT_IRIS_DATA', data]
elif key_id == 0x00 and type_name == 'CSR_OFFSET':
return ['ISIGHT_IRIS_REGS_BASE', data]
return None
# For TASCAM FireWire series.
def handle_teac_keys(key_id, type_name, data):
if key_id == 0x02 and type_name == 'LEAF':
content = data[8:].decode('US-ASCII') + '\0'
return ['MODEL_NAME', content[:content.find('\0')]]
return None
# For Digidesign Digi 00x series.
def handle_microsoft_keys(key_id, type_name, data):
if key_id == 0x01 and type_name == 'LEAF':
width = data[0] >> 4
character_set = ((data[0] & 0x0f) << 8) | data[1]
language = unpack('>H', data[2:4])[0]
if character_set != 0x00 or language != 0x00:
raise ValueError('Invalid data in descriptor leaf.')
content = data[4:].decode('US-ASCII') + '\0'
return content[:content.find('\0')]
return None
# For Cool Stream iSweet.
def handle_ame_root_keys(key_id, type_name, data):
if key_id == 0x06 and type_name == 'IMMEDIATE':
return ['DEVICE_ID', data]
return None
def handle_iidc_v1_04_keys(key_id, type_name, data):
if key_id == 0x00 and type_name == 'CSR_OFFSET':
return ['COMMAND_REGS_BASE', data]
return None
def handle_ame_unit_dep_keys(key_id, type_name, data):
if key_id == 0x02 and type_name == 'LEAF':
descriptor_type = data[0]
specifier_id = (data[1] << 16) | unpack('>H', data[2:4])[0]
if descriptor_type != 0x00 or specifier_id != 0x00:
raise ValueError('Invalid data in vendor-dep descriptor leaf.')
width = data[4] >> 4
character_set = ((data[4] & 0x0f) << 8) | data[5]
language = unpack('>H', data[6:8])[0]
if character_set != 0x00 or language != 0x00:
raise ValueError('Invalid data in descriptor leaf.')
content = data[8:].decode('US-ASCII') + '\0'
return ['MODEL_NAME', content[:content.find('\0')]]
return None
pp = PrettyPrinter(indent=2, compact=False)
node = Hinawa.FwNode()
node.open(path, 0)
_, data = node.get_config_rom()
if op == 'lex':
entries = Ieee1212ConfigRomLexer.detect_entries(data)
pp.pprint(entries)
else:
parser = Ieee1394ConfigRomParser()
parser.add_vendor_dep_handle(0x001486, handle_echoaudio_keys)
parser.add_spec_dep_handle(0x00a02d, 0x000102, handle_iidc_v1_30_keys)
parser.add_spec_dep_handle(0x000a27, 0x000010, handle_isight_audio_keys)
parser.add_spec_dep_handle(0x000a27, 0x000011, handle_isight_factory_keys)
parser.add_spec_dep_handle(0x000a27, 0x000012, handle_isight_iris_keys)
parser.add_spec_dep_handle(0x00022e, 0x800000, handle_teac_keys)
parser.add_spec_dep_handle(0x00022e, 0x800003, handle_teac_keys)
parser.add_spec_dep_handle(0x00022e, 0x800004, handle_teac_keys)
parser.add_vendor_dep_handle(0x0050f2, handle_microsoft_keys)
parser.add_spec_dep_handle(0x00a02d, 0x000100, handle_iidc_v1_04_keys)
parser.add_spec_dep_handle(0x00a02d, 0x000100, handle_ame_unit_dep_keys)
parser.add_vendor_dep_handle(0x0002f0, handle_ame_root_keys)
info = parser.parse_rom(data)
pp.pprint(info)