async def get_controller(reconnect_bt_addr=None,
                             spi_flash=None,
                             controller='PRO_CONTROLLER',
                             capture_file=None,
                             device_id=None):
        # parse the spi flash
        if spi_flash:
            with open(spi_flash, 'rb') as spi_flash_file:
                spi_flash = FlashMemory(spi_flash_file.read())
        else:
            # Create memory containing default controller stick calibration
            spi_flash = FlashMemory()

        # Get controller name to emulate from arguments
        controller = Controller.from_arg(controller)
        factory = controller_protocol_factory(controller, spi_flash=spi_flash)
        ctl_psm, itr_psm = 17, 19
        transport, protocol = await create_hid_server(
            factory,
            reconnect_bt_addr=reconnect_bt_addr,
            ctl_psm=ctl_psm,
            itr_psm=itr_psm,
            capture_file=capture_file,
            device_id=device_id)

        controller_state: ControllerState = protocol.get_controller_state()

        return SwitchController(controller_state)
Beispiel #2
0
async def _main():
    controller = Controller.from_arg("PRO_CONTROLLER")
    factory = controller_protocol_factory(controller, spi_flash=FlashMemory())
    print("waiting for 'Change Grip/Order' menu of the Switch.")
    transport, protocol = await create_hid_server(factory,
                                                  ctl_psm=17,
                                                  itr_psm=19)
    controller_state = protocol.get_controller_state()

    await controller_state.connect()
    print("controller connected.")

    await button_push(controller_state, "home", sec=0.1)
    await asyncio.sleep(1)
    await button_push(controller_state, "right", sec=0.1)
    await button_push(controller_state, "right", sec=0.1)
    await button_push(controller_state, "left", sec=0.1)

    await button_push(controller_state, "right", sec=0.1)
    await button_push(controller_state, "right", sec=0.1)
    await button_push(controller_state, "left", sec=0.1)

    await button_push(controller_state, "right", sec=0.1)
    await button_push(controller_state, "right", sec=0.1)
    await button_push(controller_state, "left", sec=0.1)

    controller_state.r_stick_state.set_right()
    await asyncio.sleep(60)
    async def get_controller(logger: Logger,
                             switch_mac_address=None,
                             spi_flash=None,
                             controller='PRO_CONTROLLER',
                             capture_file=None,
                             device_id=None):

        log.configure(logger.level, logger.level)
        if spi_flash:
            with open(spi_flash, 'rb') as spi_flash_file:
                spi_flash = FlashMemory(spi_flash_file.read())
        else:
            # Create memory containing default controller stick calibration
            spi_flash = FlashMemory()

        # Get controller name to emulate from arguments
        controller = Controller.from_arg(controller)
        factory = controller_protocol_factory(controller, spi_flash=spi_flash)
        ctl_psm, itr_psm = 17, 19
        if switch_mac_address:
            logger.info("Pairing up with Switch MAC address: %s",
                        switch_mac_address)
        transport, protocol = await create_hid_server(
            factory,
            reconnect_bt_addr=switch_mac_address,
            ctl_psm=ctl_psm,
            itr_psm=itr_psm,
            capture_file=capture_file,
            device_id=device_id)

        controller_state: ControllerState = protocol.get_controller_state()

        return SwitchController(logger, controller_state)
Beispiel #4
0
async def main(args):
    # parse the spi flash
    if args.spi_flash:
        with open(args.spi_flash, 'rb') as spi_flash_file:
            spi_flash = FlashMemory(spi_flash_file.read())
    else:
        # Create memory containing default controller stick calibration
        spi_flash = FlashMemory()

    # Get controller name to emulate from arguments
    controller = Controller.from_arg(args.controller)

    with utils.get_output(path=args.log, default=None) as capture_file:
        # prepare the the emulated controller
        factory = controller_protocol_factory(controller, spi_flash=spi_flash)
        ctl_psm, itr_psm = 17, 19
        transport, protocol = await create_hid_server(factory, reconnect_bt_addr=args.reconnect_bt_addr,
                                                      ctl_psm=ctl_psm,
                                                      itr_psm=itr_psm, capture_file=capture_file,
                                                      device_id=args.device_id)

        controller_state = protocol.get_controller_state()

        await controller_state.connect()

        ## RUN CONTROLLER CODE HERE
        await xbox(controller_state)

        await transport.close()
