diff options
-rw-r--r-- | configs/kvmd/v1.yaml | 5 | ||||
-rw-r--r-- | configs/kvmd/v2.yaml | 5 | ||||
-rw-r--r-- | kvmd/__init__.py | 3 | ||||
-rw-r--r-- | kvmd/extras/cleanup/__init__.py | 2 | ||||
-rw-r--r-- | kvmd/msd.py | 27 | ||||
-rw-r--r-- | kvmd/server.py | 6 | ||||
-rw-r--r-- | testenv/kvmd.yaml | 5 | ||||
-rw-r--r-- | web/index.html | 3 | ||||
-rw-r--r-- | web/js/msd.js | 15 |
9 files changed, 65 insertions, 6 deletions
diff --git a/configs/kvmd/v1.yaml b/configs/kvmd/v1.yaml index e7d858d3..26a2dbba 100644 --- a/configs/kvmd/v1.yaml +++ b/configs/kvmd/v1.yaml @@ -21,8 +21,13 @@ kvmd: state_poll: 0.1 msd: + pinout: + target: 12 + reset: 13 + device: "/dev/kvmd-msd" init_delay: 2.0 + reset_delay: 1.0 write_meta: true chunk_size: 65536 diff --git a/configs/kvmd/v2.yaml b/configs/kvmd/v2.yaml index 44e73cc2..99683b11 100644 --- a/configs/kvmd/v2.yaml +++ b/configs/kvmd/v2.yaml @@ -21,8 +21,13 @@ kvmd: state_poll: 0.1 msd: + pinout: + target: 12 + reset: 13 + device: "/dev/kvmd-msd" init_delay: 2.0 + reset_delay: 1.0 write_meta: true chunk_size: 65536 diff --git a/kvmd/__init__.py b/kvmd/__init__.py index 110b80a7..da430634 100644 --- a/kvmd/__init__.py +++ b/kvmd/__init__.py @@ -37,8 +37,11 @@ def main() -> None: ) msd = MassStorageDevice( + target=int(config["msd"]["pinout"]["target"]), + reset=int(config["msd"]["pinout"]["reset"]), device_path=str(config["msd"]["device"]), init_delay=float(config["msd"]["init_delay"]), + reset_delay=float(config["msd"]["reset_delay"]), write_meta=bool(config["msd"]["write_meta"]), loop=loop, ) diff --git a/kvmd/extras/cleanup/__init__.py b/kvmd/extras/cleanup/__init__.py index 5ac09ecb..75b35562 100644 --- a/kvmd/extras/cleanup/__init__.py +++ b/kvmd/extras/cleanup/__init__.py @@ -16,6 +16,8 @@ def main() -> None: logger.info("Cleaning up ...") with gpio.bcm(): for (name, pin) in [ + ("msd_target", config["msd"]["pinout"]["target"]), + ("msd_reset", config["msd"]["pinout"]["reset"]), ("atx_power_switch", config["atx"]["pinout"]["power_switch"]), ("atx_reset_switch", config["atx"]["pinout"]["reset_switch"]), ("streamer_cap", config["streamer"]["pinout"]["cap"]), diff --git a/kvmd/msd.py b/kvmd/msd.py index 5b2fa592..575f8ffb 100644 --- a/kvmd/msd.py +++ b/kvmd/msd.py @@ -16,6 +16,7 @@ import aiofiles import aiofiles.base from . import aioregion +from . import gpio from .logging import get_logger @@ -164,15 +165,25 @@ def _msd_operated(method: Callable) -> Callable: class MassStorageDevice: # pylint: disable=too-many-instance-attributes def __init__( self, + target: int, + reset: int, + device_path: str, init_delay: float, + reset_delay: float, write_meta: bool, + loop: asyncio.AbstractEventLoop, ) -> None: + self.__target = gpio.set_output(target) + self.__reset = gpio.set_output(reset) + self._device_path = device_path self.__init_delay = init_delay + self.__reset_delay = reset_delay self.__write_meta = write_meta + self.__loop = loop self.__device_info: Optional[_MassStorageDeviceInfo] = None @@ -202,7 +213,7 @@ class MassStorageDevice: # pylint: disable=too-many-instance-attributes with self.__region: if self.__device_info: raise MsdAlreadyConnectedToKvmError() - # TODO: disable gpio + gpio.write(self.__target, False) if not no_delay: await asyncio.sleep(self.__init_delay) await self.__load_device_info() @@ -213,10 +224,17 @@ class MassStorageDevice: # pylint: disable=too-many-instance-attributes with self.__region: if not self.__device_info: raise MsdAlreadyConnectedToPcError() - # TODO: enable gpio + gpio.write(self.__target, True) self.__device_info = None get_logger().info("Mass-storage device switched to Server") + @_msd_operated + async def reset(self) -> None: + with self.__region: + gpio.write(self.__reset, True) + await asyncio.sleep(self.__reset_delay) + gpio.write(self.__reset, False) + def get_state(self) -> Dict: info = (self.__saved_device_info._asdict() if self.__saved_device_info else None) if info: @@ -237,7 +255,8 @@ class MassStorageDevice: # pylint: disable=too-many-instance-attributes async def cleanup(self) -> None: await self.__close_device_file() - # TODO: disable gpio + gpio.write(self.__target, False) + gpio.write(self.__reset, False) @_msd_operated async def __aenter__(self) -> "MassStorageDevice": @@ -298,6 +317,6 @@ class MassStorageDevice: # pylint: disable=too-many-instance-attributes await self.__device_file.close() except Exception: get_logger().exception("Can't close mass-storage device file") - # TODO: reset device file + await self.reset() self.__device_file = None self.__written = 0 diff --git a/kvmd/server.py b/kvmd/server.py index a4444ecc..efdb48c0 100644 --- a/kvmd/server.py +++ b/kvmd/server.py @@ -147,6 +147,7 @@ class Server: # pylint: disable=too-many-instance-attributes app.router.add_get("/msd", self.__msd_state_handler) app.router.add_post("/msd/connect", self.__msd_connect_handler) app.router.add_post("/msd/write", self.__msd_write_handler) + app.router.add_post("/msd/reset", self.__msd_reset_handler) app.router.add_get("/streamer", self.__streamer_state_handler) app.router.add_post("/streamer/set_params", self.__streamer_set_params_handler) @@ -298,6 +299,11 @@ class Server: # pylint: disable=too-many-instance-attributes logger.info("Written %d bytes to mass-storage device", written) return _json({"written": written}) + @_wrap_exceptions_for_web("Mass-storage error") + async def __msd_reset_handler(self, _: aiohttp.web.Request) -> aiohttp.web.Response: + await self.__msd.reset() + return _json() + # ===== STREAMER async def __streamer_state_handler(self, _: aiohttp.web.Request) -> aiohttp.web.Response: diff --git a/testenv/kvmd.yaml b/testenv/kvmd.yaml index 4b1a05cc..4428cde5 100644 --- a/testenv/kvmd.yaml +++ b/testenv/kvmd.yaml @@ -21,8 +21,13 @@ kvmd: state_poll: 0.1 msd: + pinout: + target: 12 + reset: 13 + device: "/dev/kvmd-msd" init_delay: 2.0 + reset_delay: 1.0 write_meta: true chunk_size: 65536 diff --git a/web/index.html b/web/index.html index 1c16bc91..52e08f45 100644 --- a/web/index.html +++ b/web/index.html @@ -69,9 +69,7 @@ <div class="ctl-dropdown-content"> <div class="ctl-dropdown-content-buttons"> <button id="show-about-button">• Show about</button> - <hr> <button id="show-keyboard-button">• Show keyboard</button> - <hr> <button id="show-stream-button">• Show stream</button> <hr> <button disabled id="stream-screenshot-button">• Take a screenshot</button> @@ -91,6 +89,7 @@ <hr> <div class="ctl-dropdown-content-buttons"> <button disabled id="stream-reset-button">• Reset stream</button> + <button disabled id="msd-reset-button">• Reset mass storage</button> </div> </div> </div> diff --git a/web/js/msd.js b/web/js/msd.js index f90e4b05..9adb7495 100644 --- a/web/js/msd.js +++ b/web/js/msd.js @@ -18,6 +18,8 @@ function Msd() { tools.setOnClick($("msd-switch-to-kvm-button"), () => __clickSwitchButton("kvm")); tools.setOnClick($("msd-switch-to-server-button"), () => __clickSwitchButton("server")); + + tools.setOnClick($("msd-reset-button"), __clickResetButton); }; /********************************************************************************/ @@ -86,6 +88,18 @@ function Msd() { __applyState(); }; + var __clickResetButton = function() { + var http = tools.makeRequest("POST", "/kvmd/msd/reset", function() { + if (http.readyState === 4) { + if (http.status !== 200) { + ui.error("MSD reset error:<br>", http.responseText); + } + } + __applyState(); + }); + __applyState(); + }; + var __applyState = function() { if (__state.connected_to === "server") { $("msd-another-another-user-uploads").style.display = "none"; @@ -123,6 +137,7 @@ function Msd() { $("msd-select-new-image-button").disabled = (!__state.in_operate || __state.connected_to !== "kvm" || __state.busy || __upload_http); $("msd-upload-new-image-button").disabled = (!__state.in_operate || __state.connected_to !== "kvm" || __state.busy || !__image_file); $("msd-abort-uploading-button").disabled = (!__state.in_operate || !__upload_http); + $("msd-reset-button").disabled = (!__state.in_operate || __upload_http); $("msd-new-image").style.display = (__image_file ? "block" : "none"); $("msd-progress").setAttribute("data-label", "Waiting for upload ..."); |