xref: /btstack/tool/bluetooth_gatt.py (revision bdc352b16da8ddb06e0abca313290fcc1e06a43b)
1#!/usr/bin/env python
2#
3# Scrape GATT UUIDs from Bluetooth SIG page
4# Copyright 2016 BlueKitchen GmbH
5#
6
7from lxml import html
8import datetime
9import requests
10import sys
11import os
12
13headers = {'user-agent': 'curl/7.63.0'}
14
15program_info = '''
16BTstack GATT UUID Scraper for BTstack
17Copyright 2016, BlueKitchen GmbH
18'''
19
20header = '''
21/**
22 * bluetooth_gatt.h generated from Bluetooth SIG website for BTstack tool/bluetooth_gatt.py
23 * {datetime}
24 */
25
26#ifndef BLUETOOTH_GATT_H
27#define BLUETOOTH_GATT_H
28'''
29
30page_info = '''
31/**
32 * Assigned numbers from {page}
33 */
34'''
35
36trailer = '''
37#endif
38'''
39
40def strip_non_ascii(string):
41    stripped = (c for c in string if 0 < ord(c) < 127)
42    return ''.join(stripped)
43
44def scrape_page(fout, url):
45    print("Parsing %s" % url)
46    fout.write(page_info.format(page=url))
47    page = requests.get(url, headers=headers)
48    tree = html.fromstring(page.content)
49    # get all <tr> elements in <table>
50    rows = tree.xpath('//table/tbody/tr')
51    for row in rows:
52        children = row.getchildren()
53        summary = strip_non_ascii(children[0].text_content())
54        id      = children[1].text_content()
55        # fix unexpected suffix _
56        id = id.replace('.gatt_.', '.gatt.')
57        uuid    = children[2].text_content()
58        if (len(id)):
59            tag = id.upper().replace('.', '_').replace('-','_')
60            fout.write("#define %-80s %s // %s\n" %  (tag, uuid, summary))
61
62btstack_root = os.path.abspath(os.path.dirname(sys.argv[0]) + '/..')
63gen_path = btstack_root + '/src/bluetooth_gatt.h'
64
65print(program_info)
66
67with open(gen_path, 'wt') as fout:
68    fout.write(header.format(datetime=str(datetime.datetime.now())))
69    scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/declarations')
70    scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/services')
71    scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/characteristics')
72    scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/descriptors')
73    fout.write(trailer)
74
75print('Scraping successful!\n')
76