Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libcec >=v5 compatibility #10

Closed
ssalonen opened this issue Jan 27, 2022 · 3 comments
Closed

libcec >=v5 compatibility #10

ssalonen opened this issue Jan 27, 2022 · 3 comments
Labels
bug Something isn't working
Milestone

Comments

@ssalonen
Copy link
Owner

ssalonen commented Jan 27, 2022

Bug description

See ssalonen/cec-alsa-sync#7

To Reproduce

Expected behavior

Screenshots

Environment

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Additional context

  • What type of differences we are expecting with ABI versions? Will types change as well?
    -- few added functions (trivial)
    -- OSD name length changed! (impacts manually created wrappers but can utilize LIBCEC_OSD_NAME_SIZE defined constant)
    -- added enum variants (already during 4.0.x series)

Openssl example in https://doc.rust-lang.org/cargo/reference/build-script-examples.html is something to follow here with libcec-sys and cec-rs, detection version and communicating that to deps. Cec-rs can use this to enable cfg values and conditionally compile API.

@ssalonen ssalonen added the bug Something isn't working label Jan 27, 2022
@ssalonen
Copy link
Owner Author

4.0.5 vs 6.0.2 diff for files vendor/include/{cecc.h,cectypes.h,version.h.in}

diff --git a/include/cecc.h b/include/cecc.h
index 83a75e2..c63611c 100644
--- a/include/cecc.h
+++ b/include/cecc.h
@@ -53,7 +53,12 @@ extern DECLSPEC void libcec_destroy(libcec_connection_t connection);
 extern DECLSPEC int libcec_open(libcec_connection_t connection, const char* strPort, uint32_t iTimeout);
 extern DECLSPEC void libcec_close(libcec_connection_t connection);
 extern DECLSPEC void libcec_clear_configuration(CEC_NAMESPACE libcec_configuration* configuration);
+#if CEC_LIB_VERSION_MAJOR >= 5
+extern DECLSPEC int libcec_set_callbacks(libcec_connection_t connection, CEC_NAMESPACE ICECCallbacks* callbacks, void* cbParam);
+extern DECLSPEC int libcec_disabled_callbacks(libcec_connection_t connection);
+#else
 extern DECLSPEC int libcec_enable_callbacks(libcec_connection_t connection, void* cbParam, CEC_NAMESPACE ICECCallbacks* callbacks);
+#endif
 extern DECLSPEC int8_t libcec_find_adapters(libcec_connection_t connection, CEC_NAMESPACE cec_adapter* deviceList, uint8_t iBufSize, const char* strDevicePath);
 extern DECLSPEC int libcec_ping_adapters(libcec_connection_t connection);
 extern DECLSPEC int libcec_start_bootloader(libcec_connection_t connection);
