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) || (NULL == listener)) {
533 push_adaptor_error("Invalid argument");
534 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
537 g_mutex_lock(&adaptor->adaptor_listeners_mutex);
539 if (NULL == g_list_find(adaptor->adaptor_listeners, listener)) {
540 g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
541 push_adaptor_error("Could not find listener");
543 return PUSH_ADAPTOR_ERROR_NOT_FOUND;
546 adaptor->adaptor_listeners = g_list_remove(adaptor->adaptor_listeners, listener);
549 g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
551 _service_adaptor_on_notification_received = NULL;
553 return PUSH_ADAPTOR_ERROR_NONE;
556 /* //////////////////////////////////////////////////////
557 // Create / Destroy error code
558 ////////////////////////////////////////////////////// */
561 * @brief Create error code
563 * @param[in] code specifies error code number
564 * @param[in] msg specifies error message
565 * @return push_adaptor_error_code_h on success, otherwise NULL value
567 push_adaptor_error_code_h push_adaptor_create_error_code(const int64_t code, const char *msg)
573 push_adaptor_error_code_h error_code =
574 (push_adaptor_error_code_h) malloc(sizeof(push_adaptor_error_code_t));
575 if (NULL == error_code) {
579 error_code->code = code;
580 error_code->msg = strdup(msg);
586 * @brief Destroy error code
588 * @param[in] error_code specifies error code handle
591 void push_adaptor_destroy_error_code(push_adaptor_error_code_h *error_code)
593 if (NULL == *error_code) {
597 if (NULL != (*error_code)->msg) {
598 free((*error_code)->msg);
599 (*error_code)->msg = NULL;
606 /* //////////////////////////////////////////////////////
607 // Plugin context create / destroy
608 ////////////////////////////////////////////////////// */
610 * @brief Creates plugin context
612 * @param[in] plugin specifies push adaptor plugin handle
613 * @param[in] push_app_id specifies push service application ID
614 * @return push_adaptor_plugin_context_h on success, otherwise NULL value
616 push_adaptor_plugin_context_h push_adaptor_create_plugin_context(push_adaptor_plugin_h plugin,
617 const char *plugin_uri,
618 const char *push_app_id)
620 push_adaptor_warning("Create plugin context");
622 if (NULL == plugin) {
623 push_adaptor_error("Invalid argument");
627 if (NULL != plugin->handle) {
628 push_adaptor_plugin_context_h plugin_context = NULL;
631 plugin->handle->create_context(&plugin_context, push_app_id);
632 plugin_req_exit_void();
634 if (NULL != plugin_context) {
635 plugin_context->plugin_uri = strdup(plugin->handle->plugin_uri);
636 plugin_context->state = PUSH_ADAPTOR_STATE_DISCONNECTED;
638 return plugin_context;
640 push_adaptor_error("Plugin handle is null");
647 * @brief Destroys plugin context
649 * @param[in] plugin specifies push adaptor plugin handle
650 * @param[in] context specifies push adaptor plugin context handle
653 void push_adaptor_destroy_plugin_context(push_adaptor_plugin_h plugin,
654 push_adaptor_plugin_context_h plugin_context)
656 push_adaptor_warning("Destroy plugin context");
658 if ((NULL == plugin) || (NULL == plugin_context)) {
659 push_adaptor_error("Invalid argument");
663 if (NULL != plugin->handle) {
665 plugin->handle->destroy_context(plugin_context);
666 plugin_req_exit_void();
668 push_adaptor_error("Plugin handle is null");
672 /* //////////////////////////////////////////////////////
673 // Get plugin by plugin name
674 ////////////////////////////////////////////////////// */
677 * @brief Gets plugin with specified unique name
679 * @param[in] adaptor specifies push adaptor handle
680 * @param[in] plugin_name specifies plugin name to be searched for
681 * @return push_adaptor_plugin_h on success, otherwise NULL value
683 push_adaptor_plugin_h push_adaptor_get_plugin_by_name(push_adaptor_h adaptor,
684 const char *plugin_name)
686 push_adaptor_warning("Get plugin by name: %s", plugin_name);
688 if ((NULL == adaptor) || (NULL == plugin_name)) {
689 push_adaptor_error("Invalid argument");
693 push_adaptor_plugin_h plugin = NULL;
694 g_mutex_lock(&adaptor->plugins_mutex);
695 int count = g_list_length(adaptor->plugins);
697 for (i = 0; i < count; i++) {
698 push_adaptor_plugin_h temp_plugin = g_list_nth_data(adaptor->plugins, i);
699 if (NULL != temp_plugin) {
700 if (0 == strcmp(temp_plugin->handle->plugin_uri, plugin_name)) {
701 push_adaptor_plugin_ref(temp_plugin);
702 plugin = temp_plugin;
703 push_adaptor_debug("Plugin is found by name");
708 g_mutex_unlock(&adaptor->plugins_mutex);
711 push_adaptor_debug("Plugin is not found by name");
716 /* //////////////////////////////////////////////////////
717 // Plugin load / unload / get plugin list
718 ////////////////////////////////////////////////////// */
721 * @brief Loads plugin from selected path
723 * @param[in] adaptor specifies push adaptor handle
724 * @param[in] plugin_path specifies plugin's saved path
725 * @return 0 on success, otherwise a positive error value
726 * @retval error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
728 int push_adaptor_load_plugin(push_adaptor_h adaptor,
729 const char *plugin_path)
731 push_adaptor_warning("Load plugin by plugin path: %s", plugin_path);
733 if ((NULL == adaptor) || (NULL == plugin_path)) {
734 push_adaptor_error("Invalid argument");
735 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
738 if (!adaptor->started) {
739 push_adaptor_error("Push adaptor is not started");
740 return PUSH_ADAPTOR_ERROR_START;
743 push_adaptor_plugin_h plugin = push_adaptor_create_plugin(plugin_path);
744 if (NULL == plugin) {
745 push_adaptor_error("Could not load plugin %s", plugin_path);
746 return PUSH_ADAPTOR_ERROR_CREATE;
749 plugin->adaptor = adaptor;
750 push_adaptor_plugin_ref(plugin);
752 g_mutex_lock(&adaptor->plugins_mutex);
753 adaptor->plugins = g_list_append(adaptor->plugins, plugin);
754 g_mutex_unlock(&adaptor->plugins_mutex);
756 return PUSH_ADAPTOR_ERROR_NONE;
760 * @brief Unloads selected plugin
762 * @param[in] adaptor specifies push adaptor handle
763 * @param[in] plugin specifies push adaptor plugin handle
764 * @return 0 on success, otherwise a positive error value
765 * @retval error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
767 int push_adaptor_unload_plugin(push_adaptor_h adaptor,
768 push_adaptor_plugin_h plugin)
770 push_adaptor_warning("Unload plugin");
772 if ((NULL == adaptor) || (NULL == plugin)) {
773 push_adaptor_error("Invalid argument");
774 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
777 if (!adaptor->started) {
778 push_adaptor_error("Push adaptor is not started");
779 return PUSH_ADAPTOR_ERROR_START;
782 if (!push_adaptor_has_plugin(adaptor, plugin)) {
783 push_adaptor_error("Push adaptor has no plugin");
784 return PUSH_ADAPTOR_ERROR_NOT_FOUND;
787 plugin->adaptor = NULL;
789 g_mutex_lock(&adaptor->plugins_mutex);
790 adaptor->plugins = g_list_remove(adaptor->plugins, plugin);
791 g_mutex_unlock(&adaptor->plugins_mutex);
793 push_adaptor_plugin_unref(plugin);
795 return PUSH_ADAPTOR_ERROR_NONE;
799 * @brief Get plugin list
801 * @param[in] adaptor specifies push adaptor handle
802 * @return GList pointer on success, otherwise NULL value
804 GList *push_adaptor_get_plugins(push_adaptor_h adaptor)
806 push_adaptor_warning("Get plugin list");
808 if (NULL == adaptor) {
809 push_adaptor_error("Invalid argument");
813 GList *plugins = NULL;
815 g_mutex_lock(&adaptor->plugins_mutex);
816 int plugins_count = g_list_length(adaptor->plugins);
818 for (i = 0; i < plugins_count; i++) {
819 push_adaptor_plugin_h plugin = g_list_nth_data(adaptor->plugins, i);
820 if (NULL != plugin) {
821 push_adaptor_plugin_ref(plugin);
822 plugins = g_list_append(plugins, plugin);
825 g_mutex_unlock(&adaptor->plugins_mutex);
830 /* //////////////////////////////////////////////////////
831 // External Push Adaptor APIs
832 ////////////////////////////////////////////////////// */
835 * @brief Set server information for Push Plugin
837 * @param[in] plugin specifies Push Adaptor Plugin handle
838 * @param[in] context specifies Push Adaptor Plugin Context handle
839 * @param[in] server_info specifies server information for Push Plugin
840 * @param[out] error specifies error code
841 * @return 0 on success, otherwise a positive error value
842 * @retval error code defined in push_error_code_t - PUSH_ADAPTOR_ERROR_NONE if Successful
845 push_error_code_t push_adaptor_set_server_info(push_adaptor_plugin_h plugin,
846 push_adaptor_plugin_context_h context,
847 GHashTable *server_info,
848 push_adaptor_error_code_h *error_code)
850 if ((NULL == plugin) || (NULL == context)) {
851 push_adaptor_error("Invalid argument");
853 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT,
854 "Invalid argument (plugin or context)");
856 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
859 if (NULL == plugin->handle) {
860 push_adaptor_error("Plugin handle is null");
862 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_HANDLE,
863 "Plugin handle is null");
865 return PUSH_ADAPTOR_ERROR_INVALID_HANDLE;
868 /* *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_NONE, */
869 /* "Push adaptor error none"); */
870 push_error_code_t ret;
872 ret = plugin->handle->set_server_info(context, server_info);
873 plugin_req_exit(ret, plugin, error_code);
879 * @brief Connects to push service with Push App ID handed over when creates plugin context
881 * @param[in] plugin specifies push adaptor plugin handle
882 * @param[in] context specifies push adaptor plugin context handle
883 * @param[out] error specifies error code
884 * @return 0 on success, otherwise a positive error value
885 * @retval error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
887 push_error_code_t push_adaptor_connect(push_adaptor_plugin_h plugin,
888 push_adaptor_plugin_context_h context,
889 push_adaptor_error_code_h *error_code)
891 push_adaptor_warning("Connect to push adaptor");
893 if ((NULL == plugin) || (NULL == context)) {
894 push_adaptor_error("Invalid argument");
896 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT,
897 "Invalid argument (plugin or context)");
899 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
902 if (NULL == plugin->handle) {
903 push_adaptor_error("Plugin handle is null");
905 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_HANDLE,
906 "Plugin handle is null");
908 return PUSH_ADAPTOR_ERROR_INVALID_HANDLE;
911 /* *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_NONE, */
912 /* "Push adaptor error none"); */
914 push_error_code_t ret;
916 ret = plugin->handle->connect(context);
917 plugin_req_exit(ret, plugin, error_code);
923 * @brief Disconnects from push service with Push App ID handed over when creates plugin context
925 * @param[in] plugin specifies push adaptor plugin handle
926 * @param[in] context specifies push adaptor plugin context handle
927 * @param[out] error specifies error code
928 * @return 0 on success, otherwise a positive error value
929 * @retval error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
931 push_error_code_t push_adaptor_disconnect(push_adaptor_plugin_h plugin,
932 push_adaptor_plugin_context_h context,
933 push_adaptor_error_code_h *error_code)
935 push_adaptor_warning("Disconnect from push adaptor");
937 if ((NULL == plugin) || (NULL == context)) {
938 push_adaptor_error("Invalid argument");
940 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT,
941 "Invalid argument (plugin or context)");
943 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
946 if (NULL == plugin->handle) {
947 push_adaptor_error("Plugin handle is null");
949 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_HANDLE,
950 "Plugin handle is null");
952 return PUSH_ADAPTOR_ERROR_INVALID_HANDLE;
955 /* *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_NONE, */
956 /* "Push adaptor error none"); */
958 push_error_code_t ret;
960 ret = plugin->handle->disconnect(context);
961 plugin_req_exit(ret, plugin, error_code);
967 push_error_code_t push_adaptor_is_connected(push_adaptor_plugin_h plugin,
968 push_adaptor_plugin_context_h context,
971 push_adaptor_info("Check push connection");
973 if ((NULL == context) || (NULL == is_connected)) {
974 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
977 *is_connected = context->state;
979 return PUSH_ADAPTOR_ERROR_NONE;
983 * @brief Asynchronous request to get unread notifications
985 * @param[in] plugin specifies push adaptor plugin handle
986 * @param[in] context specifies push adaptor plugin context handle
987 * @param[out] error specifies error code
988 * @return 0 on success, otherwise a positive error value
989 * @retval error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
991 push_error_code_t push_adaptor_request_unread_notification(push_adaptor_plugin_h plugin,
992 push_adaptor_plugin_context_h context,
993 push_adaptor_error_code_h *error_code)
995 push_adaptor_warning("Request unread notification");
997 if ((NULL == plugin) || (NULL == context)) {
998 push_adaptor_error("Invalid argument");
1000 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT,
1001 "Invalid argument (plugin or context)");
1003 return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
1006 if (NULL == plugin->handle) {
1007 push_adaptor_error("Plugin handle is null");
1009 *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_HANDLE,
1010 "Plugin handle is null");
1012 return PUSH_ADAPTOR_ERROR_INVALID_HANDLE;
1015 /* *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_NONE, */
1016 /* "Push adaptor error none"); */
1018 push_error_code_t ret;
1020 ret = plugin->handle->request_unread_notification(context);
1021 plugin_req_exit(ret, plugin, error_code);