common: Support multi-transport on platform manifest 22/321222/6
authorYoungjae Cho <y0.cho@samsung.com>
Mon, 17 Mar 2025 08:57:19 +0000 (17:57 +0900)
committerYoungjae Cho <y0.cho@samsung.com>
Mon, 7 Apr 2025 04:40:29 +0000 (13:40 +0900)
It has changed to specify more than one transport on hal manifest if
necessary. To support this, changed 'enum hal_common_transort' to be
bitmap. Note that the actual values are same as before, 0, 1, and 2.

The property //hal/version/@transport can now have more than two transport
seperated by comma. And when it comes to an invalid transport string, it
applies passthrough as a default transport.
 • As-is: Only one transport could be specified
    <version transport="ipc">...</version>

 • To-be: All the belows are possible
    <version>...</version>
    <version transport="transport">...</version>
    <version transport="ipc">...</version>
    <version transport="transport,ipc">...</version>
    <version transport="ipc,transport">...</version>

Change-Id: I8a1eefe8350ee8df3e2b0f5321920df83eefc7c5
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
include/hal-common.h
src/hal-api-common.c
src/hal-api-compatibility-checker-parser.c
src/hal-api-compatibility-checker.c
src/hal-api-compatibility-checker.h
tests/unittest/test-hal-compatibility-checker-manifest/hal-api-tbm-manifest.xml
tests/unittest/test-hal-compatibility-checker.cc
tools/lshal/lshal.c

index 0a37294b46bc2dab508e39d55542984809cc4c39..fd28dc95889926651c81f0957790fc0eb30378fd 100644 (file)
@@ -19,6 +19,7 @@
 #ifndef __HAL_COMMON__
 #define __HAL_COMMON__
 
+#include <stdint.h>
 #include "hal-common-interface.h"
 
 #ifdef __cplusplus
@@ -114,10 +115,16 @@ enum hal_common_backend_compatibility {
        HAL_COMMON_BACKEND_COMPATIBILITY_COMPATIBLE,
 };
 
