1*c3b5b8a5SMatthias Ringwald#!/usr/bin/env python 2*c3b5b8a5SMatthias Ringwald# BlueKitchen GmbH (c) 2014 3*c3b5b8a5SMatthias Ringwald 4*c3b5b8a5SMatthias Ringwaldimport glob 5*c3b5b8a5SMatthias Ringwaldimport re 6*c3b5b8a5SMatthias Ringwaldimport sys 7*c3b5b8a5SMatthias Ringwaldimport os 8*c3b5b8a5SMatthias Ringwald 9*c3b5b8a5SMatthias Ringwaldimport btstack_parser as parser 10*c3b5b8a5SMatthias Ringwald 11*c3b5b8a5SMatthias Ringwaldprogram_info = ''' 12*c3b5b8a5SMatthias RingwaldBTstack Event Getter Generator for BTstack 13*c3b5b8a5SMatthias RingwaldCopyright 2016, BlueKitchen GmbH 14*c3b5b8a5SMatthias Ringwald''' 15*c3b5b8a5SMatthias Ringwald 16*c3b5b8a5SMatthias Ringwaldcopyright = """/* 17*c3b5b8a5SMatthias Ringwald * Copyright (C) 2016 BlueKitchen GmbH 18*c3b5b8a5SMatthias Ringwald * 19*c3b5b8a5SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 20*c3b5b8a5SMatthias Ringwald * modification, are permitted provided that the following conditions 21*c3b5b8a5SMatthias Ringwald * are met: 22*c3b5b8a5SMatthias Ringwald * 23*c3b5b8a5SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 24*c3b5b8a5SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 25*c3b5b8a5SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 26*c3b5b8a5SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 27*c3b5b8a5SMatthias Ringwald * documentation and/or other materials provided with the distribution. 28*c3b5b8a5SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 29*c3b5b8a5SMatthias Ringwald * contributors may be used to endorse or promote products derived 30*c3b5b8a5SMatthias Ringwald * from this software without specific prior written permission. 31*c3b5b8a5SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 32*c3b5b8a5SMatthias Ringwald * personal benefit and not for any commercial purpose or for 33*c3b5b8a5SMatthias Ringwald * monetary gain. 34*c3b5b8a5SMatthias Ringwald * 35*c3b5b8a5SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 36*c3b5b8a5SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37*c3b5b8a5SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 38*c3b5b8a5SMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 39*c3b5b8a5SMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 40*c3b5b8a5SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 41*c3b5b8a5SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 42*c3b5b8a5SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 43*c3b5b8a5SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 44*c3b5b8a5SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 45*c3b5b8a5SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 46*c3b5b8a5SMatthias Ringwald * SUCH DAMAGE. 47*c3b5b8a5SMatthias Ringwald * 48*c3b5b8a5SMatthias Ringwald * Please inquire about commercial licensing options at 49*c3b5b8a5SMatthias Ringwald * [email protected] 50*c3b5b8a5SMatthias Ringwald * 51*c3b5b8a5SMatthias Ringwald */ 52*c3b5b8a5SMatthias Ringwald""" 53*c3b5b8a5SMatthias Ringwald 54*c3b5b8a5SMatthias Ringwaldhfile_header_begin = """ 55*c3b5b8a5SMatthias Ringwald 56*c3b5b8a5SMatthias Ringwald/* 57*c3b5b8a5SMatthias Ringwald * btstack_event.h 58*c3b5b8a5SMatthias Ringwald * 59*c3b5b8a5SMatthias Ringwald * @brief BTstack event getter/setter 60*c3b5b8a5SMatthias Ringwald * @note Don't edit - generated by tool/btstack_event_generator.py 61*c3b5b8a5SMatthias Ringwald * 62*c3b5b8a5SMatthias Ringwald */ 63*c3b5b8a5SMatthias Ringwald 64*c3b5b8a5SMatthias Ringwald#ifndef __BTSTACK_EVENT_H 65*c3b5b8a5SMatthias Ringwald#define __BTSTACK_EVENT_H 66*c3b5b8a5SMatthias Ringwald 67*c3b5b8a5SMatthias Ringwald#if defined __cplusplus 68*c3b5b8a5SMatthias Ringwaldextern "C" { 69*c3b5b8a5SMatthias Ringwald#endif 70*c3b5b8a5SMatthias Ringwald 71*c3b5b8a5SMatthias Ringwald#include "btstack_util.h" 72*c3b5b8a5SMatthias Ringwald#include <stdint.h> 73*c3b5b8a5SMatthias Ringwald 74*c3b5b8a5SMatthias Ringwald/* API_START */ 75*c3b5b8a5SMatthias Ringwald 76*c3b5b8a5SMatthias Ringwald""" 77*c3b5b8a5SMatthias Ringwald 78*c3b5b8a5SMatthias Ringwaldhfile_header_end = """ 79*c3b5b8a5SMatthias Ringwald 80*c3b5b8a5SMatthias Ringwald/* API_END */ 81*c3b5b8a5SMatthias Ringwald 82*c3b5b8a5SMatthias Ringwald#if defined __cplusplus 83*c3b5b8a5SMatthias Ringwald} 84*c3b5b8a5SMatthias Ringwald#endif 85*c3b5b8a5SMatthias Ringwald 86*c3b5b8a5SMatthias Ringwald#endif // __BTSTACK_EVENT_H 87*c3b5b8a5SMatthias Ringwald""" 88*c3b5b8a5SMatthias Ringwald 89*c3b5b8a5SMatthias Ringwaldc_prototoype_simple_return = ''' 90*c3b5b8a5SMatthias Ringwald/** 91*c3b5b8a5SMatthias Ringwald * @brief {description} 92*c3b5b8a5SMatthias Ringwald * @param Event packet 93*c3b5b8a5SMatthias Ringwald * @return {result_name} 94*c3b5b8a5SMatthias Ringwald * @note: btstack_type {format} 95*c3b5b8a5SMatthias Ringwald */ 96*c3b5b8a5SMatthias Ringwaldstatic inline {result_type} {fn_name}(const uint8_t * event){{ 97*c3b5b8a5SMatthias Ringwald {code} 98*c3b5b8a5SMatthias Ringwald}} 99*c3b5b8a5SMatthias Ringwald''' 100*c3b5b8a5SMatthias Ringwald 101*c3b5b8a5SMatthias Ringwaldc_prototoype_struct_return = ''' 102*c3b5b8a5SMatthias Ringwald/** 103*c3b5b8a5SMatthias Ringwald * @brief {description} 104*c3b5b8a5SMatthias Ringwald * @param Event packet 105*c3b5b8a5SMatthias Ringwald * @param Pointer to storage for {result_name} 106*c3b5b8a5SMatthias Ringwald * @note: btstack_type {format} 107*c3b5b8a5SMatthias Ringwald */ 108*c3b5b8a5SMatthias Ringwaldstatic inline void {fn_name}(const uint8_t * event, {result_type} {result_name}){{ 109*c3b5b8a5SMatthias Ringwald {code} 110*c3b5b8a5SMatthias Ringwald}} 111*c3b5b8a5SMatthias Ringwald''' 112*c3b5b8a5SMatthias Ringwald 113*c3b5b8a5SMatthias Ringwaldc_prototoype_unsupported = ''' 114*c3b5b8a5SMatthias Ringwald/** 115*c3b5b8a5SMatthias Ringwald * @brief {description} 116*c3b5b8a5SMatthias Ringwald * @param Event packet 117*c3b5b8a5SMatthias Ringwald * @return {result_name} 118*c3b5b8a5SMatthias Ringwald * @note: btstack_type {format} 119*c3b5b8a5SMatthias Ringwald */ 120*c3b5b8a5SMatthias Ringwald// static inline {result_type} {fn_name}(const uint8_t * event){{ 121*c3b5b8a5SMatthias Ringwald// not implemented yet 122*c3b5b8a5SMatthias Ringwald// }} 123*c3b5b8a5SMatthias Ringwald''' 124*c3b5b8a5SMatthias Ringwald 125*c3b5b8a5SMatthias Ringwald# global variables/defines 126*c3b5b8a5SMatthias Ringwaldgen_path = '../src/btstack_event.h' 127*c3b5b8a5SMatthias Ringwald 128*c3b5b8a5SMatthias Ringwalddefines = dict() 129*c3b5b8a5SMatthias Ringwalddefines_used = set() 130*c3b5b8a5SMatthias Ringwald 131*c3b5b8a5SMatthias Ringwaldparam_read = { 132*c3b5b8a5SMatthias Ringwald '1' : 'return event[{offset}];', 133*c3b5b8a5SMatthias Ringwald 'J' : 'return event[{offset}];', 134*c3b5b8a5SMatthias Ringwald 'L' : 'return event[{offset}];', 135*c3b5b8a5SMatthias Ringwald '2' : 'return READ_BT_16(event, {offset});', 136*c3b5b8a5SMatthias Ringwald '3' : 'return READ_BT_24(event, {offset});', 137*c3b5b8a5SMatthias Ringwald '4' : 'return READ_BT_32(event, {offset});', 138*c3b5b8a5SMatthias Ringwald 'H' : 'return READ_BT_16(event, {offset});', 139*c3b5b8a5SMatthias Ringwald 'B' : 'bt_flip_addr({result_name}, (uint8_t*) &event[{offset}]);', 140*c3b5b8a5SMatthias Ringwald 'R' : 'return &event[{offset}];' 141*c3b5b8a5SMatthias Ringwald} 142*c3b5b8a5SMatthias Ringwald 143*c3b5b8a5SMatthias Ringwalddef c_type_for_btstack_type(type): 144*c3b5b8a5SMatthias Ringwald param_types = { '1' : 'uint8_t', '2' : 'uint16_t', '3' : 'uint32_t', '4' : 'uint32_t', 'H' : 'hci_con_handle_t', 'B' : 'bd_addr_t', 145*c3b5b8a5SMatthias Ringwald 'D' : 'const uint8_t *', 'E' : 'const uint8_t * ', 'N' : 'String' , 'P' : 'const uint8_t *', 'A' : 'const uint8_t *', 146*c3b5b8a5SMatthias Ringwald 'R' : 'const uint8_t *', 'S' : 'const uint8_t *', 147*c3b5b8a5SMatthias Ringwald 'J' : 'int', 'L' : 'int', 'V' : 'const uint8_t *', 'U' : 'BT_UUID', 148*c3b5b8a5SMatthias Ringwald 'X' : 'GATTService', 'Y' : 'GATTCharacteristic', 'Z' : 'GATTCharacteristicDescriptor', 149*c3b5b8a5SMatthias Ringwald 'T' : 'String'} 150*c3b5b8a5SMatthias Ringwald return param_types[type] 151*c3b5b8a5SMatthias Ringwald 152*c3b5b8a5SMatthias Ringwalddef size_for_type(type): 153*c3b5b8a5SMatthias Ringwald param_sizes = { '1' : 1, '2' : 2, '3' : 3, '4' : 4, 'H' : 2, 'B' : 6, 'D' : 8, 'E' : 240, 'N' : 248, 'P' : 16, 154*c3b5b8a5SMatthias Ringwald 'A' : 31, 'S' : -1, 'V': -1, 'J' : 1, 'L' : 2, 'U' : 16, 'X' : 20, 'Y' : 24, 'Z' : 18, 'T':-1} 155*c3b5b8a5SMatthias Ringwald return param_sizes[type] 156*c3b5b8a5SMatthias Ringwald 157*c3b5b8a5SMatthias Ringwalddef format_function_name(event_name): 158*c3b5b8a5SMatthias Ringwald return event_name.lower() 159*c3b5b8a5SMatthias Ringwald 160*c3b5b8a5SMatthias Ringwalddef template_for_type(field_type): 161*c3b5b8a5SMatthias Ringwald global c_prototoype_simple_return 162*c3b5b8a5SMatthias Ringwald global c_prototoype_struct_return 163*c3b5b8a5SMatthias Ringwald types_with_struct_return = "B" 164*c3b5b8a5SMatthias Ringwald if field_type in types_with_struct_return: 165*c3b5b8a5SMatthias Ringwald return c_prototoype_struct_return 166*c3b5b8a5SMatthias Ringwald else: 167*c3b5b8a5SMatthias Ringwald return c_prototoype_simple_return 168*c3b5b8a5SMatthias Ringwald 169*c3b5b8a5SMatthias Ringwalddef all_fields_supported(format): 170*c3b5b8a5SMatthias Ringwald global param_read 171*c3b5b8a5SMatthias Ringwald for f in format: 172*c3b5b8a5SMatthias Ringwald if not f in param_read: 173*c3b5b8a5SMatthias Ringwald return False 174*c3b5b8a5SMatthias Ringwald return True 175*c3b5b8a5SMatthias Ringwald 176*c3b5b8a5SMatthias Ringwalddef create_getter(event_name, field_name, field_type, offset, supported): 177*c3b5b8a5SMatthias Ringwald global c_prototoype_unsupported 178*c3b5b8a5SMatthias Ringwald global param_read 179*c3b5b8a5SMatthias Ringwald 180*c3b5b8a5SMatthias Ringwald description = "Get field %s from event %s" % (field_name, event_name) 181*c3b5b8a5SMatthias Ringwald result_name = field_name 182*c3b5b8a5SMatthias Ringwald fn_name = "%s_get_%s" % (event_name, field_name) 183*c3b5b8a5SMatthias Ringwald result_type = c_type_for_btstack_type(field_type) 184*c3b5b8a5SMatthias Ringwald template = c_prototoype_unsupported 185*c3b5b8a5SMatthias Ringwald code = '' 186*c3b5b8a5SMatthias Ringwald if supported and field_type in param_read: 187*c3b5b8a5SMatthias Ringwald template = template_for_type(field_type) 188*c3b5b8a5SMatthias Ringwald code = param_read[field_type].format(offset=offset, result_name=result_name) 189*c3b5b8a5SMatthias Ringwald return template.format(description=description, fn_name=fn_name, result_name=result_name, result_type=result_type, code=code, format=field_type) 190*c3b5b8a5SMatthias Ringwald 191*c3b5b8a5SMatthias Ringwalddef create_events(events): 192*c3b5b8a5SMatthias Ringwald global gen_path 193*c3b5b8a5SMatthias Ringwald global copyright 194*c3b5b8a5SMatthias Ringwald global hfile_header_begin 195*c3b5b8a5SMatthias Ringwald global hfile_header_end 196*c3b5b8a5SMatthias Ringwald 197*c3b5b8a5SMatthias Ringwald with open(gen_path, 'wt') as fout: 198*c3b5b8a5SMatthias Ringwald fout.write(copyright) 199*c3b5b8a5SMatthias Ringwald fout.write(hfile_header_begin) 200*c3b5b8a5SMatthias Ringwald for event_type, event_name, format, args in events: 201*c3b5b8a5SMatthias Ringwald event_name = format_function_name(event_name) 202*c3b5b8a5SMatthias Ringwald offset = 2 203*c3b5b8a5SMatthias Ringwald supported = all_fields_supported(format) 204*c3b5b8a5SMatthias Ringwald for f, arg in zip(format, args): 205*c3b5b8a5SMatthias Ringwald field_name = arg 206*c3b5b8a5SMatthias Ringwald field_type = f 207*c3b5b8a5SMatthias Ringwald if field_type == 'V': 208*c3b5b8a5SMatthias Ringwald break 209*c3b5b8a5SMatthias Ringwald text = create_getter(event_name, field_name, field_type, offset, supported) 210*c3b5b8a5SMatthias Ringwald fout.write(text) 211*c3b5b8a5SMatthias Ringwald if field_type == 'R': 212*c3b5b8a5SMatthias Ringwald break 213*c3b5b8a5SMatthias Ringwald offset += size_for_type(field_type) 214*c3b5b8a5SMatthias Ringwald 215*c3b5b8a5SMatthias Ringwald fout.write(hfile_header_end) 216*c3b5b8a5SMatthias Ringwald 217*c3b5b8a5SMatthias Ringwald# set root 218*c3b5b8a5SMatthias Ringwaldparser.set_btstack_root('..') 219*c3b5b8a5SMatthias Ringwald 220*c3b5b8a5SMatthias Ringwaldprint(program_info) 221*c3b5b8a5SMatthias Ringwald 222*c3b5b8a5SMatthias Ringwald# parse events 223*c3b5b8a5SMatthias Ringwald(events, le_events, event_types) = parser.parse_events() 224*c3b5b8a5SMatthias Ringwald 225*c3b5b8a5SMatthias Ringwald# create event field accesors 226*c3b5b8a5SMatthias Ringwaldcreate_events(events + le_events) 227*c3b5b8a5SMatthias Ringwald 228*c3b5b8a5SMatthias Ringwald# done 229*c3b5b8a5SMatthias Ringwaldprint('Done!') 230