@@ -83,7 +88,9 @@ extern DECLSPEC int libcec_is_active_device_type(libcec_connection_t connection,
 extern DECLSPEC int libcec_set_hdmi_port(libcec_connection_t connection, CEC_NAMESPACE cec_logical_address baseDevice, uint8_t iPort);
 extern DECLSPEC int libcec_volume_up(libcec_connection_t connection, int bSendRelease);
 extern DECLSPEC int libcec_volume_down(libcec_connection_t connection, int bSendRelease);
+#if CEC_LIB_VERSION_MAJOR >= 5
 extern DECLSPEC int libcec_mute_audio(libcec_connection_t connection, int bSendRelease);
+#endif
 extern DECLSPEC int libcec_send_keypress(libcec_connection_t connection, CEC_NAMESPACE cec_logical_address iDestination, CEC_NAMESPACE cec_user_control_code key, int bWait);
 extern DECLSPEC int libcec_send_key_release(libcec_connection_t connection, CEC_NAMESPACE cec_logical_address iDestination, int bWait);
 extern DECLSPEC int libcec_get_device_osd_name(libcec_connection_t connection, CEC_NAMESPACE cec_logical_address iAddress, CEC_NAMESPACE cec_osd_name name);
@@ -91,8 +98,12 @@ extern DECLSPEC int libcec_set_stream_path_logical(libcec_connection_t connectio
 extern DECLSPEC int libcec_set_stream_path_physical(libcec_connection_t connection, uint16_t iPhysicalAddress);
 extern DECLSPEC CEC_NAMESPACE cec_logical_addresses libcec_get_logical_addresses(libcec_connection_t connection);
 extern DECLSPEC int libcec_get_current_configuration(libcec_connection_t connection, CEC_NAMESPACE libcec_configuration* configuration);
+#if CEC_LIB_VERSION_MAJOR >= 5
+extern DECLSPEC int libcec_can_save_configuration(libcec_connection_t connection);
+#else
 extern DECLSPEC int libcec_can_persist_configuration(libcec_connection_t connection);
 extern DECLSPEC int libcec_persist_configuration(libcec_connection_t connection, CEC_NAMESPACE libcec_configuration* configuration);
+#endif
 extern DECLSPEC int libcec_set_configuration(libcec_connection_t connection, const CEC_NAMESPACE libcec_configuration* configuration);
 extern DECLSPEC void libcec_rescan_devices(libcec_connection_t connection);
 extern DECLSPEC int libcec_is_libcec_active_source(libcec_connection_t connection);
diff --git a/include/cectypes.h b/include/cectypes.h
index 35e44ea..e585f2f 100644
--- a/include/cectypes.h
+++ b/include/cectypes.h
@@ -375,7 +375,8 @@ typedef enum cec_version
   CEC_VERSION_1_2A    = 0x02,
   CEC_VERSION_1_3     = 0x03,
   CEC_VERSION_1_3A    = 0x04,
-  CEC_VERSION_1_4     = 0x05
+  CEC_VERSION_1_4     = 0x05,
+  CEC_VERSION_2_0     = 0x06,
 } cec_version;
 
 typedef enum cec_channel_identifier
@@ -886,7 +887,7 @@ typedef enum cec_adapter_type
   ADAPTERTYPE_EXYNOS           = 0x300,
   ADAPTERTYPE_LINUX            = 0x400,
   ADAPTERTYPE_AOCEC            = 0x500,
-  ADAPTERTYPE_IMX	       = 0x600
+  ADAPTERTYPE_IMX              = 0x600
 } cec_adapter_type;
 
 /** force exporting through swig */
@@ -1502,7 +1503,7 @@ struct libcec_configuration
   uint8_t               bMonitorOnly;         /*!< won't allocate a CCECClient when starting the connection when set (same as monitor mode). added in 1.6.3 */
   cec_version           cecVersion;           /*!< CEC spec version to use by libCEC. defaults to v1.4. added in 1.8.0 */
   cec_adapter_type      adapterType;          /*!< type of the CEC adapter that we're connected to. added in 1.8.2 */
-  cec_user_control_code comboKey;             /*!< key code that initiates combo keys. defaults to CEC_USER_CONTROL_CODE_F1_BLUE. CEC_USER_CONTROL_CODE_UNKNOWN to disable. added in 2.0.5 */
+  cec_user_control_code comboKey;             /*!< key code that initiates combo keys. defaults to CEC_USER_CONTROL_CODE_STOP. CEC_USER_CONTROL_CODE_UNKNOWN to disable. added in 2.0.5 */
   uint32_t              iComboKeyTimeoutMs;   /*!< timeout until the combo key is sent as normal keypress */
   uint32_t              iButtonRepeatRateMs;  /*!< rate at which buttons autorepeat. 0 means rely on CEC device */
   uint32_t              iButtonReleaseDelayMs;/*!< duration after last update until a button is considered released */
@@ -1584,7 +1585,7 @@ struct libcec_configuration
     iButtonReleaseDelayMs =           CEC_BUTTON_TIMEOUT;
     bAutoWakeAVR =                    0;
 #if CEC_LIB_VERSION_MAJOR >= 5
-    bAutoPowerOn =                    0;
+    bAutoPowerOn =                    2;
 #endif
 
     strDeviceName[0] = (char)0;

@ssalonen
Copy link
Owner Author

ssalonen commented Jan 29, 2022

4.0.4 (current version of vendor) vs 6.0.2 diff for files vendor/include/{cecc.h,cectypes.h,version.h.in}, ignoring white space changes

diff --git a/include/cecc.h b/include/cecc.h
index 83a75e2..c63611c 100644
--- a/include/cecc.h
+++ b/include/cecc.h
@@ -53,7 +53,12 @@ extern DECLSPEC void libcec_destroy(libcec_connection_t connection);
 extern DECLSPEC int libcec_open(libcec_connection_t connection, const char* strPort, uint32_t iTimeout);
 extern DECLSPEC void libcec_close(libcec_connection_t connection);
 extern DECLSPEC void libcec_clear_configuration(CEC_NAMESPACE libcec_configuration* configuration);
