xref: /btstack/tool/btstack_event_generator.py (revision 8850b501b63dea7e8e09e0ce7dbe8933ed05ea0e)
15c544019SMatthias Ringwald#!/usr/bin/env python3
2c3b5b8a5SMatthias Ringwald
3c3b5b8a5SMatthias Ringwaldimport glob
4c3b5b8a5SMatthias Ringwaldimport re
5c3b5b8a5SMatthias Ringwaldimport sys
6c3b5b8a5SMatthias Ringwaldimport os
7c3b5b8a5SMatthias Ringwald
8c3b5b8a5SMatthias Ringwaldimport btstack_parser as parser
9c3b5b8a5SMatthias Ringwald
10f1b34e8dSMatthias Ringwaldmeta_events = [
1128e59789SMilanka Ringwald    'A2DP',
12f1b34e8dSMatthias Ringwald    'ANCS',
13f1b34e8dSMatthias Ringwald    'AVDTP',
14f1b34e8dSMatthias Ringwald    'AVRCP',
15a911051fSMatthias Ringwald    'GAP',
1628e59789SMilanka Ringwald    'GATTSERVICE',
17f1b34e8dSMatthias Ringwald    'GOEP',
18f1b34e8dSMatthias Ringwald    'HFP',
19dd148ddbSMatthias Ringwald    'HID',
20a4bfc4feSMatthias Ringwald    'HIDS',
2128e59789SMilanka Ringwald    'HSP',
2228e59789SMilanka Ringwald    'LE',
23ae304283SMilanka Ringwald    'LEAUDIO',
24ad58991cSMilanka Ringwald    'MAP',
25b673498bSMatthias Ringwald    'MESH',
26ad58991cSMilanka Ringwald    'PBAP',
277c69f73aSMatthias Ringwald    'OPP'
28f1b34e8dSMatthias Ringwald]
29f1b34e8dSMatthias Ringwald
30f1b34e8dSMatthias Ringwaldsupported_event_groups = meta_events + [
3128e59789SMilanka Ringwald    'ATT',
3228e59789SMilanka Ringwald    'BNEP',
33f1b34e8dSMatthias Ringwald    'BTSTACK',
34f1b34e8dSMatthias Ringwald    'GAP',
3528e59789SMilanka Ringwald    'GATT',
36f1b34e8dSMatthias Ringwald    'HCI',
3728e59789SMilanka Ringwald    'HID',
38f1b34e8dSMatthias Ringwald    'L2CAP',
39f1b34e8dSMatthias Ringwald    'RFCOMM',
4028e59789SMilanka Ringwald    'SDP',
41*8850b501SMatthias Ringwald    'SM',
42*8850b501SMatthias Ringwald    'DAEMON',
43f1b34e8dSMatthias Ringwald]
44f1b34e8dSMatthias Ringwald
4563a4cec0SDirk Helbigopen_bracket = parser.open_bracket
4663a4cec0SDirk Helbigclosing_bracket = parser.closing_bracket
4763a4cec0SDirk Helbig
48c3b5b8a5SMatthias Ringwaldprogram_info = '''
49c3b5b8a5SMatthias RingwaldBTstack Event Getter Generator for BTstack
50c3b5b8a5SMatthias RingwaldCopyright 2016, BlueKitchen GmbH
51c3b5b8a5SMatthias Ringwald'''
52c3b5b8a5SMatthias Ringwald
53c3b5b8a5SMatthias Ringwaldcopyright = """/*
54c3b5b8a5SMatthias Ringwald * Copyright (C) 2016 BlueKitchen GmbH
55c3b5b8a5SMatthias Ringwald *
56c3b5b8a5SMatthias Ringwald * Redistribution and use in source and binary forms, with or without
57c3b5b8a5SMatthias Ringwald * modification, are permitted provided that the following conditions
58c3b5b8a5SMatthias Ringwald * are met:
59c3b5b8a5SMatthias Ringwald *
60c3b5b8a5SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright
61c3b5b8a5SMatthias Ringwald *    notice, this list of conditions and the following disclaimer.
62c3b5b8a5SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright
63c3b5b8a5SMatthias Ringwald *    notice, this list of conditions and the following disclaimer in the
64c3b5b8a5SMatthias Ringwald *    documentation and/or other materials provided with the distribution.
65c3b5b8a5SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of
66c3b5b8a5SMatthias Ringwald *    contributors may be used to endorse or promote products derived
67c3b5b8a5SMatthias Ringwald *    from this software without specific prior written permission.
68c3b5b8a5SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for
69c3b5b8a5SMatthias Ringwald *    personal benefit and not for any commercial purpose or for
70c3b5b8a5SMatthias Ringwald *    monetary gain.
71c3b5b8a5SMatthias Ringwald *
72c3b5b8a5SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
73c3b5b8a5SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
74c3b5b8a5SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
75b5c62b37SMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
76b5c62b37SMilanka Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
77c3b5b8a5SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
78c3b5b8a5SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
79c3b5b8a5SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
80c3b5b8a5SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
81c3b5b8a5SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
82c3b5b8a5SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
83c3b5b8a5SMatthias Ringwald * SUCH DAMAGE.
84c3b5b8a5SMatthias Ringwald *
85c3b5b8a5SMatthias Ringwald * Please inquire about commercial licensing options at
86c3b5b8a5SMatthias Ringwald * [email protected]
87c3b5b8a5SMatthias Ringwald *
88c3b5b8a5SMatthias Ringwald */
89c3b5b8a5SMatthias Ringwald"""
90c3b5b8a5SMatthias Ringwald
91c3b5b8a5SMatthias Ringwaldhfile_header_begin = """
92c3b5b8a5SMatthias Ringwald
932026696cSMatthias Ringwald/**
942026696cSMatthias Ringwald * HCI Event Getter
95c3b5b8a5SMatthias Ringwald *
962026696cSMatthias Ringwald * Note: Don't edit this file. It is generated by tool/btstack_event_generator.py
97c3b5b8a5SMatthias Ringwald *
98c3b5b8a5SMatthias Ringwald */
99c3b5b8a5SMatthias Ringwald
10080e33422SMatthias Ringwald#ifndef BTSTACK_EVENT_H
10180e33422SMatthias Ringwald#define BTSTACK_EVENT_H
102c3b5b8a5SMatthias Ringwald
103c3b5b8a5SMatthias Ringwald#if defined __cplusplus
104c3b5b8a5SMatthias Ringwaldextern "C" {
105c3b5b8a5SMatthias Ringwald#endif
106c3b5b8a5SMatthias Ringwald
107c3b5b8a5SMatthias Ringwald#include "btstack_util.h"
108c3b5b8a5SMatthias Ringwald#include <stdint.h>
109c3b5b8a5SMatthias Ringwald
110313e337bSMatthias Ringwald#ifdef ENABLE_BLE
111313e337bSMatthias Ringwald#include "ble/gatt_client.h"
112313e337bSMatthias Ringwald#endif
113313e337bSMatthias Ringwald
114c3b5b8a5SMatthias Ringwald/* API_START */
115c3b5b8a5SMatthias Ringwald
1160e2df43fSMatthias Ringwald/**
1170e2df43fSMatthias Ringwald * @brief Get event type
1180e2df43fSMatthias Ringwald * @param event
1190e2df43fSMatthias Ringwald * @return type of event
1200e2df43fSMatthias Ringwald */
1210e2df43fSMatthias Ringwaldstatic inline uint8_t hci_event_packet_get_type(const uint8_t * event){
1220e2df43fSMatthias Ringwald    return event[0];
1230e2df43fSMatthias Ringwald}
1240e2df43fSMatthias Ringwald
12563a4cec0SDirk Helbigtypedef uint8_t* btstack_event_iterator_t;
12663a4cec0SDirk Helbig
127c3b5b8a5SMatthias Ringwald"""
128c3b5b8a5SMatthias Ringwald
129c3b5b8a5SMatthias Ringwaldhfile_header_end = """
130c3b5b8a5SMatthias Ringwald
131c3b5b8a5SMatthias Ringwald/* API_END */
132c3b5b8a5SMatthias Ringwald
133c3b5b8a5SMatthias Ringwald#if defined __cplusplus
134c3b5b8a5SMatthias Ringwald}
135c3b5b8a5SMatthias Ringwald#endif
136c3b5b8a5SMatthias Ringwald
13780e33422SMatthias Ringwald#endif // BTSTACK_EVENT_H
138c3b5b8a5SMatthias Ringwald"""
139c3b5b8a5SMatthias Ringwald
140313e337bSMatthias Ringwaldc_prototoype_simple_return = '''/**
141c3b5b8a5SMatthias Ringwald * @brief {description}
1420e2df43fSMatthias Ringwald * @param event packet
143c3b5b8a5SMatthias Ringwald * @return {result_name}
144c3b5b8a5SMatthias Ringwald * @note: btstack_type {format}
145c3b5b8a5SMatthias Ringwald */
14663a4cec0SDirk Helbigstatic inline {result_type} {event}_get_{field}(const uint8_t * event){{
147c3b5b8a5SMatthias Ringwald    {code}
148c3b5b8a5SMatthias Ringwald}}
149c3b5b8a5SMatthias Ringwald'''
150c3b5b8a5SMatthias Ringwald
15163a4cec0SDirk Helbigc_prototype_iterator_return = '''/**
15263a4cec0SDirk Helbig * @brief {description}
15363a4cec0SDirk Helbig * @param event packet
15463a4cec0SDirk Helbig * @return {result_name}
15563a4cec0SDirk Helbig * @note: btstack_type {format}
15663a4cec0SDirk Helbig */
15763a4cec0SDirk Helbigstatic inline {result_type} {event}_get_{scope}_item_{field}(btstack_event_iterator_t * iter){{
15863a4cec0SDirk Helbig    {code}
15963a4cec0SDirk Helbig}}
16063a4cec0SDirk Helbig'''
16163a4cec0SDirk Helbig
16263a4cec0SDirk Helbigc_prototype_iterator_init = '''/**
16363a4cec0SDirk Helbig * @brief Initialize iterator for list {scope} of {event}
16463a4cec0SDirk Helbig * @param iterator
16563a4cec0SDirk Helbig * @param event packet
16663a4cec0SDirk Helbig * @note: btstack_type {format}
16763a4cec0SDirk Helbig */
16863a4cec0SDirk Helbigstatic inline void {event}_{field}_init(btstack_event_iterator_t * iter, const uint8_t * event){{
16963a4cec0SDirk Helbig    *iter = (btstack_event_iterator_t)&event[{list_field}];
17063a4cec0SDirk Helbig}}
17163a4cec0SDirk Helbig
17263a4cec0SDirk Helbig'''
17363a4cec0SDirk Helbig
17463a4cec0SDirk Helbigc_prototype_iterator_has_next = '''/**
17563a4cec0SDirk Helbig * @brief Returns true if iterator of list {scope} of {event} has more elements, false otherwise.
17663a4cec0SDirk Helbig * @param iterator
17763a4cec0SDirk Helbig * @param event packet
17863a4cec0SDirk Helbig * @return
17963a4cec0SDirk Helbig * @note: btstack_type {format}
18063a4cec0SDirk Helbig */
18163a4cec0SDirk Helbigstatic inline bool {event}_{field}_has_next(btstack_event_iterator_t * iter, const uint8_t * event){{
18263a4cec0SDirk Helbig    uint8_t length = event[{length_field}];
18363a4cec0SDirk Helbig    const uint8_t *begin = &event[{list_field}];
18463a4cec0SDirk Helbig    const uint8_t *end = begin+length;
18563a4cec0SDirk Helbig    return *iter<end;
18663a4cec0SDirk Helbig}}
18763a4cec0SDirk Helbig
18863a4cec0SDirk Helbig'''
18963a4cec0SDirk Helbig
19063a4cec0SDirk Helbigc_prototype_iterator_next = '''/**
19163a4cec0SDirk Helbig * @brief Advances the iterator to the next element
19263a4cec0SDirk Helbig * @param event packet
19363a4cec0SDirk Helbig * @note: btstack_type {format}
19463a4cec0SDirk Helbig */
19563a4cec0SDirk Helbigstatic inline void {event}_{scope}_next(btstack_event_iterator_t * iter){{
19663a4cec0SDirk Helbig    uint8_t length = {code}
19763a4cec0SDirk Helbig    *iter = *iter+length;
19863a4cec0SDirk Helbig}}
19963a4cec0SDirk Helbig
20063a4cec0SDirk Helbig'''
20163a4cec0SDirk Helbig
202396f0845SMatthias Ringwaldc_prototoype_array_getter = '''/**
203396f0845SMatthias Ringwald * @brief {description}
204396f0845SMatthias Ringwald * @param event packet
205396f0845SMatthias Ringwald * @param index
206396f0845SMatthias Ringwald * @return {result_name}
207396f0845SMatthias Ringwald * @note: btstack_type {format}
208396f0845SMatthias Ringwald */
20963a4cec0SDirk Helbigstatic inline {result_type} {event}_get_{field}(const uint8_t * event, uint8_t index){{
210396f0845SMatthias Ringwald    {code}
211396f0845SMatthias Ringwald}}
212396f0845SMatthias Ringwald'''
213396f0845SMatthias Ringwald
214313e337bSMatthias Ringwaldc_prototoype_struct_return = '''/**
215c3b5b8a5SMatthias Ringwald * @brief {description}
2160e2df43fSMatthias Ringwald * @param event packet
217c3b5b8a5SMatthias Ringwald * @param Pointer to storage for {result_name}
218c3b5b8a5SMatthias Ringwald * @note: btstack_type {format}
219c3b5b8a5SMatthias Ringwald */
22063a4cec0SDirk Helbigstatic inline void {event}_get_{field}(const uint8_t * event, {result_type} {result_name}){{
221c3b5b8a5SMatthias Ringwald    {code}
222c3b5b8a5SMatthias Ringwald}}
223c3b5b8a5SMatthias Ringwald'''
224c3b5b8a5SMatthias Ringwald
225313e337bSMatthias Ringwaldc_prototoype_unsupported = '''/**
226c3b5b8a5SMatthias Ringwald * @brief {description}
2270e2df43fSMatthias Ringwald * @param event packet
228c3b5b8a5SMatthias Ringwald * @return {result_name}
229c3b5b8a5SMatthias Ringwald * @note: btstack_type {format}
230c3b5b8a5SMatthias Ringwald */
23163a4cec0SDirk Helbig//  static inline {result_type} {event}_get_{field}(const uint8_t * event){{
232c3b5b8a5SMatthias Ringwald//      not implemented yet
233c3b5b8a5SMatthias Ringwald//  }}
234c3b5b8a5SMatthias Ringwald'''
235c3b5b8a5SMatthias Ringwald
2360e2df43fSMatthias Ringwaldmeta_event_template = '''/***
2370e2df43fSMatthias Ringwald * @brief Get subevent code for {meta_event} event
2380e2df43fSMatthias Ringwald * @param event packet
2390e2df43fSMatthias Ringwald * @return subevent_code
2400e2df43fSMatthias Ringwald */
2410e2df43fSMatthias Ringwaldstatic inline uint8_t hci_event_{meta_event}_meta_get_subevent_code(const uint8_t * event){{
2420e2df43fSMatthias Ringwald    return event[2];
2430e2df43fSMatthias Ringwald}}
2440e2df43fSMatthias Ringwald'''
2450e2df43fSMatthias Ringwald
24663a4cec0SDirk Helbig
247c3b5b8a5SMatthias Ringwald# global variables/defines
248c3b5b8a5SMatthias Ringwalddefines = dict()
249c3b5b8a5SMatthias Ringwalddefines_used = set()
250c3b5b8a5SMatthias Ringwald
251c3b5b8a5SMatthias Ringwaldparam_read = {
252c3b5b8a5SMatthias Ringwald    '1' : 'return event[{offset}];',
253c3b5b8a5SMatthias Ringwald    'J' : 'return event[{offset}];',
254f8fbdce0SMatthias Ringwald    '2' : 'return little_endian_read_16(event, {offset});',
255f8fbdce0SMatthias Ringwald    'L' : 'return little_endian_read_16(event, {offset});',
256f8fbdce0SMatthias Ringwald    '3' : 'return little_endian_read_24(event, {offset});',
257f8fbdce0SMatthias Ringwald    '4' : 'return little_endian_read_32(event, {offset});',
258f8fbdce0SMatthias Ringwald    'H' : 'return little_endian_read_16(event, {offset});',
259b1dcf9d8SMatthias Ringwald    'B' : 'reverse_bytes(&event[{offset}], {result_name}, 6);',
2607bd8e93bSMatthias Ringwald    'R' : 'return &event[{offset}];',
26147430bedSMatthias Ringwald    'N' : 'return (const char *) &event[{offset}];',
2621707474dSSimon Budig    'P' : 'return (const uint8_t *) &event[{offset}];',
2634de250b4SMatthias Ringwald    'T' : 'return (const char *) &event[{offset}];',
2648ba9588fSMatthias Ringwald    'D' : 'return (const uint8_t *) &event[{offset}];',
26575a8e4faSMatthias Ringwald    'K' : 'reverse_bytes(&event[{offset}], {result_name}, 16);',
26682180fcaSMatthias Ringwald    'Q' : 'reverse_bytes(&event[{offset}], {result_name}, 32);',
2674de250b4SMatthias Ringwald    'V' : 'return &event[{offset}];',
268313e337bSMatthias Ringwald    'X' : 'gatt_client_deserialize_service(event, {offset}, {result_name});',
269313e337bSMatthias Ringwald    'Y' : 'gatt_client_deserialize_characteristic(event, {offset}, {result_name});',
270313e337bSMatthias Ringwald    'Z' : 'gatt_client_deserialize_characteristic_descriptor(event, {offset}, {result_name});',
27147430bedSMatthias Ringwald    'V' : 'return &event[{offset}];',
27263a4cec0SDirk Helbig    'C' : 'return little_endian_read_16(event, {offset} + (2 * (int) index));',
27363a4cec0SDirk Helbig    open_bracket    : 'dummy',
27463a4cec0SDirk Helbig    closing_bracket : 'dummy',
275c3b5b8a5SMatthias Ringwald}
276c3b5b8a5SMatthias Ringwald
27763a4cec0SDirk Helbigparam_iterator_read = {
27863a4cec0SDirk Helbig    '1' : 'return (*iter)[{offset}];',
27963a4cec0SDirk Helbig    '2' : 'return little_endian_read_16(*iter, {offset});',
28063a4cec0SDirk Helbig    'J' : 'return (*iter)[{offset}] + 1;',
28163a4cec0SDirk Helbig    'V' : 'return &((*iter)[{offset}]);',
28263a4cec0SDirk Helbig    open_bracket    : '*iter = &event[{offset}];',
28363a4cec0SDirk Helbig    closing_bracket : ''
28463a4cec0SDirk Helbig}
28563a4cec0SDirk Helbig
28663a4cec0SDirk HelbiglistScope = list()
28763a4cec0SDirk Helbig
28863a4cec0SDirk Helbigdef read_template_for_type(type):
28963a4cec0SDirk Helbig    if listScope:
29063a4cec0SDirk Helbig        return param_iterator_read[type]
29163a4cec0SDirk Helbig    return param_read[type]
29263a4cec0SDirk Helbig
29363a4cec0SDirk Helbigdef description_for_type(type):
29463a4cec0SDirk Helbig    if type == 'C':
29563a4cec0SDirk Helbig        return 'Get element of array field {0} from event {1}'
29663a4cec0SDirk Helbig    if listScope:
29763a4cec0SDirk Helbig        return 'Get element of list field {0} from event {1}'
29863a4cec0SDirk Helbig    return 'Get field {0} from event {1}'
29963a4cec0SDirk Helbig
300c3b5b8a5SMatthias Ringwalddef c_type_for_btstack_type(type):
301c3b5b8a5SMatthias Ringwald    param_types = { '1' : 'uint8_t', '2' : 'uint16_t', '3' : 'uint32_t', '4' : 'uint32_t', 'H' : 'hci_con_handle_t', 'B' : 'bd_addr_t',
30247430bedSMatthias Ringwald                    'D' : 'const uint8_t *', 'E' : 'const uint8_t * ', 'N' : 'const char *' , 'P' : 'const uint8_t *', 'A' : 'const uint8_t *',
303c3b5b8a5SMatthias Ringwald                    'R' : 'const uint8_t *', 'S' : 'const uint8_t *',
30438d9ec05SMatthias Ringwald                    'J' : 'uint8_t', 'L' : 'uint16_t', 'V' : 'const uint8_t *', 'U' : 'BT_UUID',
30575a8e4faSMatthias Ringwald                    'Q' : 'uint8_t *', 'K' : 'uint8_t *',
306313e337bSMatthias Ringwald                    'X' : 'gatt_client_service_t *', 'Y' : 'gatt_client_characteristic_t *', 'Z' : 'gatt_client_characteristic_descriptor_t *',
30763a4cec0SDirk Helbig                    'T' : 'const char *', 'C' : 'uint16_t',
30863a4cec0SDirk Helbig                    open_bracket : 'void', closing_bracket : ''}
309c3b5b8a5SMatthias Ringwald    return param_types[type]
310c3b5b8a5SMatthias Ringwald
311c3b5b8a5SMatthias Ringwalddef size_for_type(type):
31275a8e4faSMatthias Ringwald    param_sizes = { '1' : 1, '2' : 2, '3' : 3, '4' : 4, 'H' : 2, 'B' : 6, 'D' : 8, 'E' : 240, 'N' : 248, 'P' : 16, 'Q':32, 'K':16,
31363a4cec0SDirk Helbig                    'A' : 31, 'S' : -1, 'V': -1, 'J' : 1, 'L' : 2, 'U' : 16, 'X' : 20, 'Y' : 24, 'Z' : 18, 'T':-1, 'C':-1,
31463a4cec0SDirk Helbig                   open_bracket : 0, closing_bracket : 0 }
315c3b5b8a5SMatthias Ringwald    return param_sizes[type]
316c3b5b8a5SMatthias Ringwald
317c3b5b8a5SMatthias Ringwalddef format_function_name(event_name):
3187bd8e93bSMatthias Ringwald    event_name = event_name.lower()
3197bd8e93bSMatthias Ringwald    if 'event' in event_name:
3207bd8e93bSMatthias Ringwald        return event_name;
3217bd8e93bSMatthias Ringwald    return event_name+'_event'
322c3b5b8a5SMatthias Ringwald
323c3b5b8a5SMatthias Ringwalddef template_for_type(field_type):
324c3b5b8a5SMatthias Ringwald    global c_prototoype_simple_return
325c3b5b8a5SMatthias Ringwald    global c_prototoype_struct_return
326396f0845SMatthias Ringwald    global c_prototoype_array_getter
327396f0845SMatthias Ringwald    if field_type == 'C':
328396f0845SMatthias Ringwald        return c_prototoype_array_getter
32963a4cec0SDirk Helbig#    if field_type == open_bracket:
33063a4cec0SDirk Helbig#        return c_prototype_iterator_init
33175a8e4faSMatthias Ringwald    types_with_struct_return = "BKQXYZ"
332c3b5b8a5SMatthias Ringwald    if field_type in types_with_struct_return:
333c3b5b8a5SMatthias Ringwald        return c_prototoype_struct_return
33463a4cec0SDirk Helbig    if listScope:
33563a4cec0SDirk Helbig        return c_prototype_iterator_return;
336c3b5b8a5SMatthias Ringwald    return c_prototoype_simple_return
337c3b5b8a5SMatthias Ringwald
338c3b5b8a5SMatthias Ringwalddef all_fields_supported(format):
339c3b5b8a5SMatthias Ringwald    global param_read
340c3b5b8a5SMatthias Ringwald    for f in format:
341c3b5b8a5SMatthias Ringwald        if not f in param_read:
342c3b5b8a5SMatthias Ringwald            return False
343c3b5b8a5SMatthias Ringwald    return True
344c3b5b8a5SMatthias Ringwald
34563a4cec0SDirk Helbigdef create_iterator( event_name, field_name, field_type, offset, offset_is_number, last_length_field_offset, supported):
34663a4cec0SDirk Helbig    if field_type == open_bracket:
34763a4cec0SDirk Helbig        # list field name, list field start, length field of list ( in bytes ), list elemet size if static
34863a4cec0SDirk Helbig        listScope.append( (field_name, offset, last_length_field_offset, 0) )
34963a4cec0SDirk Helbig    list_name_scope = ''
35063a4cec0SDirk Helbig    list_base = 0
35163a4cec0SDirk Helbig    if listScope:
35263a4cec0SDirk Helbig        list_name_scope = listScope[-1][0]
35363a4cec0SDirk Helbig        list_base = listScope[-1][1]
35463a4cec0SDirk Helbig        list_length_field_offset = listScope[-1][2]
35563a4cec0SDirk Helbig        list_static_size = listScope[-1][3]
35663a4cec0SDirk Helbig
35763a4cec0SDirk Helbig    generated = ''
35863a4cec0SDirk Helbig    if field_type == open_bracket:
35963a4cec0SDirk Helbig        generated_init = c_prototype_iterator_init.format( list_field=offset, scope=list_name_scope,
36063a4cec0SDirk Helbig                                                          event=event_name, field=field_name, format=field_type)
36163a4cec0SDirk Helbig        generated_has_next = c_prototype_iterator_has_next.format( list_field=offset, length_field=last_length_field_offset,
36263a4cec0SDirk Helbig                                                                  format=field_type, scope=list_name_scope, event=event_name,
36363a4cec0SDirk Helbig                                                                  field=field_name )
36463a4cec0SDirk Helbig        generated = generated_init + generated_has_next;
36563a4cec0SDirk Helbig    else:
36663a4cec0SDirk Helbig        # the item length is either determiend statically, format "12"
36763a4cec0SDirk Helbig        # or dynamically by an list element, format "J"
36863a4cec0SDirk Helbig        code = ''
36963a4cec0SDirk Helbig        if list_length_field_offset < last_length_field_offset:
37063a4cec0SDirk Helbig            #dynamic element size
37163a4cec0SDirk Helbig            code = '*iter[{0}] + 1;'.format( last_length_field_offset-list_base )
37263a4cec0SDirk Helbig        else:
37363a4cec0SDirk Helbig            code = '{0};'.format( list_static_size )
37463a4cec0SDirk Helbig        generated = c_prototype_iterator_next.format( event=event_name, scope=list_name_scope, format=field_type, code=code );
37563a4cec0SDirk Helbig
37663a4cec0SDirk Helbig    if field_type == closing_bracket:
37763a4cec0SDirk Helbig        listScope.pop()
37863a4cec0SDirk Helbig    return generated
37963a4cec0SDirk Helbig
38063a4cec0SDirk Helbigdef create_getter(event_name, field_name, field_type, offset, offset_is_number, last_length_field_offset, supported):
381c3b5b8a5SMatthias Ringwald    global c_prototoype_unsupported
382c3b5b8a5SMatthias Ringwald    global param_read
383c3b5b8a5SMatthias Ringwald
38463a4cec0SDirk Helbig    description_template = description_for_type(field_type)
38563a4cec0SDirk Helbig    list_name_scope = ''
38663a4cec0SDirk Helbig    if listScope:
38763a4cec0SDirk Helbig        list_name_scope = listScope[-1][0]
38863a4cec0SDirk Helbig        list_base = listScope[-1][1]
38963a4cec0SDirk Helbig        list_length_field_offset = listScope[-1][2]
39063a4cec0SDirk Helbig        list_static_size = listScope[-1][3]
39163a4cec0SDirk Helbig        if offset_is_number:
39263a4cec0SDirk Helbig            offset = offset - list_base;
39363a4cec0SDirk Helbig        listScope[-1] = (list_name_scope, list_base, list_length_field_offset, list_static_size+size_for_type(field_type))
39463a4cec0SDirk Helbig    description = description_template.format(field_name, event_name.upper())
395c3b5b8a5SMatthias Ringwald    result_name = field_name
396c3b5b8a5SMatthias Ringwald    result_type = c_type_for_btstack_type(field_type)
397c3b5b8a5SMatthias Ringwald    template = c_prototoype_unsupported
398c3b5b8a5SMatthias Ringwald    code = ''
399c3b5b8a5SMatthias Ringwald    if supported and field_type in param_read:
400c3b5b8a5SMatthias Ringwald        template = template_for_type(field_type)
40163a4cec0SDirk Helbig        read_code = read_template_for_type(field_type)
402ca1a07f4SMatthias Ringwald        requires_signed = 'little_endian' in read_code or 'gatt_client_deserialize' in read_code
403b5d69418SMatthias Ringwald        code = ''
404ca1a07f4SMatthias Ringwald        if requires_signed and not offset_is_number:
405e52cfa76SMatthias Ringwald            code += 'uint8_t offset = %s;\n    ' % offset
406e52cfa76SMatthias Ringwald            offset = '(int)(int8_t) offset'
407b5d69418SMatthias Ringwald        code += read_code.format(offset=offset, result_name=result_name)
40863a4cec0SDirk Helbig    return template.format(description=description, scope=list_name_scope, event=event_name, field=field_name, result_name=result_name, result_type=result_type, code=code, format=field_type)
409c3b5b8a5SMatthias Ringwald
410313e337bSMatthias Ringwalddef is_le_event(event_group):
411313e337bSMatthias Ringwald    return event_group in ['GATT', 'ANCS', 'SM']
412313e337bSMatthias Ringwald
413c3b5b8a5SMatthias Ringwalddef create_events(events):
414c3b5b8a5SMatthias Ringwald    global gen_path
415c3b5b8a5SMatthias Ringwald    global copyright
416c3b5b8a5SMatthias Ringwald    global hfile_header_begin
417c3b5b8a5SMatthias Ringwald    global hfile_header_end
4180e2df43fSMatthias Ringwald    global meta_event_template
419c3b5b8a5SMatthias Ringwald
420c3b5b8a5SMatthias Ringwald    with open(gen_path, 'wt') as fout:
421c3b5b8a5SMatthias Ringwald        fout.write(copyright)
422c3b5b8a5SMatthias Ringwald        fout.write(hfile_header_begin)
4230e2df43fSMatthias Ringwald
4240e2df43fSMatthias Ringwald        for meta_event in meta_events:
4250e2df43fSMatthias Ringwald            fout.write(meta_event_template.format(meta_event=meta_event.lower()))
4260e2df43fSMatthias Ringwald
427c3b5b8a5SMatthias Ringwald        for event_type, event_name, format, args in events:
42872b50801SMatthias Ringwald            parts = event_name.split("_")
429313e337bSMatthias Ringwald            event_group = parts[0]
430f1b34e8dSMatthias Ringwald            if not event_group in supported_event_groups:
431a59bfbf7SMatthias Ringwald                print("// %s " % event_name)
4327bd8e93bSMatthias Ringwald                continue
4336397af06SMatthias Ringwald            # print(event_name)
4346397af06SMatthias Ringwald            base_name = format_function_name(event_name)
4354de250b4SMatthias Ringwald            length_name = ''
436c3b5b8a5SMatthias Ringwald            offset = 2
437e222d6a0SMatthias Ringwald            offset_is_number = 1
438e222d6a0SMatthias Ringwald            offset_unknown = 0
439c3b5b8a5SMatthias Ringwald            supported = all_fields_supported(format)
440e222d6a0SMatthias Ringwald            last_variable_length_field_pos = ""
44163a4cec0SDirk Helbig            last_length_field_offset = 0
442313e337bSMatthias Ringwald            if is_le_event(event_group):
443313e337bSMatthias Ringwald                fout.write("#ifdef ENABLE_BLE\n")
4446397af06SMatthias Ringwald            if len(format) != len(args):
4456397af06SMatthias Ringwald                print(event_name.upper())
4466397af06SMatthias Ringwald                print ("Format %s does not match params %s " % (format, args))
4476397af06SMatthias Ringwald                print
448c3b5b8a5SMatthias Ringwald            for f, arg in zip(format, args):
449c3b5b8a5SMatthias Ringwald                field_name = arg
45090944a9aSMatthias Ringwald                if field_name.lower() == 'subevent_code':
45190944a9aSMatthias Ringwald                    offset += 1
45290944a9aSMatthias Ringwald                    continue
453e222d6a0SMatthias Ringwald                if offset_unknown:
454396f0845SMatthias Ringwald                    print("Param after variable length field without preceding 'J' length field")
455e222d6a0SMatthias Ringwald                    break
456c3b5b8a5SMatthias Ringwald                field_type = f
45763a4cec0SDirk Helbig                if field_type in open_bracket + closing_bracket:
45863a4cec0SDirk Helbig                    text = create_iterator( base_name, field_name, field_type, offset, offset_is_number, last_length_field_offset, supported )
45963a4cec0SDirk Helbig                else:
46063a4cec0SDirk Helbig                    text = create_getter(base_name, field_name, field_type, offset, offset_is_number, last_length_field_offset, supported)
461c3b5b8a5SMatthias Ringwald                fout.write(text)
4627bd8e93bSMatthias Ringwald                if field_type in 'RT':
463c3b5b8a5SMatthias Ringwald                    break
464e222d6a0SMatthias Ringwald                if field_type in 'J':
465e222d6a0SMatthias Ringwald                    if offset_is_number:
46663a4cec0SDirk Helbig                        last_length_field_offset = offset
467e222d6a0SMatthias Ringwald                        last_variable_length_field_pos = '%u' % offset
468e222d6a0SMatthias Ringwald                    else:
469e222d6a0SMatthias Ringwald                        last_variable_length_field_pos = offset
470e222d6a0SMatthias Ringwald                if field_type in 'V':
4715c544019SMatthias Ringwald                    if last_variable_length_field_pos != '':
472e222d6a0SMatthias Ringwald                        if offset_is_number:
473e222d6a0SMatthias Ringwald                            # convert to string
4740dd3c6c3SMatthias Ringwald                            offset = '%uu' % offset
475e222d6a0SMatthias Ringwald                            offset_is_number = 0
476e222d6a0SMatthias Ringwald                        offset = offset + ' + event[%s]' % last_variable_length_field_pos
477e222d6a0SMatthias Ringwald                    else:
478e222d6a0SMatthias Ringwald                        offset_unknown = 1
479e222d6a0SMatthias Ringwald                else:
480e222d6a0SMatthias Ringwald                    if offset_is_number:
481c3b5b8a5SMatthias Ringwald                        offset += size_for_type(field_type)
482e222d6a0SMatthias Ringwald                    else:
4830dd3c6c3SMatthias Ringwald                        offset = offset + ' + %uu' % size_for_type(field_type)
484313e337bSMatthias Ringwald            if is_le_event(event_group):
485313e337bSMatthias Ringwald                fout.write("#endif\n")
486313e337bSMatthias Ringwald            fout.write("\n")
487c3b5b8a5SMatthias Ringwald
488c3b5b8a5SMatthias Ringwald        fout.write(hfile_header_end)
489c3b5b8a5SMatthias Ringwald
4909d585a82SMatthias Ringwaldbtstack_root = os.path.abspath(os.path.dirname(sys.argv[0]) + '/..')
4919d585a82SMatthias Ringwaldgen_path = btstack_root + '/src/btstack_event.h'
492c3b5b8a5SMatthias Ringwald
493c3b5b8a5SMatthias Ringwaldprint(program_info)
494c3b5b8a5SMatthias Ringwald
495c3b5b8a5SMatthias Ringwald# parse events
496c3b5b8a5SMatthias Ringwald(events, le_events, event_types) = parser.parse_events()
497c3b5b8a5SMatthias Ringwald# create event field accesors
498c3b5b8a5SMatthias Ringwaldcreate_events(events + le_events)
499c3b5b8a5SMatthias Ringwald
500c3b5b8a5SMatthias Ringwald# done
501c3b5b8a5SMatthias Ringwaldprint('Done!')
502