+/**
+ * @brief Transport supported by platform hal module
+ * @details Each hal module can specify more than one transports that it supports.
+ * @see hal_common_get_supported_interface_versions()
+ * @see hal_common_get_transport()
+ */
 enum hal_common_transport {
        HAL_COMMON_TRANSPORT_UNKNOWN = 0,       /**< This indicates undefined communication way with hal-backend */
-       HAL_COMMON_TRANSPORT_IPC,       /**< This indicates ipc communication way with hal-backend */
-       HAL_COMMON_TRANSPORT_PASSTHROUGH,       /**< This indicates dlopen communication way with hal-backend */
+       HAL_COMMON_TRANSPORT_IPC = (1 << 0),    /**< This indicates ipc communication way with hal-backend */
+       HAL_COMMON_TRANSPORT_PASSTHROUGH = (1 << 1),    /**< This indicates dlopen communication way with hal-backend */
 };
 
 /**
@@ -326,15 +333,16 @@ int hal_common_check_backend_compatibility(enum hal_module module,
  * @param[out] minor_versions Array of minor version. An index is paired with the same
  *             index in the array major_versions. The caller takes ownership of the data
  *             so it is responsible for caller to free it using free()
- * @param[out] transports Array of transport by each version. An index is paired with the
- *             same index in the array major_versions and minor_versions. The caller takes
- *             ownership of the data so it is responsible for caller to free it using free()
+ * @param[out] transports Array of transport by each version. Each transport is bitwise OR of
+ *             enum #hal_common_transport. An index is paired with the same index in the array
+ *             major_versions and minor_versions. The caller takes ownership of the data so it
+ *             is responsible for caller to free it using free()
  * @param[out] num_versions Number of returned major and minor versions
  * @return @c 0 on success, otherwise a negative error value
  */
 int hal_common_get_supported_interface_versions(enum hal_module module,
        unsigned int **major_versions, unsigned int **minor_versions,
-       enum hal_common_transport **transports, int *num_versions);
+       uint32_t **transports, int *num_versions);
 
 /**
  * @brief Get the transport that compatible with the current hal backend
index 4a5e3c625e7c9c78a2c5166e1a942a72afda39d7..0464c1782a3ee440f6580ff3147319317d04e52c 100644 (file)
@@ -774,7 +774,7 @@ int hal_common_check_backend_compatibility(enum hal_module module,
 EXPORT
 int hal_common_get_supported_interface_versions(enum hal_module module,
        unsigned int **major_versions, unsigned int **minor_versions,
-       enum hal_common_transport **transports, int *num_versions)
+       uint32_t **transports, int *num_versions)
 {
        if (!major_versions || !minor_versions || !transports || !num_versions)
                return -EINVAL;
index 0c06d1c8dbf404fc16a08e249e88f169738807d1..eab1b3a97b600c30ed962abd0fa94594c6afeeb0 100644 (file)
@@ -85,7 +85,8 @@ static int parse_hal(xmlNode *node, halcc_manifest *manifest)
                if (xmlStrEqual(child->name, "version")) {
                        int major, minor;
                        int scanned;
-                       enum hal_common_transport transport = HAL_COMMON_TRANSPORT_PASSTHROUGH;
+                       enum hal_common_transport transports = HAL_COMMON_TRANSPORT_UNKNOWN;
+                       const char *transport = NULL;
                        __xmlchar__ xmlChar *version = xmlNodeGetContent(child);
                        __xmlchar__ xmlChar *property = xmlGetProp(child, "transport");
 
@@ -95,12 +96,33 @@ static int parse_hal(xmlNode *node, halcc_manifest *manifest)
                                continue;
                        }
 
-                       if (xmlStrEqual(property, "passthrough"))
-                               transport = HAL_COMMON_TRANSPORT_PASSTHROUGH;
-                       else if (xmlStrEqual(property, "ipc"))
-                               transport = HAL_COMMON_TRANSPORT_IPC;
+                       transport = (const char *) property;
+                       while (transport) {
+                               if (*transport == '\0')
+                                       break;
+
+                               if (*transport == ',') {
+                                       transport += 1;
+                                       continue;
+                               }
+
+                               if (strncmp(transport, "passthrough", strlen("passtrhough")) == 0) {
+                                       transports |= HAL_COMMON_TRANSPORT_PASSTHROUGH;
+                                       transport += strlen("passthrough");
+                               } else if (strncmp(transport, "ipc", strlen("ipc")) == 0) {
+                                       transports |= HAL_COMMON_TRANSPORT_IPC;
+                                       transport += strlen("ipc");
+                               } else {
+                                       _W("Invalid transport=%s", transport);
+                                       transports = HAL_COMMON_TRANSPORT_UNKNOWN;
+                                       break;
+                               }
+                       }
+
+                       if (transports == HAL_COMMON_TRANSPORT_UNKNOWN)
+                               transports = HAL_COMMON_TRANSPORT_PASSTHROUGH; // set default
 
-                       ret = halcc_hal_add_version(hal, major, minor, transport);
+                       ret = halcc_hal_add_version(hal, major, minor, transports);
                        if (ret != 0)
                                _E("Failed to halcc_hal_add_version(), ret=%d\n", ret);
                }
index 7a6f4d87e6bac954ee5c1f8fc813a052254850d6..31312f2b46cfdc375144b6a6635971a4044b5275 100644 (file)
@@ -468,14 +468,14 @@ int hal_api_cc_check_backend_compatibility_by_version(enum hal_module module,
 int hal_api_cc_get_supported_interface_versions(enum hal_module module,
        unsigned int **major_versions,
        unsigned int **minor_versions,
-       enum hal_common_transport **transports,
+       uint32_t **transports,
        int *num_versions)
 {
        int ret;
        int ret_num_versions = 0;
        unsigned int *ret_major_versions = NULL;
        unsigned int *ret_minor_versions = NULL;
-       enum hal_common_transport *ret_transports = NULL;
+       uint32_t *ret_transports = NULL;
        struct compatibility_info info = { 0 , };
 
        if (!major_versions || !minor_versions || !num_versions)
@@ -502,7 +502,7 @@ int hal_api_cc_get_supported_interface_versions(enum hal_module module,
                return -ENOMEM;
        }
 
-       ret_transports = calloc(ret_num_versions, sizeof(enum hal_common_transport));
+       ret_transports = calloc(ret_num_versions, sizeof(uint32_t));
        if (!ret_transports) {
                free(ret_major_versions);
                free(ret_minor_versions);
@@ -512,7 +512,7 @@ int hal_api_cc_get_supported_interface_versions(enum hal_module module,
        for (int i = 0; i < ret_num_versions; ++i) {
                ret_major_versions[i] = info.version_list[i][0];
                ret_minor_versions[i] = info.version_list[i][1];
-               ret_transports[i] = info.version_list[i][2];
+               ret_transports[i] = (uint32_t) info.version_list[i][2];
        }
 
        *major_versions = ret_major_versions;
index 41e5afb83928425cbbfe37227d884adfda0d1d55..daab0f15fc747418ca261aed1a2218e3564f8330 100644 (file)
@@ -30,7 +30,7 @@ int hal_api_cc_check_backend_compatibility_by_version(enum hal_module module,
        enum hal_common_backend_compatibility *backend_compatibility);
 int hal_api_cc_get_supported_interface_versions(enum hal_module module,
        unsigned int **major_versions, unsigned int **minor_versions,
-       enum hal_common_transport **transports, int *num_versions);
+       uint32_t **transports, int *num_versions);
 int hal_api_cc_get_transport(enum hal_module module, enum hal_common_transport *transport);
 
 #ifdef HAL_API_COMMON_UNITTEST /* For test use only */
index 5fc2e1deaf1a8ba641a210c710d05bc7023ea7af..d64d10729ede3358e6d6a47656765220fabd1264 100644 (file)
                        <version>3.1</version>
                </hal-module>
        </manifest>