Beispiel #5
0
async def _main(args):
    # parse the spi flash
    if args.spi_flash:
        with open(args.spi_flash, 'rb') as spi_flash_file:
            spi_flash = FlashMemory(spi_flash_file.read())
    else:
        # Create memory containing default controller stick calibration
        spi_flash = FlashMemory()

    # Get controller name to emulate from arguments
    controller = Controller.from_arg(args.controller)

    with utils.get_output(path=args.log, default=None) as capture_file:
        # prepare the the emulated controller
        factory = controller_protocol_factory(controller, spi_flash=spi_flash)
        ctl_psm, itr_psm = 17, 19
        transport, protocol = await create_hid_server(factory, reconnect_bt_addr=args.reconnect_bt_addr,
                                                      ctl_psm=ctl_psm,
                                                      itr_psm=itr_psm, capture_file=capture_file,
                                                      device_id=args.device_id)

        controller_state = protocol.get_controller_state()

        # Create keyboard and mouse interface
        kmi = KMI(controller_state)
        # run the kmi
        try:
            await kmi.run()
        finally:
            logger.info('Stopping communication...')
            await transport.close()
Beispiel #6
0
async def loader():
    if not os.geteuid() == 0:
        raise PermissionError('Script must be run as root!')
    transport, protocol = await create_hid_server(controller_protocol_factory(
        Controller.from_arg("PRO_CONTROLLER"), spi_flash=FlashMemory()),
                                                  ctl_psm=17,
                                                  itr_psm=19)
    controller_state = protocol.get_controller_state()
    return transport, controller_state
Beispiel #7
0
async def loader(recon):
    if not os.geteuid() == 0:
        raise PermissionError('Script must be run as root!')
    transport, protocol, recon_addr = await create_hid_server(
        controller_protocol_factory(Controller.from_arg("PRO_CONTROLLER"),
                                    spi_flash=FlashMemory()),
        reconnect_bt_addr=recon,
        ctl_psm=17,
        itr_psm=19)
    controller_state = protocol.get_controller_state()
    with open("./.reconnect", "w+") as f:
        f.write(recon_addr)
    return transport, controller_state
Beispiel #8
0
async def _main(args):
    # parse the spi flash
    if args.spi_flash:
        with open(args.spi_flash, 'rb') as spi_flash_file:
            spi_flash = FlashMemory(spi_flash_file.read())
    else:
        # Create memory containing default controller stick calibration
        spi_flash = FlashMemory()

    # Get controller name to emulate from arguments
    controller = Controller.from_arg(args.controller)

    with utils.get_output(path=args.log, default=None) as capture_file:
        # prepare the the emulated controller
        factory = controller_protocol_factory(controller, spi_flash=spi_flash)
        ctl_psm, itr_psm = 17, 19
        transport, protocol = await create_hid_server(
            factory,
            reconnect_bt_addr=args.reconnect_bt_addr,
            ctl_psm=ctl_psm,
            itr_psm=itr_psm,
            capture_file=capture_file,
            device_id=args.device_id)

        controller_state = protocol.get_controller_state()

        joycon_server = JoyConRestfull()

        th = threading.Thread(target=joycon_server.run)
        th.start()

        # Create command line interface and add some extra commands
        cli = ControllerCLI(controller_state, queue)
        _register_commands_with_controller_state(controller_state, cli)
        cli.add_command(
            'amiibo',
            ControllerCLI.deprecated(
                'Command was removed - use "nfc" instead!'))

        # set default nfc content supplied by argument
        if args.nfc is not None:
            await cli.commands['nfc'](args.nfc)

        #asyncio.ensure_future(cli.run())
        #asyncio.ensure_future(app.run(port='5002'))
        # run the cli
        try:
            await cli.run()
        finally:
            logger.info('Stopping communication...')
            await transport.close()
