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 */
34 GHashTable *request_table; /**< Request Hash table */
35 guint request_id; /**< Request ID */
38 static void *__zblib_service_load_plugin(gchar *filename,
39 struct zblib_plugin_descriptor **descriptor_out)
41 struct zblib_plugin_descriptor *descriptor = NULL;
46 if (G_UNLIKELY(NULL == descriptor_out)) {
47 Z_LOGE("descriptor_out is NULL!!!");
52 handle = dlopen(filename, RTLD_LAZY);
53 if (G_UNLIKELY(NULL == handle)) {
54 Z_LOGE("dlopen() failed:[%s]", filename);
58 /* Get symbol - "zigbee_plugin_descriptor" */
59 descriptor = dlsym(handle, "zigbee_plugin_descriptor");
60 if (G_UNLIKELY(NULL == descriptor)) {
61 Z_LOGE("dlsym() failed:[%s]", "plugin_define_desc");
66 Z_LOGD("%s plugin", descriptor->name);
67 Z_LOGD(" - path = %s", filename);
68 Z_LOGD(" - version = %d", descriptor->version);
70 memset(&stat_buf, 0x00, sizeof(stat_buf));
71 memset(&file_date, '\0', sizeof(file_date));
73 if (0 == stat(filename, &stat_buf)) {
74 if (NULL != ctime_r(&stat_buf.st_mtime, file_date)) {
75 if (1 < strlen(file_date))
76 file_date[strlen(file_date)-1] = '\0';
77 Z_LOGD(" - date = %s", file_date);
82 if (G_LIKELY(descriptor->load)) {
83 if (G_UNLIKELY(FALSE == descriptor->load())) {
84 Z_LOGW("load() failed... Skip this plugin!");
88 Z_LOGI("Plug-in (%s) loaded!", descriptor->name);
92 *descriptor_out = descriptor;
97 static gboolean __zblib_service_init_plugin(ZigBeePlugin *plugin)
99 const struct zblib_plugin_descriptor *descriptor = zblib_plugin_get_descriptor(plugin);
101 if ((NULL == descriptor) || (NULL == descriptor->init)) {
102 Z_LOGE("descriptor OR init function is NULL!!!");
106 if (G_UNLIKELY(FALSE == descriptor->init(plugin))) {
107 char *plugin_name = zblib_plugin_get_plugin_name(plugin);
108 if (G_UNLIKELY(NULL != plugin_name)) {
109 Z_LOGE("plugin(%s) init failed!", plugin_name);
118 static gboolean __zblib_service_unload_plugin(ZigBeePlugin *plugin)
120 const struct zblib_plugin_descriptor *descriptor = zblib_plugin_get_descriptor(plugin);
121 char *plugin_name = zblib_plugin_get_plugin_name(plugin);
123 if ((NULL == descriptor) || (NULL == descriptor->unload)) {
124 Z_LOGE("descriptor OR unload function is NULL!!!");
129 descriptor->unload(plugin);
130 Z_LOGI("plugin(%s) unloaded!", plugin_name);
135 ZigBeeService *zblib_service_new()
137 ZigBeeService *service;
139 service = g_malloc0(sizeof(struct zblib_service_type));
141 /* Create g-main loop */
142 service->main_loop = g_main_loop_new(NULL, FALSE);
143 if (G_UNLIKELY(NULL == service->main_loop)) {
144 Z_LOGE("g-main loop creation failed!!!");
149 /* Create request hash table */
150 service->request_table = g_hash_table_new_full(g_direct_hash,
151 g_direct_equal, NULL, NULL);
156 void zblib_service_free(ZigBeeService *service)
158 if (NULL == service) {
159 Z_LOGE("service is NULL");
164 if (service->plugins) {
165 g_slist_free(service->plugins);
166 service->plugins = NULL;
169 /* Unref 'g-main loop' */
170 if (service->main_loop)
171 g_main_loop_unref(service->main_loop);
176 gboolean zblib_service_run(ZigBeeService *service)
178 if ((NULL == service) || (NULL == service->main_loop)) {
179 Z_LOGE("service or mainloop is NULL");
183 g_main_loop_run(service->main_loop);
188 gboolean zblib_service_exit(ZigBeeService *service)
190 if ((NULL == service) || (NULL == service->main_loop)) {
191 Z_LOGE("service or mainloop is NULL");
195 g_main_loop_quit(service->main_loop);
200 gboolean zblib_service_add_plugin(ZigBeeService *service, ZigBeePlugin *plugin)
204 if ((NULL == service) || (plugin == NULL)) {
205 Z_LOGE("service: [%p] plugin: [%p]", service, plugin);
209 plugin_name = zblib_plugin_get_plugin_name(plugin);
211 /* All plug-ins would be appended */
212 service->plugins = g_slist_append(service->plugins, plugin);
213 Z_LOGD("%s added", plugin_name);
219 gboolean zblib_service_remove_plugin(ZigBeeService *service, ZigBeePlugin *plugin)
221 if ((NULL == service) || (plugin == NULL)) {
222 Z_LOGE("service: [%p] plugin: [%p]", service, plugin);
226 /* Specific vendor plug-in would be removed */
227 service->plugins = g_slist_remove(service->plugins, plugin);
232 gboolean zblib_service_load_plugins(ZigBeeService *service, const char *plugin_path)
234 const gchar *file = NULL;
235 gchar *filename = NULL;
238 struct zblib_plugin_descriptor *descriptor = NULL;
239 ZigBeePlugin *plugin = NULL;
242 if ((NULL == service) || (NULL == plugin_path)) {
243 Z_LOGE("service: [%p] plugin_path: [%p]", service, plugin_path);
247 /* Open plug-in directory */
248 dir = g_dir_open(plugin_path, 0, NULL);
249 if (G_UNLIKELY(dir == NULL)) {
250 Z_LOGE("Directory open failed!");
254 /* Scan through all libraries in plug-in directory */
255 while ((file = g_dir_read_name(dir)) != NULL) {
256 if ((g_str_has_prefix(file, "lib") == TRUE)
257 || (g_str_has_suffix(file, ".so") == FALSE))
260 filename = g_build_filename(plugin_path, file, NULL);
263 handle = __zblib_service_load_plugin(filename, &descriptor);
264 if (G_UNLIKELY(NULL == handle)) {
269 /* Create new plug-in */
270 plugin = zblib_plugin_new(service, filename, descriptor, handle);
271 if (G_UNLIKELY(NULL == plugin)) {
276 /* Add new plug-in */
277 ret = zblib_service_add_plugin(service, plugin);
278 if (G_UNLIKELY(FALSE == ret)) {
279 zblib_plugin_free(plugin);
289 gboolean zblib_service_initialize_plugins(ZigBeeService *service)
293 if (NULL == service) {
294 Z_LOGE("service is NULL");
298 /* Refer plug-in list */
299 list = zblib_service_ref_plugins(service);
300 while (list != NULL) {
301 /* Initialize each plug-in */
302 if (G_UNLIKELY(FALSE == __zblib_service_init_plugin((ZigBeePlugin *)(list->data)))) {
303 list = g_slist_next(list);
306 list = g_slist_next(list);
312 gboolean zblib_service_unload_plugins(ZigBeeService *service)
316 if (NULL == service) {
317 Z_LOGE("service is NULL");
321 list = zblib_service_ref_plugins(service);
322 while (list != NULL) {
323 ZigBeePlugin *plugin = list->data;
325 /* Unload each plug-in */
326 if (G_UNLIKELY(FALSE == __zblib_service_unload_plugin(plugin))) {
327 list = g_slist_next(list);
331 list = g_slist_next(list);
332 zblib_service_remove_plugin(service, plugin);
338 GSList *zblib_service_ref_plugins(ZigBeeService *service)
340 if (NULL == service) {
341 Z_LOGE("service is NULL");
345 return service->plugins;
348 gboolean zblib_service_add_service_interface(ZigBeeService *service,
349 ZigBeeServiceInterface *service_interface)
353 if ((NULL == service) || (NULL == service_interface)) {
354 Z_LOGE("service: [%p] service_interface: [%p]", service, service_interface);
358 object_name = zblib_service_interface_get_name(service_interface);
361 * All service interface objects would be appended
363 service->interface_objs = g_slist_append(service->interface_objs, service_interface);
364 Z_LOGD("%s added", object_name);
370 gboolean zblib_service_remove_service_interface(ZigBeeService *service,
371 ZigBeeServiceInterface *service_interface)
373 if ((NULL == service) || (NULL == service_interface)) {
374 Z_LOGE("service: [%p] service_interface: [%p]", service, service_interface);
379 * service interface object would be removed
381 service->interface_objs = g_slist_remove(service->interface_objs, service_interface);
386 ZigBeeServiceInterface *zblib_service_ref_service_interface(ZigBeeService *service,
387 const gchar *service_interface_name)
389 ZigBeeServiceInterface *service_interface = NULL;
390 ZigBeeServiceInterface *tmp_service_interface = NULL;
395 if ((NULL == service) || (NULL == service_interface_name)) {
396 Z_LOGE("service: [%p] service_interface_name: [%p]", service, service_interface_name);
400 list = service->interface_objs;
402 tmp_service_interface = (ZigBeeServiceInterface *)list->data;
404 /* Get object name of service_interface */
405 object_name = zblib_service_interface_get_name(tmp_service_interface);
406 if (g_strcmp0(service_interface_name, object_name) == 0) {
409 service_interface = tmp_service_interface;
413 list = g_slist_next(list);
416 if (NULL == service_interface) {
417 Z_LOGE("Service interface object of name '%s' not found!",
418 service_interface_name);
422 Z_LOGD("'%s' found", service_interface_name);
424 return service_interface;
427 GHashTable *zblib_service_ref_request_hash_table(ZigBeeService *service)
429 if (NULL == service) {
430 Z_LOGE("service is NULL");
434 return service->request_table;
437 gint zblib_service_generate_request_id(ZigBeeService *service)
439 if (NULL == service) {
440 Z_LOGE("service is NULL");
444 /* Increment request ID */
445 service->request_id++;
447 return (gint)service->request_id;