#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
+#include <string.h>
#include <stdbool.h>
#include <dlfcn.h>
#include <dirent.h>
#include "hal-common.h"
#include "hal-api-conf.h"
+#include "hal-api-list.h"
#include "common.h"
#define RPC_STUB_PROC_NAME "d::HalBackendService"
struct hal_backend_service_data {
- enum hal_module module;
+ enum hal_module *modules;
+ size_t modules_len;
tizen_core_task_h task;
+ char *task_name;
bool is_initialized;
};
user_data, NULL, 0);
}
-static int add_hal_backend_service(enum hal_module module)
+static int add_hal_backend_service(enum hal_module *modules, size_t modules_len)
{
struct hal_backend_service_data *hal_backend_service_data = NULL;
- if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
- _E("Invalid parameter of HAL module (%d)\n", module);
+ if (modules_len == 0) {
+ _E("Invalid modules len: 0");
return -EINVAL;
}
- hal_backend_service_data = g_malloc(sizeof(*hal_backend_service_data));
+ for (size_t i = 0; i < modules_len; ++i) {
+ if (modules[i] <= HAL_MODULE_UNKNOWN || modules[i] >= HAL_MODULE_END) {
+ _E("Invalid parameter of HAL module (%d)\n", modules[i]);
+ return -EINVAL;
+ }
+ }
+
+ hal_backend_service_data = calloc(1, sizeof(*hal_backend_service_data));
if (hal_backend_service_data == NULL) {
_E("Failed to allocate memory for hal_backend_service");
return -EINVAL;
}
- hal_backend_service_data->module = module;
+ hal_backend_service_data->modules = modules;
+ hal_backend_service_data->modules_len = modules_len;
hal_backend_service_data->task = NULL;
hal_backend_service_data->is_initialized = false;
return 0;
}
-static gint compare_hal_backend_service(
- struct hal_backend_service_data *hal_backend_service_data,
- enum hal_module module)
+static int find_module_by_backend_module_name(const char *module_name, enum hal_module *module_found)
{
- return (hal_backend_service_data->module == module) ? 0 : 1;
-}
+ enum hal_module module;
+ struct __hal_module_info* module_info = NULL;
+ size_t module_name_len = 0;
-static int delete_hal_backend_service(
- enum hal_module module)
-{
- if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
- _E("Invalid parameter of HAL module (%d)\n", module);
+ if (!module_name) {
+ _E("Invalid parameter of HAL module: module_name(NULL)");
return -EINVAL;
}
- GSList *slist_hal_backend_service = g_slist_find_custom(
- g_hal_backend_service_data_list, (gpointer)module,
- (GCompareFunc)compare_hal_backend_service);
- if (slist_hal_backend_service == NULL) {
- _E("No such hal_backend_service is registered: hal_module(%d)",
- module);
+ if (!module_found) {
+ _E("Invalid parameter of HAL module: module_found(NULL)");
return -EINVAL;
}
- g_hal_backend_service_data_list
- = g_slist_remove(g_hal_backend_service_data_list,
- (gpointer)(slist_hal_backend_service->data));
+ module_name_len = strlen(module_name);
- return 0;
+ for (module = HAL_MODULE_UNKNOWN + 1 ; module < HAL_MODULE_END; module++) {
+ module_info = &g_hal_module_info[module];
+
+ if (module_info->backend_module_name == NULL)
+ continue;
+
+ if (strncmp(module_name, module_info->backend_module_name, module_name_len + 1) == 0) {
+ *module_found = module;
+ return 0;
+ }
+ }
+
+ return -ENOENT;
}
-static int hal_backend_service_open_and_add_plugin(void)
+static int hal_backend_service_open_and_add_plugin(char **module_names)
{
enum hal_module module;
- int ret;
+ char *module_name = NULL;
+ int ret = 0;
+
+ size_t module_names_len = 0;
+
+ enum hal_module *modules = NULL;
+ size_t modules_len = 0;
+
+ for (size_t i = 0; module_names[i]; ++i)
+ ++module_names_len;
+
+ modules = calloc(module_names_len, sizeof(*modules));
+ if (!modules) {
+ _E("Failed to allocate memory for %zu modules", module_names_len);
+ return -ENOMEM;
+ }
+
+ for (size_t i = 0; i < module_names_len; ++i) {
+ module_name = module_names[i];
+
+ ret = find_module_by_backend_module_name(module_name, &module);
+ if (ret != 0) {
+ _W("Cannot get module by backend_module_name: ret(%d)", ret);
+ continue;
+ }
- for (module = HAL_MODULE_UNKNOWN + 1 ; module < HAL_MODULE_END; module++) {
ret = hal_common_get_backend_service(module, NULL);
if (ret == -ENOENT)
continue;
else if (ret < 0) {
- _W("Failed to get hal-backend-service\n");
+ _W("Cannot get hal-backend-service: ret(%d)\n", ret);
continue;
}
- ret = add_hal_backend_service(module);
+ modules[modules_len] = module;
+ ++modules_len;
+ }
+
+ ret = add_hal_backend_service(modules, modules_len);
+ if (ret < 0) {
+ _E("Failed to add hal-backend-service: ret(%d)\n", ret);
+
+ for (size_t i = 0; i < modules_len; ++i)
+ hal_common_put_backend_service(modules[i], NULL);
+ free(modules);
+
+ return ret;
+ }
+
+ return 0;
+}
+
+static int delete_hal_backend_service(
+ struct hal_backend_service_data *hal_backend_service_data,
+ size_t *failed_count)
+{
+ int ret = 0;
+
+ for (size_t i = 0; i < hal_backend_service_data->modules_len; ++i) {
+ ret = hal_common_put_backend_service(
+ hal_backend_service_data->modules[i],
+ NULL);
if (ret < 0) {
- _W("Failed to add hal-backend-service\n");
+ _W("Cannot put hal-backend-service: ret(%d), module(%d)\n",
+ ret, hal_backend_service_data->modules[i]);
+ ++(*failed_count);
continue;
}
}
+ free(hal_backend_service_data->modules);
+ free(hal_backend_service_data);
+
return 0;
}
static int hal_backend_service_delete_and_close_plugin(void)
{
enum hal_module module;
+ size_t failed_count = 0;
int ret;
- for (module = HAL_MODULE_END - 1 ; module > 0; module--) {
- ret = delete_hal_backend_service(module);
- if (ret < 0) {
- _W("Failed to delete hal-backend-service\n");
- continue;
- }
+ g_slist_foreach(g_hal_backend_service_data_list,
+ (GFunc)delete_hal_backend_service, &failed_count);
- ret = hal_common_put_backend_service(module, NULL);
- if (ret < 0) {
- _W("Failed to put hal-backend-service\n");
- continue;
- }
- }
+ g_slist_free(g_hal_backend_service_data_list);
+ g_hal_backend_service_data_list = NULL;
return 0;
}
if (service_data->is_initialized)
return false;
- if (service_data->module <= HAL_MODULE_UNKNOWN || service_data->module >= HAL_MODULE_END) {
- _E("Invalid parameter of HAL module (%d)\n", service_data->module);
- return false;
+ for (size_t i = 0; i < service_data->modules_len; ++i) {
+ if (service_data->modules[i] <= HAL_MODULE_UNKNOWN || service_data->modules[i] >= HAL_MODULE_END) {
+ _E("Invalid parameter of HAL module (%d)\n", service_data->modules[i]);
+ return false;
+ }
}
- ret = hal_common_init_backend_service(service_data->module, NULL);
- if (ret < 0) {
- _E("Failed to initialize hal backend service: ret(%d)", ret);
- return false;
+ for (size_t i = 0; i < service_data->modules_len; ++i) {
+ ret = hal_common_init_backend_service(service_data->modules[i], NULL);
+ if (ret < 0) {
+ _W("Cannot initialize hal backend service: ret(%d), module(%d)",
+ ret, service_data->modules[i]);
+ continue;
+ }
}
service_data->is_initialized = true;
}
service_data = (struct hal_backend_service_data *)data;
- if (service_data->module <= HAL_MODULE_UNKNOWN || service_data->module >= HAL_MODULE_END) {
- _E("Invalid parameter of HAL module (%d)\n", service_data->module);
- return;
+ for (size_t i = 0; i < service_data->modules_len; ++i) {
+ if (service_data->modules[i] <= HAL_MODULE_UNKNOWN || service_data->modules[i] >= HAL_MODULE_END) {
+ _E("Invalid parameter of HAL module (%d)\n", service_data->modules[i]);
+ return;
+ }
}
- ret = hal_common_exit_backend_service(service_data->module, NULL);
- if (ret < 0) {
- _E("Failed to exit hal backend service: ret(%d)", ret);
- return;
+ bool is_all_exit = true;
+ for (size_t i = 0; i < service_data->modules_len; ++i) {
+ ret = hal_common_exit_backend_service(service_data->modules[i], NULL);
+ if (ret < 0) {
+ _W("Cannot exit hal backend service: ret(%d), module(%d)",
+ ret, service_data->modules[i]);
+ is_all_exit = false;
+ continue;
+ }
}
- service_data->is_initialized = false;
+ service_data->is_initialized = !is_all_exit;
_D("Exit done.");
}
struct hal_backend_service_data *service_data = NULL;
struct __hal_module_info *module_info = NULL;
+ GString *task_name = NULL;
size_t *failed_count = NULL;
int ret = 0;
service_data = (struct hal_backend_service_data *)data;
failed_count = (size_t *)user_data;
- module_info = _hal_api_conf_get_module_info(service_data->module, NULL);
- ret = tizen_core_task_create(module_info->backend_module_name, true, &task);
+ task_name = g_string_new("");
+ if (!task_name) {
+ _E("Failed to allocate memory for task_name");
+ ret = -ENOMEM;
+ goto error;
+ }
+ for (size_t i = 0; i < service_data->modules_len; ++i) {
+ module_info = _hal_api_conf_get_module_info(service_data->modules[i], NULL);
+ if (module_info == NULL) {
+ _E("Failed to get module info for module(%d)", service_data->modules[i]);
+ ret = -EINVAL;
+ goto error;
+ }
+ g_string_append(task_name, "_");
+ g_string_append(task_name, module_info->backend_module_name);
+ }
+
+ ret = tizen_core_task_create(task_name->str, true, &task);
if (ret != TIZEN_CORE_ERROR_NONE) {
_E("Failed to create tizen_core task: ret(%d)", ret);
goto error;
}
service_data->task = task;
+ service_data->task_name = task_name->str;
- _D("Task created for hal_module(%d)", service_data->module);
+ _D("Task created: %s", task_name->str);
- return;
+ goto free_resources;
error:
if (source != NULL)
(*failed_count)++;
+free_resources:
+ if (task_name != NULL)
+ g_string_free(task_name, FALSE);
+
return;
}
}
service_data = (struct hal_backend_service_data *)data;
+ /* FIXME: Improve debugging message for more informatino about modules */
if (service_data->task == NULL) {
- _D("No task for hal_module(%d)", service_data->module);
+ _D("No task for %zu hal_modules", service_data->modules_len);
return;
}
ret = tizen_core_task_quit(service_data->task);
if (ret != TIZEN_CORE_ERROR_NONE) {
- _E("Failed to quit task for hal_module(%d)", service_data->module);
+ _E("Failed to quit task for %zu hal_modules", service_data->modules_len);
return;
}
ret = tizen_core_task_destroy(service_data->task);
if (ret != TIZEN_CORE_ERROR_NONE) {
- _E("Failed to destroy task for hal_module(%d)", service_data->module);
+ _E("Failed to destroy task for %zu hal_modules", service_data->modules_len);
return;
}
service_data->task = NULL;
+ g_free(service_data->task_name);
+ service_data->task_name = NULL;
- _D("Task destroyed for hal_module(%d)", service_data->module);
+ _D("Task destroyed for %zu hal_modules", service_data->modules_len);
}
static void hal_backend_service_start(void)
{
int ret = 0;
+ if (argc < 2) {
+ _E("No module name provided, exit.");
+ return 1;
+ }
+
_D("Initialize hal-backend-service");
tizen_core_init();
rpc_port_register_proc_info(RPC_STUB_PROC_NAME, NULL);
- /* Load hal-backend-service plugin */
- hal_backend_service_open_and_add_plugin();
+ for (int i = 1; i < argc; ++i) {
+ char *module_names_str = argv[i];
+ gchar **module_names = g_strsplit(module_names_str, ",", 0);
+
+ hal_backend_service_open_and_add_plugin(module_names);
+
+ g_strfreev(module_names);
+ }
+
+ if (g_slist_length(g_hal_backend_service_data_list) == 0) {
+ _E("No available modules, exit");
+
+ tizen_core_task_destroy(g_main_task);
+ tizen_core_shutdown();
+
+ return 1;
+ }
+
hal_backend_service_start();
attach_signal_handlers();