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