+       <manifest platform-version="13.0">
+               <hal-module>
+                       <name>HAL_MODULE_TBM</name>
+                       <version transport="ipc,passthrough">4.0</version>
+                       <version transport="passthrough,ipc">5.0</version>
+                       <version transport="invalid,ipc">6.0</version>
+                       <version transport="passthrough,invalid">7.0</version>
+               </hal-module>
+       </manifest>
 </hal-api>
 
index 9a94e1db7481070f149ad7a30bcb922d52f85932..89712ef87eada8c15e4078ffaf4178b2e9e8a424 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <unistd.h>
+#include <stdint.h>
 #include <string.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
@@ -129,7 +130,7 @@ static bool have_exact_version_within_halcc_hal(halcc_hal *hal, const char *vers
 struct versions_info {
        unsigned int *major_versions;
        unsigned int *minor_versions;
-       enum hal_common_transport *transports;
+       uint32_t *transports;
        int num_versions;
 };
 
@@ -160,7 +161,7 @@ static bool have_exact_version_within_array(const struct versions_info *vi, cons
 }
 
 static bool have_exact_version_transport_within_array(const struct versions_info *vi,
-       const char *version, enum hal_common_transport transport)
+       const char *version, uint32_t transport)
 {
        unsigned int major, minor;
        int ret;
@@ -172,8 +173,8 @@ static bool have_exact_version_transport_within_array(const struct versions_info
                return false;
 
        ret = sscanf(version, "%u.%u", &major, &minor);
-               if (ret != 2)
-                       return false;
+       if (ret != 2)
+               return false;
 
        for (int i = 0; i < vi->num_versions; ++i) {
                if (vi->major_versions[i] != major)
@@ -372,11 +373,16 @@ TEST_F(HalccObjectTest, hal_get_manifest_version_transport_with_result_file)
 
        ret = hal_common_get_supported_interface_versions(HAL_MODULE_TBM,
                        &vi.major_versions, &vi.minor_versions, &vi.transports, &vi.num_versions);
+
        ASSERT_EQ(ret, 0);
 
        ASSERT_THAT(&vi, HasExactVersionTransportArray("1.0", HAL_COMMON_TRANSPORT_PASSTHROUGH)); /* default : PASSTHROUGH */
        ASSERT_THAT(&vi, HasExactVersionTransportArray("2.1", HAL_COMMON_TRANSPORT_IPC));
        ASSERT_THAT(&vi, HasExactVersionTransportArray("3.1", HAL_COMMON_TRANSPORT_PASSTHROUGH));
+       ASSERT_THAT(&vi, HasExactVersionTransportArray("4.0", HAL_COMMON_TRANSPORT_PASSTHROUGH | HAL_COMMON_TRANSPORT_IPC));
+       ASSERT_THAT(&vi, HasExactVersionTransportArray("5.0", HAL_COMMON_TRANSPORT_PASSTHROUGH | HAL_COMMON_TRANSPORT_IPC));
+       ASSERT_THAT(&vi, HasExactVersionTransportArray("6.0", HAL_COMMON_TRANSPORT_PASSTHROUGH)); /* invalid: default: PASSTHROUGH */
+       ASSERT_THAT(&vi, HasExactVersionTransportArray("7.0", HAL_COMMON_TRANSPORT_PASSTHROUGH)); /* invalid: default: PASSTHROUGH */
 
        free(vi.major_versions);
        vi.major_versions = NULL;
@@ -433,7 +439,7 @@ TEST_F(HalccObjectTest, hal_get_transport_with_result_file)
        hal_api_cc_reset_compatibility_info();
 
        /* incompatible version should return error */
-       mock_hal_backend_data_set_version(HAL_MODULE_TBM, 4, 0);
+       mock_hal_backend_data_set_version(HAL_MODULE_TBM, 8, 0);
 
        ret = hal_common_get_transport(HAL_MODULE_TBM, &transport);
        ASSERT_EQ(ret, -ELIBBAD);
index 175d374a699827c685128dfcfcb8e9f489ba012e..3dfde761e78ec84c611d8883af77050e1149ab63 100644 (file)
@@ -152,7 +152,7 @@ static void lshal_print_hal_backend_info(u_int32_t flags) {
                if (LSHAL_FLAG_MANIFEST_VERSION & flags) {
                        unsigned int *major_versions = NULL;
                        unsigned int *minor_versions = NULL;
-                       enum hal_common_transport *transports = NULL;
+                       uint32_t *transports = NULL;
                        int num_versions = 0;
 
                        strncpy(str, "", BUFF_MAX - 1);
@@ -172,6 +172,7 @@ static void lshal_print_hal_backend_info(u_int32_t flags) {
 
                                        transport = (transports[i] == HAL_COMMON_TRANSPORT_IPC ? "ipc"
                                                 : transports[i] == HAL_COMMON_TRANSPORT_PASSTHROUGH ? "passthrough"
+                                                : transports[i] == (HAL_COMMON_TRANSPORT_IPC | HAL_COMMON_TRANSPORT_PASSTHROUGH) ? "ipc,passthrough"
                                                 : "Unknown");
 
                                        pos += snprintf(pos, end - pos, "%u.%u(%s), ",