#include <zblib.h>
#include <zblib_service.h>
#include <zblib_service_interface.h>
+#include <zblib_driver_manager.h>
#include "zigbee_service_interface.h"
#include "zigbee_service_interface_common.h"
/**< ZigBee D-BUS service interface name */
#define ZIGBEE_DBUS_SERVICE_INTERFACE_NAME "zigbee-dbus"
+static void _notify_zigbee_state(ZigBeeServiceInterface *service_interface,
+ gboolean result)
+{
+ ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
+ ZigBeeService *service = zblib_service_interface_ref_service(service_interface);
+
+ if (NULL == custom_data) {
+ Z_LOGE("Unexpected invalid parameter !");
+ return;
+ }
+
+ if (result) {
+ /* Notify zigbee service manually here (Enabled) */
+ zigbee_manager_emit_zigbee_state(custom_data->zigbee_mgr, result);
+ } else {
+ /* ZigBee state will be emitted on bus termination */
+ zblib_service_exit(service);
+ }
+}
+
static gboolean on_manager_enable(ZigbeeManager *zigbee_mgr,
GDBusMethodInvocation *invocation,
gpointer user_data)
zigbee_manager_complete_enable(zigbee_mgr, invocation);
- if (TRUE == custom_data->sevice_interface_init_complete) {
- /* Emit zigbee_state - enabled */
- zigbee_manager_emit_zigbee_state(zigbee_mgr, TRUE);
- }
-
return TRUE;
}
}
break;
+ case ZBLIB_DRIVER_TYPE_MANAGER: {
+ /* Handle 'enabled' notification here */
+ if (notification_id == ZBLIB_MANAGER_NOTI_ZIGBEE_ENABLED) {
+ gboolean *rsp = (gboolean*)noti_data;
+
+ Z_LOGD("Firmware update result : [%s]", ((*rsp) ? "Succeed" : "Failed"));
+ _notify_zigbee_state(service_interface, *rsp);
+ } else
+ Z_LOGE("Unhandled notification id: [%d]", notification_id);
+ }
+ break;
+
case ZBLIB_DRIVER_TYPE_NONE: /* Fall through */
default: {
Z_LOGE("Unhandled driver type: [%d]", driver_type);
/* Bus name is 'acquired' */
custom_data->name_acquired = TRUE;
-
- if (TRUE == custom_data->sevice_interface_init_complete) {
- /* Emit zigbee_state - enabled */
- zigbee_manager_emit_zigbee_state(custom_data->zigbee_mgr, TRUE);
- }
}
static void zigbee_on_bus_acquired(GDBusConnection *connection,
goto EXIT;
}
+ /* Emit zigbee_state - disabled */
+ Z_LOGD("Update zigbee_state ----");
+ zigbee_manager_emit_zigbee_state(interface_data->zigbee_mgr, FALSE);
+
/*
* Unown "org.tizen.zigbee.manager" named bus on D-BUS SYSTEM bus
*/
#include <zblib_plugin.h>
#include <zblib_service_interface.h>
#include <zblib_request.h>
+#include <zblib_driver.h>
+#include <zblib_driver_manager.h>
+
+struct _zblib_async_init_info {
+ gboolean is_initialized; /**< Does initialization succeeded? */
+ gboolean is_finished; /**< Does initialization finished? */
+
+ ZigBeePlugin *plugin; /**< ZigBee plugin */
+ void *user_data; /**< User data */
+};
/**< ZigBee Service object */
struct zblib_service_type {
GHashTable *request_table; /**< Request Hash table */
guint request_id; /**< Request ID */
+
+ GSList *async_initializer; /**< Hash table for asynchronous initializer */
+ zblib_plugin_init_finished_cb callback; /**< Callback */
};
+static GSList *__zblib_service_ref_async_initializer(ZigBeeService* service)
+{
+ zblib_check_null_ret_error("service", service, NULL);
+
+ return service->async_initializer;
+}
+
+static void __zblib_service_set_async_initializer(ZigBeeService* service, GSList* list)
+{
+ zblib_check_null_ret("service", service);
+
+ service->async_initializer = list;
+}
+
+static void __on_zblib_init_async_finished(gboolean result, void *user_data)
+{
+ GSList *list_async = NULL;
+ ZigBeeService *service = NULL;
+ ZigBeePlugin *plugin = NULL;
+ struct _zblib_async_init_info *info = (struct _zblib_async_init_info*)user_data;
+ char *plugin_name = NULL;
+
+ int i = 0;
+ int _finished_count = 0;
+ int _succeeded_count = 0;
+
+ zblib_check_null_ret("info", info);
+
+ plugin = info->plugin;
+ service = zblib_plugin_ref_service(plugin);
+ plugin_name = zblib_plugin_get_plugin_name(plugin);
+
+ zblib_check_null_ret("service", service);
+
+ info->is_finished = TRUE;
+ if (result) {
+ Z_LOGD("Plugin [%s] succeeded async init", plugin_name);
+ info->is_initialized = TRUE;
+ } else {
+ Z_LOGE("Plugin [%s] failed to init !", plugin_name);
+ }
+ g_free(plugin_name);
+
+ /* Check all async initializer list */
+ list_async = __zblib_service_ref_async_initializer(service);
+ while (list_async != NULL) {
+ /* Initialize each plug-in */
+ struct _zblib_async_init_info *in =
+ (struct _zblib_async_init_info *)(list_async->data);
+ i++;
+ if (G_UNLIKELY(NULL == in)) {
+ Z_LOGE("Invalid parameter !");
+ list_async = g_slist_next(list_async);
+ continue;
+ }
+
+ if (in->is_finished)
+ _finished_count++;
+ if (in->is_initialized)
+ _succeeded_count++;
+
+ list_async = g_slist_next(list_async);
+ }
+
+ if (i == _finished_count) {
+ gboolean ret = TRUE;
+ guint driver_noti_id = (ZBLIB_DRIVER_TYPE_MANAGER << 24)
+ | ZBLIB_MANAGER_NOTI_ZIGBEE_ENABLED;
+
+ if (_finished_count == _succeeded_count) {
+ /* All initializer finished successfully */
+ Z_LOGD("All async init finished !");
+ ret = TRUE;
+ } else {
+ /* Some initializers are failed */
+ Z_LOGE("There are some failed plugin initializer !");
+ ret = FALSE;
+ }
+ /* Notify whether zigbee service is enabled or not */
+ zblib_plugin_send_notification(plugin,
+ driver_noti_id, &ret, sizeof(ret));
+ }
+}
+
static void *__zblib_service_load_plugin(gchar *filename,
ZblibPluginDescriptor_t **descriptor_out)
{
const ZblibPluginDescriptor_t *descriptor = zblib_plugin_get_descriptor(plugin);
zblib_check_null_ret_error("descriptor", descriptor, FALSE);
- zblib_check_null_ret_error("descriptor->init", descriptor->init, FALSE);
+ if (NULL == descriptor->init) {
+ Z_LOGD("descriptor->init is NULL, trying async init");
+ return FALSE;
+ }
if (G_UNLIKELY(FALSE == descriptor->init(plugin))) {
char *plugin_name = zblib_plugin_get_plugin_name(plugin);
return TRUE;
}
+static gboolean __zblib_service_init_async_plugin(ZigBeePlugin *plugin,
+ zblib_plugin_init_finished_cb callback, void *user_data)
+{
+ const ZblibPluginDescriptor_t *descriptor = zblib_plugin_get_descriptor(plugin);
+ char *plugin_name = zblib_plugin_get_plugin_name(plugin);
+
+ zblib_check_null_ret_error("descriptor", descriptor, FALSE);
+ zblib_check_null_ret_error("descriptor->init_async", descriptor->init_async, FALSE);
+
+ if (G_UNLIKELY(NULL != plugin_name))
+ plugin_name = g_strdup("NONAME");
+
+ if (G_UNLIKELY(FALSE == descriptor->init_async(plugin, callback, user_data))) {
+ Z_LOGE("plugin(%s) init failed!", plugin_name);
+ g_free(plugin_name);
+ return FALSE;
+ }
+
+ g_free(plugin_name);
+ return TRUE;
+}
+
static gboolean __zblib_service_unload_plugin(ZigBeePlugin *plugin)
{
const ZblibPluginDescriptor_t *descriptor = zblib_plugin_get_descriptor(plugin);
}
}
+ /* Free async initializer */
+ if (service->async_initializer) {
+ g_slist_free(service->async_initializer);
+ service->async_initializer = NULL;
+ }
+
/* Free plug-ins */
if (service->plugins) {
g_slist_free(service->plugins);
gboolean zblib_service_initialize_plugins(ZigBeeService *service)
{
GSList *list;
+ GSList *list_async;
zblib_check_null_ret_error("service", service, FALSE);
/* Refer plug-in list */
list = zblib_service_ref_plugins(service);
+ list_async = __zblib_service_ref_async_initializer(service);
while (list != NULL) {
/* Initialize each plug-in */
- if (G_UNLIKELY(FALSE == __zblib_service_init_plugin((ZigBeePlugin *)(list->data)))) {
- list = g_slist_next(list);
- continue;
+ ZigBeePlugin *plugin = (ZigBeePlugin *)(list->data);
+ if (FALSE == __zblib_service_init_plugin(plugin)) {
+ /* If there is no initializer, it should have asynchronous one */
+ const ZblibPluginDescriptor_t *descriptor =
+ zblib_plugin_get_descriptor(plugin);
+ if (NULL != descriptor->init_async) {
+ /* Register async initializer */
+ struct _zblib_async_init_info *info =
+ g_try_new0(struct _zblib_async_init_info, 1);
+ if(NULL == info) {
+ Z_LOGE("Fatal : Failed to allocate memory");
+ return FALSE;
+ }
+ info->is_finished = FALSE;
+ info->is_initialized = FALSE;
+ info->plugin = plugin;
+ info->user_data = NULL;
+
+ list_async = g_slist_append(list_async, info);
+ } else {
+ Z_LOGE("Fatal : Failed to initialize plugin");
+ return FALSE;
+ }
}
list = g_slist_next(list);
}
+ __zblib_service_set_async_initializer(service, list_async);
+
+ return TRUE;
+}
+
+gboolean zblib_service_initialize_async_plugins(ZigBeeService *service)
+{
+ GSList *list_async;
+
+ zblib_check_null_ret_error("service", service, FALSE);
+
+ /* Refer async initializer list */
+ list_async = __zblib_service_ref_async_initializer(service);
+ while (list_async != NULL) {
+ /* Initialize each plug-in */
+ struct _zblib_async_init_info *info =
+ (struct _zblib_async_init_info *)(list_async->data);
+
+ if (G_UNLIKELY(NULL == info)) {
+ Z_LOGE("Invalid parameter !");
+ list_async = g_slist_next(list_async);
+ continue;
+ }
+
+ if (G_UNLIKELY(FALSE == __zblib_service_init_async_plugin(
+ info->plugin, __on_zblib_init_async_finished, info))) {
+ Z_LOGE("Fatal : Failed to initialize mandatory plugin");
+ return FALSE;
+ }
+ list_async = g_slist_next(list_async);
+ }
+
return TRUE;
}