1import asyncio
2import click
3import logging
4import json
5
6from bumble.pandora import PandoraDevice, Config, serve
7from typing import Dict, Any
8
9BUMBLE_SERVER_GRPC_PORT = 7999
10ROOTCANAL_PORT_CUTTLEFISH = 7300
11
12
13@click.command()
14@click.option('--grpc-port', help='gRPC port to serve', default=BUMBLE_SERVER_GRPC_PORT)
15@click.option(
16    '--rootcanal-port', help='Rootcanal TCP port', default=ROOTCANAL_PORT_CUTTLEFISH
17)
18@click.option(
19    '--transport',
20    help='HCI transport',
21    default=f'tcp-client:127.0.0.1:<rootcanal-port>',
22)
23@click.option(
24    '--config',
25    help='Bumble json configuration file',
26)
27def main(grpc_port: int, rootcanal_port: int, transport: str, config: str) -> None:
28    if '<rootcanal-port>' in transport:
29        transport = transport.replace('<rootcanal-port>', str(rootcanal_port))
30
31    bumble_config = retrieve_config(config)
32    bumble_config.setdefault('transport', transport)
33    device = PandoraDevice(bumble_config)
34
35    server_config = Config()
36    server_config.load_from_dict(bumble_config.get('server', {}))
37
38    logging.basicConfig(level=logging.DEBUG)
39    asyncio.run(serve(device, config=server_config, port=grpc_port))
40
41
42def retrieve_config(config: str) -> Dict[str, Any]:
43    if not config:
44        return {}
45
46    with open(config, 'r') as f:
47        return json.load(f)
48
49
50if __name__ == '__main__':
51    main()  # pylint: disable=no-value-for-parameter
52