Beispiel #9
0
    async def connect(self, controller_type: str, reconnect_address: str, spi_firm: bytes):
        if spi_firm is None:
            spi_flash = FlashMemory()
        else:
            spi_flash = FlashMemory(spi_flash_memory_data = spi_firm)
        lib_controller_type = Controller.from_arg(controller_type)

        def create_controller_protocol():
            return ControllerProtocol(lib_controller_type, spi_flash=spi_flash)

        factory = create_controller_protocol
        transport, protocol = await create_hid_server(factory, reconnect_bt_addr=reconnect_address)
        controller_state = protocol.get_controller_state()
        self.controller_state = controller_state
        self.transport = transport

        return transport._itr_sock.getpeername()[0]
async def _main(args):
    # parse the spi flash
    if args.spi_flash:
        with open(args.spi_flash, 'rb') as spi_flash_file:
            spi_flash = FlashMemory(spi_flash_file.read())
    else:
        # Create memory containing default controller stick calibration
        spi_flash = FlashMemory()

    # Get controller name to emulate from arguments
    controller = Controller.from_arg(args.controller)

    with utils.get_output(path=args.log, default=None) as capture_file:
        factory = controller_protocol_factory(controller, spi_flash=spi_flash)
        ctl_psm, itr_psm = 17, 19
        transport, protocol = await create_hid_server(
            factory,
            reconnect_bt_addr=args.reconnect_bt_addr,
            ctl_psm=ctl_psm,
            itr_psm=itr_psm,
            capture_file=capture_file,
            device_id=args.device_id)

        controller_state = protocol.get_controller_state()

        # Create command line interface and add some extra commands
        cli = ControllerCLI(controller_state)

        # Wrap the script so we can pass the controller state. The doc string will be printed when calling 'help'
        async def _run_Controller():
            '''
            - Controller
            '''
            await xbox(controller_state)

        # add the script from above
        #cli.add_command('mash', call_mash_button)
        cli.add_command('Controller', _run_Controller)
        cli.add_command('controller', _run_Controller)

        try:
            await cli.run()
        finally:
            logger.info('Stopping communication...')
            await transport.close()
Beispiel #11
0
    async def get_controller(logger: Logger,
                             switch_mac_address=None,
                             spi_flash=None,
                             controller='PRO_CONTROLLER',
                             capture_file=None,
                             device_id=None):
        logger.info("Simulating a %s controller.", controller)
        if spi_flash:
            with open(spi_flash, 'rb') as spi_flash_file:
                spi_flash = FlashMemory(spi_flash_file.read())
        else:
            # Create memory containing default controller stick calibration
            spi_flash = FlashMemory()

        # Get controller name to emulate from arguments
        controller = Controller.from_arg(controller)
        factory = controller_protocol_factory(controller, spi_flash=spi_flash)
        ctl_psm, itr_psm = 17, 19
        if switch_mac_address:
            logger.info("Pairing with Switch MAC address: %s",
                        switch_mac_address)
        while True:
            try:
                transport, protocol = await create_hid_server(
                    factory,
                    reconnect_bt_addr=switch_mac_address,
                    ctl_psm=ctl_psm,
                    itr_psm=itr_psm,
                    capture_file=capture_file,
                    device_id=device_id)

                controller_state: ControllerState = protocol.get_controller_state(
                )
                break
            except:
                # TODO Try to wake the Switch up from sleep.
                wait_s = 3
                logger.exception(
                    "Error pairing. Make sure your Switch is on."
                    " Will try again in %ds.", wait_s)
                await asyncio.sleep(wait_s)

        logger.info("Simulated %s paired.", controller.name)
        return SwitchController(logger, controller_state)
Beispiel #12
0
async def _main(args):
    # parse the spi flash
    if args.spi_flash:
        with open(args.spi_flash, 'rb') as spi_flash_file:
            spi_flash = FlashMemory(spi_flash_file.read())
    else:
        # Create memory containing default controller stick calibration
        spi_flash = FlashMemory()

    # Get controller name to emulate from arguments
    controller = Controller.from_arg(args.controller)

    with utils.get_output(path=args.log, default=None) as capture_file:
        # prepare the the emulated controller
        factory = controller_protocol_factory(controller, spi_flash=spi_flash)
        ctl_psm, itr_psm = 17, 19

        if args.bt_addr_file is not None:
            bt_addr = open(args.bt_addr_file, "r").read()
            if bt_addr == "ANY":
                bt_addr = None
        else:
            bt_addr = args.reconnect_bt_addr

        transport, protocol = await create_hid_server(
            factory,
            reconnect_bt_addr=bt_addr,
            ctl_psm=ctl_psm,
            itr_psm=itr_psm,
            capture_file=capture_file,
            device_id=args.device_id)

        controller_state = protocol.get_controller_state()

        # Create socket interface and add some extra commands
        socket_interface = ControllerSocketInterface(args.socket,
                                                     controller_state)
        _register_commands_with_controller_state(controller_state,
                                                 socket_interface)

        # run the socket_interface
        await socket_interface.start_server()
        return socket_interface, transport
