xref: /btstack/tool/bluetooth_gatt.py (revision 5c54401929043df982e040eba652f5fd7763ce15)
1*5c544019SMatthias Ringwald#!/usr/bin/env python3
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
130d9cb02cSMatthias Ringwaldheaders = {'user-agent': 'curl/7.63.0'}
140d9cb02cSMatthias Ringwald
150e0e9559SMatthias Ringwaldprogram_info = '''
160e0e9559SMatthias RingwaldBTstack GATT UUID Scraper for BTstack
170e0e9559SMatthias RingwaldCopyright 2016, BlueKitchen GmbH
180e0e9559SMatthias Ringwald'''
190e0e9559SMatthias Ringwald
200e0e9559SMatthias Ringwaldheader = '''
210e0e9559SMatthias Ringwald/**
22b436f177SMatthias Ringwald * bluetooth_gatt.h generated from Bluetooth SIG website for BTstack tool/bluetooth_gatt.py
23b436f177SMatthias Ringwald * {datetime}
240e0e9559SMatthias Ringwald */
250e0e9559SMatthias Ringwald
2680e33422SMatthias Ringwald#ifndef BLUETOOTH_GATT_H
2780e33422SMatthias Ringwald#define BLUETOOTH_GATT_H
280e0e9559SMatthias Ringwald'''
290e0e9559SMatthias Ringwald
300e0e9559SMatthias Ringwaldpage_info = '''
310e0e9559SMatthias Ringwald/**
320e0e9559SMatthias Ringwald * Assigned numbers from {page}
330e0e9559SMatthias Ringwald */
340e0e9559SMatthias Ringwald'''
350e0e9559SMatthias Ringwald
360e0e9559SMatthias Ringwaldtrailer = '''
370e0e9559SMatthias Ringwald#endif
380e0e9559SMatthias Ringwald'''
390e0e9559SMatthias Ringwald
400d9cb02cSMatthias Ringwalddef strip_non_ascii(string):
410d9cb02cSMatthias Ringwald    stripped = (c for c in string if 0 < ord(c) < 127)
420d9cb02cSMatthias Ringwald    return ''.join(stripped)
430d9cb02cSMatthias Ringwald
440e0e9559SMatthias Ringwalddef scrape_page(fout, url):
450e0e9559SMatthias Ringwald    print("Parsing %s" % url)
46d918542bSMatthias Ringwald    fout.write(page_info.format(page=url.replace('https://','')))
470d9cb02cSMatthias Ringwald    page = requests.get(url, headers=headers)
480e0e9559SMatthias Ringwald    tree = html.fromstring(page.content)
490d9cb02cSMatthias Ringwald    # get all <tr> elements in <table>
500d9cb02cSMatthias Ringwald    rows = tree.xpath('//table/tbody/tr')
510e0e9559SMatthias Ringwald    for row in rows:
520e0e9559SMatthias Ringwald        children = row.getchildren()
530d9cb02cSMatthias Ringwald        summary = strip_non_ascii(children[0].text_content())
540e0e9559SMatthias Ringwald        id      = children[1].text_content()
550d9cb02cSMatthias Ringwald        # fix unexpected suffix _
560d9cb02cSMatthias Ringwald        id = id.replace('.gatt_.', '.gatt.')
570e0e9559SMatthias Ringwald        uuid    = children[2].text_content()
580e0e9559SMatthias Ringwald        if (len(id)):
5966fd3432SMatthias Ringwald            tag = id.upper().replace('.', '_').replace('-','_')
6066fd3432SMatthias Ringwald            fout.write("#define %-80s %s // %s\n" %  (tag, uuid, summary))
610e0e9559SMatthias Ringwald
620e0e9559SMatthias Ringwaldbtstack_root = os.path.abspath(os.path.dirname(sys.argv[0]) + '/..')
630e0e9559SMatthias Ringwaldgen_path = btstack_root + '/src/bluetooth_gatt.h'
640e0e9559SMatthias Ringwald
650e0e9559SMatthias Ringwaldprint(program_info)
660e0e9559SMatthias Ringwald
670e0e9559SMatthias Ringwaldwith open(gen_path, 'wt') as fout:
680e0e9559SMatthias Ringwald    fout.write(header.format(datetime=str(datetime.datetime.now())))
690e0e9559SMatthias Ringwald    scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/declarations')
700e0e9559SMatthias Ringwald    scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/services')
710e0e9559SMatthias Ringwald    scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/characteristics')
720e0e9559SMatthias Ringwald    scrape_page(fout, 'https://www.bluetooth.com/specifications/gatt/descriptors')
7336d972adSMilanka Ringwald    fout.write("// START(manually added, missing on Bluetooth Website\n")
7436d972adSMilanka Ringwald    fout.write("#define %-80s %s // %s\n" %  ("ORG_BLUETOOTH_CHARACTERISTIC_MESH_PROVISIONING_DATA_IN" , "0x2ADB", ''))
7536d972adSMilanka Ringwald    fout.write("#define %-80s %s // %s\n" %  ("ORG_BLUETOOTH_CHARACTERISTIC_MESH_PROVISIONING_DATA_OUT", "0x2ADC", ''))
7636d972adSMilanka Ringwald    fout.write("#define %-80s %s // %s\n" %  ("ORG_BLUETOOTH_CHARACTERISTIC_MESH_PROXY_DATA_IN"        , "0x2ADD", ''))
7736d972adSMilanka Ringwald    fout.write("#define %-80s %s // %s\n" %  ("ORG_BLUETOOTH_CHARACTERISTIC_MESH_PROXY_DATA_OUT"       , "0x2ADE", ''))
7836d972adSMilanka Ringwald    fout.write("// END(manualy added, missing on Bluetooth Website\n")
790e0e9559SMatthias Ringwald    fout.write(trailer)
800e0e9559SMatthias Ringwald
810e0e9559SMatthias Ringwaldprint('Scraping successful!\n')
82