+#if CEC_LIB_VERSION_MAJOR >= 5
+extern DECLSPEC int libcec_set_callbacks(libcec_connection_t connection, CEC_NAMESPACE ICECCallbacks* callbacks, void* cbParam);
+extern DECLSPEC int libcec_disabled_callbacks(libcec_connection_t connection);
+#else
 extern DECLSPEC int libcec_enable_callbacks(libcec_connection_t connection, void* cbParam, CEC_NAMESPACE ICECCallbacks* callbacks);
+#endif
 extern DECLSPEC int8_t libcec_find_adapters(libcec_connection_t connection, CEC_NAMESPACE cec_adapter* deviceList, uint8_t iBufSize, const char* strDevicePath);
 extern DECLSPEC int libcec_ping_adapters(libcec_connection_t connection);
 extern DECLSPEC int libcec_start_bootloader(libcec_connection_t connection);
@@ -83,7 +88,9 @@ extern DECLSPEC int libcec_is_active_device_type(libcec_connection_t connection,
 extern DECLSPEC int libcec_set_hdmi_port(libcec_connection_t connection, CEC_NAMESPACE cec_logical_address baseDevice, uint8_t iPort);
 extern DECLSPEC int libcec_volume_up(libcec_connection_t connection, int bSendRelease);
 extern DECLSPEC int libcec_volume_down(libcec_connection_t connection, int bSendRelease);
+#if CEC_LIB_VERSION_MAJOR >= 5
 extern DECLSPEC int libcec_mute_audio(libcec_connection_t connection, int bSendRelease);
+#endif
 extern DECLSPEC int libcec_send_keypress(libcec_connection_t connection, CEC_NAMESPACE cec_logical_address iDestination, CEC_NAMESPACE cec_user_control_code key, int bWait);
 extern DECLSPEC int libcec_send_key_release(libcec_connection_t connection, CEC_NAMESPACE cec_logical_address iDestination, int bWait);
 extern DECLSPEC int libcec_get_device_osd_name(libcec_connection_t connection, CEC_NAMESPACE cec_logical_address iAddress, CEC_NAMESPACE cec_osd_name name);
@@ -91,8 +98,12 @@ extern DECLSPEC int libcec_set_stream_path_logical(libcec_connection_t connectio
 extern DECLSPEC int libcec_set_stream_path_physical(libcec_connection_t connection, uint16_t iPhysicalAddress);
 extern DECLSPEC CEC_NAMESPACE cec_logical_addresses libcec_get_logical_addresses(libcec_connection_t connection);
 extern DECLSPEC int libcec_get_current_configuration(libcec_connection_t connection, CEC_NAMESPACE libcec_configuration* configuration);
+#if CEC_LIB_VERSION_MAJOR >= 5
+extern DECLSPEC int libcec_can_save_configuration(libcec_connection_t connection);
+#else
 extern DECLSPEC int libcec_can_persist_configuration(libcec_connection_t connection);
 extern DECLSPEC int libcec_persist_configuration(libcec_connection_t connection, CEC_NAMESPACE libcec_configuration* configuration);
+#endif
 extern DECLSPEC int libcec_set_configuration(libcec_connection_t connection, const CEC_NAMESPACE libcec_configuration* configuration);
 extern DECLSPEC void libcec_rescan_devices(libcec_connection_t connection);
 extern DECLSPEC int libcec_is_libcec_active_source(libcec_connection_t connection);
diff --git a/include/cectypes.h b/include/cectypes.h
index 9c91842..e585f2f 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
  */
@@ -291,6 +301,16 @@ namespace CEC {
  */
 #define CEC_AOCEC_VIRTUAL_COM		"AOCEC"
 
+/*!
+ * the path to use for the i.MX CEC wire
+ */
+#define CEC_IMX_PATH		"/dev/mxc_hdmi_cec"
+
+/*!
+ * the name of the virtual COM port to use for the i.MX CEC wire
+ */
+#define CEC_IMX_VIRTUAL_COM		"i.MX"
+
 /*!
  * Mimimum client version
  */
@@ -355,7 +375,8 @@ typedef enum cec_version
   CEC_VERSION_1_2A    = 0x02,
   CEC_VERSION_1_3     = 0x03,
   CEC_VERSION_1_3A    = 0x04,
-  CEC_VERSION_1_4     = 0x05
+  CEC_VERSION_1_4     = 0x05,
+  CEC_VERSION_2_0     = 0x06,
 } cec_version;
 
 typedef enum cec_channel_identifier
@@ -792,6 +813,8 @@ typedef enum cec_opcode
   CEC_OPCODE_SET_AUDIO_RATE                   = 0x9A,
 
   /* CEC 1.4 */
+  CEC_OPCODE_REPORT_SHORT_AUDIO_DESCRIPTORS   = 0xA3,
+  CEC_OPCODE_REQUEST_SHORT_AUDIO_DESCRIPTORS  = 0xA4,
   CEC_OPCODE_START_ARC                        = 0xC0,
   CEC_OPCODE_REPORT_ARC_STARTED               = 0xC1,
   CEC_OPCODE_REPORT_ARC_ENDED                 = 0xC2,
@@ -831,6 +854,7 @@ typedef enum cec_vendor_id
   CEC_VENDOR_ONKYO          = 0x0009B0,
   CEC_VENDOR_MEDION         = 0x000CB8,
   CEC_VENDOR_TOSHIBA2       = 0x000CE7,
+  CEC_VENDOR_APPLE          = 0x0010FA,
   CEC_VENDOR_PULSE_EIGHT    = 0x001582,
   CEC_VENDOR_HARMAN_KARDON2 = 0x001950,
   CEC_VENDOR_GOOGLE         = 0x001A11,
@@ -861,7 +885,9 @@ typedef enum cec_adapter_type
   ADAPTERTYPE_RPI              = 0x100,
   ADAPTERTYPE_TDA995x          = 0x200,
   ADAPTERTYPE_EXYNOS           = 0x300,
-  ADAPTERTYPE_AOCEC            = 0x500
+  ADAPTERTYPE_LINUX            = 0x400,
+  ADAPTERTYPE_AOCEC            = 0x500,
+  ADAPTERTYPE_IMX              = 0x600
 } cec_adapter_type;
 
 /** force exporting through swig */
@@ -1354,6 +1380,15 @@ typedef struct libcec_parameter
   void*                 paramData; /**< the value of this parameter */
 } libcec_parameter;
 
