1#!/usr/bin/env python3 2# 3# Scrape GATT UUIDs from Bluetooth SIG page 4# https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers 5# 6# Copyright 2017 BlueKitchen GmbH 7# 8 9from lxml import html 10import datetime 11import requests 12import sys 13import codecs 14import os 15import re 16 17import csv 18import getopt 19 20 21program_info = ''' 22BTstack Company ID Scraper for BTstack 23Copyright 2022, BlueKitchen GmbH 24''' 25 26header = ''' 27/** 28 * bluetooth_company_id.h generated from Bluetooth SIG website for BTstack by tool/bluetooth_company_id.py 29 * {datetime} 30 */ 31 32#ifndef BLUETOOTH_COMPANY_ID_H 33#define BLUETOOTH_COMPANY_ID_H 34''' 35 36page_info = ''' 37/** 38 * Assigned numbers from {page} 39 */ 40''' 41 42trailer = ''' 43#endif 44''' 45 46tags = [] 47 48def strip_non_ascii(string): 49 stripped = (c for c in string if 0 < ord(c) < 127) 50 return ''.join(stripped) 51 52def create_name(company): 53 # limit to ascii 54 company = strip_non_ascii(company) 55 # remove parts in braces 56 p = re.compile('\(.*\)') 57 tag = p.sub('',company).rstrip().upper() 58 tag = tag.replace('&',' AND ') 59 tag = tag.replace(''','') 60 tag = tag.replace('"',' ') 61 tag = tag.replace('+',' AND ') 62 tag = tag.replace(' - ', ' ') 63 tag = tag.replace('/', ' ') 64 tag = tag.replace(';',' ') 65 tag = tag.replace(',','') 66 tag = tag.replace('.', '') 67 tag = tag.replace('-','_') 68 tag = tag.replace(' ',' ') 69 tag = tag.replace(' ','_') 70 tag = tag.replace('&','AND') 71 tag = tag.replace("'","_") 72 tag = tag.replace('"','_') 73 tag = tag.replace('!','_') 74 tag = tag.replace('|','_') 75 tag = tag.replace('[','') 76 tag = tag.replace(']','') 77 return "BLUETOOTH_COMPANY_ID_" + tag 78 79def parse_cvs(csv_file): 80 cvsreader = csv.reader(csv_file, delimiter=',', quotechar='\"') 81 # Skip header ['"Decimal","Hexadecimal","Company"'] 82 next(cvsreader) 83 84 companies = {} 85 for row in cvsreader: 86 id_dec = int(row[0]) 87 companies[id_dec] = (row[1],row[2]) 88 return companies 89 90 91def write_cvs(fout, companies, url): 92 global tags 93 fout.write(page_info.format(page=url.replace('https://',''))) 94 95 company_ids = sorted(list(companies.keys())) 96 97 for id_dec in company_ids: 98 id_hex = companies[id_dec][0] 99 company = create_name(companies[id_dec][1]) 100 101 if company in tags: 102 company = company+"2" 103 else: 104 tags.append(company) 105 106 fout.write("#define %-80s %s\n" % (company, id_hex)) 107 108 # map CSR onto QTIL 109 fout.write("#define BLUETOOTH_COMPANY_ID_CAMBRIDGE_SILICON_RADIO BLUETOOTH_COMPANY_ID_QUALCOMM_TECHNOLOGIES_INTERNATIONAL_LTD\n") 110 111def main(argv): 112 url = "https://www.bluetooth.com/de/specifications/assigned-numbers/company-identifiers/#" 113 btstack_root = os.path.abspath(os.path.dirname(sys.argv[0]) + '/..') 114 tools_root = btstack_root + '/tool' 115 src_root = btstack_root + '/src/' 116 117 header_filename = "bluetooth_company_id.h" 118 header_path = btstack_root + "/src/" + header_filename 119 120 cvs_filename = "CompanyIdentfiers - CSV.csv" 121 cvs_path = tools_root + "/" + cvs_filename 122 123 print(program_info) 124 125 try: 126 header_file = open(header_path, "w") 127 except FileNotFoundError: 128 print("\nFile \'%s\' cannot be created in \'%s\' directory." % (header_filename, src_root)) 129 exit(1) 130 131 try: 132 with open(cvs_path, "r") as csv_file: 133 companies = parse_cvs(csv_file) 134 135 header_file.write(header.format(datetime=str(datetime.datetime.now()))) 136 write_cvs(header_file, companies, url) 137 header_file.write(trailer) 138 139 print("Company IDs are stored in \'%s\'\n" % (header_path)) 140 except FileNotFoundError: 141 print("\nCVS file \'%s\' not found in \'%s\'." % (cvs_filename, tools_root)) 142 print("Please download the CVS file, then start the skript again.\n") 143 print("The CVS file can be downloaded from:") 144 print(" %s\n" % url) 145 exit(1) 146 147if __name__ == "__main__": 148 main(sys.argv[1:]) 149 150 151