2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include "push-adaptor.h"
24 #include "push-adaptor-log.h"
29 typedef struct push_adaptor_plugin_s {
30 push_adaptor_h adaptor; /* Adaptor */
31 char *path; /* Plugin library path */
32 push_adaptor_plugin_handle_h handle; /* Plugin handle */
33 void *dl_handle; /* Plugin library handle */
34 int ref_counter; /* Plugin reference counter */
35 GMutex ref_counter_mutex; /* Plugin reference counter mutex */
36 push_adaptor_plugin_listener_h plugin_listener; /* Plugin callback listener */
37 GMutex plugin_listener_mutex; /* Plugin callback listener mutex */
38 } push_adaptor_plugin_t;
43 typedef struct push_adaptor_s {
44 GMutex push_adaptor_mutex; /* Adaptor mutex */
45 int started; /* Started flag */
46 char *plugins_dir; /* Plugins directory path */
47 GList *plugins; /* List of loaded plugins */
48 GMutex plugins_mutex; /* Plugin list mutex */
49 GList *adaptor_listeners; /* List of vservice channel listener (for now not effective) */
50 GMutex adaptor_listeners_mutex; /* Listener list mutex */
56 static push_adaptor_plugin_h push_adaptor_create_plugin(const char *plugin_path);
59 * Destroys plugin and deletes all resources associated with it
61 static void push_adaptor_destroy_plugin(push_adaptor_plugin_h plugin);
64 * Loads plugins from selected directory
66 static int push_adaptor_load_plugins_from_directory(push_adaptor_h adaptor, const char *dir_path);
69 * Checks if plugin is loaded by selected plugin adaptor
71 static int push_adaptor_has_plugin(push_adaptor_h adaptor, push_adaptor_plugin_h plugin);
74 * Increases adaptor's plugin references counter
76 static void push_adaptor_plugin_ref(push_adaptor_plugin_h);
79 * Decreases adaptor's plugin references counter
81 static void push_adaptor_plugin_unref(push_adaptor_plugin_h);
84 * On notification received callback for service adaptor
86 push_adaptor_service_on_notification_received_cb _service_adaptor_on_notification_received = NULL;
89 * Called on push notification received from plugin
92 push_adaptor_on_notification_received(push_adaptor_notification_data_h notification, void *user_data)
94 push_adaptor_info("[Push MSG]: %s", notification->msg);
96 if (NULL != _service_adaptor_on_notification_received) {
97 _service_adaptor_on_notification_received(notification, user_data);
101 /* //////////////////////////////////////////////////////
102 // Mandatory: Internal adaptor management function
103 ////////////////////////////////////////////////////// */
108 static push_adaptor_plugin_h push_adaptor_create_plugin(const char *plugin_path)
110 push_adaptor_debug("Create plugin");
112 if (NULL == plugin_path) {
113 push_adaptor_error("Invalid argument");
117 void *dl_handle = dlopen(plugin_path, RTLD_LAZY);
118 if (NULL == dl_handle) {
119 push_adaptor_error("Could not load plugin %s: %s", plugin_path, dlerror());
123 push_adaptor_plugin_handle_h (*get_adaptee_handle)(void) = NULL;
125 get_adaptee_handle = (push_adaptor_plugin_handle_h (*)(void))(dlsym(dl_handle, "create_plugin_handle"));
126 if (NULL == get_adaptee_handle) {
128 push_adaptor_error("Could not get function pointer to create_plugin_handle");
133 push_adaptor_plugin_handle_h handle = get_adaptee_handle();
134 plugin_req_exit_void();
136 if (NULL == handle) {
138 push_adaptor_error("Could not get adaptee handle");
142 push_adaptor_plugin_h plugin = (push_adaptor_plugin_h) calloc(1, sizeof(push_adaptor_plugin_t));
143 if (NULL == plugin) {
145 push_adaptor_error("Could not create plugin object");
149 push_adaptor_plugin_listener_h listener =
150 (push_adaptor_plugin_listener_h) calloc(1, sizeof(push_adaptor_plugin_listener_t));
151 if (NULL == listener) {
154 push_adaptor_error("Could not create listener object");
158 plugin->path = g_strdup(plugin_path);
159 plugin->handle = handle;
160 plugin->dl_handle = dl_handle;
161 plugin->ref_counter = 0;
163 g_mutex_init(&plugin->ref_counter_mutex);
164 g_mutex_init(&plugin->plugin_listener_mutex);
166 listener->_on_notification_received = push_adaptor_on_notification_received;
169 plugin->handle->set_listener(listener);
170 plugin_req_exit_void();
172 g_mutex_lock(&plugin->plugin_listener_mutex);
173 plugin->plugin_listener = listener;
174 g_mutex_unlock(&plugin->plugin_listener_mutex);
180 * Destroys plugin and deletes all resources associated with it
182 static void push_adaptor_destroy_plugin(push_adaptor_plugin_h plugin)
184 push_adaptor_debug("Destroy plugin");
186 if (NULL == plugin) {
187 push_adaptor_error("Invalid argument");
191 if (NULL != plugin->handle) {
192 plugin->handle->destroy_handle(plugin->handle);
194 g_mutex_lock(&plugin->plugin_listener_mutex);
196 plugin->handle->unset_listener();
197 plugin_req_exit_void();
198 g_mutex_unlock(&plugin->plugin_listener_mutex);
200 plugin->handle = NULL;
203 if (NULL != plugin->dl_handle) {
204 dlclose(plugin->dl_handle);
205 plugin->dl_handle = NULL;
215 * Loads plugins from selected directory
217 static int push_adaptor_load_plugins_from_directory(push_adaptor_h adaptor, const char *dir_path)
219 push_adaptor_debug("Load plugins from directory");
221 char *plugin_path = NULL;
223 struct dirent dir_entry, *result = NULL;
225 if ((NULL == adaptor) || (NULL == dir_path)) {
226 push_adaptor_error("Invalid argument");
227 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
230 dir = opendir(dir_path);
232 push_adaptor_error("Could not open dir path (%s)", dir_path);
233 return PUSH_ADAPTOR_ERROR_NOT_FOUND;
236 int ret = PUSH_ADAPTOR_ERROR_NONE;
237 while (0 == (readdir_r(dir, &dir_entry, &result))) {
239 if (NULL == result) {
240 push_adaptor_error("Could not open directory %s", plugin_path);
244 if (dir_entry.d_type & DT_DIR) {
248 plugin_path = g_strconcat(dir_path, "/", dir_entry.d_name, NULL);
249 push_adaptor_plugin_h plugin = push_adaptor_create_plugin(plugin_path);
251 if (NULL != plugin) {
252 push_adaptor_debug("Loaded plugin: %s", plugin_path);
253 plugin->adaptor = adaptor;
254 push_adaptor_plugin_ref(plugin);
255 g_mutex_lock(&adaptor->plugins_mutex);
256 adaptor->plugins = g_list_append(adaptor->plugins, plugin);
257 g_mutex_unlock(&adaptor->plugins_mutex);
259 push_adaptor_error("Could not load plugin %s", plugin_path);
266 push_adaptor_debug("End load plugins from directory");
272 * Checks if plugin is loaded by selected plugin adaptor
274 static int push_adaptor_has_plugin(push_adaptor_h adaptor, push_adaptor_plugin_h plugin)
276 push_adaptor_debug("Find plugin in plugin list");
278 if ((NULL == adaptor) || (NULL == plugin)) {
279 push_adaptor_error("Invalid argument");
285 g_mutex_lock(&adaptor->plugins_mutex);
286 if (NULL != g_list_find(adaptor->plugins, plugin)) {
289 g_mutex_unlock(&adaptor->plugins_mutex);
295 * Increases adaptor's plugin references counter
297 static void push_adaptor_plugin_ref(push_adaptor_plugin_h plugin)
299 push_adaptor_debug("Increase plugin reference count");
301 if (NULL == plugin) {
302 push_adaptor_error("Invalid argument");
306 g_mutex_lock(&plugin->ref_counter_mutex);
307 plugin->ref_counter = plugin->ref_counter + 1;
308 push_adaptor_info("ref_counter: %d", plugin->ref_counter);
309 g_mutex_unlock(&plugin->ref_counter_mutex);
313 * Decreases adaptor's plugin references counter
315 static void push_adaptor_plugin_unref(push_adaptor_plugin_h plugin)
317 push_adaptor_debug("Decrease plugin reference count");
319 if (NULL == plugin) {
320 push_adaptor_error("Invalid argument");
324 int should_destroy = 0;
326 g_mutex_lock(&plugin->ref_counter_mutex);
327 plugin->ref_counter = plugin->ref_counter - 1;
328 push_adaptor_info("ref_counter: %d", plugin->ref_counter);
329 if (0 >= plugin->ref_counter) {
332 g_mutex_unlock(&plugin->ref_counter_mutex);
334 if (should_destroy) {
335 push_adaptor_debug("Plugin is being destroyed");
336 push_adaptor_destroy_plugin(plugin);
340 /* //////////////////////////////////////////////////////
341 // Mandatory: External adaptor management function
342 ////////////////////////////////////////////////////// */
345 * @brief Creates Push Adaptor
347 * @param[in] plugin_dir specifies directory path where plugins are stored
348 * @return push_adaptor_h on success, otherwise NULL value
350 push_adaptor_h push_adaptor_create(const char *plugins_dir)
352 push_adaptor_warning("Create push adaptor");
354 push_adaptor_h push_adaptor = (push_adaptor_h) malloc(sizeof(push_adaptor_t));
355 if (NULL == push_adaptor) {
359 push_adaptor->started = 0;
360 push_adaptor->plugins_dir = strdup(plugins_dir);
362 g_mutex_init(&push_adaptor->push_adaptor_mutex);
363 g_mutex_init(&push_adaptor->plugins_mutex);
364 g_mutex_init(&push_adaptor->adaptor_listeners_mutex);
366 g_mutex_lock(&push_adaptor->adaptor_listeners_mutex);
367 push_adaptor->adaptor_listeners = NULL;
368 g_mutex_unlock(&push_adaptor->adaptor_listeners_mutex);
370 g_mutex_lock(&push_adaptor->plugins_mutex);
371 push_adaptor->plugins = NULL;
372 g_mutex_unlock(&push_adaptor->plugins_mutex);
378 * @brief Destroys push adaptor. If push adaptor was started it is stopped first.
380 * @param[in] adaptor specifies push adaptor handle to be destroyed
383 void push_adaptor_destroy(push_adaptor_h adaptor)
385 push_adaptor_warning("Destroy push adaptor");
386 if (NULL == adaptor) {
387 push_adaptor_error("Invalid argument");
391 g_mutex_lock(&adaptor->push_adaptor_mutex);
392 if (adaptor->started) {
393 push_adaptor_error("Push adaptor is running. Forcing stop before destroy");
394 push_adaptor_stop(adaptor);
397 g_mutex_lock(&adaptor->plugins_mutex);
398 if (NULL != adaptor->plugins) {
399 g_list_free_full(adaptor->plugins, (GDestroyNotify) push_adaptor_plugin_unref);
400 adaptor->plugins = NULL;
402 g_mutex_unlock(&adaptor->plugins_mutex);
404 g_mutex_lock(&adaptor->adaptor_listeners_mutex);
405 if (NULL != adaptor->adaptor_listeners) {
406 g_list_free(adaptor->adaptor_listeners);
407 adaptor->adaptor_listeners = NULL;
409 g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
411 _service_adaptor_on_notification_received = NULL;
413 free(adaptor->plugins_dir);
414 adaptor->plugins_dir = NULL;
416 g_mutex_unlock(&adaptor->push_adaptor_mutex);
422 * @brief Starts push adaptor and loads plugins that were found in plugins search dir
423 * specified in push_adaptor_create
425 * @param[in] adaptor specifies push adaptor handle
426 * @return 0 on success, otherwise a positive error value
427 * @retval error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
429 int push_adaptor_start(push_adaptor_h adaptor)
431 push_adaptor_warning("Start push adaptor");
432 if (NULL == adaptor) {
433 push_adaptor_error("Invalid argument");
434 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
437 g_mutex_lock(&adaptor->push_adaptor_mutex);
438 int result = PUSH_ADAPTOR_ERROR_NONE;
439 if (adaptor->started) {
440 push_adaptor_error("Push adaptor is already started");
441 result = PUSH_ADAPTOR_ERROR_START;
443 adaptor->started = 1;
444 result = push_adaptor_load_plugins_from_directory(adaptor, adaptor->plugins_dir);
445 if (PUSH_ADAPTOR_ERROR_NONE != result) {
446 adaptor->started = 0;
447 push_adaptor_error("Could not load plugins from directory");
449 push_adaptor_debug("Push adaptor started successfully");
452 g_mutex_unlock(&adaptor->push_adaptor_mutex);
458 * @brief Stops push adaptor
460 * @param[in] adaptor specifies push adaptor handle
461 * @return 0 on success, otherwise a positive error value
462 * @retval error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
464 int push_adaptor_stop(push_adaptor_h adaptor)
466 push_adaptor_warning("Stop contact adaptor");
468 if (NULL == adaptor) {
469 push_adaptor_error("Invalid argument");
470 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
473 g_mutex_lock(&adaptor->push_adaptor_mutex);
474 int result = PUSH_ADAPTOR_ERROR_NONE;
475 if (!adaptor->started) {
476 result = PUSH_ADAPTOR_ERROR_START;
478 if (NULL != adaptor->plugins) {
479 g_mutex_lock(&adaptor->plugins_mutex);
480 g_list_free_full(adaptor->plugins, (GDestroyNotify) push_adaptor_plugin_unref);
481 adaptor->plugins = NULL;
482 g_mutex_unlock(&adaptor->plugins_mutex);
484 adaptor->started = 0;
485 push_adaptor_debug("Push adaptor stopped");
488 g_mutex_unlock(&adaptor->push_adaptor_mutex);
493 * @brief Registers plugin state listener
495 * @param[in] adaptor specifies push adaptor handle
496 * @param[in] listener specifies push adaptor listener handle
497 * @return 0 on success, otherwise a positive error value
498 * @retval error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
500 int push_adaptor_register_listener(push_adaptor_h adaptor, push_adaptor_listener_h listener)
502 push_adaptor_warning("Register push adaptor listener");
504 if ((NULL == adaptor) || (NULL == listener)) {
505 push_adaptor_error("Invalid argument");
506 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
509 g_mutex_lock(&adaptor->adaptor_listeners_mutex);
510 adaptor->adaptor_listeners = g_list_append(adaptor->adaptor_listeners, listener);
512 g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
514 _service_adaptor_on_notification_received =
515 (push_adaptor_service_on_notification_received_cb) listener->_on_notification_received;
517 return PUSH_ADAPTOR_ERROR_NONE;
521 * @brief Unregisters plugin state listener
523 * @param[in] adaptor specifies push adaptor handle
524 * @param[in] listener specifies push adaptor listener handle
525 * @return 0 on success, otherwise a positive error value
526 * @retval error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
528 int push_adaptor_unregister_listener(push_adaptor_h adaptor, push_adaptor_listener_h listener)
530 push_adaptor_warning("Unregister push adaptor listener");
532 if (NULL == adaptor) {
533 push_adaptor_error("Invalid argument (adaptor)");
534 if (NULL != listener) {
538 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
540 if (NULL == listener) {
541 push_adaptor_error("Invalid argument (listener)");
542 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
545 g_mutex_lock(&adaptor->adaptor_listeners_mutex);
547 if (NULL == g_list_find(adaptor->adaptor_listeners, listener)) {
548 g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
549 push_adaptor_error("Could not find listener");
551 return PUSH_ADAPTOR_ERROR_NOT_FOUND;
554 adaptor->adaptor_listeners = g_list_remove(adaptor->adaptor_listeners, listener);
557 g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
559 _service_adaptor_on_notification_received = NULL;
561 return PUSH_ADAPTOR_ERROR_NONE;
564 /* //////////////////////////////////////////////////////
565 // Create / Destroy error code
566 ////////////////////////////////////////////////////// */
569 * @brief Create error code
571 * @param[in] code specifies error code number
572 * @param[in] msg specifies error message
573 * @return push_adaptor_error_code_h on success, otherwise NULL value
575 push_adaptor_error_code_h push_adaptor_create_error_code(const int64_t code, const char *msg)
581 push_adaptor_error_code_h error_code =
582 (push_adaptor_error_code_h) malloc(sizeof(push_adaptor_error_code_t));
583 if (NULL == error_code) {
587 error_code->code = code;
588 error_code->msg = strdup(msg);
594 * @brief Destroy error code
596 * @param[in] error_code specifies error code handle
599 void push_adaptor_destroy_error_code(push_adaptor_error_code_h *error_code)
601 if (NULL == *error_code) {
605 if (NULL != (*error_code)->msg) {
606 free((*error_code)->msg);
607 (*error_code)->msg = NULL;
614 /* //////////////////////////////////////////////////////
615 // Plugin context create / destroy
616 ////////////////////////////////////////////////////// */
618 * @brief Creates plugin context
620 * @param[in] plugin specifies push adaptor plugin handle
621 * @param[in] push_app_id specifies push service application ID
622 * @return push_adaptor_plugin_context_h on success, otherwise NULL value
624 push_adaptor_plugin_context_h push_adaptor_create_plugin_context(push_adaptor_plugin_h plugin,
625 const char *plugin_uri,
626 const char *push_app_id)
628 push_adaptor_warning("Create plugin context");
630 if (NULL == plugin) {
631 push_adaptor_error("Invalid argument");
635 if (NULL != plugin->handle) {
636 push_adaptor_plugin_context_h plugin_context = NULL;
639 plugin->handle->create_context(&plugin_context, push_app_id);
640 plugin_req_exit_void();
642 if (NULL != plugin_context) {
643 plugin_context->plugin_uri = strdup(plugin->handle->plugin_uri);
644 plugin_context->state = PUSH_ADAPTOR_STATE_DISCONNECTED;
646 return plugin_context;
648 push_adaptor_error("Plugin handle is null");
655 * @brief Destroys plugin context
657 * @param[in] plugin specifies push adaptor plugin handle
658 * @param[in] context specifies push adaptor plugin context handle
661 void push_adaptor_destroy_plugin_context(push_adaptor_plugin_h plugin,
662 push_adaptor_plugin_context_h plugin_context)
664 push_adaptor_warning("Destroy plugin context");
666 if ((NULL == plugin) || (NULL == plugin_context)) {
667 push_adaptor_error("Invalid argument");
671 if (NULL != plugin->handle) {
673 plugin->handle->destroy_context(plugin_context);
674 plugin_req_exit_void();
676 push_adaptor_error("Plugin handle is null");
680 /* //////////////////////////////////////////////////////
681 // Get plugin by plugin name
682 ////////////////////////////////////////////////////// */
685 * @brief Gets plugin with specified unique name
687 * @param[in] adaptor specifies push adaptor handle
688 * @param[in] plugin_name specifies plugin name to be searched for
689 * @return push_adaptor_plugin_h on success, otherwise NULL value
691 push_adaptor_plugin_h push_adaptor_get_plugin_by_name(push_adaptor_h adaptor,
692 const char *plugin_name)
694 push_adaptor_warning("Get plugin by name: %s", plugin_name);
696 if ((NULL == adaptor) || (NULL == plugin_name)) {
697 push_adaptor_error("Invalid argument");
701 push_adaptor_plugin_h plugin = NULL;
702 g_mutex_lock(&adaptor->plugins_mutex);
703 int count = g_list_length(adaptor->plugins);
705 for (i = 0; i < count; i++) {
706 push_adaptor_plugin_h temp_plugin = g_list_nth_data(adaptor->plugins, i);
707 if (NULL != temp_plugin) {
708 if (0 == strcmp(temp_plugin->handle->plugin_uri, plugin_name)) {
709 push_adaptor_plugin_ref(temp_plugin);
710 plugin = temp_plugin;
711 push_adaptor_debug("Plugin is found by name");
716 g_mutex_unlock(&adaptor->plugins_mutex);
719 push_adaptor_debug("Plugin is not found by name");
724 /* //////////////////////////////////////////////////////
725 // Plugin load / unload / get plugin list
726 ////////////////////////////////////////////////////// */
729 * @brief Loads plugin from selected path
731 * @param[in] adaptor specifies push adaptor handle
732 * @param[in] plugin_path specifies plugin's saved path
733 * @return 0 on success, otherwise a positive error value
734 * @retval error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
736 int push_adaptor_load_plugin(push_adaptor_h adaptor,
737 const char *plugin_path)
739 push_adaptor_warning("Load plugin by plugin path: %s", plugin_path);
741 if ((NULL == adaptor) || (NULL == plugin_path)) {
742 push_adaptor_error("Invalid argument");
743 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
746 if (!adaptor->started) {
747 push_adaptor_error("Push adaptor is not started");
748 return PUSH_ADAPTOR_ERROR_START;
751 push_adaptor_plugin_h plugin = push_adaptor_create_plugin(plugin_path);
752 if (NULL == plugin) {
753 push_adaptor_error("Could not load plugin %s", plugin_path);
754 return PUSH_ADAPTOR_ERROR_CREATE;
757 plugin->adaptor = adaptor;
758 push_adaptor_plugin_ref(plugin);
760 g_mutex_lock(&adaptor->plugins_mutex);
761 adaptor->plugins = g_list_append(adaptor->plugins, plugin);
762 g_mutex_unlock(&adaptor->plugins_mutex);
764 return PUSH_ADAPTOR_ERROR_NONE;
768 * @brief Unloads selected plugin
770 * @param[in] adaptor specifies push adaptor handle
771 * @param[in] plugin specifies push adaptor plugin handle
772 * @return 0 on success, otherwise a positive error value
773 * @retval error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
775 int push_adaptor_unload_plugin(push_adaptor_h adaptor,
776 push_adaptor_plugin_h plugin)
778 push_adaptor_warning("Unload plugin");
780 if ((NULL == adaptor) || (NULL == plugin)) {
781 push_adaptor_error("Invalid argument");
782 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
785 if (!adaptor->started) {
786 push_adaptor_error("Push adaptor is not started");
787 return PUSH_ADAPTOR_ERROR_START;
790 if (!push_adaptor_has_plugin(adaptor, plugin)) {
791 push_adaptor_error("Push adaptor has no plugin");
792 return PUSH_ADAPTOR_ERROR_NOT_FOUND;
795 plugin->adaptor = NULL;
797 g_mutex_lock(&adaptor->plugins_mutex);
798 adaptor->plugins = g_list_remove(adaptor->plugins, plugin);
799 g_mutex_unlock(&adaptor->plugins_mutex);
801 push_adaptor_plugin_unref(plugin);
803 return PUSH_ADAPTOR_ERROR_NONE;
807 * @brief Get plugin list
809 * @param[in] adaptor specifies push adaptor handle
810 * @return GList pointer on success, otherwise NULL value
812 GList *push_adaptor_get_plugins(push_adaptor_h adaptor)
814 push_adaptor_warning("Get plugin list");
816 if (NULL == adaptor) {
817 push_adaptor_error("Invalid argument");
821 GList *plugins = NULL;
823 g_mutex_lock(&adaptor->plugins_mutex);
824 int plugins_count = g_list_length(adaptor->plugins);
826 for (i = 0; i < plugins_count; i++) {
827 push_adaptor_plugin_h plugin = g_list_nth_data(adaptor->plugins, i);
828 if (NULL != plugin) {
829 push_adaptor_plugin_ref(plugin);
830 plugins = g_list_append(plugins, plugin);
833 g_mutex_unlock(&adaptor->plugins_mutex);
838 /* //////////////////////////////////////////////////////
839 // External Push Adaptor APIs
840 ////////////////////////////////////////////////////// */
843 * @brief Set server information for Push Plugin
845 * @param[in] plugin specifies Push Adaptor Plugin handle
846 * @param[in] context specifies Push Adaptor Plugin Context handle
847 * @param[in] server_info specifies server information for Push Plugin
848 * @param[out] error specifies error code
849 * @return 0 on success, otherwise a positive error value
850 * @retval error code defined in push_error_code_t - PUSH_ADAPTOR_ERROR_NONE if Successful
853 push_error_code_t push_adaptor_set_server_info(push_adaptor_plugin_h plugin,
854 push_adaptor_plugin_context_h context,
855 GHashTable *server_info,
856 push_adaptor_error_code_h *error_code)
858 if ((NULL == plugin) || (NULL == context)) {
859 push_adaptor_error("Invalid argument");
861 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT,
862 "Invalid argument (plugin or context)");
864 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
867 if (NULL == plugin->handle) {
868 push_adaptor_error("Plugin handle is null");
870 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_HANDLE,
871 "Plugin handle is null");
873 return PUSH_ADAPTOR_ERROR_INVALID_HANDLE;
876 /* *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_NONE, */
877 /* "Push adaptor error none"); */
878 push_error_code_t ret;
880 ret = plugin->handle->set_server_info(context, server_info);
881 plugin_req_exit(ret, plugin, error_code);
887 * @brief Connects to push service with Push App ID handed over when creates plugin context
889 * @param[in] plugin specifies push adaptor plugin handle
890 * @param[in] context specifies push adaptor plugin context handle
891 * @param[out] error specifies error code
892 * @return 0 on success, otherwise a positive error value
893 * @retval error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
895 push_error_code_t push_adaptor_connect(push_adaptor_plugin_h plugin,
896 push_adaptor_plugin_context_h context,
897 push_adaptor_error_code_h *error_code)
899 push_adaptor_warning("Connect to push adaptor");
901 if ((NULL == plugin) || (NULL == context)) {
902 push_adaptor_error("Invalid argument");
904 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT,
905 "Invalid argument (plugin or context)");
907 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
910 if (NULL == plugin->handle) {
911 push_adaptor_error("Plugin handle is null");
913 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_HANDLE,
914 "Plugin handle is null");
916 return PUSH_ADAPTOR_ERROR_INVALID_HANDLE;
919 /* *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_NONE, */
920 /* "Push adaptor error none"); */
922 push_error_code_t ret;
924 ret = plugin->handle->connect(context);
925 plugin_req_exit(ret, plugin, error_code);
931 * @brief Disconnects from push service with Push App ID handed over when creates plugin context
933 * @param[in] plugin specifies push adaptor plugin handle
934 * @param[in] context specifies push adaptor plugin context handle
935 * @param[out] error specifies error code
936 * @return 0 on success, otherwise a positive error value
937 * @retval error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
939 push_error_code_t push_adaptor_disconnect(push_adaptor_plugin_h plugin,
940 push_adaptor_plugin_context_h context,
941 push_adaptor_error_code_h *error_code)
943 push_adaptor_warning("Disconnect from push adaptor");
945 if ((NULL == plugin) || (NULL == context)) {
946 push_adaptor_error("Invalid argument");
948 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT,
949 "Invalid argument (plugin or context)");
951 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
954 if (NULL == plugin->handle) {
955 push_adaptor_error("Plugin handle is null");
957 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_HANDLE,
958 "Plugin handle is null");
960 return PUSH_ADAPTOR_ERROR_INVALID_HANDLE;
963 /* *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_NONE, */
964 /* "Push adaptor error none"); */
966 push_error_code_t ret;
968 ret = plugin->handle->disconnect(context);
969 plugin_req_exit(ret, plugin, error_code);
975 push_error_code_t push_adaptor_is_connected(push_adaptor_plugin_h plugin,
976 push_adaptor_plugin_context_h context,
979 push_adaptor_info("Check push connection");
981 if ((NULL == context) || (NULL == is_connected)) {
982 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
985 *is_connected = context->state;
987 return PUSH_ADAPTOR_ERROR_NONE;
991 * @brief Asynchronous request to get unread notifications
993 * @param[in] plugin specifies push adaptor plugin handle
994 * @param[in] context specifies push adaptor plugin context handle
995 * @param[out] error specifies error code
996 * @return 0 on success, otherwise a positive error value
997 * @retval error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
999 push_error_code_t push_adaptor_request_unread_notification(push_adaptor_plugin_h plugin,
1000 push_adaptor_plugin_context_h context,
1001 push_adaptor_error_code_h *error_code)
1003 push_adaptor_warning("Request unread notification");
1005 if ((NULL == plugin) || (NULL == context)) {
1006 push_adaptor_error("Invalid argument");
1008 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT,
1009 "Invalid argument (plugin or context)");
1011 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
1014 if (NULL == plugin->handle) {
1015 push_adaptor_error("Plugin handle is null");
1017 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_HANDLE,
1018 "Plugin handle is null");
1020 return PUSH_ADAPTOR_ERROR_INVALID_HANDLE;
1023 /* *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_NONE, */
1024 /* "Push adaptor error none"); */
1026 push_error_code_t ret;
1028 ret = plugin->handle->request_unread_notification(context);
1029 plugin_req_exit(ret, plugin, error_code);