1b3fcedb9SMatthias Ringwald#!/usr/bin/env python 2b3fcedb9SMatthias Ringwald# 3b3fcedb9SMatthias Ringwald# BLE GATT configuration generator for use with BTstack, v0.1 4b3fcedb9SMatthias Ringwald# Copyright 2011 Matthias Ringwald 5b3fcedb9SMatthias Ringwald# 6b3fcedb9SMatthias Ringwald# Format of input file: 7b3fcedb9SMatthias Ringwald# PRIMARY_SERVICE, SERVICE_UUID 8b3fcedb9SMatthias Ringwald# CHARACTERISTIC, ATTRIBUTE_TYPE_UUID, [READ | WRITE | DYNAMIC], VALUE 9b3fcedb9SMatthias Ringwald 10b3fcedb9SMatthias Ringwaldimport codecs 11b165f97bSMatthias Ringwaldimport csv 12b165f97bSMatthias Ringwaldimport io 13b165f97bSMatthias Ringwaldimport os 14b165f97bSMatthias Ringwaldimport re 15b165f97bSMatthias Ringwaldimport string 1660b51a4cSMatthias Ringwaldimport sys 17b3fcedb9SMatthias Ringwald 18b3fcedb9SMatthias Ringwaldheader = ''' 19b3fcedb9SMatthias Ringwald// {0} generated from {1} for BTstack 20b3fcedb9SMatthias Ringwald 21b3fcedb9SMatthias Ringwald// binary representation 22b3fcedb9SMatthias Ringwald// attribute size in bytes (16), flags(16), handle (16), uuid (16/128), value(...) 23b3fcedb9SMatthias Ringwald 24b3fcedb9SMatthias Ringwald#include <stdint.h> 25b3fcedb9SMatthias Ringwald 26b3fcedb9SMatthias Ringwaldconst uint8_t profile_data[] = 27b3fcedb9SMatthias Ringwald''' 28b3fcedb9SMatthias Ringwald 29b3fcedb9SMatthias Ringwaldusage = ''' 30b3fcedb9SMatthias RingwaldUsage: ./compile_gatt.py profile.gatt profile.h 31b3fcedb9SMatthias Ringwald''' 32b3fcedb9SMatthias Ringwald 33b3fcedb9SMatthias Ringwald 34b3fcedb9SMatthias Ringwaldprint(''' 35b3fcedb9SMatthias RingwaldBLE configuration generator for use with BTstack, v0.1 36b3fcedb9SMatthias RingwaldCopyright 2011 Matthias Ringwald 37b3fcedb9SMatthias Ringwald''') 38b3fcedb9SMatthias Ringwald 39b3fcedb9SMatthias Ringwaldassigned_uuids = { 40b3fcedb9SMatthias Ringwald 'GAP_SERVICE' : 0x1800, 41b3fcedb9SMatthias Ringwald 'GATT_SERVICE' : 0x1801, 42b3fcedb9SMatthias Ringwald 'GAP_DEVICE_NAME' : 0x2a00, 43b3fcedb9SMatthias Ringwald 'GAP_APPEARANCE' : 0x2a01, 44b3fcedb9SMatthias Ringwald 'GAP_PERIPHERAL_PRIVACY_FLAG' : 0x2A02, 45b3fcedb9SMatthias Ringwald 'GAP_RECONNECTION_ADDRESS' : 0x2A03, 46b3fcedb9SMatthias Ringwald 'GAP_PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS' : 0x2A04, 47b3fcedb9SMatthias Ringwald 'GATT_SERVICE_CHANGED' : 0x2a05, 48b3fcedb9SMatthias Ringwald} 49b3fcedb9SMatthias Ringwald 50b3fcedb9SMatthias Ringwaldproperty_flags = { 51eb6072adSMatthias Ringwald # GATT Characteristic Properties 52b3fcedb9SMatthias Ringwald 'BROADCAST' : 0x01, 53b3fcedb9SMatthias Ringwald 'READ' : 0x02, 54b3fcedb9SMatthias Ringwald 'WRITE_WITHOUT_RESPONSE' : 0x04, 55b3fcedb9SMatthias Ringwald 'WRITE' : 0x08, 56b3fcedb9SMatthias Ringwald 'NOTIFY': 0x10, 57b3fcedb9SMatthias Ringwald 'INDICATE' : 0x20, 58b3fcedb9SMatthias Ringwald 'AUTHENTICATED_SIGNED_WRITE' : 0x40, 59b3fcedb9SMatthias Ringwald 'EXTENDED_PROPERTIES' : 0x80, 60b3fcedb9SMatthias Ringwald # custom BTstack extension 61b3fcedb9SMatthias Ringwald 'DYNAMIC': 0x100, 62b3fcedb9SMatthias Ringwald 'LONG_UUID': 0x200, 63b3fcedb9SMatthias Ringwald 'AUTHENTICATION_REQUIRED': 0x400, 64b3fcedb9SMatthias Ringwald 'AUTHORIZATION_REQUIRED': 0x800, 65b3fcedb9SMatthias Ringwald 'ENCRYPTION_KEY_SIZE_7': 0x6000, 66b3fcedb9SMatthias Ringwald 'ENCRYPTION_KEY_SIZE_8': 0x7000, 67b3fcedb9SMatthias Ringwald 'ENCRYPTION_KEY_SIZE_9': 0x8000, 68b3fcedb9SMatthias Ringwald 'ENCRYPTION_KEY_SIZE_10': 0x9000, 69b3fcedb9SMatthias Ringwald 'ENCRYPTION_KEY_SIZE_11': 0xa000, 70b3fcedb9SMatthias Ringwald 'ENCRYPTION_KEY_SIZE_12': 0xb000, 71b3fcedb9SMatthias Ringwald 'ENCRYPTION_KEY_SIZE_13': 0xc000, 72b3fcedb9SMatthias Ringwald 'ENCRYPTION_KEY_SIZE_14': 0xd000, 73b3fcedb9SMatthias Ringwald 'ENCRYPTION_KEY_SIZE_15': 0xe000, 74b3fcedb9SMatthias Ringwald 'ENCRYPTION_KEY_SIZE_16': 0xf000, 75eb6072adSMatthias Ringwald 76b3fcedb9SMatthias Ringwald # only used by gatt compiler >= 0xffff 77b3fcedb9SMatthias Ringwald # Extended Properties 78b3fcedb9SMatthias Ringwald 'RELIABLE_WRITE': 0x10000, 79eb6072adSMatthias Ringwald 80eb6072adSMatthias Ringwald # Broadcast, Notify, Indicate, Extended Properties are only used to describe a GATT Characteristic, but are free to use with att_db 81eb6072adSMatthias Ringwald 'READ_WITHOUT_AUTHENTICATION': 0x0001, 82eb6072adSMatthias Ringwald # 0x10 83eb6072adSMatthias Ringwald # 0x20 84eb6072adSMatthias Ringwald # 0x80 85b3fcedb9SMatthias Ringwald} 86b3fcedb9SMatthias Ringwald 8760b51a4cSMatthias Ringwaldbtstack_root = '' 88b3fcedb9SMatthias Ringwaldservices = dict() 89b3fcedb9SMatthias Ringwaldcharacteristic_indices = dict() 90b3fcedb9SMatthias Ringwaldpresentation_formats = dict() 91b3fcedb9SMatthias Ringwaldcurrent_service_uuid_string = "" 92b3fcedb9SMatthias Ringwaldcurrent_service_start_handle = 0 93b3fcedb9SMatthias Ringwaldcurrent_characteristic_uuid_string = "" 94729074c4SMatthias Ringwalddefines_for_characteristics = [] 95729074c4SMatthias Ringwalddefines_for_services = [] 96b3fcedb9SMatthias Ringwald 97b3fcedb9SMatthias Ringwaldhandle = 1 98b3fcedb9SMatthias Ringwaldtotal_size = 0 99b3fcedb9SMatthias Ringwald 100b165f97bSMatthias Ringwalddef read_defines(infile): 101b165f97bSMatthias Ringwald defines = dict() 102b165f97bSMatthias Ringwald with open (infile, 'rt') as fin: 103b165f97bSMatthias Ringwald for line in fin: 104b165f97bSMatthias Ringwald parts = re.match('#define\s+(\w+)\s+(\w+)',line) 105b165f97bSMatthias Ringwald if parts and len(parts.groups()) == 2: 106b165f97bSMatthias Ringwald (key, value) = parts.groups() 107b165f97bSMatthias Ringwald defines[key] = int(value, 16) 108b165f97bSMatthias Ringwald return defines 109b165f97bSMatthias Ringwald 110b3fcedb9SMatthias Ringwalddef keyForUUID(uuid): 111b3fcedb9SMatthias Ringwald keyUUID = "" 112b3fcedb9SMatthias Ringwald for i in uuid: 113b3fcedb9SMatthias Ringwald keyUUID += "%02x" % i 114b3fcedb9SMatthias Ringwald return keyUUID 115b3fcedb9SMatthias Ringwald 116b3fcedb9SMatthias Ringwalddef c_string_for_uuid(uuid): 117b3fcedb9SMatthias Ringwald return uuid.replace('-', '_') 118b3fcedb9SMatthias Ringwald 119b3fcedb9SMatthias Ringwalddef twoByteLEFor(value): 120b3fcedb9SMatthias Ringwald return [ (value & 0xff), (value >> 8)] 121b3fcedb9SMatthias Ringwald 122b3fcedb9SMatthias Ringwalddef is_128bit_uuid(text): 123b3fcedb9SMatthias Ringwald if re.match("[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}", text): 124b3fcedb9SMatthias Ringwald return True 125b3fcedb9SMatthias Ringwald return False 126b3fcedb9SMatthias Ringwald 127b3fcedb9SMatthias Ringwalddef parseUUID128(uuid): 128b3fcedb9SMatthias Ringwald parts = re.match("([0-9A-Fa-f]{4})([0-9A-Fa-f]{4})-([0-9A-Fa-f]{4})-([0-9A-Fa-f]{4})-([0-9A-Fa-f]{4})-([0-9A-Fa-f]{4})([0-9A-Fa-f]{4})([0-9A-Fa-f]{4})", uuid) 129b3fcedb9SMatthias Ringwald uuid_bytes = [] 130b3fcedb9SMatthias Ringwald for i in range(8, 0, -1): 131b3fcedb9SMatthias Ringwald uuid_bytes = uuid_bytes + twoByteLEFor(int(parts.group(i),16)) 132b3fcedb9SMatthias Ringwald return uuid_bytes 133b3fcedb9SMatthias Ringwald 134b3fcedb9SMatthias Ringwalddef parseUUID(uuid): 135b3fcedb9SMatthias Ringwald if uuid in assigned_uuids: 136b3fcedb9SMatthias Ringwald return twoByteLEFor(assigned_uuids[uuid]) 137b165f97bSMatthias Ringwald uuid_upper = uuid.upper().replace('.','_') 138b165f97bSMatthias Ringwald if uuid_upper in bluetooth_gatt: 139b165f97bSMatthias Ringwald return twoByteLEFor(bluetooth_gatt[uuid_upper]) 140b3fcedb9SMatthias Ringwald if is_128bit_uuid(uuid): 141b3fcedb9SMatthias Ringwald return parseUUID128(uuid) 142b3fcedb9SMatthias Ringwald uuidInt = int(uuid, 16) 143b3fcedb9SMatthias Ringwald return twoByteLEFor(uuidInt) 144b3fcedb9SMatthias Ringwald 145b3fcedb9SMatthias Ringwalddef parseProperties(properties): 146b3fcedb9SMatthias Ringwald value = 0 147b3fcedb9SMatthias Ringwald parts = properties.split("|") 148b3fcedb9SMatthias Ringwald for property in parts: 149b3fcedb9SMatthias Ringwald property = property.strip() 150b3fcedb9SMatthias Ringwald if property in property_flags: 151b3fcedb9SMatthias Ringwald value |= property_flags[property] 152b3fcedb9SMatthias Ringwald else: 153b3fcedb9SMatthias Ringwald print("WARNING: property %s undefined" % (property)) 154b3fcedb9SMatthias Ringwald return value 155b3fcedb9SMatthias Ringwald 156b3fcedb9SMatthias Ringwalddef write_8(fout, value): 157b3fcedb9SMatthias Ringwald fout.write( "0x%02x, " % (value & 0xff)) 158b3fcedb9SMatthias Ringwald 159b3fcedb9SMatthias Ringwalddef write_16(fout, value): 160b3fcedb9SMatthias Ringwald fout.write('0x%02x, 0x%02x, ' % (value & 0xff, (value >> 8) & 0xff)) 161b3fcedb9SMatthias Ringwald 162b3fcedb9SMatthias Ringwalddef write_uuid(uuid): 163b3fcedb9SMatthias Ringwald for byte in uuid: 164b3fcedb9SMatthias Ringwald fout.write( "0x%02x, " % byte) 165b3fcedb9SMatthias Ringwald 166b3fcedb9SMatthias Ringwalddef write_string(fout, text): 167b3fcedb9SMatthias Ringwald for l in text.lstrip('"').rstrip('"'): 168b3fcedb9SMatthias Ringwald write_8(fout, ord(l)) 169b3fcedb9SMatthias Ringwald 170b3fcedb9SMatthias Ringwalddef write_sequence(fout, text): 171b3fcedb9SMatthias Ringwald parts = text.split() 172b3fcedb9SMatthias Ringwald for part in parts: 173b3fcedb9SMatthias Ringwald fout.write("0x%s, " % (part.strip())) 174b3fcedb9SMatthias Ringwald 175b3fcedb9SMatthias Ringwalddef write_indent(fout): 176b3fcedb9SMatthias Ringwald fout.write(" ") 177b3fcedb9SMatthias Ringwald 178b3fcedb9SMatthias Ringwalddef is_string(text): 179b3fcedb9SMatthias Ringwald for item in text.split(" "): 180b3fcedb9SMatthias Ringwald if not all(c in string.hexdigits for c in item): 181b3fcedb9SMatthias Ringwald return True 182b3fcedb9SMatthias Ringwald return False 183b3fcedb9SMatthias Ringwald 184b3fcedb9SMatthias Ringwalddef add_client_characteristic_configuration(properties): 185b3fcedb9SMatthias Ringwald return properties & (property_flags['NOTIFY'] | property_flags['INDICATE']) 186b3fcedb9SMatthias Ringwald 187729074c4SMatthias Ringwalddef serviceDefinitionComplete(fout): 188729074c4SMatthias Ringwald global services 189729074c4SMatthias Ringwald if current_service_uuid_string: 190729074c4SMatthias Ringwald fout.write("\n") 191729074c4SMatthias Ringwald # print("append service %s = [%d, %d]" % (current_characteristic_uuid_string, current_service_start_handle, handle-1)) 192729074c4SMatthias Ringwald defines_for_services.append('#define ATT_SERVICE_%s_START_HANDLE 0x%04x' % (current_service_uuid_string, current_service_start_handle)) 193729074c4SMatthias Ringwald defines_for_services.append('#define ATT_SERVICE_%s_END_HANDLE 0x%04x' % (current_service_uuid_string, handle-1)) 194729074c4SMatthias Ringwald services[current_service_uuid_string] = [current_service_start_handle, handle-1] 195729074c4SMatthias Ringwald 196b3fcedb9SMatthias Ringwalddef parseService(fout, parts, service_type): 197b3fcedb9SMatthias Ringwald global handle 198b3fcedb9SMatthias Ringwald global total_size 199b3fcedb9SMatthias Ringwald global current_service_uuid_string 200b3fcedb9SMatthias Ringwald global current_service_start_handle 201b3fcedb9SMatthias Ringwald 202729074c4SMatthias Ringwald serviceDefinitionComplete(fout) 203b3fcedb9SMatthias Ringwald 204b3fcedb9SMatthias Ringwald property = property_flags['READ']; 205b3fcedb9SMatthias Ringwald 206b3fcedb9SMatthias Ringwald write_indent(fout) 207b3fcedb9SMatthias Ringwald fout.write('// 0x%04x %s\n' % (handle, '-'.join(parts))) 208b3fcedb9SMatthias Ringwald 209b3fcedb9SMatthias Ringwald uuid = parseUUID(parts[1]) 210b3fcedb9SMatthias Ringwald uuid_size = len(uuid) 211b3fcedb9SMatthias Ringwald 212b3fcedb9SMatthias Ringwald size = 2 + 2 + 2 + uuid_size + 2 213b3fcedb9SMatthias Ringwald 214b3fcedb9SMatthias Ringwald if service_type == 0x2802: 215b3fcedb9SMatthias Ringwald size += 4 216b3fcedb9SMatthias Ringwald 217b3fcedb9SMatthias Ringwald write_indent(fout) 218b3fcedb9SMatthias Ringwald write_16(fout, size) 219b3fcedb9SMatthias Ringwald write_16(fout, property) 220b3fcedb9SMatthias Ringwald write_16(fout, handle) 221b3fcedb9SMatthias Ringwald write_16(fout, service_type) 222b3fcedb9SMatthias Ringwald write_uuid(uuid) 223b3fcedb9SMatthias Ringwald fout.write("\n") 224b3fcedb9SMatthias Ringwald 225729074c4SMatthias Ringwald current_service_uuid_string = c_string_for_uuid(parts[1]) 226b3fcedb9SMatthias Ringwald current_service_start_handle = handle 227b3fcedb9SMatthias Ringwald handle = handle + 1 228b3fcedb9SMatthias Ringwald total_size = total_size + size 229b3fcedb9SMatthias Ringwald 230b3fcedb9SMatthias Ringwalddef parsePrimaryService(fout, parts): 231b3fcedb9SMatthias Ringwald parseService(fout, parts, 0x2800) 232b3fcedb9SMatthias Ringwald 233b3fcedb9SMatthias Ringwalddef parseSecondaryService(fout, parts): 234b3fcedb9SMatthias Ringwald parseService(fout, parts, 0x2801) 235b3fcedb9SMatthias Ringwald 236b3fcedb9SMatthias Ringwalddef parseIncludeService(fout, parts): 237b3fcedb9SMatthias Ringwald global handle 238b3fcedb9SMatthias Ringwald global total_size 239b3fcedb9SMatthias Ringwald 240b3fcedb9SMatthias Ringwald property = property_flags['READ']; 241b3fcedb9SMatthias Ringwald 242b3fcedb9SMatthias Ringwald write_indent(fout) 243b3fcedb9SMatthias Ringwald fout.write('// 0x%04x %s\n' % (handle, '-'.join(parts))) 244b3fcedb9SMatthias Ringwald 245b3fcedb9SMatthias Ringwald uuid = parseUUID(parts[1]) 246b3fcedb9SMatthias Ringwald uuid_size = len(uuid) 247b3fcedb9SMatthias Ringwald if uuid_size > 2: 248b3fcedb9SMatthias Ringwald uuid_size = 0 249729074c4SMatthias Ringwald # print("Include Service ", c_string_for_uuid(uuid)) 250b3fcedb9SMatthias Ringwald 251b3fcedb9SMatthias Ringwald size = 2 + 2 + 2 + 2 + 4 + uuid_size 252b3fcedb9SMatthias Ringwald 253729074c4SMatthias Ringwald keyUUID = c_string_for_uuid(parts[1]) 254b3fcedb9SMatthias Ringwald 255b3fcedb9SMatthias Ringwald write_indent(fout) 256b3fcedb9SMatthias Ringwald write_16(fout, size) 257b3fcedb9SMatthias Ringwald write_16(fout, property) 258b3fcedb9SMatthias Ringwald write_16(fout, handle) 259b3fcedb9SMatthias Ringwald write_16(fout, 0x2802) 260b3fcedb9SMatthias Ringwald write_16(fout, services[keyUUID][0]) 261b3fcedb9SMatthias Ringwald write_16(fout, services[keyUUID][1]) 262b3fcedb9SMatthias Ringwald if uuid_size > 0: 263b3fcedb9SMatthias Ringwald write_uuid(uuid) 264b3fcedb9SMatthias Ringwald fout.write("\n") 265b3fcedb9SMatthias Ringwald 266b3fcedb9SMatthias Ringwald handle = handle + 1 267b3fcedb9SMatthias Ringwald total_size = total_size + size 268b3fcedb9SMatthias Ringwald 269b3fcedb9SMatthias Ringwald 270b3fcedb9SMatthias Ringwalddef parseCharacteristic(fout, parts): 271b3fcedb9SMatthias Ringwald global handle 272b3fcedb9SMatthias Ringwald global total_size 273b3fcedb9SMatthias Ringwald global current_characteristic_uuid_string 274b3fcedb9SMatthias Ringwald global characteristic_indices 275b3fcedb9SMatthias Ringwald 276b3fcedb9SMatthias Ringwald property_read = property_flags['READ']; 277b3fcedb9SMatthias Ringwald 278b3fcedb9SMatthias Ringwald # enumerate characteristics with same UUID, using optional name tag if available 279b3fcedb9SMatthias Ringwald current_characteristic_uuid_string = c_string_for_uuid(parts[1]); 280b3fcedb9SMatthias Ringwald index = 1 281b3fcedb9SMatthias Ringwald if current_characteristic_uuid_string in characteristic_indices: 282b3fcedb9SMatthias Ringwald index = characteristic_indices[current_characteristic_uuid_string] + 1 283b3fcedb9SMatthias Ringwald characteristic_indices[current_characteristic_uuid_string] = index 284b3fcedb9SMatthias Ringwald if len(parts) > 4: 285b3fcedb9SMatthias Ringwald current_characteristic_uuid_string += '_' + parts[4].upper().replace(' ','_') 286b3fcedb9SMatthias Ringwald else: 287b3fcedb9SMatthias Ringwald current_characteristic_uuid_string += ('_%02x' % index) 288b3fcedb9SMatthias Ringwald 289b3fcedb9SMatthias Ringwald uuid = parseUUID(parts[1]) 290b3fcedb9SMatthias Ringwald uuid_size = len(uuid) 291b3fcedb9SMatthias Ringwald properties = parseProperties(parts[2]) 292b3fcedb9SMatthias Ringwald value = ', '.join([str(x) for x in parts[3:]]) 293b3fcedb9SMatthias Ringwald 294b3fcedb9SMatthias Ringwald # reliable writes is defined in an extended properties 295b3fcedb9SMatthias Ringwald if (properties & property_flags['RELIABLE_WRITE']): 296b3fcedb9SMatthias Ringwald properties = properties | property_flags['EXTENDED_PROPERTIES'] 297b3fcedb9SMatthias Ringwald 298b3fcedb9SMatthias Ringwald write_indent(fout) 299b3fcedb9SMatthias Ringwald fout.write('// 0x%04x %s\n' % (handle, '-'.join(parts[0:3]))) 300b3fcedb9SMatthias Ringwald 301b3fcedb9SMatthias Ringwald size = 2 + 2 + 2 + 2 + (1+2+uuid_size) 302b3fcedb9SMatthias Ringwald write_indent(fout) 303b3fcedb9SMatthias Ringwald write_16(fout, size) 304b3fcedb9SMatthias Ringwald write_16(fout, property_read) 305b3fcedb9SMatthias Ringwald write_16(fout, handle) 306b3fcedb9SMatthias Ringwald write_16(fout, 0x2803) 307b3fcedb9SMatthias Ringwald write_8(fout, properties) 308b3fcedb9SMatthias Ringwald write_16(fout, handle+1) 309b3fcedb9SMatthias Ringwald write_uuid(uuid) 310b3fcedb9SMatthias Ringwald fout.write("\n") 311b3fcedb9SMatthias Ringwald handle = handle + 1 312b3fcedb9SMatthias Ringwald total_size = total_size + size 313b3fcedb9SMatthias Ringwald 314b3fcedb9SMatthias Ringwald size = 2 + 2 + 2 + uuid_size 315b3fcedb9SMatthias Ringwald if is_string(value): 316b3fcedb9SMatthias Ringwald size = size + len(value) 317b3fcedb9SMatthias Ringwald else: 318b3fcedb9SMatthias Ringwald size = size + len(value.split()) 319b3fcedb9SMatthias Ringwald 320*8ea3236cSMatthias Ringwald # drop Broadcast, Notify, Indicate - not used for flags 321*8ea3236cSMatthias Ringwald value_properties = properties & 0x1ffce 322*8ea3236cSMatthias Ringwald 323*8ea3236cSMatthias Ringwald # add UUID128 flag for value handle 324b3fcedb9SMatthias Ringwald if uuid_size == 16: 325*8ea3236cSMatthias Ringwald value_properties = value_properties | property_flags['LONG_UUID']; 326b3fcedb9SMatthias Ringwald 327b3fcedb9SMatthias Ringwald write_indent(fout) 328b3fcedb9SMatthias Ringwald fout.write('// 0x%04x VALUE-%s-'"'%s'"'\n' % (handle, '-'.join(parts[1:3]),value)) 329b3fcedb9SMatthias Ringwald write_indent(fout) 330b3fcedb9SMatthias Ringwald write_16(fout, size) 331eb6072adSMatthias Ringwald write_16(fout, value_properties) 332b3fcedb9SMatthias Ringwald write_16(fout, handle) 333b3fcedb9SMatthias Ringwald write_uuid(uuid) 334b3fcedb9SMatthias Ringwald if is_string(value): 335b3fcedb9SMatthias Ringwald write_string(fout, value) 336b3fcedb9SMatthias Ringwald else: 337b3fcedb9SMatthias Ringwald write_sequence(fout,value) 338b3fcedb9SMatthias Ringwald 339b3fcedb9SMatthias Ringwald fout.write("\n") 340729074c4SMatthias Ringwald defines_for_characteristics.append('#define ATT_CHARACTERISTIC_%s_VALUE_HANDLE 0x%04x' % (current_characteristic_uuid_string, handle)) 341b3fcedb9SMatthias Ringwald handle = handle + 1 342b3fcedb9SMatthias Ringwald 343b3fcedb9SMatthias Ringwald if add_client_characteristic_configuration(properties): 344eb6072adSMatthias Ringwald # replace GATT Characterstic Properties with READ|WRITE|READ_WITHOUT_AUTHENTICATION|DYNAMIC 345*8ea3236cSMatthias Ringwald ccc_properties = (properties & 0x1fc00) | property_flags['READ_WITHOUT_AUTHENTICATION'] | property_flags['READ'] | property_flags['WRITE'] | property_flags['DYNAMIC']; 346b3fcedb9SMatthias Ringwald size = 2 + 2 + 2 + 2 + 2 347b3fcedb9SMatthias Ringwald write_indent(fout) 348b3fcedb9SMatthias Ringwald fout.write('// 0x%04x CLIENT_CHARACTERISTIC_CONFIGURATION\n' % (handle)) 349b3fcedb9SMatthias Ringwald write_indent(fout) 350b3fcedb9SMatthias Ringwald write_16(fout, size) 351eb6072adSMatthias Ringwald write_16(fout, ccc_properties) 352b3fcedb9SMatthias Ringwald write_16(fout, handle) 353b3fcedb9SMatthias Ringwald write_16(fout, 0x2902) 354b3fcedb9SMatthias Ringwald write_16(fout, 0) 355b3fcedb9SMatthias Ringwald fout.write("\n") 356729074c4SMatthias Ringwald defines_for_characteristics.append('#define ATT_CHARACTERISTIC_%s_CLIENT_CONFIGURATION_HANDLE 0x%04x' % (current_characteristic_uuid_string, handle)) 357b3fcedb9SMatthias Ringwald handle = handle + 1 358b3fcedb9SMatthias Ringwald 359b3fcedb9SMatthias Ringwald if properties & property_flags['RELIABLE_WRITE']: 360b3fcedb9SMatthias Ringwald size = 2 + 2 + 2 + 2 + 2 361b3fcedb9SMatthias Ringwald write_indent(fout) 362b3fcedb9SMatthias Ringwald fout.write('// 0x%04x CHARACTERISTIC_EXTENDED_PROPERTIES\n' % (handle)) 363b3fcedb9SMatthias Ringwald write_indent(fout) 364b3fcedb9SMatthias Ringwald write_16(fout, size) 365b3fcedb9SMatthias Ringwald write_16(fout, property_flags['READ']) 366b3fcedb9SMatthias Ringwald write_16(fout, handle) 367b3fcedb9SMatthias Ringwald write_16(fout, 0x2900) 368b3fcedb9SMatthias Ringwald write_16(fout, 1) # Reliable Write 369b3fcedb9SMatthias Ringwald fout.write("\n") 370b3fcedb9SMatthias Ringwald handle = handle + 1 371b3fcedb9SMatthias Ringwald 372b3fcedb9SMatthias Ringwalddef parseCharacteristicUserDescription(fout, parts): 373b3fcedb9SMatthias Ringwald global handle 374b3fcedb9SMatthias Ringwald global total_size 375b3fcedb9SMatthias Ringwald global current_characteristic_uuid_string 376b3fcedb9SMatthias Ringwald 377b3fcedb9SMatthias Ringwald properties = parseProperties(parts[1]) 378b3fcedb9SMatthias Ringwald value = parts[2] 379b3fcedb9SMatthias Ringwald 380b3fcedb9SMatthias Ringwald size = 2 + 2 + 2 + 2 381b3fcedb9SMatthias Ringwald if is_string(value): 382b3fcedb9SMatthias Ringwald size = size + len(value) - 2 383b3fcedb9SMatthias Ringwald else: 384b3fcedb9SMatthias Ringwald size = size + len(value.split()) 385b3fcedb9SMatthias Ringwald 386b3fcedb9SMatthias Ringwald write_indent(fout) 387b3fcedb9SMatthias Ringwald fout.write('// 0x%04x CHARACTERISTIC_USER_DESCRIPTION-%s\n' % (handle, '-'.join(parts[1:]))) 388b3fcedb9SMatthias Ringwald write_indent(fout) 389b3fcedb9SMatthias Ringwald write_16(fout, size) 390b3fcedb9SMatthias Ringwald write_16(fout, properties) 391b3fcedb9SMatthias Ringwald write_16(fout, handle) 392b3fcedb9SMatthias Ringwald write_16(fout, 0x2901) 393b3fcedb9SMatthias Ringwald if is_string(value): 394b3fcedb9SMatthias Ringwald write_string(fout, value) 395b3fcedb9SMatthias Ringwald else: 396b3fcedb9SMatthias Ringwald write_sequence(fout,value) 397b3fcedb9SMatthias Ringwald fout.write("\n") 398729074c4SMatthias Ringwald defines_for_characteristics.append('#define ATT_CHARACTERISTIC_%s_USER_DESCRIPTION_HANDLE 0x%04x' % (current_characteristic_uuid_string, handle)) 399b3fcedb9SMatthias Ringwald handle = handle + 1 400b3fcedb9SMatthias Ringwald 401b3fcedb9SMatthias Ringwalddef parseServerCharacteristicConfiguration(fout, parts): 402b3fcedb9SMatthias Ringwald global handle 403b3fcedb9SMatthias Ringwald global total_size 404b3fcedb9SMatthias Ringwald global current_characteristic_uuid_string 405b3fcedb9SMatthias Ringwald 406b3fcedb9SMatthias Ringwald properties = parseProperties(parts[1]) 407b3fcedb9SMatthias Ringwald properties = properties | property_flags['DYNAMIC'] 408b3fcedb9SMatthias Ringwald size = 2 + 2 + 2 + 2 409b3fcedb9SMatthias Ringwald 410b3fcedb9SMatthias Ringwald write_indent(fout) 411b3fcedb9SMatthias Ringwald fout.write('// 0x%04x SERVER_CHARACTERISTIC_CONFIGURATION-%s\n' % (handle, '-'.join(parts[1:]))) 412b3fcedb9SMatthias Ringwald write_indent(fout) 413b3fcedb9SMatthias Ringwald write_16(fout, size) 414b3fcedb9SMatthias Ringwald write_16(fout, properties) 415b3fcedb9SMatthias Ringwald write_16(fout, handle) 416b3fcedb9SMatthias Ringwald write_16(fout, 0x2903) 417b3fcedb9SMatthias Ringwald fout.write("\n") 418729074c4SMatthias Ringwald defines_for_characteristics.append('#define ATT_CHARACTERISTIC_%s_SERVER_CONFIGURATION_HANDLE 0x%04x' % (current_characteristic_uuid_string, handle)) 419b3fcedb9SMatthias Ringwald handle = handle + 1 420b3fcedb9SMatthias Ringwald 421b3fcedb9SMatthias Ringwalddef parseCharacteristicFormat(fout, parts): 422b3fcedb9SMatthias Ringwald global handle 423b3fcedb9SMatthias Ringwald global total_size 424b3fcedb9SMatthias Ringwald 425b3fcedb9SMatthias Ringwald property_read = property_flags['READ']; 426b3fcedb9SMatthias Ringwald 427b3fcedb9SMatthias Ringwald identifier = parts[1] 428b3fcedb9SMatthias Ringwald presentation_formats[identifier] = handle 429b3fcedb9SMatthias Ringwald # print("format '%s' with handle %d\n" % (identifier, handle)) 430b3fcedb9SMatthias Ringwald 431b3fcedb9SMatthias Ringwald format = parts[2] 432b3fcedb9SMatthias Ringwald exponent = parts[3] 433b3fcedb9SMatthias Ringwald unit = parseUUID(parts[4]) 434b3fcedb9SMatthias Ringwald name_space = parts[5] 435b3fcedb9SMatthias Ringwald description = parseUUID(parts[6]) 436b3fcedb9SMatthias Ringwald 437b3fcedb9SMatthias Ringwald size = 2 + 2 + 2 + 2 + 7 438b3fcedb9SMatthias Ringwald 439b3fcedb9SMatthias Ringwald write_indent(fout) 440b3fcedb9SMatthias Ringwald fout.write('// 0x%04x CHARACTERISTIC_FORMAT-%s\n' % (handle, '-'.join(parts[1:]))) 441b3fcedb9SMatthias Ringwald write_indent(fout) 442b3fcedb9SMatthias Ringwald write_16(fout, size) 443b3fcedb9SMatthias Ringwald write_16(fout, property_read) 444b3fcedb9SMatthias Ringwald write_16(fout, handle) 445b3fcedb9SMatthias Ringwald write_16(fout, 0x2904) 446b3fcedb9SMatthias Ringwald write_sequence(fout, format) 447b3fcedb9SMatthias Ringwald write_sequence(fout, exponent) 448b3fcedb9SMatthias Ringwald write_uuid(unit) 449b3fcedb9SMatthias Ringwald write_sequence(fout, name_space) 450b3fcedb9SMatthias Ringwald write_uuid(description) 451b3fcedb9SMatthias Ringwald fout.write("\n") 452b3fcedb9SMatthias Ringwald handle = handle + 1 453b3fcedb9SMatthias Ringwald 454b3fcedb9SMatthias Ringwald 455b3fcedb9SMatthias Ringwalddef parseCharacteristicAggregateFormat(fout, parts): 456b3fcedb9SMatthias Ringwald global handle 457b3fcedb9SMatthias Ringwald global total_size 458b3fcedb9SMatthias Ringwald 459b3fcedb9SMatthias Ringwald property_read = property_flags['READ']; 460b3fcedb9SMatthias Ringwald size = 2 + 2 + 2 + 2 + (len(parts)-1) * 2 461b3fcedb9SMatthias Ringwald 462b3fcedb9SMatthias Ringwald write_indent(fout) 463b3fcedb9SMatthias Ringwald fout.write('// 0x%04x CHARACTERISTIC_AGGREGATE_FORMAT-%s\n' % (handle, '-'.join(parts[1:]))) 464b3fcedb9SMatthias Ringwald write_indent(fout) 465b3fcedb9SMatthias Ringwald write_16(fout, size) 466b3fcedb9SMatthias Ringwald write_16(fout, property_read) 467b3fcedb9SMatthias Ringwald write_16(fout, handle) 468b3fcedb9SMatthias Ringwald write_16(fout, 0x2905) 469b3fcedb9SMatthias Ringwald for identifier in parts[1:]: 470b3fcedb9SMatthias Ringwald format_handle = presentation_formats[identifier] 471b3fcedb9SMatthias Ringwald if format == 0: 472b3fcedb9SMatthias Ringwald print("ERROR: identifier '%s' in CHARACTERISTIC_AGGREGATE_FORMAT undefined" % identifier) 473b3fcedb9SMatthias Ringwald sys.exit(1) 474b3fcedb9SMatthias Ringwald write_16(fout, format_handle) 475b3fcedb9SMatthias Ringwald fout.write("\n") 476b3fcedb9SMatthias Ringwald handle = handle + 1 477b3fcedb9SMatthias Ringwald 478b3fcedb9SMatthias Ringwalddef parseReportReference(fout, parts): 479b3fcedb9SMatthias Ringwald global handle 480b3fcedb9SMatthias Ringwald global total_size 481b3fcedb9SMatthias Ringwald 482b3fcedb9SMatthias Ringwald property_read = property_flags['READ']; 483b3fcedb9SMatthias Ringwald size = 2 + 2 + 2 + 2 + 1 + 1 484b3fcedb9SMatthias Ringwald 485231a3c5dSMatthias Ringwald properties = parseProperties(parts[1]) 486231a3c5dSMatthias Ringwald 487231a3c5dSMatthias Ringwald report_id = parts[2] 488231a3c5dSMatthias Ringwald report_type = parts[3] 489b3fcedb9SMatthias Ringwald 490b3fcedb9SMatthias Ringwald write_indent(fout) 491b3fcedb9SMatthias Ringwald fout.write('// 0x%04x REPORT_REFERENCE-%s\n' % (handle, '-'.join(parts[1:]))) 492b3fcedb9SMatthias Ringwald write_indent(fout) 493b3fcedb9SMatthias Ringwald write_16(fout, size) 494b3fcedb9SMatthias Ringwald write_16(fout, property_read) 495b3fcedb9SMatthias Ringwald write_16(fout, handle) 496b3fcedb9SMatthias Ringwald write_16(fout, 0x2908) 497b3fcedb9SMatthias Ringwald write_sequence(fout, report_id) 498b3fcedb9SMatthias Ringwald write_sequence(fout, report_type) 499b3fcedb9SMatthias Ringwald fout.write("\n") 500b3fcedb9SMatthias Ringwald handle = handle + 1 501b3fcedb9SMatthias Ringwald 502b3fcedb9SMatthias Ringwald 503b3fcedb9SMatthias Ringwalddef parseNumberOfDigitals(fout, parts): 504b3fcedb9SMatthias Ringwald global handle 505b3fcedb9SMatthias Ringwald global total_size 506b3fcedb9SMatthias Ringwald 507b3fcedb9SMatthias Ringwald property_read = property_flags['READ']; 508b3fcedb9SMatthias Ringwald size = 2 + 2 + 2 + 2 + 1 509b3fcedb9SMatthias Ringwald 510b3fcedb9SMatthias Ringwald no_of_digitals = parts[1] 511b3fcedb9SMatthias Ringwald 512b3fcedb9SMatthias Ringwald write_indent(fout) 513b3fcedb9SMatthias Ringwald fout.write('// 0x%04x NUMBER_OF_DIGITALS-%s\n' % (handle, '-'.join(parts[1:]))) 514b3fcedb9SMatthias Ringwald write_indent(fout) 515b3fcedb9SMatthias Ringwald write_16(fout, size) 516b3fcedb9SMatthias Ringwald write_16(fout, property_read) 517b3fcedb9SMatthias Ringwald write_16(fout, handle) 518b3fcedb9SMatthias Ringwald write_16(fout, 0x2909) 519b3fcedb9SMatthias Ringwald write_sequence(fout, no_of_digitals) 520b3fcedb9SMatthias Ringwald fout.write("\n") 521b3fcedb9SMatthias Ringwald handle = handle + 1 522b3fcedb9SMatthias Ringwald 52360b51a4cSMatthias Ringwalddef parseLines(fname_in, fin, fout): 524b3fcedb9SMatthias Ringwald global handle 525b3fcedb9SMatthias Ringwald global total_size 526b3fcedb9SMatthias Ringwald 527b165f97bSMatthias Ringwald line_count = 0; 528b3fcedb9SMatthias Ringwald for line in fin: 529b3fcedb9SMatthias Ringwald line = line.strip("\n\r ") 530b165f97bSMatthias Ringwald line_count += 1 531b3fcedb9SMatthias Ringwald 532b165f97bSMatthias Ringwald if line.startswith("//"): 533b165f97bSMatthias Ringwald fout.write(" //" + line.lstrip('/') + '\n') 534b165f97bSMatthias Ringwald continue 535b165f97bSMatthias Ringwald 53660b51a4cSMatthias Ringwald if line.startswith("#import"): 53760b51a4cSMatthias Ringwald imported_file = '' 53860b51a4cSMatthias Ringwald parts = re.match('#import\s+<(.*)>\w*',line) 53960b51a4cSMatthias Ringwald if parts and len(parts.groups()) == 1: 54085a677ecSMatthias Ringwald imported_file = btstack_root+'/src/ble/gatt-service/' + parts.groups()[0] 54160b51a4cSMatthias Ringwald parts = re.match('#import\s+"(.*)"\w*',line) 54260b51a4cSMatthias Ringwald if parts and len(parts.groups()) == 1: 54360b51a4cSMatthias Ringwald imported_file = os.path.abspath(os.path.dirname(fname_in) + '/'+parts.groups()[0]) 54460b51a4cSMatthias Ringwald if len(imported_file) == 0: 54560b51a4cSMatthias Ringwald print('ERROR: #import in file %s - line %u neither <name.gatt> nor "name.gatt" form', (fname_in, line_count)) 54660b51a4cSMatthias Ringwald continue 54760b51a4cSMatthias Ringwald 54860b51a4cSMatthias Ringwald print("Importing %s" % imported_file) 54960b51a4cSMatthias Ringwald try: 55060b51a4cSMatthias Ringwald imported_fin = codecs.open (imported_file, encoding='utf-8') 55160b51a4cSMatthias Ringwald fout.write(' // ' + line + ' -- BEGIN\n') 55260b51a4cSMatthias Ringwald parseLines(imported_file, imported_fin, fout) 55360b51a4cSMatthias Ringwald fout.write(' // ' + line + ' -- END\n') 55460b51a4cSMatthias Ringwald except IOError as e: 55560b51a4cSMatthias Ringwald print('ERROR: Import failed. Please check path.') 55660b51a4cSMatthias Ringwald 55760b51a4cSMatthias Ringwald continue 55860b51a4cSMatthias Ringwald 55960b51a4cSMatthias Ringwald if line.startswith("#TODO"): 56060b51a4cSMatthias Ringwald print ("WARNING: #TODO in file %s - line %u not handled, skipping declaration:" % (fname_in, line_count)) 561b165f97bSMatthias Ringwald print ("'%s'" % line) 562b165f97bSMatthias Ringwald fout.write("// " + line + '\n') 563b3fcedb9SMatthias Ringwald continue 564b3fcedb9SMatthias Ringwald 565b3fcedb9SMatthias Ringwald if len(line) == 0: 566b3fcedb9SMatthias Ringwald continue 567b3fcedb9SMatthias Ringwald 568b3fcedb9SMatthias Ringwald f = io.StringIO(line) 569b3fcedb9SMatthias Ringwald parts_list = csv.reader(f, delimiter=',', quotechar='"') 570b3fcedb9SMatthias Ringwald 571b3fcedb9SMatthias Ringwald for parts in parts_list: 572b3fcedb9SMatthias Ringwald for index, object in enumerate(parts): 573b3fcedb9SMatthias Ringwald parts[index] = object.strip().lstrip('"').rstrip('"') 574b3fcedb9SMatthias Ringwald 575b3fcedb9SMatthias Ringwald if parts[0] == 'PRIMARY_SERVICE': 576b3fcedb9SMatthias Ringwald parsePrimaryService(fout, parts) 577b3fcedb9SMatthias Ringwald continue 578b3fcedb9SMatthias Ringwald 579b3fcedb9SMatthias Ringwald if parts[0] == 'SECONDARY_SERVICE': 580b3fcedb9SMatthias Ringwald parseSecondaryService(fout, parts) 581b3fcedb9SMatthias Ringwald continue 582b3fcedb9SMatthias Ringwald 583b3fcedb9SMatthias Ringwald if parts[0] == 'INCLUDE_SERVICE': 584b3fcedb9SMatthias Ringwald parseIncludeService(fout, parts) 585b3fcedb9SMatthias Ringwald continue 586b3fcedb9SMatthias Ringwald 587b3fcedb9SMatthias Ringwald # 2803 588b3fcedb9SMatthias Ringwald if parts[0] == 'CHARACTERISTIC': 589b3fcedb9SMatthias Ringwald parseCharacteristic(fout, parts) 590b3fcedb9SMatthias Ringwald continue 591b3fcedb9SMatthias Ringwald 592b3fcedb9SMatthias Ringwald # 2900 Characteristic Extended Properties 593b3fcedb9SMatthias Ringwald 594b3fcedb9SMatthias Ringwald # 2901 595b3fcedb9SMatthias Ringwald if parts[0] == 'CHARACTERISTIC_USER_DESCRIPTION': 596b3fcedb9SMatthias Ringwald parseCharacteristicUserDescription(fout, parts) 597b3fcedb9SMatthias Ringwald continue 598b3fcedb9SMatthias Ringwald 599b165f97bSMatthias Ringwald 600b165f97bSMatthias Ringwald # 2902 Client Characteristic Configuration - automatically included in Characteristic if 601b3fcedb9SMatthias Ringwald # notification / indication is supported 602231a3c5dSMatthias Ringwald if parts[0] == 'CLIENT_CHARACTERISTIC_CONFIGURATION': 603b165f97bSMatthias Ringwald continue 604b3fcedb9SMatthias Ringwald 605b3fcedb9SMatthias Ringwald # 2903 606b3fcedb9SMatthias Ringwald if parts[0] == 'SERVER_CHARACTERISTIC_CONFIGURATION': 607b3fcedb9SMatthias Ringwald parseServerCharacteristicConfiguration(fout, parts) 608b3fcedb9SMatthias Ringwald continue 609b3fcedb9SMatthias Ringwald 610b3fcedb9SMatthias Ringwald # 2904 611b3fcedb9SMatthias Ringwald if parts[0] == 'CHARACTERISTIC_FORMAT': 612b3fcedb9SMatthias Ringwald parseCharacteristicFormat(fout, parts) 613b3fcedb9SMatthias Ringwald continue 614b3fcedb9SMatthias Ringwald 615b3fcedb9SMatthias Ringwald # 2905 616b3fcedb9SMatthias Ringwald if parts[0] == 'CHARACTERISTIC_AGGREGATE_FORMAT': 617b3fcedb9SMatthias Ringwald parseCharacteristicAggregateFormat(fout, parts) 618b3fcedb9SMatthias Ringwald continue 619b3fcedb9SMatthias Ringwald 620b3fcedb9SMatthias Ringwald # 2906 621b3fcedb9SMatthias Ringwald if parts[0] == 'VALID_RANGE': 622b3fcedb9SMatthias Ringwald print("WARNING: %s not implemented yet\n" % (parts[0])) 623b3fcedb9SMatthias Ringwald continue 624b3fcedb9SMatthias Ringwald 625b3fcedb9SMatthias Ringwald # 2907 626b3fcedb9SMatthias Ringwald if parts[0] == 'EXTERNAL_REPORT_REFERENCE': 627b3fcedb9SMatthias Ringwald print("WARNING: %s not implemented yet\n" % (parts[0])) 628b3fcedb9SMatthias Ringwald continue 629b3fcedb9SMatthias Ringwald 630b3fcedb9SMatthias Ringwald # 2908 631b3fcedb9SMatthias Ringwald if parts[0] == 'REPORT_REFERENCE': 632b3fcedb9SMatthias Ringwald parseReportReference(fout, parts) 633b3fcedb9SMatthias Ringwald continue 634b3fcedb9SMatthias Ringwald 635b3fcedb9SMatthias Ringwald # 2909 636b3fcedb9SMatthias Ringwald if parts[0] == 'NUMBER_OF_DIGITALS': 637b3fcedb9SMatthias Ringwald parseNumberOfDigitals(fout, parts) 638b3fcedb9SMatthias Ringwald continue 639b3fcedb9SMatthias Ringwald 640b3fcedb9SMatthias Ringwald # 290A 641b3fcedb9SMatthias Ringwald if parts[0] == 'VALUE_TRIGGER_SETTING': 642b3fcedb9SMatthias Ringwald print("WARNING: %s not implemented yet\n" % (parts[0])) 643b3fcedb9SMatthias Ringwald continue 644b3fcedb9SMatthias Ringwald 645b3fcedb9SMatthias Ringwald # 290B 646b3fcedb9SMatthias Ringwald if parts[0] == 'ENVIRONMENTAL_SENSING_CONFIGURATION': 647b3fcedb9SMatthias Ringwald print("WARNING: %s not implemented yet\n" % (parts[0])) 648b3fcedb9SMatthias Ringwald continue 649b3fcedb9SMatthias Ringwald 650b3fcedb9SMatthias Ringwald # 290C 651b3fcedb9SMatthias Ringwald if parts[0] == 'ENVIRONMENTAL_SENSING_MEASUREMENT': 652b3fcedb9SMatthias Ringwald print("WARNING: %s not implemented yet\n" % (parts[0])) 653b3fcedb9SMatthias Ringwald continue 654b3fcedb9SMatthias Ringwald 655b3fcedb9SMatthias Ringwald # 290D 656b3fcedb9SMatthias Ringwald if parts[0] == 'ENVIRONMENTAL_SENSING_TRIGGER_SETTING': 657b3fcedb9SMatthias Ringwald print("WARNING: %s not implemented yet\n" % (parts[0])) 658b3fcedb9SMatthias Ringwald continue 659b3fcedb9SMatthias Ringwald 660b3fcedb9SMatthias Ringwald # 2906 661b3fcedb9SMatthias Ringwald if parts[0] == 'VALID_RANGE': 662b3fcedb9SMatthias Ringwald print("WARNING: %s not implemented yet\n" % (parts[0])) 663b3fcedb9SMatthias Ringwald continue 664b3fcedb9SMatthias Ringwald 665b3fcedb9SMatthias Ringwald print("WARNING: unknown token: %s\n" % (parts[0])) 666b3fcedb9SMatthias Ringwald 66760b51a4cSMatthias Ringwalddef parse(fname_in, fin, fname_out, fout): 66860b51a4cSMatthias Ringwald global handle 66960b51a4cSMatthias Ringwald global total_size 67060b51a4cSMatthias Ringwald 67160b51a4cSMatthias Ringwald fout.write(header.format(fname_out, fname_in)) 67260b51a4cSMatthias Ringwald fout.write('{\n') 67360b51a4cSMatthias Ringwald 67460b51a4cSMatthias Ringwald parseLines(fname_in, fin, fout) 67560b51a4cSMatthias Ringwald 676729074c4SMatthias Ringwald serviceDefinitionComplete(fout) 677b3fcedb9SMatthias Ringwald write_indent(fout) 678b3fcedb9SMatthias Ringwald fout.write("// END\n"); 679b3fcedb9SMatthias Ringwald write_indent(fout) 680b3fcedb9SMatthias Ringwald write_16(fout,0) 681b3fcedb9SMatthias Ringwald fout.write("\n") 682b3fcedb9SMatthias Ringwald total_size = total_size + 2 683b3fcedb9SMatthias Ringwald 684b3fcedb9SMatthias Ringwald fout.write("}; // total size %u bytes \n" % total_size); 685b3fcedb9SMatthias Ringwald 686b3fcedb9SMatthias Ringwalddef listHandles(fout): 687b3fcedb9SMatthias Ringwald fout.write('\n\n') 688b3fcedb9SMatthias Ringwald fout.write('//\n') 689729074c4SMatthias Ringwald fout.write('// list service handle ranges\n') 690729074c4SMatthias Ringwald fout.write('//\n') 691729074c4SMatthias Ringwald for define in defines_for_services: 692729074c4SMatthias Ringwald fout.write(define) 693729074c4SMatthias Ringwald fout.write('\n') 694729074c4SMatthias Ringwald fout.write('\n') 695729074c4SMatthias Ringwald fout.write('//\n') 696b3fcedb9SMatthias Ringwald fout.write('// list mapping between characteristics and handles\n') 697b3fcedb9SMatthias Ringwald fout.write('//\n') 698729074c4SMatthias Ringwald for define in defines_for_characteristics: 699b3fcedb9SMatthias Ringwald fout.write(define) 700b3fcedb9SMatthias Ringwald fout.write('\n') 701b3fcedb9SMatthias Ringwald 702b3fcedb9SMatthias Ringwaldif (len(sys.argv) < 3): 703b3fcedb9SMatthias Ringwald print(usage) 704b3fcedb9SMatthias Ringwald sys.exit(1) 705b3fcedb9SMatthias Ringwaldtry: 706b165f97bSMatthias Ringwald # read defines from bluetooth_gatt.h 707b165f97bSMatthias Ringwald btstack_root = os.path.abspath(os.path.dirname(sys.argv[0]) + '/..') 708b165f97bSMatthias Ringwald gen_path = btstack_root + '/src/bluetooth_gatt.h' 709b165f97bSMatthias Ringwald bluetooth_gatt = read_defines(gen_path) 710b165f97bSMatthias Ringwald 711b3fcedb9SMatthias Ringwald filename = sys.argv[2] 712b3fcedb9SMatthias Ringwald fin = codecs.open (sys.argv[1], encoding='utf-8') 713b3fcedb9SMatthias Ringwald fout = open (filename, 'w') 714b3fcedb9SMatthias Ringwald parse(sys.argv[1], fin, filename, fout) 715b3fcedb9SMatthias Ringwald listHandles(fout) 716b3fcedb9SMatthias Ringwald fout.close() 717b165f97bSMatthias Ringwald print('Created %s' % filename) 718b3fcedb9SMatthias Ringwald 719b3fcedb9SMatthias Ringwaldexcept IOError as e: 720b3fcedb9SMatthias Ringwald print(usage) 721b3fcedb9SMatthias Ringwald sys.exit(1) 722b3fcedb9SMatthias Ringwald 723b3fcedb9SMatthias Ringwaldprint('Compilation successful!\n') 724