xref: /btstack/tool/btstack_event_generator.py (revision 63a4cec072210152724610b97cfc41046ea1aab9)
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',
4128e59789SMilanka Ringwald    'SM'
42f1b34e8dSMatthias Ringwald]
43f1b34e8dSMatthias Ringwald
44*63a4cec0SDirk Helbigopen_bracket = parser.open_bracket
45*63a4cec0SDirk Helbigclosing_bracket = parser.closing_bracket
46*63a4cec0SDirk Helbig
47c3b5b8a5SMatthias Ringwaldprogram_info = '''
48c3b5b8a5SMatthias RingwaldBTstack Event Getter Generator for BTstack
49c3b5b8a5SMatthias RingwaldCopyright 2016, BlueKitchen GmbH
50c3b5b8a5SMatthias Ringwald'''
51c3b5b8a5SMatthias Ringwald
52c3b5b8a5SMatthias Ringwaldcopyright = """/*
53c3b5b8a5SMatthias Ringwald * Copyright (C) 2016 BlueKitchen GmbH
54c3b5b8a5SMatthias Ringwald *
55c3b5b8a5SMatthias Ringwald * Redistribution and use in source and binary forms, with or without
56c3b5b8a5SMatthias Ringwald * modification, are permitted provided that the following conditions
57c3b5b8a5SMatthias Ringwald * are met:
58c3b5b8a5SMatthias Ringwald *
59c3b5b8a5SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright
60c3b5b8a5SMatthias Ringwald *    notice, this list of conditions and the following disclaimer.
61c3b5b8a5SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright
62c3b5b8a5SMatthias Ringwald *    notice, this list of conditions and the following disclaimer in the
63c3b5b8a5SMatthias Ringwald *    documentation and/or other materials provided with the distribution.
64c3b5b8a5SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of
65c3b5b8a5SMatthias Ringwald *    contributors may be used to endorse or promote products derived
66c3b5b8a5SMatthias Ringwald *    from this software without specific prior written permission.
67c3b5b8a5SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for
68c3b5b8a5SMatthias Ringwald *    personal benefit and not for any commercial purpose or for
69c3b5b8a5SMatthias Ringwald *    monetary gain.
70c3b5b8a5SMatthias Ringwald *
71c3b5b8a5SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
72c3b5b8a5SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
73c3b5b8a5SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
74b5c62b37SMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
75b5c62b37SMilanka Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
76c3b5b8a5SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
77c3b5b8a5SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
78c3b5b8a5SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
79c3b5b8a5SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
80c3b5b8a5SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
81c3b5b8a5SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
82c3b5b8a5SMatthias Ringwald * SUCH DAMAGE.
83c3b5b8a5SMatthias Ringwald *
84c3b5b8a5SMatthias Ringwald * Please inquire about commercial licensing options at
85c3b5b8a5SMatthias Ringwald * [email protected]
86c3b5b8a5SMatthias Ringwald *
87c3b5b8a5SMatthias Ringwald */
88c3b5b8a5SMatthias Ringwald"""
89c3b5b8a5SMatthias Ringwald
90c3b5b8a5SMatthias Ringwaldhfile_header_begin = """
91c3b5b8a5SMatthias Ringwald
922026696cSMatthias Ringwald/**
932026696cSMatthias Ringwald * HCI Event Getter
94c3b5b8a5SMatthias Ringwald *
952026696cSMatthias Ringwald * Note: Don't edit this file. It is generated by tool/btstack_event_generator.py
96c3b5b8a5SMatthias Ringwald *
97c3b5b8a5SMatthias Ringwald */
98c3b5b8a5SMatthias Ringwald
9980e33422SMatthias Ringwald#ifndef BTSTACK_EVENT_H
10080e33422SMatthias Ringwald#define BTSTACK_EVENT_H
101c3b5b8a5SMatthias Ringwald
102c3b5b8a5SMatthias Ringwald#if defined __cplusplus
103c3b5b8a5SMatthias Ringwaldextern "C" {
104c3b5b8a5SMatthias Ringwald#endif
105c3b5b8a5SMatthias Ringwald
106c3b5b8a5SMatthias Ringwald#include "btstack_util.h"
107c3b5b8a5SMatthias Ringwald#include <stdint.h>
108c3b5b8a5SMatthias Ringwald
109313e337bSMatthias Ringwald#ifdef ENABLE_BLE
110313e337bSMatthias Ringwald#include "ble/gatt_client.h"
111313e337bSMatthias Ringwald#endif
112313e337bSMatthias Ringwald
113c3b5b8a5SMatthias Ringwald/* API_START */
114c3b5b8a5SMatthias Ringwald
1150e2df43fSMatthias Ringwald/**
1160e2df43fSMatthias Ringwald * @brief Get event type
1170e2df43fSMatthias Ringwald * @param event
1180e2df43fSMatthias Ringwald * @return type of event
1190e2df43fSMatthias Ringwald */
1200e2df43fSMatthias Ringwaldstatic inline uint8_t hci_event_packet_get_type(const uint8_t * event){
1210e2df43fSMatthias Ringwald    return event[0];
1220e2df43fSMatthias Ringwald}
1230e2df43fSMatthias Ringwald
124*63a4cec0SDirk Helbigtypedef uint8_t* btstack_event_iterator_t;
125*63a4cec0SDirk Helbig
126c3b5b8a5SMatthias Ringwald"""
127c3b5b8a5SMatthias Ringwald
128c3b5b8a5SMatthias Ringwaldhfile_header_end = """
129c3b5b8a5SMatthias Ringwald
130c3b5b8a5SMatthias Ringwald/* API_END */
131c3b5b8a5SMatthias Ringwald
132c3b5b8a5SMatthias Ringwald#if defined __cplusplus
133c3b5b8a5SMatthias Ringwald}
134c3b5b8a5SMatthias Ringwald#endif
135c3b5b8a5SMatthias Ringwald
13680e33422SMatthias Ringwald#endif // BTSTACK_EVENT_H
137c3b5b8a5SMatthias Ringwald"""
138c3b5b8a5SMatthias Ringwald
139313e337bSMatthias Ringwaldc_prototoype_simple_return = '''/**
140c3b5b8a5SMatthias Ringwald * @brief {description}
1410e2df43fSMatthias Ringwald * @param event packet
142c3b5b8a5SMatthias Ringwald * @return {result_name}
143c3b5b8a5SMatthias Ringwald * @note: btstack_type {format}
144c3b5b8a5SMatthias Ringwald */
145*63a4cec0SDirk Helbigstatic inline {result_type} {event}_get_{field}(const uint8_t * event){{
146c3b5b8a5SMatthias Ringwald    {code}
147c3b5b8a5SMatthias Ringwald}}
148c3b5b8a5SMatthias Ringwald'''
149c3b5b8a5SMatthias Ringwald
150*63a4cec0SDirk Helbigc_prototype_iterator_return = '''/**
151*63a4cec0SDirk Helbig * @brief {description}
152*63a4cec0SDirk Helbig * @param event packet
153*63a4cec0SDirk Helbig * @return {result_name}
154*63a4cec0SDirk Helbig * @note: btstack_type {format}
155*63a4cec0SDirk Helbig */
156*63a4cec0SDirk Helbigstatic inline {result_type} {event}_get_{scope}_item_{field}(btstack_event_iterator_t * iter){{
157*63a4cec0SDirk Helbig    {code}
158*63a4cec0SDirk Helbig}}
159*63a4cec0SDirk Helbig'''
160*63a4cec0SDirk Helbig
161*63a4cec0SDirk Helbigc_prototype_iterator_init = '''/**
162*63a4cec0SDirk Helbig * @brief Initialize iterator for list {scope} of {event}
163*63a4cec0SDirk Helbig * @param iterator
164*63a4cec0SDirk Helbig * @param event packet
165*63a4cec0SDirk Helbig * @note: btstack_type {format}
166*63a4cec0SDirk Helbig */
167*63a4cec0SDirk Helbigstatic inline void {event}_{field}_init(btstack_event_iterator_t * iter, const uint8_t * event){{
168*63a4cec0SDirk Helbig    *iter = (btstack_event_iterator_t)&event[{list_field}];
169*63a4cec0SDirk Helbig}}
170*63a4cec0SDirk Helbig
171*63a4cec0SDirk Helbig'''
172*63a4cec0SDirk Helbig
173*63a4cec0SDirk Helbigc_prototype_iterator_has_next = '''/**
174*63a4cec0SDirk Helbig * @brief Returns true if iterator of list {scope} of {event} has more elements, false otherwise.
175*63a4cec0SDirk Helbig * @param iterator
176*63a4cec0SDirk Helbig * @param event packet
177*63a4cec0SDirk Helbig * @return
178*63a4cec0SDirk Helbig * @note: btstack_type {format}
179*63a4cec0SDirk Helbig */
180*63a4cec0SDirk Helbigstatic inline bool {event}_{field}_has_next(btstack_event_iterator_t * iter, const uint8_t * event){{
181*63a4cec0SDirk Helbig    uint8_t length = event[{length_field}];
182*63a4cec0SDirk Helbig    const uint8_t *begin = &event[{list_field}];
183*63a4cec0SDirk Helbig    const uint8_t *end = begin+length;
184*63a4cec0SDirk Helbig    return *iter<end;
185*63a4cec0SDirk Helbig}}
186*63a4cec0SDirk Helbig
187*63a4cec0SDirk Helbig'''
188*63a4cec0SDirk Helbig
189*63a4cec0SDirk Helbigc_prototype_iterator_next = '''/**
190*63a4cec0SDirk Helbig * @brief Advances the iterator to the next element
191*63a4cec0SDirk Helbig * @param event packet
192*63a4cec0SDirk Helbig * @note: btstack_type {format}
193*63a4cec0SDirk Helbig */
194*63a4cec0SDirk Helbigstatic inline void {event}_{scope}_next(btstack_event_iterator_t * iter){{
195*63a4cec0SDirk Helbig    uint8_t length = {code}
196*63a4cec0SDirk Helbig    *iter = *iter+length;
197*63a4cec0SDirk Helbig}}
198*63a4cec0SDirk Helbig
199*63a4cec0SDirk Helbig'''
200*63a4cec0SDirk Helbig
201396f0845SMatthias Ringwaldc_prototoype_array_getter = '''/**
202396f0845SMatthias Ringwald * @brief {description}
203396f0845SMatthias Ringwald * @param event packet
204396f0845SMatthias Ringwald * @param index
205396f0845SMatthias Ringwald * @return {result_name}
206396f0845SMatthias Ringwald * @note: btstack_type {format}
207396f0845SMatthias Ringwald */
208*63a4cec0SDirk Helbigstatic inline {result_type} {event}_get_{field}(const uint8_t * event, uint8_t index){{
209396f0845SMatthias Ringwald    {code}
210396f0845SMatthias Ringwald}}
211396f0845SMatthias Ringwald'''
212396f0845SMatthias Ringwald
213313e337bSMatthias Ringwaldc_prototoype_struct_return = '''/**
214c3b5b8a5SMatthias Ringwald * @brief {description}
2150e2df43fSMatthias Ringwald * @param event packet
216c3b5b8a5SMatthias Ringwald * @param Pointer to storage for {result_name}
217c3b5b8a5SMatthias Ringwald * @note: btstack_type {format}
218c3b5b8a5SMatthias Ringwald */
219*63a4cec0SDirk Helbigstatic inline void {event}_get_{field}(const uint8_t * event, {result_type} {result_name}){{
220c3b5b8a5SMatthias Ringwald    {code}
221c3b5b8a5SMatthias Ringwald}}
222c3b5b8a5SMatthias Ringwald'''
223c3b5b8a5SMatthias Ringwald
224313e337bSMatthias Ringwaldc_prototoype_unsupported = '''/**
225c3b5b8a5SMatthias Ringwald * @brief {description}
2260e2df43fSMatthias Ringwald * @param event packet
227c3b5b8a5SMatthias Ringwald * @return {result_name}
228c3b5b8a5SMatthias Ringwald * @note: btstack_type {format}
229c3b5b8a5SMatthias Ringwald */
230*63a4cec0SDirk Helbig//  static inline {result_type} {event}_get_{field}(const uint8_t * event){{
231c3b5b8a5SMatthias Ringwald//      not implemented yet
232c3b5b8a5SMatthias Ringwald//  }}
233c3b5b8a5SMatthias Ringwald'''
234c3b5b8a5SMatthias Ringwald
2350e2df43fSMatthias Ringwaldmeta_event_template = '''/***
2360e2df43fSMatthias Ringwald * @brief Get subevent code for {meta_event} event
2370e2df43fSMatthias Ringwald * @param event packet
2380e2df43fSMatthias Ringwald * @return subevent_code
2390e2df43fSMatthias Ringwald */
2400e2df43fSMatthias Ringwaldstatic inline uint8_t hci_event_{meta_event}_meta_get_subevent_code(const uint8_t * event){{
2410e2df43fSMatthias Ringwald    return event[2];
2420e2df43fSMatthias Ringwald}}
2430e2df43fSMatthias Ringwald'''
2440e2df43fSMatthias Ringwald
245*63a4cec0SDirk Helbig
246c3b5b8a5SMatthias Ringwald# global variables/defines
247c3b5b8a5SMatthias Ringwalddefines = dict()
248c3b5b8a5SMatthias Ringwalddefines_used = set()
249c3b5b8a5SMatthias Ringwald
250c3b5b8a5SMatthias Ringwaldparam_read = {
251c3b5b8a5SMatthias Ringwald    '1' : 'return event[{offset}];',
252c3b5b8a5SMatthias Ringwald    'J' : 'return event[{offset}];',
253f8fbdce0SMatthias Ringwald    '2' : 'return little_endian_read_16(event, {offset});',
254f8fbdce0SMatthias Ringwald    'L' : 'return little_endian_read_16(event, {offset});',
255f8fbdce0SMatthias Ringwald    '3' : 'return little_endian_read_24(event, {offset});',
256f8fbdce0SMatthias Ringwald    '4' : 'return little_endian_read_32(event, {offset});',
257f8fbdce0SMatthias Ringwald    'H' : 'return little_endian_read_16(event, {offset});',
258b1dcf9d8SMatthias Ringwald    'B' : 'reverse_bytes(&event[{offset}], {result_name}, 6);',
2597bd8e93bSMatthias Ringwald    'R' : 'return &event[{offset}];',
26047430bedSMatthias Ringwald    'N' : 'return (const char *) &event[{offset}];',
2611707474dSSimon Budig    'P' : 'return (const uint8_t *) &event[{offset}];',
2624de250b4SMatthias Ringwald    'T' : 'return (const char *) &event[{offset}];',
2638ba9588fSMatthias Ringwald    'D' : 'return (const uint8_t *) &event[{offset}];',
26475a8e4faSMatthias Ringwald    'K' : 'reverse_bytes(&event[{offset}], {result_name}, 16);',
26582180fcaSMatthias Ringwald    'Q' : 'reverse_bytes(&event[{offset}], {result_name}, 32);',
2664de250b4SMatthias Ringwald    'V' : 'return &event[{offset}];',
267313e337bSMatthias Ringwald    'X' : 'gatt_client_deserialize_service(event, {offset}, {result_name});',
268313e337bSMatthias Ringwald    'Y' : 'gatt_client_deserialize_characteristic(event, {offset}, {result_name});',
269313e337bSMatthias Ringwald    'Z' : 'gatt_client_deserialize_characteristic_descriptor(event, {offset}, {result_name});',
27047430bedSMatthias Ringwald    'V' : 'return &event[{offset}];',
271*63a4cec0SDirk Helbig    'C' : 'return little_endian_read_16(event, {offset} + (2 * (int) index));',
272*63a4cec0SDirk Helbig    open_bracket    : 'dummy',
273*63a4cec0SDirk Helbig    closing_bracket : 'dummy',
274c3b5b8a5SMatthias Ringwald}
275c3b5b8a5SMatthias Ringwald
276*63a4cec0SDirk Helbigparam_iterator_read = {
277*63a4cec0SDirk Helbig    '1' : 'return (*iter)[{offset}];',
278*63a4cec0SDirk Helbig    '2' : 'return little_endian_read_16(*iter, {offset});',
279*63a4cec0SDirk Helbig    'J' : 'return (*iter)[{offset}] + 1;',
280*63a4cec0SDirk Helbig    'V' : 'return &((*iter)[{offset}]);',
281*63a4cec0SDirk Helbig    open_bracket    : '*iter = &event[{offset}];',
282*63a4cec0SDirk Helbig    closing_bracket : ''
283*63a4cec0SDirk Helbig}
284*63a4cec0SDirk Helbig
285*63a4cec0SDirk HelbiglistScope = list()
286*63a4cec0SDirk Helbig
287*63a4cec0SDirk Helbigdef read_template_for_type(type):
288*63a4cec0SDirk Helbig    if listScope:
289*63a4cec0SDirk Helbig        return param_iterator_read[type]
290*63a4cec0SDirk Helbig    return param_read[type]
291*63a4cec0SDirk Helbig
292*63a4cec0SDirk Helbigdef description_for_type(type):
293*63a4cec0SDirk Helbig    if type == 'C':
294*63a4cec0SDirk Helbig        return 'Get element of array field {0} from event {1}'
295*63a4cec0SDirk Helbig    if listScope:
296*63a4cec0SDirk Helbig        return 'Get element of list field {0} from event {1}'
297*63a4cec0SDirk Helbig    return 'Get field {0} from event {1}'
298*63a4cec0SDirk Helbig
299c3b5b8a5SMatthias Ringwalddef c_type_for_btstack_type(type):
300c3b5b8a5SMatthias Ringwald    param_types = { '1' : 'uint8_t', '2' : 'uint16_t', '3' : 'uint32_t', '4' : 'uint32_t', 'H' : 'hci_con_handle_t', 'B' : 'bd_addr_t',
30147430bedSMatthias Ringwald                    'D' : 'const uint8_t *', 'E' : 'const uint8_t * ', 'N' : 'const char *' , 'P' : 'const uint8_t *', 'A' : 'const uint8_t *',
302c3b5b8a5SMatthias Ringwald                    'R' : 'const uint8_t *', 'S' : 'const uint8_t *',
30338d9ec05SMatthias Ringwald                    'J' : 'uint8_t', 'L' : 'uint16_t', 'V' : 'const uint8_t *', 'U' : 'BT_UUID',
30475a8e4faSMatthias Ringwald                    'Q' : 'uint8_t *', 'K' : 'uint8_t *',
305313e337bSMatthias Ringwald                    'X' : 'gatt_client_service_t *', 'Y' : 'gatt_client_characteristic_t *', 'Z' : 'gatt_client_characteristic_descriptor_t *',
306*63a4cec0SDirk Helbig                    'T' : 'const char *', 'C' : 'uint16_t',
307*63a4cec0SDirk Helbig                    open_bracket : 'void', closing_bracket : ''}
308c3b5b8a5SMatthias Ringwald    return param_types[type]
309c3b5b8a5SMatthias Ringwald
310c3b5b8a5SMatthias Ringwalddef size_for_type(type):
31175a8e4faSMatthias 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,
312*63a4cec0SDirk Helbig                    'A' : 31, 'S' : -1, 'V': -1, 'J' : 1, 'L' : 2, 'U' : 16, 'X' : 20, 'Y' : 24, 'Z' : 18, 'T':-1, 'C':-1,
313*63a4cec0SDirk Helbig                   open_bracket : 0, closing_bracket : 0 }
314c3b5b8a5SMatthias Ringwald    return param_sizes[type]
315c3b5b8a5SMatthias Ringwald
316c3b5b8a5SMatthias Ringwalddef format_function_name(event_name):
3177bd8e93bSMatthias Ringwald    event_name = event_name.lower()
3187bd8e93bSMatthias Ringwald    if 'event' in event_name:
3197bd8e93bSMatthias Ringwald        return event_name;
3207bd8e93bSMatthias Ringwald    return event_name+'_event'
321c3b5b8a5SMatthias Ringwald
322c3b5b8a5SMatthias Ringwalddef template_for_type(field_type):
323c3b5b8a5SMatthias Ringwald    global c_prototoype_simple_return
324c3b5b8a5SMatthias Ringwald    global c_prototoype_struct_return
325396f0845SMatthias Ringwald    global c_prototoype_array_getter
326396f0845SMatthias Ringwald    if field_type == 'C':
327396f0845SMatthias Ringwald        return c_prototoype_array_getter
328*63a4cec0SDirk Helbig#    if field_type == open_bracket:
329*63a4cec0SDirk Helbig#        return c_prototype_iterator_init
33075a8e4faSMatthias Ringwald    types_with_struct_return = "BKQXYZ"
331c3b5b8a5SMatthias Ringwald    if field_type in types_with_struct_return:
332c3b5b8a5SMatthias Ringwald        return c_prototoype_struct_return
333*63a4cec0SDirk Helbig    if listScope:
334*63a4cec0SDirk Helbig        return c_prototype_iterator_return;
335c3b5b8a5SMatthias Ringwald    return c_prototoype_simple_return
336c3b5b8a5SMatthias Ringwald
337c3b5b8a5SMatthias Ringwalddef all_fields_supported(format):
338c3b5b8a5SMatthias Ringwald    global param_read
339c3b5b8a5SMatthias Ringwald    for f in format:
340c3b5b8a5SMatthias Ringwald        if not f in param_read:
341c3b5b8a5SMatthias Ringwald            return False
342c3b5b8a5SMatthias Ringwald    return True
343c3b5b8a5SMatthias Ringwald
344*63a4cec0SDirk Helbigdef create_iterator( event_name, field_name, field_type, offset, offset_is_number, last_length_field_offset, supported):
345*63a4cec0SDirk Helbig    if field_type == open_bracket:
346*63a4cec0SDirk Helbig        # list field name, list field start, length field of list ( in bytes ), list elemet size if static
347*63a4cec0SDirk Helbig        listScope.append( (field_name, offset, last_length_field_offset, 0) )
348*63a4cec0SDirk Helbig    list_name_scope = ''
349*63a4cec0SDirk Helbig    list_base = 0
350*63a4cec0SDirk Helbig    if listScope:
351*63a4cec0SDirk Helbig        list_name_scope = listScope[-1][0]
352*63a4cec0SDirk Helbig        list_base = listScope[-1][1]
353*63a4cec0SDirk Helbig        list_length_field_offset = listScope[-1][2]
354*63a4cec0SDirk Helbig        list_static_size = listScope[-1][3]
355*63a4cec0SDirk Helbig
356*63a4cec0SDirk Helbig    generated = ''
357*63a4cec0SDirk Helbig    if field_type == open_bracket:
358*63a4cec0SDirk Helbig        generated_init = c_prototype_iterator_init.format( list_field=offset, scope=list_name_scope,
359*63a4cec0SDirk Helbig                                                          event=event_name, field=field_name, format=field_type)
360*63a4cec0SDirk Helbig        generated_has_next = c_prototype_iterator_has_next.format( list_field=offset, length_field=last_length_field_offset,
361*63a4cec0SDirk Helbig                                                                  format=field_type, scope=list_name_scope, event=event_name,
362*63a4cec0SDirk Helbig                                                                  field=field_name )
363*63a4cec0SDirk Helbig        generated = generated_init + generated_has_next;
364*63a4cec0SDirk Helbig    else:
365*63a4cec0SDirk Helbig        # the item length is either determiend statically, format "12"
366*63a4cec0SDirk Helbig        # or dynamically by an list element, format "J"
367*63a4cec0SDirk Helbig        code = ''
368*63a4cec0SDirk Helbig        if list_length_field_offset < last_length_field_offset:
369*63a4cec0SDirk Helbig            #dynamic element size
370*63a4cec0SDirk Helbig            code = '*iter[{0}] + 1;'.format( last_length_field_offset-list_base )
371*63a4cec0SDirk Helbig        else:
372*63a4cec0SDirk Helbig            code = '{0};'.format( list_static_size )
373*63a4cec0SDirk Helbig        generated = c_prototype_iterator_next.format( event=event_name, scope=list_name_scope, format=field_type, code=code );
374*63a4cec0SDirk Helbig
375*63a4cec0SDirk Helbig    if field_type == closing_bracket:
376*63a4cec0SDirk Helbig        listScope.pop()
377*63a4cec0SDirk Helbig    return generated
378*63a4cec0SDirk Helbig
379*63a4cec0SDirk Helbigdef create_getter(event_name, field_name, field_type, offset, offset_is_number, last_length_field_offset, supported):
380c3b5b8a5SMatthias Ringwald    global c_prototoype_unsupported
381c3b5b8a5SMatthias Ringwald    global param_read
382c3b5b8a5SMatthias Ringwald
383*63a4cec0SDirk Helbig    description_template = description_for_type(field_type)
384*63a4cec0SDirk Helbig    list_name_scope = ''
385*63a4cec0SDirk Helbig    if listScope:
386*63a4cec0SDirk Helbig        list_name_scope = listScope[-1][0]
387*63a4cec0SDirk Helbig        list_base = listScope[-1][1]
388*63a4cec0SDirk Helbig        list_length_field_offset = listScope[-1][2]
389*63a4cec0SDirk Helbig        list_static_size = listScope[-1][3]
390*63a4cec0SDirk Helbig        if offset_is_number:
391*63a4cec0SDirk Helbig            offset = offset - list_base;
392*63a4cec0SDirk Helbig        listScope[-1] = (list_name_scope, list_base, list_length_field_offset, list_static_size+size_for_type(field_type))
393*63a4cec0SDirk Helbig    description = description_template.format(field_name, event_name.upper())
394c3b5b8a5SMatthias Ringwald    result_name = field_name
395c3b5b8a5SMatthias Ringwald    result_type = c_type_for_btstack_type(field_type)
396c3b5b8a5SMatthias Ringwald    template = c_prototoype_unsupported
397c3b5b8a5SMatthias Ringwald    code = ''
398c3b5b8a5SMatthias Ringwald    if supported and field_type in param_read:
399c3b5b8a5SMatthias Ringwald        template = template_for_type(field_type)
400*63a4cec0SDirk Helbig        read_code = read_template_for_type(field_type)
401ca1a07f4SMatthias Ringwald        requires_signed = 'little_endian' in read_code or 'gatt_client_deserialize' in read_code
402b5d69418SMatthias Ringwald        code = ''
403ca1a07f4SMatthias Ringwald        if requires_signed and not offset_is_number:
404e52cfa76SMatthias Ringwald            code += 'uint8_t offset = %s;\n    ' % offset
405e52cfa76SMatthias Ringwald            offset = '(int)(int8_t) offset'
406b5d69418SMatthias Ringwald        code += read_code.format(offset=offset, result_name=result_name)
407*63a4cec0SDirk 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)
408c3b5b8a5SMatthias Ringwald
409313e337bSMatthias Ringwalddef is_le_event(event_group):
410313e337bSMatthias Ringwald    return event_group in ['GATT', 'ANCS', 'SM']
411313e337bSMatthias Ringwald
412c3b5b8a5SMatthias Ringwalddef create_events(events):
413c3b5b8a5SMatthias Ringwald    global gen_path
414c3b5b8a5SMatthias Ringwald    global copyright
415c3b5b8a5SMatthias Ringwald    global hfile_header_begin
416c3b5b8a5SMatthias Ringwald    global hfile_header_end
4170e2df43fSMatthias Ringwald    global meta_event_template
418c3b5b8a5SMatthias Ringwald
419c3b5b8a5SMatthias Ringwald    with open(gen_path, 'wt') as fout:
420c3b5b8a5SMatthias Ringwald        fout.write(copyright)
421c3b5b8a5SMatthias Ringwald        fout.write(hfile_header_begin)
4220e2df43fSMatthias Ringwald
4230e2df43fSMatthias Ringwald        for meta_event in meta_events:
4240e2df43fSMatthias Ringwald            fout.write(meta_event_template.format(meta_event=meta_event.lower()))
4250e2df43fSMatthias Ringwald
426c3b5b8a5SMatthias Ringwald        for event_type, event_name, format, args in events:
42772b50801SMatthias Ringwald            parts = event_name.split("_")
428313e337bSMatthias Ringwald            event_group = parts[0]
429f1b34e8dSMatthias Ringwald            if not event_group in supported_event_groups:
430a59bfbf7SMatthias Ringwald                print("// %s " % event_name)
4317bd8e93bSMatthias Ringwald                continue
4326397af06SMatthias Ringwald            # print(event_name)
4336397af06SMatthias Ringwald            base_name = format_function_name(event_name)
4344de250b4SMatthias Ringwald            length_name = ''
435c3b5b8a5SMatthias Ringwald            offset = 2
436e222d6a0SMatthias Ringwald            offset_is_number = 1
437e222d6a0SMatthias Ringwald            offset_unknown = 0
438c3b5b8a5SMatthias Ringwald            supported = all_fields_supported(format)
439e222d6a0SMatthias Ringwald            last_variable_length_field_pos = ""
440*63a4cec0SDirk Helbig            last_length_field_offset = 0
441313e337bSMatthias Ringwald            if is_le_event(event_group):
442313e337bSMatthias Ringwald                fout.write("#ifdef ENABLE_BLE\n")
4436397af06SMatthias Ringwald            if len(format) != len(args):
4446397af06SMatthias Ringwald                print(event_name.upper())
4456397af06SMatthias Ringwald                print ("Format %s does not match params %s " % (format, args))
4466397af06SMatthias Ringwald                print
447c3b5b8a5SMatthias Ringwald            for f, arg in zip(format, args):
448c3b5b8a5SMatthias Ringwald                field_name = arg
44990944a9aSMatthias Ringwald                if field_name.lower() == 'subevent_code':
45090944a9aSMatthias Ringwald                    offset += 1
45190944a9aSMatthias Ringwald                    continue
452e222d6a0SMatthias Ringwald                if offset_unknown:
453396f0845SMatthias Ringwald                    print("Param after variable length field without preceding 'J' length field")
454e222d6a0SMatthias Ringwald                    break
455c3b5b8a5SMatthias Ringwald                field_type = f
456*63a4cec0SDirk Helbig                if field_type in open_bracket + closing_bracket:
457*63a4cec0SDirk Helbig                    text = create_iterator( base_name, field_name, field_type, offset, offset_is_number, last_length_field_offset, supported )
458*63a4cec0SDirk Helbig                else:
459*63a4cec0SDirk Helbig                    text = create_getter(base_name, field_name, field_type, offset, offset_is_number, last_length_field_offset, supported)
460c3b5b8a5SMatthias Ringwald                fout.write(text)
4617bd8e93bSMatthias Ringwald                if field_type in 'RT':
462c3b5b8a5SMatthias Ringwald                    break
463e222d6a0SMatthias Ringwald                if field_type in 'J':
464e222d6a0SMatthias Ringwald                    if offset_is_number:
465*63a4cec0SDirk Helbig                        last_length_field_offset = offset
466e222d6a0SMatthias Ringwald                        last_variable_length_field_pos = '%u' % offset
467e222d6a0SMatthias Ringwald                    else:
468e222d6a0SMatthias Ringwald                        last_variable_length_field_pos = offset
469e222d6a0SMatthias Ringwald                if field_type in 'V':
4705c544019SMatthias Ringwald                    if last_variable_length_field_pos != '':
471e222d6a0SMatthias Ringwald                        if offset_is_number:
472e222d6a0SMatthias Ringwald                            # convert to string
4730dd3c6c3SMatthias Ringwald                            offset = '%uu' % offset
474e222d6a0SMatthias Ringwald                            offset_is_number = 0
475e222d6a0SMatthias Ringwald                        offset = offset + ' + event[%s]' % last_variable_length_field_pos
476e222d6a0SMatthias Ringwald                    else:
477e222d6a0SMatthias Ringwald                        offset_unknown = 1
478e222d6a0SMatthias Ringwald                else:
479e222d6a0SMatthias Ringwald                    if offset_is_number:
480c3b5b8a5SMatthias Ringwald                        offset += size_for_type(field_type)
481e222d6a0SMatthias Ringwald                    else:
4820dd3c6c3SMatthias Ringwald                        offset = offset + ' + %uu' % size_for_type(field_type)
483313e337bSMatthias Ringwald            if is_le_event(event_group):
484313e337bSMatthias Ringwald                fout.write("#endif\n")
485313e337bSMatthias Ringwald            fout.write("\n")
486c3b5b8a5SMatthias Ringwald
487c3b5b8a5SMatthias Ringwald        fout.write(hfile_header_end)
488c3b5b8a5SMatthias Ringwald
4899d585a82SMatthias Ringwaldbtstack_root = os.path.abspath(os.path.dirname(sys.argv[0]) + '/..')
4909d585a82SMatthias Ringwaldgen_path = btstack_root + '/src/btstack_event.h'
491c3b5b8a5SMatthias Ringwald
492c3b5b8a5SMatthias Ringwaldprint(program_info)
493c3b5b8a5SMatthias Ringwald
494c3b5b8a5SMatthias Ringwald# parse events
495c3b5b8a5SMatthias Ringwald(events, le_events, event_types) = parser.parse_events()
496c3b5b8a5SMatthias Ringwald# create event field accesors
497c3b5b8a5SMatthias Ringwaldcreate_events(events + le_events)
498c3b5b8a5SMatthias Ringwald
499c3b5b8a5SMatthias Ringwald# done
500c3b5b8a5SMatthias Ringwaldprint('Done!')
501