+struct cec_adapter_stats
+{
+  unsigned int tx_ack;
+  unsigned int tx_nack;
+  unsigned int tx_error;
+  unsigned int rx_total;
+  unsigned int rx_error;
+};
+
 typedef struct libcec_configuration libcec_configuration;
 
 typedef struct ICECCallbacks
@@ -1432,10 +1467,16 @@ typedef struct ICECCallbacks
 #endif
 } ICECCallbacks;
 
+#if CEC_LIB_VERSION_MAJOR >= 5
+#define LIBCEC_OSD_NAME_SIZE (15)
+#else
+#define LIBCEC_OSD_NAME_SIZE (13)
+#endif
+
 struct libcec_configuration
 {
   uint32_t              clientVersion;        /*!< the version of the client that is connecting */
-  char                  strDeviceName[13];    /*!< the device name to use on the CEC bus */
+  char                  strDeviceName[LIBCEC_OSD_NAME_SIZE]; /*!< the device name to use on the CEC bus, name + 0 terminator */
   cec_device_type_list  deviceTypes;          /*!< the device type(s) to use on the CEC bus for libCEC */
   uint8_t               bAutodetectAddress;   /*!< (read only) set to 1 by libCEC when the physical address was autodetected */
   uint16_t              iPhysicalAddress;     /*!< the physical address of the CEC adapter */
@@ -1462,12 +1503,15 @@ struct libcec_configuration
   uint8_t               bMonitorOnly;         /*!< won't allocate a CCECClient when starting the connection when set (same as monitor mode). added in 1.6.3 */
   cec_version           cecVersion;           /*!< CEC spec version to use by libCEC. defaults to v1.4. added in 1.8.0 */
   cec_adapter_type      adapterType;          /*!< type of the CEC adapter that we're connected to. added in 1.8.2 */
-  cec_user_control_code comboKey;             /*!< key code that initiates combo keys. defaults to CEC_USER_CONTROL_CODE_F1_BLUE. CEC_USER_CONTROL_CODE_UNKNOWN to disable. added in 2.0.5 */
+  cec_user_control_code comboKey;             /*!< key code that initiates combo keys. defaults to CEC_USER_CONTROL_CODE_STOP. CEC_USER_CONTROL_CODE_UNKNOWN to disable. added in 2.0.5 */
   uint32_t              iComboKeyTimeoutMs;   /*!< timeout until the combo key is sent as normal keypress */
   uint32_t              iButtonRepeatRateMs;  /*!< rate at which buttons autorepeat. 0 means rely on CEC device */
   uint32_t              iButtonReleaseDelayMs;/*!< duration after last update until a button is considered released */
   uint32_t              iDoubleTapTimeoutMs;  /*!< prevent double taps within this timeout. defaults to 200ms. added in 4.0.0 */
   uint8_t               bAutoWakeAVR;         /*!< set to 1 to automatically waking an AVR when the source is activated. added in 4.0.0 */
+#if CEC_LIB_VERSION_MAJOR >= 5
+  uint8_t               bAutoPowerOn;         /*!< set to 1 and save eeprom config to wake the tv when usb is powered. added in 5.0.0 / fw v9 */
+#endif
 
 #ifdef __cplusplus
    libcec_configuration(void) { Clear(); }
@@ -1476,7 +1520,7 @@ struct libcec_configuration
   bool operator==(const libcec_configuration &other) const
   {
     return (     clientVersion             == other.clientVersion &&
-        !strncmp(strDeviceName,               other.strDeviceName, 13) &&
+         !strcmp(strDeviceName,               other.strDeviceName) &&
                  deviceTypes               == other.deviceTypes &&
                  bAutodetectAddress        == other.bAutodetectAddress &&
                  iPhysicalAddress          == other.iPhysicalAddress &&
@@ -1501,7 +1545,11 @@ struct libcec_configuration
                  iButtonReleaseDelayMs     == other.iButtonReleaseDelayMs &&
                  comboKey                  == other.comboKey &&
                  iComboKeyTimeoutMs        == other.iComboKeyTimeoutMs &&
-                 bAutoWakeAVR              == other.bAutoWakeAVR);
+                 bAutoWakeAVR              == other.bAutoWakeAVR
+#if CEC_LIB_VERSION_MAJOR >= 5
+              && bAutoPowerOn              == other.bAutoPowerOn
+#endif
+        );
   }
 
   bool operator!=(const libcec_configuration &other) const
