10e0e9559SMatthias Ringwald#!/usr/bin/env python 20e0e9559SMatthias Ringwald# 30e0e9559SMatthias Ringwald# Scrape GATT UUIDs from Bluetooth SIG page 40e0e9559SMatthias Ringwald# Copyright 2016 BlueKitchen GmbH 50e0e9559SMatthias Ringwald# 60e0e9559SMatthias Ringwald 70e0e9559SMatthias Ringwaldfrom lxml import html 80e0e9559SMatthias Ringwaldimport datetime 90e0e9559SMatthias Ringwaldimport requests 100e0e9559SMatthias Ringwaldimport sys 110e0e9559SMatthias Ringwaldimport os 120e0e9559SMatthias Ringwald 130e0e9559SMatthias Ringwaldprogram_info = ''' 140e0e9559SMatthias RingwaldBTstack GATT UUID Scraper for BTstack 150e0e9559SMatthias RingwaldCopyright 2016, BlueKitchen GmbH 160e0e9559SMatthias Ringwald''' 170e0e9559SMatthias Ringwald 180e0e9559SMatthias Ringwaldheader = ''' 190e0e9559SMatthias Ringwald/** 20*b436f177SMatthias Ringwald * bluetooth_gatt.h generated from Bluetooth SIG website for BTstack tool/bluetooth_gatt.py 21*b436f177SMatthias Ringwald * {datetime} 220e0e9559SMatthias Ringwald */ 230e0e9559SMatthias Ringwald 240e0e9559SMatthias Ringwald#ifndef __BLUETOOTH_GATT_H 250e0e9559SMatthias Ringwald#define __BLUETOOTH_GATT_H 260e0e9559SMatthias Ringwald''' 270e0e9559SMatthias Ringwald 280e0e9559SMatthias Ringwaldpage_info = ''' 290e0e9559SMatthias Ringwald/** 300e0e9559SMatthias Ringwald * Assigned numbers from {page} 310e0e9559SMatthias Ringwald */ 320e0e9559SMatthias Ringwald''' 330e0e9559SMatthias Ringwald 340e0e9559SMatthias Ringwaldtrailer = ''' 350e0e9559SMatthias Ringwald#endif 360e0e9559SMatthias Ringwald''' 370e0e9559SMatthias Ringwald 380e0e9559SMatthias Ringwalddef scrape_page(fout, url): 390e0e9559SMatthias Ringwald print("Parsing %s" % url) 400e0e9559SMatthias Ringwald fout.write(page_info.format(page=url)) 410e0e9559SMatthias Ringwald page = requests.get(url) 420e0e9559SMatthias Ringwald tree = html.fromstring(page.content) 430e0e9559SMatthias Ringwald # get all <tr> elements in <table id="gattTable"> 4486f9f81aSMatthias Ringwald rows = tree.xpath('//table[@id="gattTable"]/tbody/tr') 450e0e9559SMatthias Ringwald for row in rows: 460e0e9559SMatthias Ringwald children = row.getchildren() 470e0e9559SMatthias Ringwald summary = children[0].text_content() 480e0e9559SMatthias Ringwald id = children[1].text_content() 490e0e9559SMatthias Ringwald uuid = children[2].text_content() 500e0e9559SMatthias Ringwald if (len(id)): 5166fd3432SMatthias Ringwald tag = id.upper().replace('.', '_').replace('-','_') 5266fd3432SMatthias Ringwald fout.write("#define %-80s %s // %s\n" % (tag, uuid, summary)) 530e0e9559SMatthias Ringwald 540e0e9559SMatthias Ringwaldbtstack_root = os.path.abspath(os.path.dirname(sys.argv[0]) + '/..') 550e0e9559SMatthias Ringwaldgen_path = btstack_root + '/src/bluetooth_gatt.h' 560e0e9559SMatthias Ringwald 570e0e9559SMatthias Ringwaldprint(program_info) 580e0e9559SMatthias Ringwald 590e0e9559SMatthias Ringwaldwith open(gen_path, 'wt') as fout: 600e0e9559SMatthias Ringwald fout.write(header.format(datetime=str(datetime.datetime.now()))) 610e0e9559SMatthias Ringwald scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/declarations') 620e0e9559SMatthias Ringwald scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/services') 630e0e9559SMatthias Ringwald scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/characteristics') 640e0e9559SMatthias Ringwald scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/descriptors') 650e0e9559SMatthias Ringwald fout.write(trailer) 660e0e9559SMatthias Ringwald 670e0e9559SMatthias Ringwaldprint('Scraping successful!\n') 68