xref: /btstack/tool/python_generator.py (revision 9fb9416b065bab7144ed8aae4d2cac07fe588a81)
173a17974SMatthias Ringwald#!/usr/bin/env python
273a17974SMatthias Ringwald# BlueKitchen GmbH (c) 2018
373a17974SMatthias Ringwald
473a17974SMatthias Ringwaldimport glob
573a17974SMatthias Ringwaldimport re
673a17974SMatthias Ringwaldimport sys
773a17974SMatthias Ringwaldimport os
873a17974SMatthias Ringwald
973a17974SMatthias Ringwaldimport btstack_parser as parser
1073a17974SMatthias Ringwald
1173a17974SMatthias Ringwaldprint('''
1273a17974SMatthias RingwaldPython binding generator for BTstack Server
1373a17974SMatthias RingwaldCopyright 2018, BlueKitchen GmbH
1473a17974SMatthias Ringwald''')
1573a17974SMatthias Ringwald
1673a17974SMatthias Ringwald# com.bluekitchen.btstack.BTstack.java templates
1773a17974SMatthias Ringwaldcommand_builder_header = \
1873a17974SMatthias Ringwald'''#!/usr/bin/env python3
1973a17974SMatthias Ringwald
2073a17974SMatthias Ringwaldimport struct
2173a17974SMatthias Ringwald
2201aeeea2SMatthias Ringwalddef opcode(ogf, ocf):
2301aeeea2SMatthias Ringwald    return ocf | (ogf << 10)
2473a17974SMatthias Ringwald
2573a17974SMatthias Ringwalddef pack24(value):
2673a17974SMatthias Ringwald    return struct.pack("B", value & 0xff) + struct.pack("<H", value >> 8)
2773a17974SMatthias Ringwald
2873a17974SMatthias Ringwalddef name248(str):
2973a17974SMatthias Ringwald    arg = str.encode('utf-8')
3073a17974SMatthias Ringwald    return arg[:248] + bytes(248-len(arg))
3173a17974SMatthias Ringwald
3201aeeea2SMatthias Ringwald# Command Builder
3301aeeea2SMatthias Ringwald
3401aeeea2SMatthias Ringwaldclass CommandBuilder(object):
3501aeeea2SMatthias Ringwald    def __init__(self):
3601aeeea2SMatthias Ringwald        pass
3701aeeea2SMatthias Ringwald
3873a17974SMatthias Ringwald    def send_command(command):
3973a17974SMatthias Ringwald        return FALSE
4073a17974SMatthias Ringwald
4173a17974SMatthias Ringwald'''
4273a17974SMatthias Ringwaldcommand_builder_command = '''
4301aeeea2SMatthias Ringwald    def {name}(self, {args}):
4473a17974SMatthias Ringwald        cmd_args = bytes()
4573a17974SMatthias Ringwald{args_builder}
4601aeeea2SMatthias Ringwald        cmd = struct.pack("<HB", opcode(self.{ogf}, self.{ocf}), len(cmd_args)) + cmd_args
4773a17974SMatthias Ringwald        return self.send_hci_command(cmd)
4873a17974SMatthias Ringwald'''
4973a17974SMatthias Ringwald
5073a17974SMatthias Ringwald# com.bluekitchen.btstack.EventFactory template
5173a17974SMatthias Ringwaldjava_event_factory_template = \
5273a17974SMatthias Ringwald'''package {0};
5373a17974SMatthias Ringwald
5473a17974SMatthias Ringwaldimport {0}.event.*;
5573a17974SMatthias Ringwald
5673a17974SMatthias Ringwaldpublic class EventFactory {{
5773a17974SMatthias Ringwald
5873a17974SMatthias Ringwald    /** @brief event codes */
5973a17974SMatthias Ringwald
6073a17974SMatthias Ringwald{1}
6173a17974SMatthias Ringwald    public static Event eventForPacket(Packet packet){{
6273a17974SMatthias Ringwald        int eventType = Util.readByte(packet.getBuffer(), 0);
6373a17974SMatthias Ringwald        switch (eventType){{
6473a17974SMatthias Ringwald{2}
6573a17974SMatthias Ringwald        case 0x3e:  // LE_META_EVENT
6673a17974SMatthias Ringwald            int subEventType = Util.readByte(packet.getBuffer(), 2);
6773a17974SMatthias Ringwald            switch (subEventType){{
6873a17974SMatthias Ringwald{3}
6973a17974SMatthias Ringwald            default:
7073a17974SMatthias Ringwald                return new Event(packet);
7173a17974SMatthias Ringwald            }}
7273a17974SMatthias Ringwald
7373a17974SMatthias Ringwald        default:
7473a17974SMatthias Ringwald            return new Event(packet);
7573a17974SMatthias Ringwald        }}
7673a17974SMatthias Ringwald    }}
7773a17974SMatthias Ringwald}}
7873a17974SMatthias Ringwald'''
7973a17974SMatthias Ringwaldjava_event_factory_event = '''
8073a17974SMatthias Ringwald        case {0}:
8173a17974SMatthias Ringwald            return new {1}(packet);
8273a17974SMatthias Ringwald'''
8373a17974SMatthias Ringwaldjava_event_factory_subevent = '''
8473a17974SMatthias Ringwald            case {0}:
8573a17974SMatthias Ringwald                return new {1}(packet);
8673a17974SMatthias Ringwald'''
8773a17974SMatthias Ringwald
8873a17974SMatthias Ringwald# com.bluekitchen.btstack.events.* template
8973a17974SMatthias Ringwaldjava_event_template = \
9073a17974SMatthias Ringwald'''package {0}.event;
9173a17974SMatthias Ringwald
9273a17974SMatthias Ringwaldimport {0}.*;
9373a17974SMatthias Ringwald
9473a17974SMatthias Ringwaldpublic class {1} extends Event {{
9573a17974SMatthias Ringwald
9673a17974SMatthias Ringwald    public {1}(Packet packet) {{
9773a17974SMatthias Ringwald        super(packet);
9873a17974SMatthias Ringwald    }}
9973a17974SMatthias Ringwald    {2}
10073a17974SMatthias Ringwald    {3}
10173a17974SMatthias Ringwald}}
10273a17974SMatthias Ringwald'''
10373a17974SMatthias Ringwald
10473a17974SMatthias Ringwaldjava_event_getter = \
10573a17974SMatthias Ringwald'''
10673a17974SMatthias Ringwald    /**
10773a17974SMatthias Ringwald     * @return {1} as {0}
10873a17974SMatthias Ringwald     */
10973a17974SMatthias Ringwald    public {0} get{1}(){{
11073a17974SMatthias Ringwald        {2}
11173a17974SMatthias Ringwald    }}
11273a17974SMatthias Ringwald'''
11373a17974SMatthias Ringwald
11473a17974SMatthias Ringwaldjava_event_getter_data = \
11573a17974SMatthias Ringwald'''int len = get{0}();
11673a17974SMatthias Ringwald        byte[] result = new byte[len];
11773a17974SMatthias Ringwald        System.arraycopy(data, {1}, result, 0, len);
11873a17974SMatthias Ringwald        return result;'''
11973a17974SMatthias Ringwald
12073a17974SMatthias Ringwaldjava_event_getter_data_fixed = \
12173a17974SMatthias Ringwald'''int len = {0};
12273a17974SMatthias Ringwald        byte[] result = new byte[len];
12373a17974SMatthias Ringwald        System.arraycopy(data, {1}, result, 0, len);
12473a17974SMatthias Ringwald        return result;'''
12573a17974SMatthias Ringwald
12673a17974SMatthias Ringwaldjava_event_getter_remaining_data = \
12773a17974SMatthias Ringwald'''int len = getPayloadLen() - {0};
12873a17974SMatthias Ringwald        byte[] result = new byte[len];
12973a17974SMatthias Ringwald        System.arraycopy(data, {0}, result, 0, len);
13073a17974SMatthias Ringwald        return result;'''
13173a17974SMatthias Ringwald
13273a17974SMatthias Ringwaldjava_event_to_string = \
13373a17974SMatthias Ringwald'''
13473a17974SMatthias Ringwald    public String toString(){{
13573a17974SMatthias Ringwald        StringBuffer t = new StringBuffer();
13673a17974SMatthias Ringwald        t.append("{0} < type = ");
13773a17974SMatthias Ringwald        t.append(String.format("0x%02x, ", getEventType()));
13873a17974SMatthias Ringwald        t.append(getEventType());
13973a17974SMatthias Ringwald{1}        t.append(" >");
14073a17974SMatthias Ringwald        return t.toString();
14173a17974SMatthias Ringwald    }}
14273a17974SMatthias Ringwald'''
14373a17974SMatthias Ringwald
14473a17974SMatthias Ringwald
14573a17974SMatthias Ringwald# global variables/defines
14673a17974SMatthias Ringwaldpackage  ='com.bluekitchen.btstack'
14773a17974SMatthias Ringwaldgen_path = 'gen/' + package.replace('.', '/')
14873a17974SMatthias Ringwald
14973a17974SMatthias Ringwalddefines = dict()
15073a17974SMatthias Ringwalddefines_used = set()
15173a17974SMatthias Ringwald
15273a17974SMatthias Ringwalddef java_type_for_btstack_type(type):
15373a17974SMatthias Ringwald    param_types = { '1' : 'int', '2' : 'int', '3' : 'int', '4' : 'long', 'H' : 'int', 'B' : 'BD_ADDR',
15473a17974SMatthias Ringwald                    'D' : 'byte []', 'E' : 'byte [] ', 'N' : 'String' , 'P' : 'byte []', 'A' : 'byte []',
15573a17974SMatthias Ringwald                    'R' : 'byte []', 'S' : 'byte []', 'Q' : 'byte []',
15673a17974SMatthias Ringwald                    'J' : 'int', 'L' : 'int', 'V' : 'byte []', 'U' : 'BT_UUID',
15773a17974SMatthias Ringwald                    'X' : 'GATTService', 'Y' : 'GATTCharacteristic', 'Z' : 'GATTCharacteristicDescriptor',
15873a17974SMatthias Ringwald                    'T' : 'String'}
15973a17974SMatthias Ringwald    return param_types[type]
16073a17974SMatthias Ringwald
16173a17974SMatthias Ringwalddef size_for_type(type):
16273a17974SMatthias Ringwald    param_sizes = { '1' : 1, '2' : 2, '3' : 3, '4' : 4, 'H' : 2, 'B' : 6, 'D' : 8, 'E' : 240, 'N' : 248, 'P' : 16,
16373a17974SMatthias Ringwald                    'A' : 31, 'S' : -1, 'V': -1, 'J' : 1, 'L' : 2, 'Q' : 32, 'U' : 16, 'X' : 20, 'Y' : 24, 'Z' : 18, 'T':-1}
16473a17974SMatthias Ringwald    return param_sizes[type]
16573a17974SMatthias Ringwald
16673a17974SMatthias Ringwalddef create_command_python(fout, name, ogf, ocf, format, params):
16773a17974SMatthias Ringwald    global command_builder_command
16873a17974SMatthias Ringwald
16973a17974SMatthias Ringwald    ind = '        '
17073a17974SMatthias Ringwald    param_store = {
17173a17974SMatthias Ringwald     '1' : 'cmd_args += struct.pack("B", %s)',
17273a17974SMatthias Ringwald     'J' : 'cmd_args += struct.pack("B", %s)',
17373a17974SMatthias Ringwald     '2' : 'cmd_args += struct.pack("<H", %s)',
17473a17974SMatthias Ringwald     'H' : 'cmd_args += struct.pack("<H", %s)',
17573a17974SMatthias Ringwald     'L' : 'cmd_args += struct.pack("<H", %s)',
17601aeeea2SMatthias Ringwald     '3' : 'cmd_args += pack24(%s)',
17773a17974SMatthias Ringwald     '4' : 'cmd_args += struct.pack("<H", %s)',
17801aeeea2SMatthias Ringwald     'N' : 'cmd_args += name248(%s)',
17973a17974SMatthias Ringwald     'B' : 'cmd_args += %s.get_bytes()',
18073a17974SMatthias Ringwald     'U' : 'cmd_args += %s.get_bytes()',
18173a17974SMatthias Ringwald     'X' : 'cmd_args += %s.get_bytes()',
18273a17974SMatthias Ringwald     'Y' : 'cmd_args += %s.get_bytes()',
18373a17974SMatthias Ringwald     'Z' : 'cmd_args += %s.get_bytes()',
18473a17974SMatthias Ringwald     'S' : 'cmd_args += %s',
18573a17974SMatthias Ringwald     # TODO: support serialization for these
18673a17974SMatthias Ringwald     'D' : '# D / TODO Util.storeBytes(command, offset, %s, 8)',
18773a17974SMatthias Ringwald     'E' : '# E / TODO Util.storeBytes(command, offset, %s, 240)',
18873a17974SMatthias Ringwald     'P' : '# P / TODO Util.storeBytes(command, offset, %s, 16)',
18973a17974SMatthias Ringwald     'Q' : '# Q / TODO Util.storeBytes(command, offset, %s, 32)',
19073a17974SMatthias Ringwald     'A' : '# A / TODO Util.storeBytes(command, offset, %s, 31)',
19173a17974SMatthias Ringwald     }
19273a17974SMatthias Ringwald    # method arguments
19373a17974SMatthias Ringwald    arg_counter = 1
19473a17974SMatthias Ringwald    args = []
19573a17974SMatthias Ringwald    for param_type, arg_name in zip(format, params):
19673a17974SMatthias Ringwald        arg_size = size_for_type(param_type)
19773a17974SMatthias Ringwald        arg = (param_type, arg_size, arg_name)
19873a17974SMatthias Ringwald        args.append(arg)
19973a17974SMatthias Ringwald        arg_counter += 1
20073a17974SMatthias Ringwald
20173a17974SMatthias Ringwald    # method argument declaration
20273a17974SMatthias Ringwald    args2 = []
20373a17974SMatthias Ringwald    for arg in args:
20473a17974SMatthias Ringwald        args2.append(arg[2])
20573a17974SMatthias Ringwald    args_string = ', '.join(args2)
20673a17974SMatthias Ringwald
20773a17974SMatthias Ringwald    # command size (opcode, len)
20873a17974SMatthias Ringwald    size_fixed = 3
20973a17974SMatthias Ringwald    size_var = ''
21073a17974SMatthias Ringwald    for arg in args:
21173a17974SMatthias Ringwald        size = arg[1]
21273a17974SMatthias Ringwald        if size > 0:
21373a17974SMatthias Ringwald            size_fixed += size
21473a17974SMatthias Ringwald        else:
21573a17974SMatthias Ringwald            size_var += ' + %s.length' % arg[2]
21673a17974SMatthias Ringwald    size_string = '%u%s' % (size_fixed, size_var)
21773a17974SMatthias Ringwald
21873a17974SMatthias Ringwald    store_params = ''
21973a17974SMatthias Ringwald
22073a17974SMatthias Ringwald    length_name = ''
22173a17974SMatthias Ringwald    for (param_type, arg_size, arg_name) in args:
22273a17974SMatthias Ringwald        if param_type in ['L', 'J']:
22373a17974SMatthias Ringwald            length_name = arg_name
22473a17974SMatthias Ringwald        if param_type == 'V':
22573a17974SMatthias Ringwald            store_params += ind + 'Util.storeBytes(command, offset, %s, %s);' % (arg_name, length_name) + '\n';
22673a17974SMatthias Ringwald            length_name = ''
22773a17974SMatthias Ringwald        else:
22873a17974SMatthias Ringwald            store_params += ind + (param_store[param_type] % arg_name) + '\n';
22973a17974SMatthias Ringwald            size = arg_size
23073a17974SMatthias Ringwald
23173a17974SMatthias Ringwald    fout.write( command_builder_command.format(name=name, args=args_string, ogf=ogf, ocf=ocf, args_builder=store_params))
23273a17974SMatthias Ringwald
23373a17974SMatthias Ringwalddef mark_define_as_used(term):
23473a17974SMatthias Ringwald    if term.startswith('0'):
23573a17974SMatthias Ringwald        return
23673a17974SMatthias Ringwald    defines_used.add(term)
23773a17974SMatthias Ringwald
23801aeeea2SMatthias Ringwalddef python_define_string(key):
23973a17974SMatthias Ringwald    global defines
24073a17974SMatthias Ringwald    if key in defines:
24101aeeea2SMatthias Ringwald        return '    %s = %s\n' % (key, defines[key])
24273a17974SMatthias Ringwald    else:
24301aeeea2SMatthias Ringwald        return '    # defines[%s] not set\n' % key
24473a17974SMatthias Ringwald
245b2929115SMatthias Ringwalddef python_defines_string(keys):
24601aeeea2SMatthias Ringwald    return '\n'.join( map(python_define_string, sorted(keys)))
24773a17974SMatthias Ringwald
24873a17974SMatthias Ringwalddef create_command_builder(commands):
24973a17974SMatthias Ringwald    global gen_path
25073a17974SMatthias Ringwald    parser.assert_dir(gen_path)
25173a17974SMatthias Ringwald
25273a17974SMatthias Ringwald    outfile = '%s/command_builder.py' % gen_path
25373a17974SMatthias Ringwald
25473a17974SMatthias Ringwald    with open(outfile, 'wt') as fout:
25573a17974SMatthias Ringwald
25673a17974SMatthias Ringwald        fout.write(command_builder_header)
25773a17974SMatthias Ringwald
25873a17974SMatthias Ringwald        for command in commands:
25973a17974SMatthias Ringwald                (command_name, ogf, ocf, format, params) = command
26073a17974SMatthias Ringwald                create_command_python(fout, command_name, ogf, ocf, format, params);
26173a17974SMatthias Ringwald                mark_define_as_used(ogf)
26273a17974SMatthias Ringwald                mark_define_as_used(ocf)
26373a17974SMatthias Ringwald
26401aeeea2SMatthias Ringwald        fout.write('\n    # defines used\n\n')
26501aeeea2SMatthias Ringwald        for key in sorted(defines_used):
26601aeeea2SMatthias Ringwald            fout.write(python_define_string(key))
26773a17974SMatthias Ringwald
268b2929115SMatthias Ringwalddef create_event(fout, event_name, format, args):
26973a17974SMatthias Ringwald    global gen_path
27073a17974SMatthias Ringwald    global package
27173a17974SMatthias Ringwald    global java_event_template
27273a17974SMatthias Ringwald
27373a17974SMatthias Ringwald    param_read = {
27473a17974SMatthias Ringwald     '1' : 'return Util.readByte(data, %u);',
27573a17974SMatthias Ringwald     'J' : 'return Util.readByte(data, %u);',
27673a17974SMatthias Ringwald     '2' : 'return Util.readBt16(data, %u);',
27773a17974SMatthias Ringwald     'H' : 'return Util.readBt16(data, %u);',
27873a17974SMatthias Ringwald     'L' : 'return Util.readBt16(data, %u);',
27973a17974SMatthias Ringwald     '3' : 'return Util.readBt24(data, %u);',
28073a17974SMatthias Ringwald     '4' : 'return Util.readBt32(data, %u);',
28173a17974SMatthias Ringwald     'B' : 'return Util.readBdAddr(data, %u);',
28273a17974SMatthias Ringwald     'X' : 'return Util.readGattService(data, %u);',
28373a17974SMatthias Ringwald     'Y' : 'return Util.readGattCharacteristic(data, %u);',
28473a17974SMatthias Ringwald     'Z' : 'return Util.readGattCharacteristicDescriptor(data, %u);',
28573a17974SMatthias Ringwald     'T' : 'int offset = %u; \n        return Util.getText(data, offset, getPayloadLen()-offset);',
28673a17974SMatthias Ringwald     'N' : 'return Util.getText(data, %u, 248);',
28773a17974SMatthias Ringwald     'D' : 'Util.storeBytes(data, %u, 8);',
28873a17974SMatthias Ringwald     'Q' : 'Util.storeBytes(data, %u, 32);',
28973a17974SMatthias Ringwald     # 'E' : 'Util.storeBytes(data, %u, 240);',
29073a17974SMatthias Ringwald     # 'P' : 'Util.storeBytes(data, %u, 16);',
29173a17974SMatthias Ringwald     # 'A' : 'Util.storeBytes(data, %u, 31);',
29273a17974SMatthias Ringwald     # 'S' : 'Util.storeBytes(data, %u);'
29373a17974SMatthias Ringwald     }
29473a17974SMatthias Ringwald
29573a17974SMatthias Ringwald    offset = 2
29673a17974SMatthias Ringwald    getters = ''
29773a17974SMatthias Ringwald    length_name = ''
29873a17974SMatthias Ringwald    for f, arg in zip(format, args):
29973a17974SMatthias Ringwald        # just remember name
30073a17974SMatthias Ringwald        if f in ['L','J']:
30173a17974SMatthias Ringwald            length_name = parser.camel_case(arg)
30273a17974SMatthias Ringwald        if f == 'R':
30373a17974SMatthias Ringwald            # remaining data
30473a17974SMatthias Ringwald            access = java_event_getter_remaining_data.format(offset)
30573a17974SMatthias Ringwald            size = 0
30673a17974SMatthias Ringwald        elif f == 'V':
30773a17974SMatthias Ringwald            access = java_event_getter_data.format(length_name, offset)
30873a17974SMatthias Ringwald            size = 0
30973a17974SMatthias Ringwald        elif f in ['D', 'Q']:
31073a17974SMatthias Ringwald            size = size_for_type(f)
31173a17974SMatthias Ringwald            access = java_event_getter_data_fixed.format(size, offset)
31273a17974SMatthias Ringwald        else:
31373a17974SMatthias Ringwald            access = param_read[f] % offset
31473a17974SMatthias Ringwald            size = size_for_type(f)
31573a17974SMatthias Ringwald        getters += java_event_getter.format(java_type_for_btstack_type(f), parser.camel_case(arg), access)
31673a17974SMatthias Ringwald        offset += size
31773a17974SMatthias Ringwald    to_string_args = ''
31873a17974SMatthias Ringwald    for arg in args:
31973a17974SMatthias Ringwald        to_string_args += '        t.append(", %s = ");\n' % arg
32073a17974SMatthias Ringwald        to_string_args += '        t.append(get%s());\n' % parser.camel_case(arg)
32173a17974SMatthias Ringwald    to_string_method = java_event_to_string.format(event_name, to_string_args)
32273a17974SMatthias Ringwald    fout.write(java_event_template.format(package, event_name, getters, to_string_method))
32373a17974SMatthias Ringwald
32473a17974SMatthias Ringwalddef event_supported(event_name):
32573a17974SMatthias Ringwald    parts = event_name.split('_')
32673a17974SMatthias Ringwald    return parts[0] in ['ATT', 'BTSTACK', 'DAEMON', 'L2CAP', 'RFCOMM', 'SDP', 'GATT', 'GAP', 'HCI', 'SM', 'BNEP']
32773a17974SMatthias Ringwald
32873a17974SMatthias Ringwalddef class_name_for_event(event_name):
32973a17974SMatthias Ringwald    return parser.camel_case(event_name.replace('SUBEVENT','EVENT'))
33073a17974SMatthias Ringwald
331b2929115SMatthias Ringwalddef create_events(fout, events):
33273a17974SMatthias Ringwald    global gen_path
33373a17974SMatthias Ringwald    gen_path_events = gen_path + '/event'
33473a17974SMatthias Ringwald    parser.assert_dir(gen_path_events)
33573a17974SMatthias Ringwald
33673a17974SMatthias Ringwald    for event_type, event_name, format, args in events:
33773a17974SMatthias Ringwald        if not event_supported(event_name):
33873a17974SMatthias Ringwald            continue
33973a17974SMatthias Ringwald        class_name = class_name_for_event(event_name)
340b2929115SMatthias Ringwald        create_event(fout, class_name, format, args)
34173a17974SMatthias Ringwald
34273a17974SMatthias Ringwald
34373a17974SMatthias Ringwalddef create_event_factory(events, subevents, defines):
34473a17974SMatthias Ringwald    global gen_path
34573a17974SMatthias Ringwald    global package
34673a17974SMatthias Ringwald    global java_event_factory_event
34773a17974SMatthias Ringwald    global java_event_factory_template
34873a17974SMatthias Ringwald
349b2929115SMatthias Ringwald    outfile = '%s/event_factory.py' % gen_path
35073a17974SMatthias Ringwald
35173a17974SMatthias Ringwald    cases = ''
35273a17974SMatthias Ringwald    for event_type, event_name, format, args in events:
35373a17974SMatthias Ringwald        event_name = parser.camel_case(event_name)
35473a17974SMatthias Ringwald        cases += java_event_factory_event.format(event_type, event_name)
35573a17974SMatthias Ringwald    subcases = ''
35673a17974SMatthias Ringwald    for event_type, event_name, format, args in subevents:
35773a17974SMatthias Ringwald        if not event_supported(event_name):
35873a17974SMatthias Ringwald            continue
35973a17974SMatthias Ringwald        class_name = class_name_for_event(event_name)
36073a17974SMatthias Ringwald        subcases += java_event_factory_subevent.format(event_type, class_name)
36173a17974SMatthias Ringwald
36273a17974SMatthias Ringwald    with open(outfile, 'wt') as fout:
363b2929115SMatthias Ringwald        # event classes
364b2929115SMatthias Ringwald        create_events(fout, events)
365b2929115SMatthias Ringwald        create_events(fout, subevents)
366b2929115SMatthias Ringwald        #
367b2929115SMatthias Ringwald        defines_text = python_defines_string(defines)
36873a17974SMatthias Ringwald        fout.write(java_event_factory_template.format(package, defines_text, cases, subcases))
36973a17974SMatthias Ringwald
37073a17974SMatthias Ringwald# find root
37173a17974SMatthias Ringwaldbtstack_root = os.path.abspath(os.path.dirname(sys.argv[0]) + '/..')
37273a17974SMatthias Ringwaldgen_path = btstack_root + '/platform/daemon/binding/python/btstack/'
37373a17974SMatthias Ringwald
37473a17974SMatthias Ringwald
37573a17974SMatthias Ringwald# read defines from hci_cmds.h and hci.h
37673a17974SMatthias Ringwalddefines = parser.parse_defines()
37773a17974SMatthias Ringwald
37873a17974SMatthias Ringwald# parse commands
379*9fb9416bSMatthias Ringwaldcommands = parser.parse_commands(camel_case=False)
38073a17974SMatthias Ringwald
38173a17974SMatthias Ringwald# parse bluetooth.h to get used events
382b2929115SMatthias Ringwald(events, le_events, event_types) = parser.parse_events()
38373a17974SMatthias Ringwald
38473a17974SMatthias Ringwald# create events, le meta events, event factory, and
385b2929115SMatthias Ringwaldcreate_event_factory(events, le_events, event_types)
38673a17974SMatthias Ringwaldcreate_command_builder(commands)
38773a17974SMatthias Ringwald
38873a17974SMatthias Ringwald# done
38973a17974SMatthias Ringwaldprint('Done!')
390