From b299cebffabb729032dec4d5c3025008e619170f Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Thu, 21 Oct 2021 14:47:56 +0200 Subject: [PATCH] Update CEC Add-on (#2240) * Update CEC Add-on * cleanup patch * second cleanup * fix s6 copy * set S0 for this kind of finish * Update cec_scan/CHANGELOG.md Co-authored-by: Stefan Agner Co-authored-by: Stefan Agner --- cec_scan/CHANGELOG.md | 6 + cec_scan/Dockerfile | 52 +- cec_scan/build.json | 12 +- cec_scan/config.json | 2 +- cec_scan/data/libcec.patch | 887 ------------------ cec_scan/data/run.sh | 5 - .../rootfs/etc/services.d/cec-scan/finish | 5 + cec_scan/rootfs/etc/services.d/cec-scan/run | 7 + 8 files changed, 36 insertions(+), 940 deletions(-) delete mode 100644 cec_scan/data/libcec.patch delete mode 100755 cec_scan/data/run.sh create mode 100644 cec_scan/rootfs/etc/services.d/cec-scan/finish create mode 100644 cec_scan/rootfs/etc/services.d/cec-scan/run diff --git a/cec_scan/CHANGELOG.md b/cec_scan/CHANGELOG.md index 7f4dfe2d82d..c20a47d9b32 100644 --- a/cec_scan/CHANGELOG.md +++ b/cec_scan/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 3.0 + +- Using the Upstream Linux support only +- Using s6-overlay style +- Update to Alpine 3.14 + ## 2.4 - Use new `video` feature of Supervisor 199 diff --git a/cec_scan/Dockerfile b/cec_scan/Dockerfile index f9c07ff71fb..c4c6f9a2fd9 100644 --- a/cec_scan/Dockerfile +++ b/cec_scan/Dockerfile @@ -1,21 +1,11 @@ ARG BUILD_FROM FROM $BUILD_FROM -# Set shell -SHELL ["/bin/bash", "-o", "pipefail", "-c"] - -# Meta -WORKDIR /usr/src -ARG BUILD_ARCH -ARG LIBCEC_VERSION - # Build libcec for HDMI-CEC -COPY data/libcec.patch /usr/src/ +ARG LIBCEC_VERSION +WORKDIR /usr/src RUN \ - if [[ "armhf armv7 aarch64" = *"$BUILD_ARCH"* ]]; then \ - apk add --no-cache raspberrypi-dev raspberrypi-libs; \ - fi \ - && apk add --no-cache \ + apk add --no-cache \ eudev-libs\ p8-platform \ && apk add --no-cache --virtual .build-dependencies \ @@ -27,38 +17,18 @@ RUN \ swig \ linux-headers \ && git clone --depth 1 -b libcec-${LIBCEC_VERSION} \ - "https://github.com/Pulse-Eight/libcec" /usr/src/libcec \ - && cd /usr/src/libcec \ - && git apply /usr/src/libcec.patch \ - && mkdir -p /usr/src/libcec/build \ - && cd /usr/src/libcec/build \ - && if [[ "armhf armv7 aarch64" = *"$BUILD_ARCH"* ]]; then \ - cmake \ - -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ - -DRPI_INCLUDE_DIR=/opt/vc/include \ - -DRPI_LIB_DIR=/opt/vc/lib \ - -DHAVE_EXYNOS_API=1 \ - -DHAVE_AOCEC_API=1 \ - -DHAVE_LINUX_API=1 \ - ..; \ - else \ - cmake \ - -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ - -DHAVE_LINUX_API=1 \ - ..; \ - fi \ + "https://github.com/Pulse-Eight/libcec" libcec \ + && mkdir -p libcec/build \ + && cd libcec/build \ + && cmake \ + -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DHAVE_LINUX_API=1 \ + .. \ && make -j$(nproc) \ && make install \ && apk del --no-cache .build-dependencies \ - && if [[ "armhf armv7 aarch64" = *"$BUILD_ARCH"* ]]; then \ - apk del --no-cache raspberrypi-dev; \ - fi \ && rm -rf /usr/src/* -ENV LD_LIBRARY_PATH=/opt/vc/lib:${LD_LIBRARY_PATH} - # Copy data -COPY data/run.sh / - WORKDIR / -CMD [ "/run.sh" ] +COPY rootfs / diff --git a/cec_scan/build.json b/cec_scan/build.json index 46c2a5bfa0a..eda9a0d541c 100644 --- a/cec_scan/build.json +++ b/cec_scan/build.json @@ -1,12 +1,12 @@ { "build_from": { - "aarch64": "homeassistant/aarch64-base:3.11", - "amd64": "homeassistant/amd64-base:3.11", - "armhf": "homeassistant/armhf-base:3.11", - "armv7": "homeassistant/armv7-base:3.11", - "i386": "homeassistant/i386-base:3.11" + "aarch64": "homeassistant/aarch64-base:3.14", + "amd64": "homeassistant/amd64-base:3.14", + "armhf": "homeassistant/armhf-base:3.14", + "armv7": "homeassistant/armv7-base:3.14", + "i386": "homeassistant/i386-base:3.14" }, "args": { - "LIBCEC_VERSION": "4.0.3" + "LIBCEC_VERSION": "6.0.2" } } diff --git a/cec_scan/config.json b/cec_scan/config.json index f9d31811130..d272cc3bab3 100644 --- a/cec_scan/config.json +++ b/cec_scan/config.json @@ -1,6 +1,6 @@ { "name": "CEC Scanner", - "version": "2.4", + "version": "3.0", "slug": "cec_scan", "description": "Scan for HDMI CEC devices", "url": "https://github.com/home-assistant/hassio-addons/tree/master/cec_scan", diff --git a/cec_scan/data/libcec.patch b/cec_scan/data/libcec.patch deleted file mode 100644 index 49af7eadf31..00000000000 --- a/cec_scan/data/libcec.patch +++ /dev/null @@ -1,887 +0,0 @@ -From 467cc79fd289403e7d4f6e4e817b906c0c0027dd Mon Sep 17 00:00:00 2001 -From: Jonas Karlman -Date: Wed, 6 Sep 2017 17:37:05 +0200 -Subject: [PATCH] Add Linux CEC Adapter - ---- - docs/README.linux.md | 6 + - include/cectypes.h | 11 + - src/libcec/CECTypeUtils.h | 2 + - src/libcec/CMakeLists.txt | 2 + - src/libcec/adapter/AdapterFactory.cpp | 26 +- - .../Linux/LinuxCECAdapterCommunication.cpp | 438 ++++++++++++++++++ - .../Linux/LinuxCECAdapterCommunication.h | 95 ++++ - .../Linux/LinuxCECAdapterDetection.cpp | 50 ++ - .../adapter/Linux/LinuxCECAdapterDetection.h | 51 ++ - src/libcec/cmake/CheckPlatformSupport.cmake | 12 + - src/libcec/cmake/DisplayPlatformSupport.cmake | 6 + - src/libcec/env.h.in | 3 + - 12 files changed, 700 insertions(+), 2 deletions(-) - create mode 100644 src/libcec/adapter/Linux/LinuxCECAdapterCommunication.cpp - create mode 100644 src/libcec/adapter/Linux/LinuxCECAdapterCommunication.h - create mode 100644 src/libcec/adapter/Linux/LinuxCECAdapterDetection.cpp - create mode 100644 src/libcec/adapter/Linux/LinuxCECAdapterDetection.h - -diff --git a/docs/README.linux.md b/docs/README.linux.md -index c59fb80..e8053cc 100644 ---- a/docs/README.linux.md -+++ b/docs/README.linux.md -@@ -51,5 +51,11 @@ Pass the argument `-DHAVE_TDA995X_API=1` to the cmake command in the compilation - cmake -DHAVE_TDA995X_API=1 .. - ``` - -+### Linux CEC Framework (v4.10+) -+Pass the argument `-DHAVE_LINUX_API=1` to the cmake command in the compilation instructions: -+``` -+cmake -DHAVE_LINUX_API=1 .. -+``` -+ - ### Debian / Ubuntu .deb packaging - See [docs/README.debian.md](README.debian.md). -\ No newline at end of file -diff --git a/include/cectypes.h b/include/cectypes.h -index 9c91842..2c32e4d 100644 ---- a/include/cectypes.h -+++ b/include/cectypes.h -@@ -281,6 +281,16 @@ namespace CEC { - */ - #define CEC_MAX_DATA_PACKET_SIZE (16 * 4) - -+/*! -+ * the path to use for the Linux CEC device -+ */ -+#define CEC_LINUX_PATH "/dev/cec0" -+ -+/*! -+ * the name of the virtual COM port to use for the Linux' CEC wire -+ */ -+#define CEC_LINUX_VIRTUAL_COM "Linux" -+ - /*! - * the path to use for the AOCEC HDMI CEC device - */ -@@ -861,6 +871,7 @@ typedef enum cec_adapter_type - ADAPTERTYPE_RPI = 0x100, - ADAPTERTYPE_TDA995x = 0x200, - ADAPTERTYPE_EXYNOS = 0x300, -+ ADAPTERTYPE_LINUX = 0x400, - ADAPTERTYPE_AOCEC = 0x500 - } cec_adapter_type; - -diff --git a/src/libcec/CECTypeUtils.h b/src/libcec/CECTypeUtils.h -index 25c1c6e..15f9543 100644 ---- a/src/libcec/CECTypeUtils.h -+++ b/src/libcec/CECTypeUtils.h -@@ -766,6 +766,8 @@ namespace CEC - return "Raspberry Pi"; - case ADAPTERTYPE_TDA995x: - return "TDA995x"; -+ case ADAPTERTYPE_LINUX: -+ return "Linux"; - default: - return "unknown"; - } -diff --git a/src/libcec/CMakeLists.txt b/src/libcec/CMakeLists.txt -index 6baee69..74fe5f3 100644 ---- a/src/libcec/CMakeLists.txt -+++ b/src/libcec/CMakeLists.txt -@@ -89,6 +89,8 @@ set(CEC_HEADERS devices/CECRecordingDevice.h - adapter/Exynos/ExynosCEC.h - adapter/Exynos/ExynosCECAdapterDetection.h - adapter/Exynos/ExynosCECAdapterCommunication.h -+ adapter/Linux/LinuxCECAdapterDetection.h -+ adapter/Linux/LinuxCECAdapterCommunication.h - adapter/AOCEC/AOCEC.h - adapter/AOCEC/AOCECAdapterDetection.h - adapter/AOCEC/AOCECAdapterCommunication.h -diff --git a/src/libcec/adapter/AdapterFactory.cpp b/src/libcec/adapter/AdapterFactory.cpp -index 91195ea..323c272 100644 ---- a/src/libcec/adapter/AdapterFactory.cpp -+++ b/src/libcec/adapter/AdapterFactory.cpp -@@ -58,6 +58,11 @@ - #include "Exynos/ExynosCECAdapterCommunication.h" - #endif - -+#if defined(HAVE_LINUX_API) -+#include "Linux/LinuxCECAdapterDetection.h" -+#include "Linux/LinuxCECAdapterCommunication.h" -+#endif -+ - #if defined(HAVE_AOCEC_API) - #include "AOCEC/AOCECAdapterDetection.h" - #include "AOCEC/AOCECAdapterCommunication.h" -@@ -131,6 +136,18 @@ int8_t CAdapterFactory::DetectAdapters(cec_adapter_descriptor *deviceList, uint8 - } - #endif - -+#if defined(HAVE_LINUX_API) -+ if (iAdaptersFound < iBufSize && CLinuxCECAdapterDetection::FindAdapter()) -+ { -+ snprintf(deviceList[iAdaptersFound].strComPath, sizeof(deviceList[iAdaptersFound].strComPath), CEC_LINUX_PATH); -+ snprintf(deviceList[iAdaptersFound].strComName, sizeof(deviceList[iAdaptersFound].strComName), CEC_LINUX_VIRTUAL_COM); -+ deviceList[iAdaptersFound].iVendorId = 0; -+ deviceList[iAdaptersFound].iProductId = 0; -+ deviceList[iAdaptersFound].adapterType = ADAPTERTYPE_LINUX; -+ iAdaptersFound++; -+ } -+#endif -+ - #if defined(HAVE_AOCEC_API) - if (iAdaptersFound < iBufSize && CAOCECAdapterDetection::FindAdapter()) - { -@@ -144,7 +161,7 @@ int8_t CAdapterFactory::DetectAdapters(cec_adapter_descriptor *deviceList, uint8 - #endif - - --#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_AOCEC_API) -+#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_LINUX_API) && !defined(HAVE_AOCEC_API) - #error "libCEC doesn't have support for any type of adapter. please check your build system or configuration" - #endif - -@@ -163,6 +180,11 @@ IAdapterCommunication *CAdapterFactory::GetInstance(const char *strPort, uint16_ - return new CExynosCECAdapterCommunication(m_lib->m_cec); - #endif - -+#if defined(HAVE_LINUX_API) -+ if (!strcmp(strPort, CEC_LINUX_VIRTUAL_COM)) -+ return new CLinuxCECAdapterCommunication(m_lib->m_cec); -+#endif -+ - #if defined(HAVE_AOCEC_API) - if (!strcmp(strPort, CEC_AOCEC_VIRTUAL_COM)) - return new CAOCECAdapterCommunication(m_lib->m_cec); -@@ -177,7 +199,7 @@ IAdapterCommunication *CAdapterFactory::GetInstance(const char *strPort, uint16_ - return new CUSBCECAdapterCommunication(m_lib->m_cec, strPort, iBaudRate); - #endif - --#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_EXYNOS_API) && !defined(HAVE_AOCEC_API) -+#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_EXYNOS_API) && !defined(HAVE_LINUX_API) && !defined(HAVE_AOCEC_API) - return NULL; - #endif - } -diff --git a/src/libcec/adapter/Linux/LinuxCECAdapterCommunication.cpp b/src/libcec/adapter/Linux/LinuxCECAdapterCommunication.cpp -new file mode 100644 -index 0000000..6a28835 ---- /dev/null -+++ b/src/libcec/adapter/Linux/LinuxCECAdapterCommunication.cpp -@@ -0,0 +1,438 @@ -+/* -+ * This file is part of the libCEC(R) library. -+ * -+ * libCEC Linux CEC Adapter is Copyright (C) 2017-2019 Jonas Karlman -+ * based heavily on: -+ * libCEC AOCEC Code is Copyright (C) 2016 Gerald Dachs -+ * libCEC Exynos Code is Copyright (C) 2014 Valentin Manea -+ * libCEC(R) is Copyright (C) 2011-2015 Pulse-Eight Limited. All rights reserved. -+ * libCEC(R) is an original work, containing original code. -+ * -+ * libCEC(R) is a trademark of Pulse-Eight Limited. -+ * -+ * This program is dual-licensed; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * -+ * Alternatively, you can license this library under a commercial license, -+ * please contact Pulse-Eight Licensing for more information. -+ * -+ * For more information contact: -+ * Pulse-Eight Licensing -+ * http://www.pulse-eight.com/ -+ * http://www.pulse-eight.net/ -+ */ -+ -+#include "env.h" -+#include -+#include -+ -+#if defined(HAVE_LINUX_API) -+#include "LinuxCECAdapterCommunication.h" -+#include "CECTypeUtils.h" -+#include "LibCEC.h" -+#include "p8-platform/util/buffer.h" -+#include -+ -+using namespace CEC; -+using namespace P8PLATFORM; -+ -+#define LIB_CEC m_callback->GetLib() -+ -+// Required capabilities -+#define CEC_LINUX_CAPABILITIES (CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | CEC_CAP_PASSTHROUGH) -+ -+CLinuxCECAdapterCommunication::CLinuxCECAdapterCommunication(IAdapterCommunicationCallback *callback) -+ : IAdapterCommunication(callback) -+{ -+ m_fd = INVALID_SOCKET_VALUE; -+} -+ -+CLinuxCECAdapterCommunication::~CLinuxCECAdapterCommunication(void) -+{ -+ Close(); -+} -+ -+bool CLinuxCECAdapterCommunication::Open(uint32_t UNUSED(iTimeoutMs), bool UNUSED(bSkipChecks), bool bStartListening) -+{ -+ if (IsOpen()) -+ Close(); -+ -+ if ((m_fd = open(CEC_LINUX_PATH, O_RDWR)) >= 0) -+ { -+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "CLinuxCECAdapterCommunication::Open - m_fd=%d bStartListening=%d", m_fd, bStartListening); -+ -+ // Ensure the CEC device supports required capabilities -+ struct cec_caps caps = {}; -+ if (ioctl(m_fd, CEC_ADAP_G_CAPS, &caps) || (caps.capabilities & CEC_LINUX_CAPABILITIES) != CEC_LINUX_CAPABILITIES) -+ { -+ LIB_CEC->AddLog(CEC_LOG_ERROR, "CLinuxCECAdapterCommunication::Open - ioctl CEC_ADAP_G_CAPS failed - capabilities=%02x errno=%d", caps.capabilities, errno); -+ Close(); -+ return false; -+ } -+ -+ if (!bStartListening) -+ { -+ Close(); -+ return true; -+ } -+ -+ // This is an exclusive follower, in addition put the CEC device into passthrough mode -+ uint32_t mode = CEC_MODE_INITIATOR | CEC_MODE_EXCL_FOLLOWER_PASSTHRU; -+ if (ioctl(m_fd, CEC_S_MODE, &mode)) -+ { -+ LIB_CEC->AddLog(CEC_LOG_ERROR, "CLinuxCECAdapterCommunication::Open - ioctl CEC_S_MODE failed - errno=%d", errno); -+ Close(); -+ return false; -+ } -+ -+ uint16_t addr; -+ if (ioctl(m_fd, CEC_ADAP_G_PHYS_ADDR, &addr)) -+ { -+ LIB_CEC->AddLog(CEC_LOG_ERROR, "CLinuxCECAdapterCommunication::Open - ioctl CEC_ADAP_G_PHYS_ADDR failed - errno=%d", errno); -+ Close(); -+ return false; -+ } -+ -+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "CLinuxCECAdapterCommunication::Open - ioctl CEC_ADAP_G_PHYS_ADDR - addr=%04x", addr); -+ -+ if (addr == CEC_PHYS_ADDR_INVALID) -+ LIB_CEC->AddLog(CEC_LOG_WARNING, "CLinuxCECAdapterCommunication::Open - physical address is invalid"); -+ -+ // Clear existing logical addresses and set the CEC device to the unconfigured state -+ struct cec_log_addrs log_addrs = {}; -+ if (ioctl(m_fd, CEC_ADAP_S_LOG_ADDRS, &log_addrs)) -+ { -+ LIB_CEC->AddLog(CEC_LOG_ERROR, "CLinuxCECAdapterCommunication::Open - ioctl CEC_ADAP_S_LOG_ADDRS failed - errno=%d", errno); -+ Close(); -+ return false; -+ } -+ -+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "CLinuxCECAdapterCommunication::Open - ioctl CEC_ADAP_S_LOG_ADDRS - log_addr_mask=%04x num_log_addrs=%u", log_addrs.log_addr_mask, log_addrs.num_log_addrs); -+ -+ // Set logical address to unregistered, without any logical address configured no messages is transmitted or received -+ log_addrs = {}; -+ log_addrs.cec_version = CEC_OP_CEC_VERSION_1_4; -+ log_addrs.vendor_id = CEC_VENDOR_PULSE_EIGHT; -+ log_addrs.num_log_addrs = 1; -+ log_addrs.flags = CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK; -+ log_addrs.log_addr[0] = CEC_LOG_ADDR_UNREGISTERED; -+ log_addrs.primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_SWITCH; -+ log_addrs.log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; -+ log_addrs.all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; -+ if (ioctl(m_fd, CEC_ADAP_S_LOG_ADDRS, &log_addrs)) -+ { -+ LIB_CEC->AddLog(CEC_LOG_ERROR, "CLinuxCECAdapterCommunication::Open - ioctl CEC_ADAP_S_LOG_ADDRS failed - errno=%d", errno); -+ Close(); -+ return false; -+ } -+ -+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "CLinuxCECAdapterCommunication::Open - ioctl CEC_ADAP_S_LOG_ADDRS - log_addr_mask=%04x num_log_addrs=%u", log_addrs.log_addr_mask, log_addrs.num_log_addrs); -+ -+ if (CreateThread()) -+ return true; -+ -+ Close(); -+ } -+ -+ return false; -+} -+ -+void CLinuxCECAdapterCommunication::Close(void) -+{ -+ StopThread(0); -+ -+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "CLinuxCECAdapterCommunication::Close - m_fd=%d", m_fd); -+ -+ close(m_fd); -+ m_fd = INVALID_SOCKET_VALUE; -+} -+ -+bool CLinuxCECAdapterCommunication::IsOpen(void) -+{ -+ return m_fd != INVALID_SOCKET_VALUE; -+} -+ -+cec_adapter_message_state CLinuxCECAdapterCommunication::Write(const cec_command &data, bool &bRetry, uint8_t UNUSED(iLineTimeout), bool UNUSED(bIsReply)) -+{ -+ if (IsOpen()) -+ { -+ struct cec_msg msg; -+ cec_msg_init(&msg, data.initiator, data.destination); -+ -+ if (data.opcode_set) -+ { -+ msg.msg[msg.len++] = data.opcode; -+ -+ if (data.parameters.size) -+ { -+ memcpy(&msg.msg[msg.len], data.parameters.data, data.parameters.size); -+ msg.len += data.parameters.size; -+ } -+ } -+ -+ if (ioctl(m_fd, CEC_TRANSMIT, &msg)) -+ { -+ LIB_CEC->AddLog(CEC_LOG_ERROR, "CLinuxCECAdapterCommunication::Write - ioctl CEC_TRANSMIT failed - tx_status=%02x errno=%d", msg.tx_status, errno); -+ return ADAPTER_MESSAGE_STATE_ERROR; -+ } -+ -+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "CLinuxCECAdapterCommunication::Write - ioctl CEC_TRANSMIT - tx_status=%02x len=%d addr=%02x opcode=%02x", msg.tx_status, msg.len, msg.msg[0], cec_msg_opcode(&msg)); -+ -+ // The CEC driver will make re-transmission attempts -+ bRetry = false; -+ -+ if (msg.tx_status & CEC_TX_STATUS_OK) -+ return ADAPTER_MESSAGE_STATE_SENT_ACKED; -+ -+ if (msg.tx_status & CEC_TX_STATUS_NACK) -+ return ADAPTER_MESSAGE_STATE_SENT_NOT_ACKED; -+ -+ return ADAPTER_MESSAGE_STATE_ERROR; -+ } -+ -+ return ADAPTER_MESSAGE_STATE_UNKNOWN; -+} -+ -+bool CLinuxCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses) -+{ -+ if (IsOpen()) -+ { -+ struct cec_log_addrs log_addrs = {}; -+ if (ioctl(m_fd, CEC_ADAP_G_LOG_ADDRS, &log_addrs)) -+ { -+ LIB_CEC->AddLog(CEC_LOG_ERROR, "CLinuxCECAdapterCommunication::SetLogicalAddresses - ioctl CEC_ADAP_G_LOG_ADDRS failed - errno=%d", errno); -+ return false; -+ } -+ -+ // TODO: Claiming a logical address will only work when CEC device has a valid physical address -+ -+ // Clear existing logical addresses and set the CEC device to the unconfigured state -+ if (log_addrs.num_log_addrs) -+ { -+ log_addrs = {}; -+ if (ioctl(m_fd, CEC_ADAP_S_LOG_ADDRS, &log_addrs)) -+ { -+ LIB_CEC->AddLog(CEC_LOG_ERROR, "CLinuxCECAdapterCommunication::SetLogicalAddresses - ioctl CEC_ADAP_S_LOG_ADDRS failed - errno=%d", errno); -+ return false; -+ } -+ -+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "CLinuxCECAdapterCommunication::SetLogicalAddresses - ioctl CEC_ADAP_S_LOG_ADDRS - log_addr_mask=%04x num_log_addrs=%u", log_addrs.log_addr_mask, log_addrs.num_log_addrs); -+ } -+ -+ if (!addresses.IsEmpty()) -+ { -+ // NOTE: This can only be configured when num_log_addrs > 0 -+ // and gets reset when num_log_addrs = 0 -+ log_addrs.cec_version = CEC_OP_CEC_VERSION_1_4; -+ log_addrs.vendor_id = CEC_VENDOR_PULSE_EIGHT; -+ -+ // TODO: Support more then the primary logical address -+ log_addrs.num_log_addrs = 1; -+ log_addrs.log_addr[0] = addresses.primary; -+ -+ switch (addresses.primary) -+ { -+ case CECDEVICE_AUDIOSYSTEM: -+ log_addrs.primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM; -+ log_addrs.log_addr_type[0] = CEC_LOG_ADDR_TYPE_AUDIOSYSTEM; -+ log_addrs.all_device_types[0] = CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM; -+ break; -+ case CECDEVICE_PLAYBACKDEVICE1: -+ case CECDEVICE_PLAYBACKDEVICE2: -+ case CECDEVICE_PLAYBACKDEVICE3: -+ log_addrs.primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_PLAYBACK; -+ log_addrs.log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK; -+ log_addrs.all_device_types[0] = CEC_OP_ALL_DEVTYPE_PLAYBACK; -+ break; -+ case CECDEVICE_RECORDINGDEVICE1: -+ case CECDEVICE_RECORDINGDEVICE2: -+ case CECDEVICE_RECORDINGDEVICE3: -+ log_addrs.primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_RECORD; -+ log_addrs.log_addr_type[0] = CEC_LOG_ADDR_TYPE_RECORD; -+ log_addrs.all_device_types[0] = CEC_OP_ALL_DEVTYPE_RECORD; -+ break; -+ case CECDEVICE_TUNER1: -+ case CECDEVICE_TUNER2: -+ case CECDEVICE_TUNER3: -+ case CECDEVICE_TUNER4: -+ log_addrs.primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_TUNER; -+ log_addrs.log_addr_type[0] = CEC_LOG_ADDR_TYPE_TUNER; -+ log_addrs.all_device_types[0] = CEC_OP_ALL_DEVTYPE_TUNER; -+ break; -+ case CECDEVICE_TV: -+ log_addrs.primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_TV; -+ log_addrs.log_addr_type[0] = CEC_LOG_ADDR_TYPE_TV; -+ log_addrs.all_device_types[0] = CEC_OP_ALL_DEVTYPE_TV; -+ break; -+ default: -+ log_addrs.primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_SWITCH; -+ log_addrs.log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; -+ log_addrs.all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; -+ break; -+ } -+ } -+ else -+ log_addrs.num_log_addrs = 0; -+ -+ if (ioctl(m_fd, CEC_ADAP_S_LOG_ADDRS, &log_addrs)) -+ { -+ LIB_CEC->AddLog(CEC_LOG_ERROR, "CLinuxCECAdapterCommunication::SetLogicalAddresses - ioctl CEC_ADAP_S_LOG_ADDRS failed - errno=%d", errno); -+ return false; -+ } -+ -+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "CLinuxCECAdapterCommunication::SetLogicalAddresses - ioctl CEC_ADAP_S_LOG_ADDRS - log_addr_mask=%04x num_log_addrs=%u", log_addrs.log_addr_mask, log_addrs.num_log_addrs); -+ -+ if (log_addrs.num_log_addrs && !log_addrs.log_addr_mask) -+ return false; -+ -+ return true; -+ } -+ -+ return false; -+} -+ -+cec_logical_addresses CLinuxCECAdapterCommunication::GetLogicalAddresses(void) const -+{ -+ cec_logical_addresses addresses; -+ addresses.Clear(); -+ -+ if (m_fd != INVALID_SOCKET_VALUE) -+ { -+ struct cec_log_addrs log_addrs = {}; -+ if (ioctl(m_fd, CEC_ADAP_G_LOG_ADDRS, &log_addrs)) -+ { -+ LIB_CEC->AddLog(CEC_LOG_ERROR, "CLinuxCECAdapterCommunication::GetLogicalAddresses - ioctl CEC_ADAP_G_LOG_ADDRS failed - errno=%d", errno); -+ return addresses; -+ } -+ -+ for (int i = 0; i < log_addrs.num_log_addrs; i++) -+ addresses.Set(cec_logical_address(log_addrs.log_addr[i])); -+ } -+ -+ return addresses; -+} -+ -+uint16_t CLinuxCECAdapterCommunication::GetPhysicalAddress(void) -+{ -+ if (IsOpen()) -+ { -+ uint16_t addr; -+ if (!ioctl(m_fd, CEC_ADAP_G_PHYS_ADDR, &addr)) -+ return addr; -+ -+ LIB_CEC->AddLog(CEC_LOG_ERROR, "CLinuxCECAdapterCommunication::GetPhysicalAddress - ioctl CEC_ADAP_G_PHYS_ADDR failed - errno=%d", errno); -+ } -+ -+ return CEC_INVALID_PHYSICAL_ADDRESS; -+} -+ -+cec_vendor_id CLinuxCECAdapterCommunication::GetVendorId(void) -+{ -+ if (IsOpen()) -+ { -+ struct cec_log_addrs log_addrs = {}; -+ if (!ioctl(m_fd, CEC_ADAP_G_LOG_ADDRS, &log_addrs)) -+ return cec_vendor_id(log_addrs.vendor_id); -+ -+ LIB_CEC->AddLog(CEC_LOG_ERROR, "CLinuxCECAdapterCommunication::GetVendorId - ioctl CEC_ADAP_G_LOG_ADDRS failed - errno=%d", errno); -+ } -+ -+ return CEC_VENDOR_UNKNOWN; -+} -+ -+void *CLinuxCECAdapterCommunication::Process(void) -+{ -+ CTimeout phys_addr_timeout; -+ bool phys_addr_changed = false; -+ uint16_t phys_addr = CEC_INVALID_PHYSICAL_ADDRESS; -+ fd_set rd_fds; -+ fd_set ex_fds; -+ -+ while (!IsStopped()) -+ { -+ struct timeval timeval = {}; -+ timeval.tv_sec = 1; -+ -+ FD_ZERO(&rd_fds); -+ FD_ZERO(&ex_fds); -+ FD_SET(m_fd, &rd_fds); -+ FD_SET(m_fd, &ex_fds); -+ -+ if (select(m_fd + 1, &rd_fds, NULL, &ex_fds, &timeval) < 0) -+ { -+ LIB_CEC->AddLog(CEC_LOG_ERROR, "CLinuxCECAdapterCommunication::Process - select failed - errno=%d", errno); -+ break; -+ } -+ -+ if (FD_ISSET(m_fd, &ex_fds)) -+ { -+ struct cec_event ev = {}; -+ if (ioctl(m_fd, CEC_DQEVENT, &ev)) -+ LIB_CEC->AddLog(CEC_LOG_ERROR, "CLinuxCECAdapterCommunication::Process - ioctl CEC_DQEVENT failed - errno=%d", errno); -+ else if (ev.event == CEC_EVENT_STATE_CHANGE) -+ { -+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "CLinuxCECAdapterCommunication::Process - CEC_DQEVENT - CEC_EVENT_STATE_CHANGE - log_addr_mask=%04x phys_addr=%04x", ev.state_change.log_addr_mask, ev.state_change.phys_addr); -+ -+ // TODO: handle ev.state_change.log_addr_mask change -+ -+ phys_addr = ev.state_change.phys_addr; -+ phys_addr_changed = true; -+ -+ if (ev.state_change.phys_addr == CEC_PHYS_ADDR_INVALID) -+ { -+ // Debounce change to invalid physical address with 2 seconds because -+ // EDID refresh and other events may cause short periods of invalid physical address -+ phys_addr_timeout.Init(2000); -+ } -+ else -+ { -+ // Debounce change to valid physical address with 500 ms when no logical address have been claimed -+ phys_addr_timeout.Init(ev.state_change.log_addr_mask ? 0 : 500); -+ } -+ } -+ } -+ -+ if (phys_addr_changed && !phys_addr_timeout.TimeLeft() && !IsStopped()) -+ { -+ phys_addr_changed = false; -+ m_callback->HandlePhysicalAddressChanged(phys_addr); -+ } -+ -+ if (FD_ISSET(m_fd, &rd_fds)) -+ { -+ struct cec_msg msg = {}; -+ if (ioctl(m_fd, CEC_RECEIVE, &msg)) -+ LIB_CEC->AddLog(CEC_LOG_ERROR, "CLinuxCECAdapterCommunication::Process - ioctl CEC_RECEIVE failed - rx_status=%02x errno=%d", msg.rx_status, errno); -+ else if (msg.len > 0) -+ { -+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "CLinuxCECAdapterCommunication::Process - ioctl CEC_RECEIVE - rx_status=%02x len=%d addr=%02x opcode=%02x", msg.rx_status, msg.len, msg.msg[0], cec_msg_opcode(&msg)); -+ -+ cec_command cmd; -+ cmd.PushArray(msg.len, msg.msg); -+ -+ if (!IsStopped()) -+ m_callback->OnCommandReceived(cmd); -+ } -+ } -+ -+ if (!IsStopped()) -+ Sleep(5); -+ } -+ -+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "CLinuxCECAdapterCommunication::Process - stopped - m_fd=%d", m_fd); -+ return 0; -+} -+ -+#endif -diff --git a/src/libcec/adapter/Linux/LinuxCECAdapterCommunication.h b/src/libcec/adapter/Linux/LinuxCECAdapterCommunication.h -new file mode 100644 -index 0000000..f4fac87 ---- /dev/null -+++ b/src/libcec/adapter/Linux/LinuxCECAdapterCommunication.h -@@ -0,0 +1,95 @@ -+#pragma once -+/* -+ * This file is part of the libCEC(R) library. -+ * -+ * libCEC Linux CEC Adapter is Copyright (C) 2017-2018 Jonas Karlman -+ * based heavily on: -+ * libCEC AOCEC Code is Copyright (C) 2016 Gerald Dachs -+ * libCEC Exynos Code is Copyright (C) 2014 Valentin Manea -+ * libCEC(R) is Copyright (C) 2011-2015 Pulse-Eight Limited. All rights reserved. -+ * libCEC(R) is an original work, containing original code. -+ * -+ * libCEC(R) is a trademark of Pulse-Eight Limited. -+ * -+ * This program is dual-licensed; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * -+ * Alternatively, you can license this library under a commercial license, -+ * please contact Pulse-Eight Licensing for more information. -+ * -+ * For more information contact: -+ * Pulse-Eight Licensing -+ * http://www.pulse-eight.com/ -+ * http://www.pulse-eight.net/ -+ */ -+ -+#include "env.h" -+ -+#if defined(HAVE_LINUX_API) -+#include "p8-platform/threads/threads.h" -+#include "../AdapterCommunication.h" -+ -+namespace CEC -+{ -+ class CLinuxCECAdapterCommunication : public IAdapterCommunication, public P8PLATFORM::CThread -+ { -+ public: -+ /*! -+ * @brief Create a new Linux CEC communication handler. -+ * @param callback The callback to use for incoming CEC commands. -+ */ -+ CLinuxCECAdapterCommunication(IAdapterCommunicationCallback *callback); -+ virtual ~CLinuxCECAdapterCommunication(void); -+ -+ /** @name IAdapterCommunication implementation */ -+ ///{ -+ bool Open(uint32_t iTimeoutMs = CEC_DEFAULT_CONNECT_TIMEOUT, bool bSkipChecks = false, bool bStartListening = true) override; -+ void Close(void) override; -+ bool IsOpen(void) override; -+ cec_adapter_message_state Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout, bool bIsReply) override; -+ -+ bool SetLineTimeout(uint8_t UNUSED(iTimeout)) override { return true; } -+ bool StartBootloader(void) override { return false; } -+ bool SetLogicalAddresses(const cec_logical_addresses &addresses) override; -+ cec_logical_addresses GetLogicalAddresses(void) const override; -+ bool PingAdapter(void) override { return true; } -+ uint16_t GetFirmwareVersion(void) override { return 0; } -+ uint32_t GetFirmwareBuildDate(void) override { return 0; } -+ bool IsRunningLatestFirmware(void) override { return true; } -+ bool SetControlledMode(bool UNUSED(controlled)) override { return true; } -+ bool PersistConfiguration(const libcec_configuration & UNUSED(configuration)) override { return false; } -+ bool SetAutoMode(bool UNUSED(automode)) override { return false; } -+ bool GetConfiguration(libcec_configuration & UNUSED(configuration)) override { return false; } -+ std::string GetPortName(void) override { return std::string("LINUX"); } -+ uint16_t GetPhysicalAddress(void) override; -+ cec_vendor_id GetVendorId(void) override; -+ bool SupportsSourceLogicalAddress(const cec_logical_address address) override { return address > CECDEVICE_TV && address <= CECDEVICE_BROADCAST; } -+ cec_adapter_type GetAdapterType(void) override { return ADAPTERTYPE_LINUX; } -+ uint16_t GetAdapterVendorId(void) const override { return 1; } -+ uint16_t GetAdapterProductId(void) const override { return 1; } -+ void SetActiveSource(bool UNUSED(bSetTo), bool UNUSED(bClientUnregistered)) override {} -+ ///} -+ -+ /** @name P8PLATFORM::CThread implementation */ -+ ///{ -+ void *Process(void) override; -+ ///} -+ -+ private: -+ int m_fd; -+ }; -+}; -+ -+#endif -diff --git a/src/libcec/adapter/Linux/LinuxCECAdapterDetection.cpp b/src/libcec/adapter/Linux/LinuxCECAdapterDetection.cpp -new file mode 100644 -index 0000000..7b72238 ---- /dev/null -+++ b/src/libcec/adapter/Linux/LinuxCECAdapterDetection.cpp -@@ -0,0 +1,50 @@ -+/* -+ * This file is part of the libCEC(R) library. -+ * -+ * libCEC Linux CEC Adapter is Copyright (C) 2017 Jonas Karlman -+ * based heavily on: -+ * libCEC AOCEC Code is Copyright (C) 2016 Gerald Dachs -+ * libCEC Exynos Code is Copyright (C) 2014 Valentin Manea -+ * libCEC(R) is Copyright (C) 2011-2015 Pulse-Eight Limited. All rights reserved. -+ * libCEC(R) is an original work, containing original code. -+ * -+ * libCEC(R) is a trademark of Pulse-Eight Limited. -+ * -+ * This program is dual-licensed; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * -+ * Alternatively, you can license this library under a commercial license, -+ * please contact Pulse-Eight Licensing for more information. -+ * -+ * For more information contact: -+ * Pulse-Eight Licensing -+ * http://www.pulse-eight.com/ -+ * http://www.pulse-eight.net/ -+ */ -+ -+#include "env.h" -+#include -+ -+#if defined(HAVE_LINUX_API) -+#include "LinuxCECAdapterDetection.h" -+ -+using namespace CEC; -+ -+bool CLinuxCECAdapterDetection::FindAdapter(void) -+{ -+ return access(CEC_LINUX_PATH, 0) == 0; -+} -+ -+#endif -diff --git a/src/libcec/adapter/Linux/LinuxCECAdapterDetection.h b/src/libcec/adapter/Linux/LinuxCECAdapterDetection.h -new file mode 100644 -index 0000000..f5ea2c4 ---- /dev/null -+++ b/src/libcec/adapter/Linux/LinuxCECAdapterDetection.h -@@ -0,0 +1,51 @@ -+#pragma once -+/* -+ * This file is part of the libCEC(R) library. -+ * -+ * libCEC Linux CEC Adapter is Copyright (C) 2017 Jonas Karlman -+ * based heavily on: -+ * libCEC AOCEC Code is Copyright (C) 2016 Gerald Dachs -+ * libCEC Exynos Code is Copyright (C) 2014 Valentin Manea -+ * libCEC(R) is Copyright (C) 2011-2015 Pulse-Eight Limited. All rights reserved. -+ * libCEC(R) is an original work, containing original code. -+ * -+ * libCEC(R) is a trademark of Pulse-Eight Limited. -+ * -+ * This program is dual-licensed; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * -+ * Alternatively, you can license this library under a commercial license, -+ * please contact Pulse-Eight Licensing for more information. -+ * -+ * For more information contact: -+ * Pulse-Eight Licensing -+ * http://www.pulse-eight.com/ -+ * http://www.pulse-eight.net/ -+ */ -+ -+#include "env.h" -+ -+#if defined(HAVE_LINUX_API) -+ -+namespace CEC -+{ -+ class CLinuxCECAdapterDetection -+ { -+ public: -+ static bool FindAdapter(void); -+ }; -+}; -+ -+#endif -diff --git a/src/libcec/cmake/CheckPlatformSupport.cmake b/src/libcec/cmake/CheckPlatformSupport.cmake -index 2d7102f..dacca0f 100644 ---- a/src/libcec/cmake/CheckPlatformSupport.cmake -+++ b/src/libcec/cmake/CheckPlatformSupport.cmake -@@ -9,6 +9,7 @@ - # HAVE_RPI_API ON if Raspberry Pi is supported - # HAVE_TDA995X_API ON if TDA995X is supported - # HAVE_EXYNOS_API ON if Exynos is supported -+# HAVE_LINUX_API ON if Linux is supported - # HAVE_AOCEC_API ON if AOCEC is supported - # HAVE_P8_USB ON if Pulse-Eight devices are supported - # HAVE_P8_USB_DETECT ON if Pulse-Eight devices can be auto-detected -@@ -30,6 +31,7 @@ SET(HAVE_LIBUDEV OFF CACHE BOOL "udev not supported") - SET(HAVE_RPI_API OFF CACHE BOOL "raspberry pi not supported") - SET(HAVE_TDA995X_API OFF CACHE BOOL "tda995x not supported") - SET(HAVE_EXYNOS_API OFF CACHE BOOL "exynos not supported") -+SET(HAVE_LINUX_API OFF CACHE BOOL "linux not supported") - SET(HAVE_AOCEC_API OFF CACHE BOOL "aocec not supported") - # Pulse-Eight devices are always supported - set(HAVE_P8_USB ON CACHE BOOL "p8 usb-cec supported" FORCE) -@@ -139,6 +141,16 @@ else() - list(APPEND CEC_SOURCES ${CEC_SOURCES_ADAPTER_EXYNOS}) - endif() - -+ # Linux -+ if (${HAVE_LINUX_API}) -+ set(LIB_INFO "${LIB_INFO}, Linux") -+ SET(HAVE_LINUX_API ON CACHE BOOL "linux supported" FORCE) -+ set(CEC_SOURCES_ADAPTER_LINUX adapter/Linux/LinuxCECAdapterDetection.cpp -+ adapter/Linux/LinuxCECAdapterCommunication.cpp) -+ source_group("Source Files\\adapter\\Linux" FILES ${CEC_SOURCES_ADAPTER_LINUX}) -+ list(APPEND CEC_SOURCES ${CEC_SOURCES_ADAPTER_LINUX}) -+ endif() -+ - # AOCEC - if (${HAVE_AOCEC_API}) - set(LIB_INFO "${LIB_INFO}, AOCEC") -diff --git a/src/libcec/cmake/DisplayPlatformSupport.cmake b/src/libcec/cmake/DisplayPlatformSupport.cmake -index 83a778a..f47b1f7 100644 ---- a/src/libcec/cmake/DisplayPlatformSupport.cmake -+++ b/src/libcec/cmake/DisplayPlatformSupport.cmake -@@ -44,6 +44,12 @@ else() - message(STATUS "DRM support: no") - endif() - -+if (HAVE_LINUX_API) -+ message(STATUS "Linux support: yes") -+else() -+ message(STATUS "Linux support: no") -+endif() -+ - if (HAVE_AOCEC_API) - message(STATUS "AOCEC support: yes") - else() -diff --git a/src/libcec/env.h.in b/src/libcec/env.h.in -index 456a2e7..71895a8 100644 ---- a/src/libcec/env.h.in -+++ b/src/libcec/env.h.in -@@ -76,6 +76,9 @@ - /* Define to 1 for Exynos support */ - #cmakedefine HAVE_EXYNOS_API @HAVE_EXYNOS_API@ - -+/* Define to 1 for Linux support */ -+#cmakedefine HAVE_LINUX_API @HAVE_LINUX_API@ -+ - /* Define to 1 for AOCEC support */ - #cmakedefine HAVE_AOCEC_API @HAVE_AOCEC_API@ - diff --git a/cec_scan/data/run.sh b/cec_scan/data/run.sh deleted file mode 100755 index 4b898e7f358..00000000000 --- a/cec_scan/data/run.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bashio -set -e - -bashio::log.info "Starting CEC client scan..." -echo scan | cec-client -s -d 1 diff --git a/cec_scan/rootfs/etc/services.d/cec-scan/finish b/cec_scan/rootfs/etc/services.d/cec-scan/finish new file mode 100644 index 00000000000..4e3864c52a3 --- /dev/null +++ b/cec_scan/rootfs/etc/services.d/cec-scan/finish @@ -0,0 +1,5 @@ +#!/usr/bin/execlineb -S0 +# ============================================================================== +# Take down the S6 supervision tree when config check is done +# ============================================================================== +s6-svscanctl -t /var/run/s6/services diff --git a/cec_scan/rootfs/etc/services.d/cec-scan/run b/cec_scan/rootfs/etc/services.d/cec-scan/run new file mode 100644 index 00000000000..953fa237213 --- /dev/null +++ b/cec_scan/rootfs/etc/services.d/cec-scan/run @@ -0,0 +1,7 @@ +#!/usr/bin/with-contenv bashio +# ============================================================================== +# Start CEC scan service +# ============================================================================== + +bashio::log.info "Starting CEC client scan..." +echo scan | cec-client -s -d 1