1*0e0e9559SMatthias Ringwald#!/usr/bin/env python 2*0e0e9559SMatthias Ringwald# 3*0e0e9559SMatthias Ringwald# Scrape GATT UUIDs from Bluetooth SIG page 4*0e0e9559SMatthias Ringwald# Copyright 2016 BlueKitchen GmbH 5*0e0e9559SMatthias Ringwald# 6*0e0e9559SMatthias Ringwald 7*0e0e9559SMatthias Ringwaldfrom lxml import html 8*0e0e9559SMatthias Ringwaldimport datetime 9*0e0e9559SMatthias Ringwaldimport requests 10*0e0e9559SMatthias Ringwaldimport sys 11*0e0e9559SMatthias Ringwaldimport os 12*0e0e9559SMatthias Ringwald 13*0e0e9559SMatthias Ringwaldprogram_info = ''' 14*0e0e9559SMatthias RingwaldBTstack GATT UUID Scraper for BTstack 15*0e0e9559SMatthias RingwaldCopyright 2016, BlueKitchen GmbH 16*0e0e9559SMatthias Ringwald''' 17*0e0e9559SMatthias Ringwald 18*0e0e9559SMatthias Ringwaldheader = ''' 19*0e0e9559SMatthias Ringwald/** 20*0e0e9559SMatthias Ringwald * bluetooth_gatt.h generated from Bluetooth SIG website for BTstack 21*0e0e9559SMatthias Ringwald * {datetime} 22*0e0e9559SMatthias Ringwald */ 23*0e0e9559SMatthias Ringwald 24*0e0e9559SMatthias Ringwald#ifndef __BLUETOOTH_GATT_H 25*0e0e9559SMatthias Ringwald#define __BLUETOOTH_GATT_H 26*0e0e9559SMatthias Ringwald''' 27*0e0e9559SMatthias Ringwald 28*0e0e9559SMatthias Ringwaldpage_info = ''' 29*0e0e9559SMatthias Ringwald/** 30*0e0e9559SMatthias Ringwald * Assigned numbers from {page} 31*0e0e9559SMatthias Ringwald */ 32*0e0e9559SMatthias Ringwald''' 33*0e0e9559SMatthias Ringwald 34*0e0e9559SMatthias Ringwaldtrailer = ''' 35*0e0e9559SMatthias Ringwald#endif 36*0e0e9559SMatthias Ringwald''' 37*0e0e9559SMatthias Ringwald 38*0e0e9559SMatthias Ringwalddef scrape_page(fout, url): 39*0e0e9559SMatthias Ringwald print("Parsing %s" % url) 40*0e0e9559SMatthias Ringwald fout.write(page_info.format(page=url)) 41*0e0e9559SMatthias Ringwald page = requests.get(url) 42*0e0e9559SMatthias Ringwald tree = html.fromstring(page.content) 43*0e0e9559SMatthias Ringwald # get all <tr> elements in <table id="gattTable"> 44*0e0e9559SMatthias Ringwald rows = tree.xpath('//table[@id="gattTable"]/tr') 45*0e0e9559SMatthias Ringwald for row in rows: 46*0e0e9559SMatthias Ringwald children = row.getchildren() 47*0e0e9559SMatthias Ringwald summary = children[0].text_content() 48*0e0e9559SMatthias Ringwald id = children[1].text_content() 49*0e0e9559SMatthias Ringwald uuid = children[2].text_content() 50*0e0e9559SMatthias Ringwald if (len(id)): 51*0e0e9559SMatthias Ringwald tag = id.upper().replace('.', '_') 52*0e0e9559SMatthias Ringwald fout.write("#define %s %s // %s\n" % (tag, uuid, summary)) 53*0e0e9559SMatthias Ringwald 54*0e0e9559SMatthias Ringwaldbtstack_root = os.path.abspath(os.path.dirname(sys.argv[0]) + '/..') 55*0e0e9559SMatthias Ringwaldgen_path = btstack_root + '/src/bluetooth_gatt.h' 56*0e0e9559SMatthias Ringwald 57*0e0e9559SMatthias Ringwaldprint(program_info) 58*0e0e9559SMatthias Ringwald 59*0e0e9559SMatthias Ringwaldwith open(gen_path, 'wt') as fout: 60*0e0e9559SMatthias Ringwald fout.write(header.format(datetime=str(datetime.datetime.now()))) 61*0e0e9559SMatthias Ringwald scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/declarations') 62*0e0e9559SMatthias Ringwald scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/services') 63*0e0e9559SMatthias Ringwald scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/characteristics') 64*0e0e9559SMatthias Ringwald scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/descriptors') 65*0e0e9559SMatthias Ringwald fout.write(trailer) 66*0e0e9559SMatthias Ringwald 67*0e0e9559SMatthias Ringwaldprint('Scraping successful!\n')