diff --git a/joycontrol/ir_nfc_mcu.py b/joycontrol/ir_nfc_mcu.py deleted file mode 100644 index 076e965..0000000 --- a/joycontrol/ir_nfc_mcu.py +++ /dev/null @@ -1,156 +0,0 @@ -import logging -from enum import Enum -from crc8 import crc8 - -logger = logging.getLogger(__name__) - - -class Action(Enum): - NON = 0 - REQUEST_STATUS = 1 - START_TAG_POLLING = 2 - START_TAG_DISCOVERY = 3 - READ_TAG = 4 - READ_TAG_2 = 5 - READ_FINISHED = 6 - - -class McuState(Enum): - NOT_INITIALIZED = 0 - IRC = 1 - NFC = 2 - STAND_BY = 3 - BUSY = 4 - - -def copyarray(dest, offset, src): - for i in range(len(src)): - dest[offset + i] = src[i] - - -class IrNfcMcu: - """ - TODO: cleanup - """ - - def __init__(self): - self._fw_major = [0, 3] - self._fw_minor = [0, 5] - - self._bytes = [0] * 313 - - self._action = Action.NON - self._state = McuState.NOT_INITIALIZED - - self._nfc_content = None - - def get_fw_major(self): - return self._fw_major - - def get_fw_minor(self): - return self._fw_minor - - def set_action(self, v): - self._action = v - - def get_action(self): - return self._action - - def set_state(self, v): - self._state = v - - def get_state(self): - return self._state - - def _get_state_byte(self): - if self.get_state() == McuState.NFC: - return 4 - elif self.get_state() == McuState.BUSY: - return 6 - elif self.get_state() == McuState.NOT_INITIALIZED: - return 1 - elif self.get_state() == McuState.STAND_BY: - return 1 - else: - return 0 - - def update_status(self): - self._bytes[0] = 1 - self._bytes[1] = 0 - self._bytes[2] = 0 - self._bytes[3] = self._fw_major[0] - self._bytes[4] = self._fw_major[1] - self._bytes[5] = self._fw_minor[0] - self._bytes[6] = self._fw_minor[1] - self._bytes[7] = self._get_state_byte() - - def update_nfc_report(self): - self._bytes = [0] * 313 - if self.get_action() == Action.REQUEST_STATUS: - self.update_status() - elif self.get_action() == Action.NON: - self._bytes[0] = 0xff - elif self.get_action() == Action.START_TAG_DISCOVERY: - self._bytes[0] = 0x2a - self._bytes[1] = 0 - self._bytes[2] = 5 - self._bytes[3] = 0 - self._bytes[4] = 0 - self._bytes[5] = 9 - self._bytes[6] = 0x31 - self._bytes[7] = 0 - elif self.get_action() == Action.START_TAG_POLLING: - self._bytes[0] = 0x2a - self._bytes[1] = 0 - self._bytes[2] = 5 - self._bytes[3] = 0 - self._bytes[4] = 0 - if self._nfc_content is not None: - data = [0x09, 0x31, 0x09, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x07] - copyarray(self._bytes, 5, data) - copyarray(self._bytes, 5 + len(data), self._nfc_content[0:3]) - copyarray(self._bytes, 5 + len(data) + 3, self._nfc_content[4:8]) - else: - logger.info('nfc content is none') - self._bytes[5] = 9 - self._bytes[6] = 0x31 - self._bytes[7] = 0 - elif self.get_action() in (Action.READ_TAG, Action.READ_TAG_2): - self._bytes[0] = 0x3a - self._bytes[1] = 0 - self._bytes[2] = 7 - if self.get_action() == Action.READ_TAG: - data1 = bytes.fromhex('010001310200000001020007') - copyarray(self._bytes, 3, data1) - copyarray(self._bytes, 3 + len(data1), self._nfc_content[0:3]) - copyarray(self._bytes, 3 + len(data1) + 3, self._nfc_content[4:8]) - data2 = bytes.fromhex('000000007DFDF0793651ABD7466E39C191BABEB856CEEDF1CE44CC75EAFB27094D087AE803003B3C7778860000') - copyarray(self._bytes, 3 + len(data1) + 3 + 4, data2) - copyarray(self._bytes, 3 + len(data1) + 3 + 4 + len(data2), self._nfc_content[0:245]) - self.set_action(Action.READ_TAG_2) - else: - data = bytes.fromhex('02000927') - copyarray(self._bytes, 3, data) - copyarray(self._bytes, 3 + len(data), self._nfc_content[245:540]) - self.set_action(Action.READ_FINISHED) - elif self.get_action() == Action.READ_FINISHED: - self._bytes[0] = 0x2a - self._bytes[1] = 0 - self._bytes[2] = 5 - self._bytes[3] = 0 - self._bytes[4] = 0 - data = bytes.fromhex('0931040000000101020007') - copyarray(self._bytes, 5, data) - copyarray(self._bytes, 5 + len(data), self._nfc_content[0:3]) - copyarray(self._bytes, 5 + len(data) + 3, self._nfc_content[4:8]) - self.set_action(Action.NON) - - crc = crc8() - crc.update(bytes(self._bytes[:-1])) - self._bytes[-1] = ord(crc.digest()) - - def set_nfc(self, nfc_content): - self._nfc_content = nfc_content - - def __bytes__(self): - return bytes(self._bytes) diff --git a/joycontrol/protocol.py b/joycontrol/protocol.py index 7134f0d..f83a9d9 100644 --- a/joycontrol/protocol.py +++ b/joycontrol/protocol.py @@ -11,8 +11,6 @@ from joycontrol.controller_state import ControllerState from joycontrol.memory import FlashMemory from joycontrol.report import OutputReport, SubCommand, InputReport, OutputReportID from joycontrol.transport import NotConnectedError -from joycontrol.ir_nfc_mcu import IrNfcMcu, McuState, Action -from crc8 import crc8 logger = logging.getLogger(__name__) @@ -42,8 +40,6 @@ class ControllerProtocol(BaseProtocol): self._controller_state = ControllerState(self, controller, spi_flash=spi_flash) self._controller_state_sender = None - self._mcu = IrNfcMcu() - # None = Just answer to sub commands self._input_report_mode = None @@ -166,9 +162,8 @@ class ControllerProtocol(BaseProtocol): elif output_report_id == OutputReportID.SUB_COMMAND: reply_send = await self._reply_to_sub_command(report) elif output_report_id == OutputReportID.REQUEST_IR_NFC_MCU: - # TODO: This does not reply anything - # reply_send = await self._reply_to_ir_nfc_mcu(report) - await self._reply_to_ir_nfc_mcu(report) + # TODO NFC + raise NotImplementedError('NFC communictation is not implemented.') else: logger.warning(f'Report unknown output report "{output_report_id}" - IGNORE') except ValueError as v_err: @@ -184,11 +179,9 @@ class ControllerProtocol(BaseProtocol): # TODO: set some sensor data input_report.set_6axis_data() - # set nfc data + # TODO NFC - set nfc data if input_report.get_input_report_id() == 0x31: - self._mcu.set_nfc(self._controller_state.get_nfc()) - self._mcu.update_nfc_report() - input_report.set_ir_nfc_data(bytes(self._mcu)) + pass await self.write(input_report) @@ -237,50 +230,6 @@ class ControllerProtocol(BaseProtocol): else: logger.warning(f'Output report {output_report_id} not implemented - ignoring') - async def _reply_to_ir_nfc_mcu(self, report): - """ - TODO: Cleanup - We aren't replying to anything here, do we need to? - """ - sub_command = report.data[11] - sub_command_data = report.data[12:] - - # logging.info(f'received output report - Request MCU sub command {sub_command}') - - if self._mcu.get_action() in (Action.READ_TAG, Action.READ_TAG_2, Action.READ_FINISHED): - return - - # Request mcu state - if sub_command == 0x01: - # input_report = InputReport() - # input_report.set_input_report_id(0x21) - # input_report.set_misc() - - # input_report.set_ack(0xA0) - # input_report.reply_to_subcommand_id(0x21) - - self._mcu.set_action(Action.REQUEST_STATUS) - # input_report.set_mcu(self._mcu) - - # await self.write(input_report) - # Send Start tag discovery - elif sub_command == 0x02: - # 0: Cancel all, 4: StartWaitingReceive - if sub_command_data[0] == 0x04: - self._mcu.set_action(Action.START_TAG_DISCOVERY) - # 1: Start polling - elif sub_command_data[0] == 0x01: - self._mcu.set_action(Action.START_TAG_POLLING) - # 2: stop polling - elif sub_command_data[0] == 0x02: - self._mcu.set_action(Action.NON) - elif sub_command_data[0] == 0x06: - self._mcu.set_action(Action.READ_TAG) - else: - logging.info(f'Unknown sub_command_data arg {sub_command_data}') - else: - logging.info(f'Unknown MCU sub command {sub_command}') - async def _reply_to_sub_command(self, report): # classify sub command try: @@ -467,6 +416,7 @@ class ControllerProtocol(BaseProtocol): await self.write(input_report) async def _command_set_nfc_ir_mcu_config(self, sub_command_data): + # TODO NFC input_report = InputReport() input_report.set_input_report_id(0x21) input_report.set_misc() @@ -474,30 +424,14 @@ class ControllerProtocol(BaseProtocol): input_report.set_ack(0xA0) input_report.reply_to_subcommand_id(SubCommand.SET_NFC_IR_MCU_CONFIG.value) - self._mcu.update_status() - data = list(bytes(self._mcu)[0:34]) - crc = crc8() - crc.update(bytes(data[:-1])) - checksum = crc.digest() - data[-1] = ord(checksum) - + data = [1, 0, 255, 0, 8, 0, 27, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200] for i in range(len(data)): - input_report.data[16+i] = data[i] - - # Set MCU mode cmd - if sub_command_data[1] == 0: - if sub_command_data[2] == 0: - self._mcu.set_state(McuState.STAND_BY) - elif sub_command_data[2] == 4: - self._mcu.set_state(McuState.NFC) - else: - logger.info(f"unknown mcu state {sub_command_data[2]}") - else: - logger.info(f"unknown mcu config command {sub_command_data}") + input_report.data[16 + i] = data[i] await self.write(input_report) async def _command_set_nfc_ir_mcu_state(self, sub_command_data): + # TODO NFC input_report = InputReport() input_report.set_input_report_id(0x21) input_report.set_misc() @@ -506,13 +440,10 @@ class ControllerProtocol(BaseProtocol): # 0x01 = Resume input_report.set_ack(0x80) input_report.reply_to_subcommand_id(SubCommand.SET_NFC_IR_MCU_STATE.value) - self._mcu.set_action(Action.NON) - self._mcu.set_state(McuState.STAND_BY) elif sub_command_data[0] == 0x00: # 0x00 = Suspend input_report.set_ack(0x80) input_report.reply_to_subcommand_id(SubCommand.SET_NFC_IR_MCU_STATE.value) - self._mcu.set_state(McuState.STAND_BY) else: raise NotImplementedError(f'Argument {sub_command_data[0]} of {SubCommand.SET_NFC_IR_MCU_STATE} ' f'not implemented.') diff --git a/run_controller_cli.py b/run_controller_cli.py index 22bd2c5..c84597b 100755 --- a/run_controller_cli.py +++ b/run_controller_cli.py @@ -248,6 +248,7 @@ def _register_commands_with_controller_state(controller_state, cli): nfc Set controller state NFC content to file nfc remove Remove NFC content from controller state """ + logger.error('NFC Support was removed from joycontrol - see https://github.com/mart1nro/joycontrol/issues/80') if controller_state.get_controller() == Controller.JOYCON_L: raise ValueError('NFC content cannot be set for JOYCON_L') elif not args: diff --git a/setup.py b/setup.py index de46acb..7743742 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup(name='joycontrol', - version='0.14', + version='0.15', author='Robert Martin', author_email='martinro@informatik.hu-berlin.de', description='Emulate Nintendo Switch Controllers over Bluetooth', @@ -10,7 +10,7 @@ setup(name='joycontrol', package_data={'joycontrol': ['profile/sdp_record_hid.xml']}, zip_safe=False, install_requires=[ - 'hid', 'aioconsole', 'dbus-python', 'crc8' + 'hid', 'aioconsole', 'dbus-python' ] )