Beispiel #13
0
async def main(args, q):
    # parse the spi flash
    logger.name = "CLI进程"
    if args.spi_flash:
        with open(args.spi_flash, 'rb') as spi_flash_file:
            spi_flash = FlashMemory(spi_flash_file.read())
    else:
        # Create memory containing default controller stick calibration
        spi_flash = FlashMemory()

    # Get controller name to emulate from arguments
    controller = Controller.from_arg(args.controller)

    with utils.get_output(path=args.log, default=None) as capture_file:
        # prepare the the emulated controller
        factory = controller_protocol_factory(controller, spi_flash=spi_flash)
        ctl_psm, itr_psm = 17, 19
        transport, protocol = await create_hid_server(
            factory,
            reconnect_bt_addr=args.reconnect_bt_addr,
            ctl_psm=ctl_psm,
            itr_psm=itr_psm,
            capture_file=capture_file,
            device_id=args.device_id)

        controller_state = protocol.get_controller_state()
        joycontrol_http.controller_state = controller_state
        method = controller_state.button_state.set_button
        q.put(method)
        logger.debug("controller开始监听")
        while True:
            await asyncio.sleep(0.1)
            if q.empty():
                continue
            msg = q.get()
            if isinstance(msg, Command):
                if msg.target == "controller":
                    if msg.cmd == "btn_push":
                        from joycontrol.controller_state import button_push
                        await button_push(controller_state, msg.obj)
Beispiel #14
0
    async def start(self, args):
        # Create memory containing default controller stick calibration
        spi_flash = FlashMemory()

        # Get controller name to emulate from arguments
        controller = Controller.from_arg('PRO_CONTROLLER')

        with utils.get_output(path=None, default=None) as capture_file:
            factory = controller_protocol_factory(controller,
                                                  spi_flash=spi_flash)
            ctl_psm, itr_psm = 17, 19
            transport, protocol = await create_hid_server(
                factory,
                reconnect_bt_addr=args.reconnect_bt_addr,
                ctl_psm=ctl_psm,
                itr_psm=itr_psm,
                capture_file=capture_file,
                device_id=args.device_id)

            controller_state = protocol.get_controller_state()
            self.transport = transport

            try:
                # waits until controller is fully connected
                await controller_state.connect()
                joycontrol_plugin = self.__load_plugin(args.plugin,
                                                       controller_state,
                                                       args.plugin_options)
                await joycontrol_plugin.run()
            except Exception as e:
                logger.error(e)
            finally:
                logger.info('Stopping communication...')
                await transport.close()
                self.transport = None
                self.joycontrol_cmd = None