@@ -1536,8 +1584,11 @@ struct libcec_configuration
     iButtonRepeatRateMs =             0;
     iButtonReleaseDelayMs =           CEC_BUTTON_TIMEOUT;
     bAutoWakeAVR =                    0;
+#if CEC_LIB_VERSION_MAJOR >= 5
+    bAutoPowerOn =                    2;
+#endif
 
-    memset(strDeviceName, 0, 13);
+    strDeviceName[0] = (char)0;
     deviceTypes.Clear();
     logicalAddresses.Clear();
     wakeDevices.Clear();

ssalonen added a commit that referenced this issue Jan 29, 2022
#10

Signed-off-by: Sami Salonen <ssalonen@gmail.com>
ssalonen added a commit that referenced this issue Feb 9, 2022
* wip for #10

#10

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* wip

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* Test using system libcec

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* syntax fix

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* libcec6 from manually installed deb

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* libp8 platform

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* missing sudo

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* fix

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* Update ci.yml

* Update bindgen.sh

* Delete abis.env

* Update ci.yml

* clippy

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* tests asserting ABI and cfg

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* CI test for asserting version

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* fix

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* test

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* foolproofing

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* build diagnostics

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* even more build output

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* libudev as build dep for non cross builds

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* lint

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* pkg-config

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* more tests

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* clear names

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* CI fixes

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* verbosity

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* CI discovery without pkg-config

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* nicer labels maybe

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* Cleaner checkout

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* README

Signed-off-by: Sami Salonen <ssalonen@gmail.com>

* changelog

Signed-off-by: Sami Salonen <ssalonen@gmail.com>
@ssalonen ssalonen added this to the 3.0.0 milestone Feb 9, 2022
@ssalonen
Copy link
Owner Author

Positive report from user ssalonen/cec-alsa-sync#7 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant