def __get_power_state_handler(self, _: Dict, session: IpmiServerSession) -> None: # https://github.com/arcress0/ipmiutil/blob/e2f6e95127d22e555f959f136d9bb9543c763896/util/ireset.c#L654 result = self.__make_request(session, "atx.get_state() [power]", "atx.get_state") data = [(0 if result["leds"]["power"] else 5)] session.send_ipmi_response(data=data)
def __get_selftest_status_handler(self, _: Dict, session: IpmiServerSession) -> None: # https://github.com/arcress0/ipmiutil/blob/e2f6e95127d22e555f959f136d9bb9543c763896/util/ihealth.c#L858 data = [0x0055] try: self.__make_request(session, "atx.get_state() [health]", "atx.get_state") except Exception: data = [0] session.send_ipmi_response(data=data)
def __deactivate_sol_handler(self, _: Dict, session: IpmiServerSession) -> None: with self.__sol_lock: if not self.__sol_device_path: session.send_ipmi_response(code=0x81) elif not self.__is_sol_activated(): session.send_ipmi_response(code=0x80) else: get_logger(0).info("Deactivating SOL ...") self.__stop_sol_worker()
def __activate_sol_handler(self, _: Dict, session: IpmiServerSession) -> None: with self.__sol_lock: if not self.__sol_device_path: session.send_ipmi_response(code=0x81) # SOL disabled elif not os.access(self.__sol_device_path, os.R_OK | os.W_OK): get_logger(0).info( "Can't activate SOL because %s is unavailable", self.__sol_device_path) session.send_ipmi_response(code=0x81) # SOL disabled elif self.__is_sol_activated(): session.send_ipmi_response(code=0x80) # Already activated else: get_logger(0).info("Activating SOL ...") self.__stop_sol_worker() # Join if dead session.send_ipmi_response(data=[ 0, 0, 0, 0, 1, 0, 1, 0, (self.__sol_proxy_port >> 8 & 0xFF), (self.__sol_proxy_port & 0xFF), 0xFF, 0xFF, ]) self.__start_sol_worker(session)
def __chassis_control_handler(self, request: Dict, session: IpmiServerSession) -> None: action = { 0: "off_hard", 1: "on", 3: "reset_hard", 5: "off", }.get(request["data"][0], "") if action: if not self.__make_request(session, f"atx.switch_power({action})", "atx.switch_power", action=action): code = 0xC0 # Try again later else: code = 0 else: code = 0xCC # Invalid request session.send_ipmi_response(code=code)
def __chassis_control_handler(self, request: Dict, session: IpmiServerSession) -> None: handle = { 0: "/atx/power?action=off_hard", 1: "/atx/power?action=on", 3: "/atx/power?action=reset_hard", 5: "/atx/power?action=off", }.get(request["data"][0], "") if handle: if self.__make_request("POST", handle, session)[0] == 409: code = 0xC0 # Try again later else: code = 0 else: code = 0xCC # Invalid request session.send_ipmi_response(code=code)
def handle_raw_request(self, request: Dict, session: IpmiServerSession) -> None: handler = { (6, 1): (lambda _, session: self.send_device_id(session)), # Get device ID (6, 7): self.__get_power_state_handler, # Power state (6, 4): self.__get_selftest_status_handler, # Self-test (6, 0x38): (lambda _, session: session.send_ipmi_response() ), # Get channel auth types (0, 1): self.__get_chassis_status_handler, # Get chassis status (0, 2): self.__chassis_control_handler, # Chassis control (6, 0x48): self.__activate_sol_handler, # Enable SOL (6, 0x49): self.__deactivate_sol_handler, # Disable SOL }.get((request["netfn"], request["command"])) if handler is not None: try: handler(request, session) except (aiohttp.ClientError, asyncio.TimeoutError): session.send_ipmi_response(code=0xFF) except Exception: get_logger(0).exception( "[%s]: Unexpected exception while handling IPMI request: netfn=%d; command=%d", session.sockaddr[0], request["netfn"], request["command"]) session.send_ipmi_response(code=0xFF) else: session.send_ipmi_response(code=0xC1)
def handle_raw_request(self, request: Dict, session: IpmiServerSession) -> None: handler = { (6, 1): lambda _, session: self.send_device_id(session), # Get device ID (0, 1): self.__get_chassis_status_handler, # Get chassis status (0, 2): self.__chassis_control_handler, # Chassis control }.get((request["netfn"], request["command"])) if handler is not None: try: handler(request, session) except (aiohttp.ClientError, asyncio.TimeoutError): session.send_ipmi_response(code=0xFF) except Exception: get_logger(0).exception( "Unexpected exception while handling IPMI request: netfn=%d; command=%d", request["netfn"], request["command"]) session.send_ipmi_response(code=0xFF) else: session.send_ipmi_response(code=0xC1)
def __get_chassis_status_handler(self, _: Dict, session: IpmiServerSession) -> None: result = self.__make_request(session, "atx.get_state()", self.__kvmd.atx.get_state) data = [int(result["leds"]["power"]), 0, 0] session.send_ipmi_response(data=data)
def __get_chassis_status_handler(self, _: Dict, session: IpmiServerSession) -> None: result = self.__make_request("GET", "/atx", session)[1] data = [int(result["leds"]["power"]), 0, 0] session.send_ipmi_response(data=data)