2 * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
4 * Contact: Suresh Kumar N (suresh.n@samsung.com)
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 #include <zblib_service.h>
24 #include <zblib_plugin.h>
25 #include <zblib_service_interface.h>
27 /**< ZigBee Service object */
28 struct zblib_service_type {
29 GMainLoop *main_loop; /**< Service main-loop */
31 GSList *interface_objs; /**< ZigBee Service interface objects */
32 GSList *plugins; /**< ZigBee plug-ins */
35 static void *__zblib_service_load_plugin(gchar *filename,
36 struct zblib_plugin_descriptor **descriptor_out)
38 struct zblib_plugin_descriptor *descriptor = NULL;
43 if (descriptor_out == NULL) {
44 Z_LOGE("descriptor_out is NULL!!!");
49 handle = dlopen(filename, RTLD_LAZY);
51 Z_LOGE("dlopen() failed:[%s]", filename);
55 /* Get symbol - "zigbee_plugin_descriptor" */
56 descriptor = dlsym(handle, "zigbee_plugin_descriptor");
57 if (NULL == descriptor) {
58 Z_LOGE("dlsym() failed:[%s]", "plugin_define_desc");
63 Z_LOGD("%s plugin", descriptor->name);
64 Z_LOGD(" - path = %s", filename);
65 Z_LOGD(" - version = %d", descriptor->version);
67 memset(&stat_buf, 0x00, sizeof(stat_buf));
68 memset(&file_date, '\0', sizeof(file_date));
70 if (0 == stat(filename, &stat_buf)) {
71 if (NULL != ctime_r(&stat_buf.st_mtime, file_date)) {
72 if (1 < strlen(file_date))
73 file_date[strlen(file_date)-1] = '\0';
74 Z_LOGD(" - date = %s", file_date);
79 if (G_LIKELY(descriptor->load)) {
80 if (G_UNLIKELY(FALSE == descriptor->load())) {
81 Z_LOGW("load() failed... Skip this plugin!");
85 Z_LOGI("Plug-in (%s) loaded!", descriptor->name);
89 *descriptor_out = descriptor;
94 static gboolean __zblib_service_init_plugin(ZigBeePlugin *plugin)
96 const struct zblib_plugin_descriptor *descriptor = zblib_plugin_get_descriptor(plugin);
98 if ((descriptor == NULL) || (descriptor->init == NULL)) {
99 Z_LOGE("descriptor OR init function is NULL!!!");
103 if (descriptor->init(plugin) == FALSE) {
104 char *plugin_name = zblib_plugin_get_plugin_name(plugin);
105 if (NULL != plugin_name) {
106 Z_LOGE("plugin(%s) init failed!", plugin_name);
115 static gboolean __zblib_service_unload_plugin(ZigBeePlugin *plugin)
117 const struct zblib_plugin_descriptor *descriptor = zblib_plugin_get_descriptor(plugin);
118 char *plugin_name = zblib_plugin_get_plugin_name(plugin);
120 if ((descriptor == NULL) || (descriptor->unload == NULL)) {
121 Z_LOGE("descriptor OR unload function is NULL!!!");
126 descriptor->unload(plugin);
127 Z_LOGI("plugin(%s) unloaded!", plugin_name);
132 ZigBeeService *zblib_service_new()
134 ZigBeeService *service;
136 service = g_malloc0(sizeof(struct zblib_service_type));
138 /* Create g-main loop */
139 service->main_loop = g_main_loop_new(NULL, FALSE);
140 if (service->main_loop == NULL) {
141 Z_LOGE("g-main loop creation failed!!!");
149 void zblib_service_free(ZigBeeService *service)
151 if (service == NULL) {
152 Z_LOGE("service is NULL");
157 if (service->plugins) {
158 g_slist_free(service->plugins);
159 service->plugins = NULL;
162 /* Unref 'g-main loop' */
163 if (service->main_loop)
164 g_main_loop_unref(service->main_loop);
169 gboolean zblib_service_run(ZigBeeService *service)
171 if ((service == NULL) || (service->main_loop == NULL)) {
172 Z_LOGE("service or mainloop is NULL");
176 g_main_loop_run(service->main_loop);
181 gboolean zblib_service_exit(ZigBeeService *service)
183 if ((service == NULL) || (service->main_loop == NULL)) {
184 Z_LOGE("service or mainloop is NULL");
188 g_main_loop_quit(service->main_loop);
193 gboolean zblib_service_add_plugin(ZigBeeService *service, ZigBeePlugin *plugin)
197 if ((service == NULL) || (plugin == NULL)) {
198 Z_LOGE("service: [%p] plugin: [%p]", service, plugin);
202 plugin_name = zblib_plugin_get_plugin_name(plugin);
204 /* All plug-ins would be appended */
205 service->plugins = g_slist_append(service->plugins, plugin);
206 Z_LOGD("%s added", plugin_name);
212 gboolean zblib_service_remove_plugin(ZigBeeService *service, ZigBeePlugin *plugin)
214 if ((service == NULL) || (plugin == NULL)) {
215 Z_LOGE("service: [%p] plugin: [%p]", service, plugin);
219 /* Specific vendor plug-in would be removed */
220 service->plugins = g_slist_remove(service->plugins, plugin);
225 gboolean zblib_service_load_plugins(ZigBeeService *service, const char *plugin_path)
227 const gchar *file = NULL;
228 gchar *filename = NULL;
231 struct zblib_plugin_descriptor *descriptor = NULL;
232 ZigBeePlugin *plugin = NULL;
235 if ((service == NULL) || (plugin_path == NULL)) {
236 Z_LOGE("service: [%p] plugin_path: [%p]", service, plugin_path);
240 /* Open plug-in directory */
241 dir = g_dir_open(plugin_path, 0, NULL);
243 Z_LOGE("Directory open failed!");
247 /* Scan through all libraries in plug-in directory */
248 while ((file = g_dir_read_name(dir)) != NULL) {
249 if ((g_str_has_prefix(file, "lib") == TRUE)
250 || (g_str_has_suffix(file, ".so") == FALSE))
253 filename = g_build_filename(plugin_path, file, NULL);
256 handle = __zblib_service_load_plugin(filename, &descriptor);
257 if (NULL == handle) {
262 /* Create new plug-in */
263 plugin = zblib_plugin_new(service, filename, descriptor, handle);
264 if (NULL == plugin) {
269 /* Add new plug-in */
270 ret = zblib_service_add_plugin(service, plugin);
272 zblib_plugin_free(plugin);
282 gboolean zblib_service_initialize_plugins(ZigBeeService *service)
286 if (service == NULL) {
287 Z_LOGE("service is NULL");
291 /* Refer plug-in list */
292 list = zblib_service_ref_plugins(service);
293 while (list != NULL) {
294 /* Initialize each plug-in */
295 if (G_UNLIKELY(FALSE == __zblib_service_init_plugin((ZigBeePlugin *)(list->data)))) {
296 list = g_slist_next(list);
299 list = g_slist_next(list);
305 gboolean zblib_service_unload_plugins(ZigBeeService *service)
309 if (service == NULL) {
310 Z_LOGE("service is NULL");
314 list = zblib_service_ref_plugins(service);
315 while (list != NULL) {
316 ZigBeePlugin *plugin = list->data;
318 /* Unload each plug-in */
319 if (G_UNLIKELY(FALSE == __zblib_service_unload_plugin(plugin))) {
320 list = g_slist_next(list);
324 list = g_slist_next(list);
325 zblib_service_remove_plugin(service, plugin);
331 GSList *zblib_service_ref_plugins(ZigBeeService *service)
333 if (service == NULL) {
334 Z_LOGE("service is NULL");
338 return service->plugins;
341 gboolean zblib_service_add_service_interface(ZigBeeService *service,
342 ZigBeeServiceInterface *service_interface)
346 if ((service == NULL) || (service_interface == NULL)) {
347 Z_LOGE("service: [%p] service_interface: [%p]", service, service_interface);
351 object_name = zblib_service_interface_get_name(service_interface);
354 * All service interface objects would be appended
356 service->interface_objs = g_slist_append(service->interface_objs, service_interface);
357 Z_LOGD("%s added", object_name);
363 gboolean zblib_service_remove_service_interface(ZigBeeService *service,
364 ZigBeeServiceInterface *service_interface)
366 if ((service == NULL) || (service_interface == NULL)) {
367 Z_LOGE("service: [%p] service_interface: [%p]", service, service_interface);
372 * service interface object would be removed
374 service->interface_objs = g_slist_remove(service->interface_objs, service_interface);
379 ZigBeeServiceInterface *zblib_service_ref_service_interface(ZigBeeService *service,
380 const gchar *service_interface_name)
382 ZigBeeServiceInterface *service_interface = NULL;
383 ZigBeeServiceInterface *tmp_service_interface = NULL;
388 if ((service == NULL) || (service_interface_name == NULL)) {
389 Z_LOGE("service: [%p] service_interface_name: [%p]", service, service_interface_name);
393 list = service->interface_objs;
395 tmp_service_interface = (ZigBeeServiceInterface *)list->data;
397 /* Get object name of service_interface */
398 object_name = zblib_service_interface_get_name(tmp_service_interface);
399 if (g_strcmp0(service_interface_name, object_name) == 0) {
402 service_interface = tmp_service_interface;
406 list = g_slist_next(list);
409 if (service_interface == NULL) {
410 Z_LOGE("Service interface object of name '%s' not found!",
411 service_interface_name);
415 Z_LOGD("'%s' found", service_interface_name);
417 return service_interface;