Beispiel #15
0
async def _main(args):
    # parse the spi flash
    if args.spi_flash:
        with open(args.spi_flash, 'rb') as spi_flash_file:
            spi_flash = FlashMemory(spi_flash_file.read())
    else:
        # Create memory containing default controller stick calibration
        spi_flash = FlashMemory()

    # Get controller name to emulate from arguments
    controller = Controller.from_arg(args.controller)
    async def nfc(*args):
        if controller_state.get_controller() == Controller.JOYCON_L:
            raise ValueError('NFC content cannot be set for JOYCON_L')
        elif not args:
            raise ValueError('"nfc" command requires file path to an nfc dump as argument!')
        elif args[0] == 'remove':
            controller_state.set_nfc(None)
            print('Removed nfc content.')
        else:
            _loop = asyncio.get_event_loop()
            with open(args[0], 'rb') as nfc_file:
                content = await _loop.run_in_executor(None, nfc_file.read)
                controller_state.set_nfc(content)

    with utils.get_output(path=args.log, default=None) as capture_file:
        # prepare the the emulated controller
        factory = controller_protocol_factory(controller, spi_flash=spi_flash)
        ctl_psm, itr_psm = 17, 19
        draw.text((x, top + 16), str("Waiting for Switch to"), font=font, fill=255)
        draw.text((x + 40, top + 24), str("Connect,"), font=font, fill=255)
        draw.text((x + 18, top + 40), str("Please open the"), font=font, fill=255)
        draw.text((x + 6, top + 48), str("'Change Grip/Order'"), font=font, fill=255)
        draw.text((x + 46, top + 56), str("menu."), font=font, fill=255)

        disp.image(image)
        disp.display()
        transport, protocol = await create_hid_server(factory, reconnect_bt_addr=args.reconnect_bt_addr,
                                                      ctl_psm=ctl_psm,
                                                      itr_psm=itr_psm, capture_file=capture_file,
                                                      device_id=args.device_id)

        controller_state = protocol.get_controller_state()

        # Create command line interface and add some extra commands
        cli = ControllerCLI(controller_state)

        # set default nfc content supplied by argument
        if args.nfc is not None:
            await cli.commands['nfc'](args.nfc)

        # run the cli
        try:
            await nfc(args.nfc)
            await run_at_start(controller_state)
            #await cli.run()


        finally:
            logger.info('Stopping communication...')
            await transport.close()
async def _main(args):
    # parse the spi flash
    if args.spi_flash:
        with open(args.spi_flash, 'rb') as spi_flash_file:
            spi_flash = FlashMemory(spi_flash_file.read())
    else:
        # Create memory containing default controller stick calibration
        spi_flash = FlashMemory()

    # Get controller name to emulate from arguments
    controller = Controller.from_arg(args.controller)

    with utils.get_output(path=args.log, default=None) as capture_file:
        factory = controller_protocol_factory(controller, spi_flash=spi_flash)
        ctl_psm, itr_psm = 17, 19
        transport, protocol = await create_hid_server(
            factory,
            reconnect_bt_addr=args.reconnect_bt_addr,
            ctl_psm=ctl_psm,
            itr_psm=itr_psm,
            capture_file=capture_file,
            device_id=args.device_id)

        controller_state = protocol.get_controller_state()

        # Create command line interface and add some extra commands
        cli = ControllerCLI(controller_state)

        # Wrap the script so we can pass the controller state. The doc string will be printed when calling 'help'
        async def _run_test_controller_buttons():
            """
            test_buttons - Navigates to the "Test Controller Buttons" menu and presses all buttons.
            """
            await test_controller_buttons(controller_state)

        # add the script from above
        cli.add_command('test_buttons', _run_test_controller_buttons)

        # Mash a button command
        async def call_mash_button(*args):
            """
            mash - Mash a specified button at a set interval

            Usage:
                mash <button> <interval>
            """
            if not len(args) == 2:
                raise ValueError(
                    '"mash_button" command requires a button and interval as arguments!'
                )

            button, interval = args
            await mash_button(controller_state, button, interval)

        # add the script from above
        cli.add_command('mash', call_mash_button)

        # Create nfc command
        async def nfc(*args):
            """
            nfc - Sets nfc content

            Usage:
                nfc <file_name>          Set controller state NFC content to file
                nfc remove               Remove NFC content from controller state
            """
            if controller_state.get_controller() == Controller.JOYCON_L:
                raise ValueError('NFC content cannot be set for JOYCON_L')
            elif not args:
                raise ValueError(
                    '"nfc" command requires file path to an nfc dump as argument!'
                )
            elif args[0] == 'remove':
                controller_state.set_nfc(None)
                print('Removed nfc content.')
            else:
                await set_nfc(controller_state, args[0])

        # add the script from above
        cli.add_command('nfc', nfc)
        cli.add_command(
            'amiibo',
            ControllerCLI.deprecated(
                'Command is deprecated - use "nfc" instead!'))

        if args.nfc is not None:
            await nfc(args.nfc)
        eventToButton = {
            304: 'b',
            305: 'a',
            307: 'y',
            308: 'x',
            704: 'left',
            705: 'right',
            706: 'up',
            707: 'down',
            311: 'r',
            310: 'l',
            312: 'zl',
            313: 'zr',
            314: 'minus',
            315: 'plus',
            317: 'l_stick',
            318: 'r_stick',
        }

        device = evdev.InputDevice(
            "/dev/input/by-id/usb-045e_0291-event-joystick")
        caps = device.capabilities()
        try:
            t1 = time.perf_counter()
            cnt = 0
            async for event in device.async_read_loop():
                if event.type == ecodes.EV_SYN:
                    lasttask = asyncio.ensure_future(
                        sync_controller(controller_state))
                if event.type == ecodes.EV_ABS:
                    if event.code == 0:
                        controller_state.l_stick_state.set_h(event.value //
                                                             22 + 2048)
                    elif event.code == 1:
                        controller_state.l_stick_state.set_v(
                            -(event.value - 15) // 22 + 2047)
                    elif event.code == 3:
                        controller_state.r_stick_state.set_h(event.value //
                                                             22 + 2048)
                    elif event.code == 4:
                        controller_state.r_stick_state.set_v(
                            -(event.value - 15) // 22 + 2047)
                elif event.type == ecodes.EV_KEY:
                    if event.code in eventToButton:
                        buttonCode = eventToButton[event.code]
                        button_set_state(controller_state, buttonCode, event)
                        if event.code == 305:
                            if event.value == 1:
                                if controller_state.button_state.get_button(
                                        'zr'):
                                    button_set_state(controller_state, 'home',
                                                     event)
                            else:
                                button_set_state(controller_state, 'home',
                                                 event)
                        lasttask = asyncio.ensure_future(
                            sync_controller(controller_state))
                cnt = cnt + 1
                if cnt > 50:
                    cnt = 0
                    t2 = time.perf_counter()
                    deltaT = t2 - t1
                    freq = 50.00 / deltaT
                    str = " 50 event takes  " + format(
                        deltaT, '.2f') + " secs freq = " + format(freq, '.2f')
                    logger.info(str)
                    t1 = t2
        except:
            logger.info('unexpected')
            logger.info(sys.exc_info()[0])
        finally:
            logger.info('Stopping communication...')
            await transport.close()
Beispiel #17
0
async def _main(args):
    # parse the spi flash
    if args.spi_flash:
        with open(args.spi_flash, 'rb') as spi_flash_file:
            spi_flash = FlashMemory(spi_flash_file.read())
    else:
        # Create memory containing default controller stick calibration
        spi_flash = FlashMemory()

    # Get controller name to emulate from arguments
    controller = Controller.from_arg(args.controller)

    with utils.get_output(path=args.log, default=None) as capture_file:
        factory = controller_protocol_factory(controller, spi_flash=spi_flash)
        ctl_psm, itr_psm = 17, 19
        transport, protocol = await create_hid_server(
            factory,
            reconnect_bt_addr=args.reconnect_bt_addr,
            ctl_psm=ctl_psm,
            itr_psm=itr_psm,
            capture_file=capture_file,
            device_id=args.device_id)

        controller_state = protocol.get_controller_state()

        # Create command line interface and add some extra commands
        cli = ControllerCLI(controller_state)

        # Wrap the script so we can pass the controller state. The doc string will be printed when calling 'help'
        async def _run_test_controller_buttons():
            """
            test_buttons - Navigates to the "Test Controller Buttons" menu and presses all buttons.
            """
            await test_controller_buttons(controller_state)

        # add the script from above
        cli.add_command('test_buttons', _run_test_controller_buttons)

        # Create amiibo command
        async def amiibo(*args):
            """
            amiibo - Sets amiibo content

            Usage:
                amiibo <file_name>          Set controller state NFC content to file
                amiibo remove               Remove NFC content from controller state
            """
            if controller_state.get_controller() == Controller.JOYCON_L:
                raise ValueError('NFC content cannot be set for JOYCON_L')
            elif not args:
                raise ValueError(
                    '"amiibo" command requires amiibo dump file path as argument!'
                )
            elif args[0] == 'remove':
                controller_state.set_nfc(None)
                print('Removed nfc content.')
            else:
                await set_amiibo(controller_state, args[0])

        # add the script from above
        cli.add_command('amiibo', amiibo)

        try:
            await cli.run()
        finally:
            logger.info('Stopping communication...')
            await transport.close()
Beispiel #18
0
async def _main(args):
    # parse the spi flash
    if args.spi_flash:
        with open(args.spi_flash, 'rb') as spi_flash_file:
            spi_flash = FlashMemory(spi_flash_file.read())
    else:
        # Create memory containing default controller stick calibration
        spi_flash = FlashMemory()

    # Get controller name to emulate from arguments
    controller = Controller.from_arg(args.controller)

    with utils.get_output(path=args.log, default=None) as capture_file:
        factory = controller_protocol_factory(controller, spi_flash=spi_flash)
        ctl_psm, itr_psm = 17, 19
        transport, protocol = await create_hid_server(
            factory,
            reconnect_bt_addr=args.reconnect_bt_addr,
            ctl_psm=ctl_psm,
            itr_psm=itr_psm,
            capture_file=capture_file,
            device_id=args.device_id)

        controller_state = protocol.get_controller_state()

        # Create command line interface and add some extra commands
        cli = ControllerCLI(controller_state)

        # Wrap the script so we can pass the controller state. The doc string will be printed when calling 'help'
        async def _run_test_control():
            """
            test_control - test method that will be removed later
            """
            await test_control(controller_state)

        async def _run_keyboard_control():
            """
            keyboard - binds controls to keyboard. Keybinding:
            q=LEFT w=LstickUP e=UP r=ZL t=L y=R u=ZR i=RstickUP
            a=LstickLEFT s=LstickDOWN d=LstickRIGHT f=RIGHT g=capture h=home j=RstickLEFT k=RStickDOWN l=RstickRIGHT
            c=DOWN up=X down=B left=Y right=A
            plus= + minus= -
            """
            await keyboard_control(controller_state)

        async def _run_recording_control():
            """
            recording - binds controls to keyboard, and records input until recording stopped.
            saved recordings can be replayed using cmd >> recording_playback
            Keybinding:
            q=LEFT w=LstickUP e=UP r=ZL t=L y=R u=ZR i=RstickUP
            a=LstickLEFT s=LstickDOWN d=LstickRIGHT f=RIGHT g=capture h=home j=RstickLEFT k=RStickDOWN l=RstickRIGHT
            c=DOWN up=X down=B left=Y right=A
            plus= + minus= -
            """
            await record_keyboard(controller_state)

        async def _run_recording_playback():
            """
            playback - select a saved recording and replay it
            """
            await recording_playback(controller_state)

        async def _run_delete_recording():
            """
            delete_rec - select a saved recording and delete it
            """
            await delete_recording(controller_state)

        async def _run_test_controller_buttons():
            """
            test_buttons - Navigates to the "Test Controller Buttons" menu and presses all buttons.
            """
            await test_controller_buttons(controller_state)

        # Mash a button command
        async def call_mash_button(*args):
            """
            mash - Mash a specified button at a set interval
            Usage:
                mash <button> <interval>
            """
            if not len(args) == 2:
                raise ValueError(
                    '"mash_button" command requires a button and interval as arguments!'
                )

            button, interval = args
            await mash_button(controller_state, button, interval)

        # Create nfc command
        async def nfc(*args):
            """
            nfc - Sets nfc content

            Usage:
                nfc <file_name>          Set controller state NFC content to file
                nfc remove               Remove NFC content from controller state
            """
            if controller_state.get_controller() == Controller.JOYCON_L:
                raise ValueError('NFC content cannot be set for JOYCON_L')
            elif not args:
                raise ValueError(
                    '"nfc" command requires file path to an nfc dump as argument!'
                )
            elif args[0] == 'remove':
                controller_state.set_nfc(None)
                print('Removed nfc content.')
            else:
                await set_nfc(controller_state, args[0])

        cli.add_command('test_buttons', _run_test_controller_buttons)
        cli.add_command('keyboard', _run_keyboard_control)
        cli.add_command('recording', _run_recording_control)
        cli.add_command('playback', _run_recording_playback)
        cli.add_command('delete_rec', _run_delete_recording)
        cli.add_command('mash', call_mash_button)
        # add the script from above
        cli.add_command('nfc', nfc)

        if args.nfc is not None:
            await nfc(args.nfc)

        try:
            await cli.run()
        finally:
            logger.info('Stopping communication...')
            await transport.close()