Fixed svace issue
[platform/core/convergence/service-adaptor.git] / adaptor / contact-adaptor / contact-adaptor.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <dirent.h>
21 #include <dlfcn.h>
22 #include <glib.h>
23
24 #include "contact-adaptor.h"
25 #include "contact-adaptor-log.h"
26
27 /**
28  * Contact adaptor plugin
29  */
30 typedef struct contact_adaptor_plugin_s {
31         contact_adaptor_h                       adaptor;                /* Adaptor */
32         char                                    *path;                  /* Plugin library path */
33         contact_adaptor_plugin_handle_h         handle;                 /* Plugin handle */
34         void                                    *dl_handle;             /* Plugin library handle */
35         int                                     ref_counter;            /* Plugin reference counter */
36         GMutex                                  ref_counter_mutex;      /* Plugin reference counter mutex */
37         contact_adaptor_plugin_listener_h       plugin_listener;        /* Plugin callback listener */
38         GMutex                                  plugin_listener_mutex;  /* Plugin callback listener mutex */
39 } contact_adaptor_plugin_t;
40
41 /**
42  * Contact adaptor
43  */
44 typedef struct contact_adaptor_s {
45         GMutex  contact_adaptor_mutex;          /* Adaptor mutex */
46         int     started;                        /* Started flag */
47         char    *plugins_dir;                   /* Plugins directory path */
48         GList   *plugins;                       /* List of loaded plugins */
49         GMutex  plugins_mutex;                  /* Plugin list mutex */
50         GList   *adaptor_listeners;             /* List of vservice channel listener (for now not effective) */
51         GMutex  adaptor_listeners_mutex;        /* Listener list mutex */
52 } contact_adaptor_t;
53
54 /**
55  * Creates plugin
56  */
57 static contact_adaptor_plugin_h contact_adaptor_create_plugin(const char *plugin_path);
58
59 /**
60  * Destroys plugin and deletes all resources associated with it
61  */
62 static void contact_adaptor_destroy_plugin(contact_adaptor_plugin_h plugin);
63
64 /**
65  * Loads plugins from selected directory
66  */
67 static int contact_adaptor_load_plugins_from_directory(contact_adaptor_h adaptor,
68                                                 const char *dir_path);
69
70 /**
71  * Checks if plugin is loaded by selected plugin adaptor
72  */
73 static int contact_adaptor_has_plugin(contact_adaptor_h adaptor,
74                                                 contact_adaptor_plugin_h plugin);
75
76 /**
77  * Increases adaptor's plugin references counter
78  */
79 static void contact_adaptor_plugin_ref(contact_adaptor_plugin_h);
80
81 /**
82  * Decreases adaptor's plugin references counter
83  */
84 static void contact_adaptor_plugin_unref(contact_adaptor_plugin_h);
85
86 /**
87  * On message received callback for service adaptor
88  */
89 contact_adaptor_service_on_message_received_cb _service_adaptor_on_message_received = NULL;
90
91 /**
92  * Callback on message received from plugin
93  */
94 void
95 contact_adaptor_on_message_received(void *user_data)
96 {
97         if (NULL != _service_adaptor_on_message_received) {
98                 _service_adaptor_on_message_received(user_data);
99         }
100 }
101
102 /* /////////////////////////////////////////////////////////////
103    // Plugin create / destroy / ref. count / get plugin name
104    ///////////////////////////////////////////////////////////// */
105
106 /**
107 * Creates plugin
108 */
109 static contact_adaptor_plugin_h contact_adaptor_create_plugin(const char *plugin_path)
110 {
111         contact_adaptor_debug("Create plugin");
112
113         if (NULL == plugin_path) {
114                 contact_adaptor_error("Invalid argument");
115                 return NULL;
116         }
117
118         void *dl_handle = dlopen(plugin_path, RTLD_LAZY);
119         if (NULL == dl_handle) {
120                 contact_adaptor_error("Could not load plugin %s: %s", plugin_path, dlerror());
121                 return NULL;
122         }
123
124         contact_adaptor_plugin_handle_h (*get_adaptee_handle)(void) = NULL;
125
126         get_adaptee_handle = (contact_adaptor_plugin_handle_h (*)(void))(dlsym(dl_handle, "create_plugin_handle"));
127         if (NULL == get_adaptee_handle) {
128                 dlclose(dl_handle);
129                 contact_adaptor_error("Could not get function pointer to create_plugin_handle");
130                 return NULL;
131         }
132
133         plugin_req_enter();
134         contact_adaptor_plugin_handle_h handle = get_adaptee_handle();
135         plugin_req_exit_void();
136
137         if (NULL == handle) {
138                 dlclose(dl_handle);
139                 contact_adaptor_error("Could not get adaptee handle");
140                 return NULL;
141         }
142
143         contact_adaptor_plugin_h plugin = (contact_adaptor_plugin_h) calloc(1, sizeof(contact_adaptor_plugin_t));
144         if (NULL == plugin) {
145                 dlclose(dl_handle);
146                 contact_adaptor_error("Could not create plugin object");
147                 return NULL;
148         }
149
150         contact_adaptor_plugin_listener_h listener =
151                 (contact_adaptor_plugin_listener_h) calloc(1, sizeof(contact_adaptor_plugin_listener_t));
152         if (NULL == listener) {
153                 free(plugin);
154                 dlclose(dl_handle);
155                 contact_adaptor_error("Could not create listener object");
156                 return NULL;
157         }
158
159         plugin->path = g_strdup(plugin_path);
160         plugin->handle = handle;
161         plugin->dl_handle = dl_handle;
162         plugin->ref_counter = 0;
163
164         g_mutex_init(&plugin->ref_counter_mutex);
165         g_mutex_init(&plugin->plugin_listener_mutex);
166
167         listener->_on_message_received  = contact_adaptor_on_message_received;
168
169         plugin_req_enter();
170         plugin->handle->set_listener(listener);
171         plugin_req_exit_void();
172
173         g_mutex_lock(&plugin->plugin_listener_mutex);
174         plugin->plugin_listener = listener;
175         g_mutex_unlock(&plugin->plugin_listener_mutex);
176
177         return plugin;
178 }
179
180 /**
181 * Destroys plugin and deletes all resources associated with it
182 */
183 static void contact_adaptor_destroy_plugin(contact_adaptor_plugin_h plugin)
184 {
185         contact_adaptor_debug("Destroy plugin");
186
187         if (NULL == plugin) {
188                 contact_adaptor_error("Invalid argument");
189                 return;
190         }
191
192         if (NULL != plugin->handle) {
193                 plugin->handle->destroy_handle(plugin->handle);
194
195                 g_mutex_lock(&plugin->plugin_listener_mutex);
196                 plugin_req_enter();
197                 plugin->handle->unset_listener();
198                 plugin_req_exit_void();
199                 g_mutex_unlock(&plugin->plugin_listener_mutex);
200
201                 plugin->handle = NULL;
202         }
203
204         if (NULL != plugin->dl_handle) {
205                 dlclose(plugin->dl_handle);
206                 plugin->dl_handle = NULL;
207         }
208
209         free(plugin->path);
210         plugin->path = NULL;
211
212         free(plugin);
213 }
214
215 /**
216 * Loads plugins from selected directory
217 */
218 static int contact_adaptor_load_plugins_from_directory(contact_adaptor_h adaptor,
219                                                 const char *dir_path)
220 {
221         contact_adaptor_debug("Load plugins from directory");
222
223         char *plugin_path = NULL;
224         DIR *dir = NULL;
225         struct dirent dir_entry, *result = NULL;
226
227         if ((NULL == adaptor) || (NULL == dir_path)) {
228                 contact_adaptor_error("Invalid argument");
229                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
230         }
231
232         dir = opendir(dir_path);
233         if (NULL == dir) {
234                 contact_adaptor_error("Could not open dir path (%s)", dir_path);
235                 return CONTACT_ADAPTOR_ERROR_NOT_FOUND;
236         }
237
238         int ret = CONTACT_ADAPTOR_ERROR_NONE;
239         while (0 == (readdir_r(dir, &dir_entry, &result))) {
240
241                 if (NULL == result) {
242                         contact_adaptor_error("Could not open directory %s", plugin_path);
243                         break;
244                 }
245
246                 if (dir_entry.d_type & DT_DIR) {
247                         continue;
248                 }
249
250                 plugin_path = g_strconcat(dir_path, "/", dir_entry.d_name, NULL);
251                 contact_adaptor_plugin_h plugin = contact_adaptor_create_plugin(plugin_path);
252
253                 if (NULL != plugin) {
254                         contact_adaptor_debug("Loaded plugin: %s", plugin_path);
255                         plugin->adaptor = adaptor;
256                         contact_adaptor_plugin_ref(plugin);
257                         g_mutex_lock(&adaptor->plugins_mutex);
258                         adaptor->plugins = g_list_append(adaptor->plugins, plugin);
259                         g_mutex_unlock(&adaptor->plugins_mutex);
260                 } else {
261                         contact_adaptor_error("Could not load plugin %s", plugin_path);
262                 }
263
264                 free(plugin_path);
265                 plugin_path = NULL;
266         }
267
268         contact_adaptor_debug("End load plugins from directory");
269         closedir(dir);
270         return ret;
271 }
272
273 /**
274 * Checks if plugin is loaded by selected plugin adaptor
275 */
276 static int contact_adaptor_has_plugin(contact_adaptor_h adaptor,
277                                                 contact_adaptor_plugin_h plugin)
278 {
279         contact_adaptor_debug("Find plugin in plugin list");
280
281         if ((NULL == adaptor) || (NULL == plugin)) {
282                 contact_adaptor_error("Invalid argument");
283                 return 0;
284         }
285
286         int result = 0;
287
288         g_mutex_lock(&adaptor->plugins_mutex);
289         if (NULL != g_list_find(adaptor->plugins, plugin)) {
290                 result = 1;
291         }
292         g_mutex_unlock(&adaptor->plugins_mutex);
293
294         return result;
295 }
296
297 /**
298 * Increases adaptor's plugin references counter
299 */
300 static void contact_adaptor_plugin_ref(contact_adaptor_plugin_h plugin)
301 {
302         contact_adaptor_debug("Increase plugin reference count");
303
304         if (NULL == plugin) {
305                 contact_adaptor_error("Invalid argument");
306                 return;
307         }
308
309         g_mutex_lock(&plugin->ref_counter_mutex);
310         plugin->ref_counter = plugin->ref_counter + 1;
311         contact_adaptor_info("ref_counter: %d", plugin->ref_counter);
312         g_mutex_unlock(&plugin->ref_counter_mutex);
313 }
314
315 /**
316 * Decreases adaptor's plugin references counter
317 */
318 static void contact_adaptor_plugin_unref(contact_adaptor_plugin_h plugin)
319 {
320         contact_adaptor_debug("Decrease plugin reference count");
321
322         if (NULL == plugin) {
323                 contact_adaptor_error("Invalid argument");
324                 return ;
325         }
326
327         int should_destroy = 0;
328
329         g_mutex_lock(&plugin->ref_counter_mutex);
330         plugin->ref_counter = plugin->ref_counter - 1;
331         contact_adaptor_info("ref_counter: %d", plugin->ref_counter);
332         if (0 >= plugin->ref_counter) {
333                 should_destroy = 1;
334         }
335         g_mutex_unlock(&plugin->ref_counter_mutex);
336
337         if (should_destroy) {
338                 contact_adaptor_debug("Plugin is being destroyed");
339                 contact_adaptor_destroy_plugin(plugin);
340         }
341 }
342
343 /* //////////////////////////////////////////////////////
344    // Mandatory: External adaptor management function
345    ////////////////////////////////////////////////////// */
346
347 /**
348 * @brief Creates Contact Adaptor.
349 *
350 * @param[in]    plugin_dir      specifies directory path where plugins are stored
351 * @return       contact_adaptor_h on success, otherwise NULL value
352 */
353 contact_adaptor_h contact_adaptor_create(const char *plugins_dir)
354 {
355         contact_adaptor_warning("Create contact adaptor");
356
357         contact_adaptor_h contact_adaptor = (contact_adaptor_h) malloc(sizeof(contact_adaptor_t));
358         if (NULL == contact_adaptor) {
359                 return NULL;
360         }
361
362         contact_adaptor->started = 0;
363         contact_adaptor->plugins_dir = strdup(plugins_dir);
364
365         g_mutex_init(&contact_adaptor->contact_adaptor_mutex);
366         g_mutex_init(&contact_adaptor->plugins_mutex);
367         g_mutex_init(&contact_adaptor->adaptor_listeners_mutex);
368
369         g_mutex_lock(&contact_adaptor->adaptor_listeners_mutex);
370         contact_adaptor->adaptor_listeners = NULL;
371         g_mutex_unlock(&contact_adaptor->adaptor_listeners_mutex);
372
373         g_mutex_lock(&contact_adaptor->plugins_mutex);
374         contact_adaptor->plugins = NULL;
375         g_mutex_unlock(&contact_adaptor->plugins_mutex);
376
377         return contact_adaptor;
378 }
379
380 /**
381 * @brief Destroys contact adaptor. If contact adaptor was started it is stopped first.
382 *
383 * @param[in]    adaptor         specifies contact adaptor handle to be destroyed
384 * @return       void
385 */
386 void contact_adaptor_destroy(contact_adaptor_h adaptor)
387 {
388         contact_adaptor_warning("Destroy contact adaptor");
389
390         if (NULL == adaptor) {
391                 contact_adaptor_error("Invalid argument");
392                 return ;
393         }
394
395         g_mutex_lock(&adaptor->contact_adaptor_mutex);
396         if (adaptor->started) {
397                 contact_adaptor_error("Contact adaptor is running. Forcing stop before destroy");
398                 contact_adaptor_stop(adaptor);
399         }
400
401         g_mutex_lock(&adaptor->plugins_mutex);
402         if (NULL != adaptor->plugins) {
403                 g_list_free_full(adaptor->plugins, (GDestroyNotify) contact_adaptor_plugin_unref);
404                 adaptor->plugins = NULL;
405         }
406         g_mutex_unlock(&adaptor->plugins_mutex);
407
408         g_mutex_lock(&adaptor->adaptor_listeners_mutex);
409         if (NULL != adaptor->adaptor_listeners) {
410                 g_list_free(adaptor->adaptor_listeners);
411                 adaptor->adaptor_listeners = NULL;
412         }
413         g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
414
415         _service_adaptor_on_message_received    = NULL;
416
417         free(adaptor->plugins_dir);
418         adaptor->plugins_dir = NULL;
419
420         g_mutex_unlock(&adaptor->contact_adaptor_mutex);
421
422         free(adaptor);
423 }
424
425 /**
426 * @brief Starts contact adaptor and loads plugins that are found in contact_adaptor_create().
427 *
428 * @param[in]    adaptor         specifies contact adaptor handle
429 * @return       0 on success, otherwise a positive error value
430 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
431 */
432 int contact_adaptor_start(contact_adaptor_h adaptor)
433 {
434         contact_adaptor_warning("Start contact adaptor");
435
436         if (NULL == adaptor) {
437                 contact_adaptor_error("Invalid argument");
438                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
439         }
440
441         g_mutex_lock(&adaptor->contact_adaptor_mutex);
442         int result = CONTACT_ADAPTOR_ERROR_NONE;
443         if (adaptor->started) {
444                 contact_adaptor_error("Contact adaptor is already started");
445                 result = CONTACT_ADAPTOR_ERROR_START;
446         } else {
447                 adaptor->started = 1;
448                 result = contact_adaptor_load_plugins_from_directory(adaptor, adaptor->plugins_dir);
449                 if (CONTACT_ADAPTOR_ERROR_NONE != result) {
450                         adaptor->started = 0;
451                         contact_adaptor_error("Could not load plugins from directory");
452                 } else {
453                         contact_adaptor_debug("Contact adaptor started successfully");
454                 }
455         }
456         g_mutex_unlock(&adaptor->contact_adaptor_mutex);
457
458         return result;
459 }
460
461 /**
462 * @brief Stops contact adaptor.
463 *
464 * @param[in]    adaptor         specifies contact adaptor handle
465 * @return       0 on success, otherwise a positive error value
466 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
467 */
468 int contact_adaptor_stop(contact_adaptor_h adaptor)
469 {
470         contact_adaptor_warning("Stop contact adaptor");
471
472         if (NULL == adaptor) {
473                 contact_adaptor_error("Invalid argument");
474                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
475         }
476
477         g_mutex_lock(&adaptor->contact_adaptor_mutex);
478         int result = CONTACT_ADAPTOR_ERROR_NONE;
479         if (!adaptor->started) {
480                 result = CONTACT_ADAPTOR_ERROR_START;
481         } else {
482                 if (NULL != adaptor->plugins) {
483                         g_mutex_lock(&adaptor->plugins_mutex);
484                         g_list_free_full(adaptor->plugins, (GDestroyNotify) contact_adaptor_plugin_unref);
485                         adaptor->plugins = NULL;
486                         g_mutex_unlock(&adaptor->plugins_mutex);
487                 }
488                 adaptor->started = 0;
489                 contact_adaptor_debug("Contact adaptor stopped");
490         }
491
492         g_mutex_unlock(&adaptor->contact_adaptor_mutex);
493         return result;
494 }
495
496 /**
497 * @brief Registers plugin state listener
498 *
499 * @param[in]    adaptor         specifies contact adaptor handle
500 * @param[in]    listener        specifies contact adaptor listener handle
501 * @return       0 on success, otherwise a positive error value
502 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
503 */
504 int contact_adaptor_register_listener(contact_adaptor_h adaptor,
505                                                 contact_adaptor_listener_h listener)
506 {
507         contact_adaptor_warning("Register contact adaptor listener");
508
509         if ((NULL == adaptor) || (NULL == listener)) {
510                 contact_adaptor_error("Invalid argument");
511                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
512         }
513
514         g_mutex_lock(&adaptor->adaptor_listeners_mutex);
515
516         adaptor->adaptor_listeners = g_list_append(adaptor->adaptor_listeners, listener);
517
518         g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
519
520         _service_adaptor_on_message_received =
521                         (contact_adaptor_service_on_message_received_cb) listener->_on_message_received;
522
523         return CONTACT_ADAPTOR_ERROR_NONE;
524 }
525
526 /**
527 * @brief Unregisters plugin state listener
528 *
529 * @param[in]    adaptor         specifies contact adaptor handle
530 * @param[in]    listener        specifies contact adaptor listener handle
531 * @return       0 on success, otherwise a positive error value
532 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
533 */
534 int contact_adaptor_unregister_listener(contact_adaptor_h adaptor,
535                                                 contact_adaptor_listener_h listener)
536 {
537         contact_adaptor_warning("Deregister contact adaptor listener");
538
539         if (NULL == adaptor)  {
540                 contact_adaptor_error("Invalid argument (adaptor)");
541                 if (NULL != listener) {
542                         free(listener);
543                         listener = NULL;
544                 }
545                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
546         }
547         if (NULL == listener) {
548                 contact_adaptor_error("Invalid argument (listener)");
549                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
550         }
551
552         g_mutex_lock(&adaptor->adaptor_listeners_mutex);
553
554         if (NULL == g_list_find(adaptor->adaptor_listeners, listener)) {
555                 g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
556                 contact_adaptor_error("Could not find listener");
557                 free(listener);
558                 return CONTACT_ADAPTOR_ERROR_NOT_FOUND;
559         }
560
561         adaptor->adaptor_listeners = g_list_remove(adaptor->adaptor_listeners, listener);
562         free(listener);
563
564         g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
565
566         _service_adaptor_on_message_received    = NULL;
567
568         return CONTACT_ADAPTOR_ERROR_NONE;
569 }
570
571 /* //////////////////////////////////////////////////////
572    // Plugin context create / destroy
573    ////////////////////////////////////////////////////// */
574
575 /**
576 * @brief Creates plugin context
577 *
578 * @param[in]    plugin          specifies contact adaptor plugin handle
579 * @param[in]    duid            specifies device unique ID
580 * @param[in]    access_token    specifies access token issued by Auth Adaptor
581 * @return       contact_adaptor_plugin_context_h on success, otherwise NULL value
582 */
583 contact_adaptor_plugin_context_h contact_adaptor_create_plugin_context(contact_adaptor_plugin_h plugin,
584                                                 const char *duid,
585                                                 const char *access_token,
586                                                 const char *service_name)
587 {
588         contact_adaptor_warning("Create plugin context");
589
590         if ((NULL == plugin) || (NULL == duid) || (NULL == access_token) || (NULL == service_name)) {
591                 contact_adaptor_error("Invalid argument: %s, %s", duid, access_token);
592                 return NULL;
593         }
594
595         if (NULL != plugin->handle) {
596                 contact_adaptor_plugin_context_h plugin_context = NULL;
597
598                 plugin_req_enter();
599                 plugin->handle->create_context(&plugin_context, duid, access_token);
600                 plugin_req_exit_void();
601
602                 plugin_context->plugin_uri = strdup(plugin->handle->plugin_uri);
603                 plugin_context->service_name = strdup(service_name);
604                 return plugin_context;
605         } else {
606                 contact_adaptor_error("Plugin handle is null");
607         }
608
609         return NULL;
610 }
611
612 /**
613 * @brief Destroys plugin context.
614 *
615 * @param[in]    plugin          specifies contact adaptor plugin handle
616 * @param[in]    context         specifies contact adaptor plugin context handle
617 * @return       void
618 */
619 void contact_adaptor_destroy_plugin_context(contact_adaptor_plugin_h plugin,
620                                                 contact_adaptor_plugin_context_h plugin_context)
621 {
622         contact_adaptor_warning("Destroy plugin context");
623
624         if ((NULL == plugin) || (NULL == plugin_context)) {
625                 contact_adaptor_error("Invalid argument");
626                 return;
627         }
628
629         if (NULL != plugin->handle) {
630                 free(plugin_context->plugin_uri);
631                 plugin_context->plugin_uri = NULL;
632                 free(plugin_context->service_name);
633                 plugin_context->service_name = NULL;
634
635                 plugin_req_enter();
636                 plugin->handle->destroy_context(plugin_context);
637                 plugin_req_exit_void();
638         } else {
639                 contact_adaptor_error("Plugin handle is null");
640         }
641 }
642
643 /* //////////////////////////////////////////////////////
644    // Get plugin by plugin name
645    ////////////////////////////////////////////////////// */
646
647 /**
648 * @brief Gets plugin with specified unique name
649 *
650 * @param[in]    adaptor         specifies contact adaptor handle
651 * @param[in]    plugin_name     specifies plugin name to be searched for
652 * @return       contact_adaptor_plugin_h on success, otherwise NULL value
653 */
654 contact_adaptor_plugin_h contact_adaptor_get_plugin_by_name(contact_adaptor_h adaptor,
655                                                 const char *plugin_name)
656 {
657         contact_adaptor_warning("Get plugin by name: %s", plugin_name);
658
659         if ((NULL == adaptor) || (NULL == plugin_name)) {
660                 contact_adaptor_error("Invalid argument");
661                 return NULL;
662         }
663
664         contact_adaptor_plugin_h plugin = NULL;
665         g_mutex_lock(&adaptor->plugins_mutex);
666         int count = g_list_length(adaptor->plugins);
667         int i = 0;
668         for (i = 0; i < count; i++) {
669                 contact_adaptor_plugin_h temp_plugin = g_list_nth_data(adaptor->plugins, i);
670                 if (NULL != temp_plugin) {
671                         if (0 == strcmp(temp_plugin->handle->plugin_uri, plugin_name)) {
672                                 contact_adaptor_plugin_ref(temp_plugin);
673                                 plugin = temp_plugin;
674                                 contact_adaptor_debug("Plugin is found by name");
675                                 g_mutex_unlock(&adaptor->plugins_mutex);
676                                 return plugin;
677                         }
678                 }
679         }
680         g_mutex_unlock(&adaptor->plugins_mutex);
681
682         if (NULL == plugin) {
683                 contact_adaptor_debug("Plugin is not found by name");
684         }
685
686         return plugin;
687 }
688
689 /* //////////////////////////////////////////////////////
690    // Plugin load / unload / get plugin list
691    ////////////////////////////////////////////////////// */
692
693 /**
694 * @brief Loads plugin from selected path
695 *
696 * @param[in]    adaptor         specifies contact adaptor handle
697 * @param[in]    plugin_path     specifies plugin's saved path
698 * @return       0 on success, otherwise a positive error value
699 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
700 */
701 int contact_adaptor_load_plugin(contact_adaptor_h adaptor,
702                                                 const char *plugin_path)
703 {
704         contact_adaptor_warning("Load plugin by plugin path: %s", plugin_path);
705
706         if ((NULL == adaptor) || (NULL == plugin_path)) {
707                 contact_adaptor_error("Invalid argument");
708                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
709         }
710
711         if (!adaptor->started) {
712                 contact_adaptor_error("Contact adaptor is not started");
713                 return CONTACT_ADAPTOR_ERROR_START;
714         }
715
716         contact_adaptor_plugin_h plugin = contact_adaptor_create_plugin(plugin_path);
717         if (NULL == plugin) {
718                 contact_adaptor_error("Could not load plugin %s", plugin_path);
719                 return CONTACT_ADAPTOR_ERROR_CREATE;
720         }
721
722         plugin->adaptor = adaptor;
723         contact_adaptor_plugin_ref(plugin);
724
725         g_mutex_lock(&adaptor->plugins_mutex);
726         adaptor->plugins = g_list_append(adaptor->plugins, plugin);
727         g_mutex_unlock(&adaptor->plugins_mutex);
728
729         return CONTACT_ADAPTOR_ERROR_NONE;
730 }
731
732 /**
733 * @brief Unloads selected plugin
734 *
735 * @param[in]    adaptor         specifies contact adaptor handle
736 * @param[in]    plugin          specifies contact adaptor plugin handle
737 * @return       0 on success, otherwise a positive error value
738 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
739 */
740 int contact_adaptor_unload_plugin(contact_adaptor_h adaptor,
741                                                 contact_adaptor_plugin_h plugin)
742 {
743         contact_adaptor_warning("Unload plugin");
744
745         if ((NULL == adaptor) || (NULL == plugin)) {
746                 contact_adaptor_error("Invalid argument");
747                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
748         }
749
750         if (!adaptor->started) {
751                 contact_adaptor_error("Contact adaptor is not started");
752                 return CONTACT_ADAPTOR_ERROR_START;
753         }
754
755         if (!contact_adaptor_has_plugin(adaptor, plugin)) {
756                 contact_adaptor_error("Contact adaptor has no plugin");
757                 return CONTACT_ADAPTOR_ERROR_NOT_FOUND;
758         }
759
760         plugin->adaptor = NULL;
761
762         g_mutex_lock(&adaptor->plugins_mutex);
763         adaptor->plugins = g_list_remove(adaptor->plugins, plugin);
764         g_mutex_unlock(&adaptor->plugins_mutex);
765
766         contact_adaptor_plugin_unref(plugin);
767
768         return CONTACT_ADAPTOR_ERROR_NONE;
769 }
770
771 /**
772 * @brief Get plugin list of contact adaptor handle has
773 *
774 * @param[in]    adaptor         specifies contact adaptor handle
775 * @return       GList pointer on success, otherwise NULL value
776 */
777 GList *contact_adaptor_get_plugins(contact_adaptor_h adaptor)
778 {
779         contact_adaptor_warning("Get plugin list");
780
781         if (NULL == adaptor) {
782                 contact_adaptor_error("Invalid argument");
783                 return NULL;
784         }
785
786         GList *plugins = NULL;
787
788         g_mutex_lock(&adaptor->plugins_mutex);
789         int plugins_count = g_list_length(adaptor->plugins);
790         int i;
791         for (i = 0; i < plugins_count; i++) {
792                 contact_adaptor_plugin_h plugin = g_list_nth_data(adaptor->plugins, i);
793                 if (NULL != plugin) {
794                         contact_adaptor_plugin_ref(plugin);
795                         plugins = g_list_append(plugins, plugin);
796                 }
797         }
798         g_mutex_unlock(&adaptor->plugins_mutex);
799
800         return plugins;
801 }
802
803 /**
804 * @brief Refresh access token was issued from auth-adaptor
805 *
806 * @param[in]    context                 specifies Contact Adaptor Plugin Context handle
807 * @param[in]    new_access_token        specifies New access token
808 * @return       contact_adaptor_error_code_h on success, otherwise NULL value
809 */
810 EXPORT_API
811 contact_error_code_t contact_adaptor_refresh_access_token(contact_adaptor_plugin_context_h context,
812                                                 const char *new_access_token)
813 {
814         if ((NULL == context) || (NULL == new_access_token) || (0 >= strlen(new_access_token))) {
815                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
816         }
817         contact_adaptor_debug("New access token : %s", new_access_token);
818
819         free(context->access_token);
820         context->access_token = NULL;
821         context->access_token = strdup(new_access_token);
822
823         return CONTACT_ADAPTOR_ERROR_NONE;
824 }
825
826 EXPORT_API
827 contact_error_code_t contact_adaptor_refresh_uid(contact_adaptor_plugin_context_h context,
828                                                 const char *new_uid)
829 {
830         if ((NULL == context) || (NULL == new_uid) || (0 >= strlen(new_uid))) {
831                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
832         }
833         contact_adaptor_debug("New uid : %s", new_uid);
834
835         free(context->duid);
836         context->duid = NULL;
837         context->duid = strdup(new_uid);
838
839         return CONTACT_ADAPTOR_ERROR_NONE;
840 }
841
842
843 /* //////////////////////////////////////////////////////
844    // Create / Destroy error code
845    ////////////////////////////////////////////////////// */
846
847 /**
848 * @brief Create error code
849 *
850 * @param[in]    code            specifies error code number
851 * @param[in]    msg             specifies error message
852 * @return       contact_adaptor_error_code_h on success, otherwise NULL value
853 */
854 contact_adaptor_error_code_h contact_adaptor_create_error_code(const int64_t code,
855                                                 const char *msg)
856 {
857         if (NULL == msg) {
858                 return NULL;
859         }
860
861         contact_adaptor_error_code_h error_code = (contact_adaptor_error_code_h) malloc(sizeof(contact_adaptor_error_code_t));
862         if (NULL == error_code) {
863                 return NULL;
864         }
865
866         error_code->code = code;
867         error_code->msg = strdup(msg);
868
869         return error_code;
870 }
871
872 /**
873 * @brief Destroy error code
874 *
875 * @param[in]    error_code      specifies error code handle
876 * @return       void
877 */
878 void contact_adaptor_destroy_error_code(contact_adaptor_error_code_h *error_code)
879 {
880         if (NULL == *error_code) {
881                 return;
882         }
883
884         if (NULL != (*error_code)->msg) {
885                 free((*error_code)->msg);
886                 (*error_code)->msg = NULL;
887         }
888
889         free(*error_code);
890         *error_code = NULL;
891 }
892
893 void __contact_adaptor_destroy_char_array(char **arr, unsigned int len)
894 {
895         if ((NULL != arr) && (0U < len)) {
896                 for (int i = 0; i < len; i++) {
897                         free(arr[i]);
898                 }
899                 free(arr);
900         }
901 }
902
903 EXPORT_API
904 void contact_adaptor_destroy_contact_req_s(contact_adaptor_contact_req_h req)
905 {
906         if (NULL != req) {
907                 if ((req->cts != NULL) && (0U < req->cts_len)) {
908                         for (int i = 0; i < req->cts_len; i++) {
909                                 if (NULL != req->cts[i]) {
910                                         free(req->cts[i]->tp);
911                                         free(req->cts[i]->id);
912                                         free(req->cts[i]->pn);
913                                         free(req->cts[i]->nm);
914                                         free(req->cts[i]->cc);
915                                 }
916                                 free(req->cts[i]);
917                         }
918                         free(req->cts);
919                 }
920                 free(req);
921         }
922 }
923
924 EXPORT_API
925 void contact_adaptor_destroy_contact_res_s(contact_adaptor_contact_res_h res)
926 {
927         if (NULL == res) {
928                 return;
929         } else if ((res->cts == NULL) || (0U == res->cts_len)) {
930                 free(res);
931                 return;
932         }
933
934         for (int i = 0; i < res->cts_len; i++) {
935                 if (NULL != res->cts[i]) {
936                         free(res->cts[i]->duid);
937                         free(res->cts[i]->id);
938                         free(res->cts[i]->msisdn);
939                         free(res->cts[i]->ty);
940                         free(res->cts[i]->cc);
941                         free(res->cts[i]->pn);
942                         free(res->cts[i]->nm);
943                         /*
944                            if ((NULL != res->cts[i]->evnt) && (0U > res->cts[i]->evnt_len)) {
945                            for (int j = 0; j < res->cts[i]->evnt_len; j++) {
946                            free(res->cts[i]->evnt[j]);
947                            }
948                            free(res->cts[i]->evnt);
949                            }
950                          */
951                         __contact_adaptor_destroy_char_array(res->cts[i]->evnt, res->cts[i]->evnt_len);
952                         /* free(res->cts[i]->img);*/
953
954                         __contact_adaptor_destroy_char_array(res->cts[i]->adrs, res->cts[i]->adrs_len);
955                         __contact_adaptor_destroy_char_array(res->cts[i]->mail, res->cts[i]->mail_len);
956                         /*
957                            if ((NULL != res->cts[i]->adrs) && (0U > res->cts[i]->adrs_len)) {
958                            for (int j = 0; j < res->cts[i]->adrs_len; j++) {
959                            free(res->cts[i]->adrs[j]);
960                            }
961                            free(res->cts[i]->adrs);
962                            }
963                            if ((NULL != res->cts[i]->mail) && (0U > res->cts[i]->mail_len)) {
964                            for (int j = 0; j < res->cts[i]->mail_len; j++) {
965                            free(res->cts[i]->mail[j]);
966                            }
967                            free(res->cts[i]->mail);
968                            }
969                          */
970                         free(res->cts[i]->org);
971                         free(res->cts[i]->prsc);
972                         free(res->cts[i]->status);
973                 }
974                 free(res->cts[i]);
975         }
976         free(res->cts);
977         free(res);
978 }
979
980 EXPORT_API
981 void contact_adaptor_destroy_profile_req_s(contact_adaptor_profile_req_h req)
982 {
983         if (NULL == req) {
984                 return;
985         }
986
987         free(req->cc);
988         free(req->pn);
989         free(req->nm);
990         __contact_adaptor_destroy_char_array(req->evnt, req->evnt_len);
991         free(req->img);
992         __contact_adaptor_destroy_char_array(req->adrs, req->adrs_len);
993         __contact_adaptor_destroy_char_array(req->mail, req->mail_len);
994         free(req->org);
995         free(req->prsc);
996         free(req->status);
997
998         free(req);
999 }
1000
1001 EXPORT_API
1002 void contact_adaptor_destroy_profile_res_s(contact_adaptor_profile_res_h res)
1003 {
1004         if (NULL == res) {
1005                 return;
1006         }
1007
1008         free(res->nm);
1009         free(res->img);
1010         free(res->prsc);
1011         free(res->status);
1012
1013         free(res);
1014 }
1015
1016 EXPORT_API
1017 void contact_adaptor_destroy_file_path_s(contact_adaptor_file_path_h path)
1018 {
1019         if (NULL == path) {
1020                 return;
1021         }
1022
1023         __contact_adaptor_destroy_char_array(path->file_paths, path->file_paths_len);
1024
1025         free(path);
1026 }
1027
1028 EXPORT_API
1029 void contact_adaptor_destroy_privacy_req_s(contact_adaptor_privacy_req_h req)
1030 {
1031         if (NULL == req) {
1032                 return;
1033         }
1034
1035         if ((NULL != req->cts) && (0U < req->cts_len)) {
1036                 for (int i = 0; i < req->cts_len; i++) {
1037                         free(req->cts[i]->cc);
1038                         free(req->cts[i]->pn);
1039                         free(req->cts[i]);
1040                 }
1041                 free(req->cts);
1042         }
1043         free(req);
1044 }
1045
1046 EXPORT_API
1047 void contact_adaptor_destroy_privacy_res_s(contact_adaptor_privacy_res_h res)
1048 {
1049         free(res);
1050 }
1051
1052 EXPORT_API
1053 void contact_adaptor_destroy_presence_info_s(contact_adaptor_presence_info_h info)
1054 {
1055         if (NULL == info) {
1056                 return;
1057         }
1058
1059         free(info->prsc);
1060         free(info->status);
1061         free(info);
1062 }
1063
1064 /* //////////////////////////////////////////////////////
1065    // Contact Adaptor External APIs
1066    ////////////////////////////////////////////////////// */
1067
1068 /**
1069 * @brief Set server information for Contact Plugin
1070 *
1071 * @param[in]    plugin          specifies Contact Adaptor Plugin handle
1072 * @param[in]    context specifies Contact Adaptor Plugin Context handle
1073 * @param[in]    server_info     specifies server information for Contact Plugin
1074 * @param[in]    request specifies optional parameter
1075 * @param[out]   error           specifies error code
1076 * @param[out]   response        specifies optional parameter
1077 * @return 0 on success, otherwise a positive error value
1078 * @retval error code defined in contact_error_code_t - CONTACT_ADAPTOR_ERROR_NONE if Successful
1079 */
1080 EXPORT_API
1081 contact_error_code_t contact_adaptor_set_server_info(contact_adaptor_plugin_h plugin,
1082                                                 contact_adaptor_plugin_context_h context,
1083                                                 GHashTable *server_info,
1084                                                 void *user_data,
1085                                                 contact_adaptor_error_code_h *error,
1086                                                 void **server_data)
1087 {
1088         if ((NULL == plugin) || (NULL == context)) {
1089                 contact_adaptor_error("Invalid argument");
1090
1091                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
1092                                                                 "Invalid argument (plugin or context)");
1093
1094                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
1095         }
1096
1097         if (NULL == plugin->handle) {
1098                 contact_adaptor_error("Plugin handle is null");
1099
1100                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
1101                                                                 "Plugin handle is null");
1102
1103                 return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
1104         }
1105
1106         contact_error_code_t ret;
1107         plugin_req_enter();
1108         ret = plugin->handle->set_server_info(context, server_info, user_data, error, server_data);
1109         plugin_req_exit(ret, plugin, error);
1110
1111         return ret;
1112 }
1113
1114 /**
1115 * @brief Resets contact information in Contact server and upload native contact information of device to
1116 * the server
1117 *
1118 * @param[in]    plugin          specifies contact adaptor plugin handle
1119 * @param[in]    context         specifies contact adaptor plugin context handle
1120 * @param[in]    request         specifies contact adaptor contact API request handle
1121 * @param[in]    user_data       specifies user side arbitrary data
1122 * @param[out]   response        specifies contact adaptor contact API response handle
1123 * @param[out]   error           specifies returned error code handle
1124 * @param[out]   server_data     specifies server side arbitrary data
1125 * @return       0 on success, otherwise a positive error value
1126 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
1127 */
1128 contact_error_code_t contact_adaptor_new_contact_list(contact_adaptor_plugin_h plugin,
1129                                                 contact_adaptor_plugin_context_h context,
1130                                                 contact_adaptor_contact_req_h request,
1131                                                 void *user_data,
1132                                                 contact_adaptor_contact_res_h *response,
1133                                                 contact_adaptor_error_code_h *error,
1134                                                 void **server_data)
1135 {
1136         contact_adaptor_warning("New contact list");
1137
1138         if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
1139                 contact_adaptor_error("Invalid argument");
1140
1141                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
1142                                                         "Invalid argument (plugin or context or request)");
1143
1144                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
1145         }
1146
1147         if (NULL == plugin->handle) {
1148                 contact_adaptor_error("Plugin handle is null");
1149
1150                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
1151                                                         "Plugin handle is null");
1152
1153                 return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
1154         }
1155
1156         contact_error_code_t ret;
1157         plugin_req_enter();
1158         ret = plugin->handle->new_contact_list(context, request, user_data, response, error, server_data);
1159         plugin_req_exit(ret, plugin, error);
1160
1161         return ret;
1162 }
1163
1164 /**
1165 * @brief Synchronized native contact information of device with contact server according to type
1166 * "type" field of each contact
1167 *
1168 * @param[in]    plugin          specifies contact adaptor plugin handle
1169 * @param[in]    context         specifies contact adaptor plugin context handle
1170 * @param[in]    request         specifies contact adaptor contact API request handle
1171 * @param[in]    user_data       specifies user side arbitrary data
1172 * @param[out]   response        specifies contact adaptor contact API response handle
1173 * @param[out]   error           specifies returned error code handle
1174 * @param[out]   server_data     specifies server side arbitrary data
1175 * @return       0 on success, otherwise a positive error value
1176 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
1177 */
1178 contact_error_code_t contact_adaptor_set_contact_list(contact_adaptor_plugin_h plugin,
1179                                                 contact_adaptor_plugin_context_h context,
1180                                                 contact_adaptor_contact_req_h request,
1181                                                 void *user_data,
1182                                                 contact_adaptor_contact_res_h *response,
1183                                                 contact_adaptor_error_code_h *error,
1184                                                 void **server_data)
1185 {
1186         contact_adaptor_warning("Set contact list");
1187
1188         if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
1189                 contact_adaptor_error("Invalid argument");
1190
1191                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
1192                                                         "Invalid argument (plugin or context or request)");
1193
1194                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
1195         }
1196
1197         if (NULL == plugin->handle) {
1198                 contact_adaptor_error("Plugin handle is null");
1199
1200                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
1201                                                         "Plugin handle is null");
1202
1203                 return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
1204         }
1205
1206         contact_error_code_t ret;
1207         plugin_req_enter();
1208         ret = plugin->handle->set_contact_list(context, request, user_data,
1209                                                 response, error, server_data);
1210         plugin_req_exit(ret, plugin, error);
1211
1212         return ret;
1213 }
1214
1215 /**
1216 * @brief Gets profile and service registration information of each contact
1217 *
1218 * @param[in]    plugin          specifies contact adaptor plugin handle
1219 * @param[in]    context         specifies contact adaptor plugin context handle
1220 * @param[in]    request         specifies contact adaptor contact API request handle
1221 * @param[in]    user_data       specifies user side arbitrary data
1222 * @param[out]   response        specifies contact adaptor contact API response handle
1223 * @param[out]   error           specifies returned error code handle
1224 * @param[out]   server_data     specifies server side arbitrary data
1225 * @return       0 on success, otherwise a positive error value
1226 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
1227 */
1228 contact_error_code_t contact_adaptor_get_contact_infos_latest(contact_adaptor_plugin_h plugin,
1229                                                 contact_adaptor_plugin_context_h context,
1230                                                 contact_adaptor_contact_req_h request,
1231                                                 void *user_data,
1232                                                 contact_adaptor_contact_res_h *response,
1233                                                 contact_adaptor_error_code_h *error,
1234                                                 void **server_data)
1235 {
1236         contact_adaptor_warning("Get contact infos latest");
1237
1238         if ((NULL == plugin) || (NULL == context)) {
1239                 contact_adaptor_error("Invalid argument");
1240
1241                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
1242                                                         "Invalid argument (plugin or context)");
1243
1244                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
1245         }
1246
1247         if (NULL == plugin->handle) {
1248                 contact_adaptor_error("Plugin handle is null");
1249
1250                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
1251                                                         "Plugin handle is null");
1252
1253                 return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
1254         }
1255
1256         contact_error_code_t ret;
1257         plugin_req_enter();
1258         ret = plugin->handle->get_contact_infos_latest(context, request, user_data,
1259                                                 response, error, server_data);
1260         plugin_req_exit(ret, plugin, error);
1261
1262         return ret;
1263 }
1264
1265 /**
1266 * @brief Gets profile and service registration information of contact that have been updated since
1267 * last update
1268 *
1269 * @param[in]    plugin          specifies contact adaptor plugin handle
1270 * @param[in]    context         specifies contact adaptor plugin context handle
1271 * @param[in]    request         specifies contact adaptor contact API request handle
1272 * @param[in]    user_data       specifies user side arbitrary data
1273 * @param[out]   response        specifies contact adaptor contact API response handle
1274 * @param[out]   error           specifies returned error code handle
1275 * @param[out]   server_data     specifies server side arbitrary data
1276 * @return       0 on success, otherwise a positive error value
1277 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
1278 */
1279 contact_error_code_t contact_adaptor_get_contact_infos_polling(contact_adaptor_plugin_h plugin,
1280                                                 contact_adaptor_plugin_context_h context,
1281                                                 contact_adaptor_contact_req_h request,
1282                                                 void *user_data,
1283                                                 contact_adaptor_contact_res_h *response,
1284                                                 contact_adaptor_error_code_h *error,
1285                                                 void **server_data)
1286 {
1287         contact_adaptor_warning("Get contact infos polling");
1288
1289         if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
1290                 contact_adaptor_error("Invalid argument");
1291
1292                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
1293                                                         "Invalid argument (plugin or context or request)");
1294
1295                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
1296         }
1297
1298         if (NULL == plugin->handle) {
1299                 contact_adaptor_error("Plugin handle is null");
1300
1301                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
1302                                                         "Plugin handle is null");
1303
1304                 return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
1305         }
1306
1307         contact_error_code_t ret;
1308         plugin_req_enter();
1309         ret = plugin->handle->get_contact_infos_polling(context, request, user_data,
1310                                                 response, error, server_data);
1311         plugin_req_exit(ret, plugin, error);
1312
1313         return ret;
1314 }
1315
1316 /**
1317 * @brief Sets or updates device's profile to server
1318 *
1319 * @param[in]    plugin          specifies contact adaptor plugin handle
1320 * @param[in]    context         specifies contact adaptor plugin context handle
1321 * @param[in]    request         specifies contact adaptor profile API request handle
1322 * @param[in]    user_data       specifies user side arbitrary data
1323 * @param[out]   response        specifies contact adaptor profile API response handle
1324 * @param[out]   error           specifies returned error code handle
1325 * @param[out]   server_data     specifies server side arbitrary data
1326 * @return       0 on success, otherwise a positive error value
1327 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
1328 */
1329 contact_error_code_t contact_adaptor_set_me_profile_with_push(contact_adaptor_plugin_h plugin,
1330                                                 contact_adaptor_plugin_context_h context,
1331                                                 contact_adaptor_profile_req_h request,
1332                                                 void *user_data,
1333                                                 contact_adaptor_profile_res_h *response,
1334                                                 contact_adaptor_error_code_h *error,
1335                                                 void **server_data)
1336 {
1337         contact_adaptor_warning("Set me profile with push");
1338
1339         if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
1340                 contact_adaptor_error("Invalid argument");
1341
1342                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
1343                                                         "Invalid argument (plugin or context or request)");
1344
1345                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
1346         }
1347
1348         if (NULL == plugin->handle) {
1349                 contact_adaptor_error("Plugin handle is null");
1350
1351                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
1352                                                         "Plugin handle is null");
1353
1354                 return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
1355         }
1356
1357         contact_error_code_t ret;
1358         plugin_req_enter();
1359         ret = plugin->handle->set_me_profile_with_push(context, request, user_data,
1360                                                 response, error, server_data);
1361         plugin_req_exit(ret, plugin, error);
1362
1363         return ret;
1364 }
1365
1366 /**
1367 * @brief Gets the profile information of a contact which is correspondent with country code and phone number
1368 *
1369 * @param[in]    plugin          specifies contact adaptor plugin handle
1370 * @param[in]    context         specifies contact adaptor plugin context handle
1371 * @param[in]    request         specifies contact adaptor profile API request handle
1372 * @param[in]    user_data       specifies user side arbitrary data
1373 * @param[out]   response        specifies contact adaptor profile API response handle
1374 * @param[out]   error           specifies returned error code handle
1375 * @param[out]   server_data     specifies server side arbitrary data
1376 * @return       0 on success, otherwise a positive error value
1377 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
1378 */
1379 contact_error_code_t contact_adaptor_get_profile(contact_adaptor_plugin_h plugin,
1380                                                 contact_adaptor_plugin_context_h context,
1381                                                 contact_adaptor_profile_req_h request,
1382                                                 void *user_data,
1383                                                 contact_adaptor_profile_res_h *response,
1384                                                 contact_adaptor_error_code_h *error,
1385                                                 void **server_data)
1386 {
1387         contact_adaptor_warning("Get profile");
1388
1389         if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
1390                 contact_adaptor_error("Invalid argument");
1391
1392                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
1393                                                         "Invalid argument (plugin or context or request)");
1394
1395                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
1396         }
1397
1398         if (NULL == plugin->handle) {
1399                 contact_adaptor_error("Plugin handle is null");
1400
1401                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
1402                                                         "Plugin handle is null");
1403
1404                 return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
1405         }
1406
1407         contact_error_code_t ret;
1408         plugin_req_enter();
1409         ret = plugin->handle->get_profile(context, request, user_data, response, error, server_data);
1410         plugin_req_exit(ret, plugin, error);
1411
1412         return ret;
1413 }
1414
1415 /**
1416 * @brief Uploads profile image meta to file server
1417 *
1418 * @param[in]    plugin          specifies contact adaptor plugin handle
1419 * @param[in]    context         specifies contact adaptor plugin context handle
1420 * @param[in]    request         specifies contact adaptor profile API image file request handle
1421 * @param[in]    user_data       specifies user side arbitrary data
1422 * @param[out]   response        specifies contact adaptor profile API image file response handle
1423 * @param[out]   error           specifies returned error code handle
1424 * @param[out]   server_data     specifies server side arbitrary data
1425 * @return       0 on success, otherwise a positive error value
1426 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
1427 */
1428 contact_error_code_t contact_adaptor_set_me_profile_image_meta_with_push(contact_adaptor_plugin_h plugin,
1429                                                 contact_adaptor_plugin_context_h context,
1430                                                 contact_adaptor_contact_image_h *imgs,
1431                                                 unsigned int imgs_len,
1432                                                 void *user_data,
1433                                                 contact_adaptor_error_code_h *error,
1434                                                 void **server_data)
1435 {
1436         contact_adaptor_warning("Set me profile image meta with push");
1437
1438         if ((NULL == plugin) || (NULL == context) || (NULL == imgs) || (0U == imgs_len)) {
1439                 contact_adaptor_error("Invalid argument");
1440
1441                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
1442                                                         "Invalid argument (plugin or context or request)");
1443
1444                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
1445         }
1446
1447         if (NULL == plugin->handle) {
1448                 contact_adaptor_error("Plugin handle is null");
1449
1450                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
1451                                                         "Plugin handle is null");
1452
1453                 return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
1454         }
1455
1456         contact_error_code_t ret;
1457         plugin_req_enter();
1458         ret = plugin->handle->set_me_profile_image_meta_with_push(context, imgs, imgs_len, user_data,
1459                                                 error, server_data);
1460         plugin_req_exit(ret, plugin, error);
1461
1462         return ret;
1463 }
1464
1465 /**
1466 * @brief Deletes profile image meta from profile server
1467 *
1468 * @param[in]    plugin          specifies contact adaptor plugin handle
1469 * @param[in]    context         specifies contact adaptor plugin context handle
1470 * @param[in]    request         specifies contact adaptor profile API image file request handle
1471 * @param[in]    user_data       specifies user side arbitrary data
1472 * @param[out]   response        specifies contact adaptor profile API image file response handle
1473 * @param[out]   error           specifies returned error code handle
1474 * @param[out]   server_data     specifies server side arbitrary data
1475 * @return       0 on success, otherwise a positive error value
1476 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
1477 */
1478 contact_error_code_t contact_adaptor_delete_me_profile_image_meta_with_push(contact_adaptor_plugin_h plugin,
1479                                                 contact_adaptor_plugin_context_h context,
1480                                                 void *user_data,
1481                                                 contact_adaptor_error_code_h *error,
1482                                                 void **server_data)
1483 {
1484         contact_adaptor_warning("Delete me profile image meta with push");
1485
1486         if ((NULL == plugin) || (NULL == context)) {
1487                 contact_adaptor_error("Invalid argument");
1488
1489                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
1490                                                         "Invalid argument (plugin or context or request)");
1491
1492                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
1493         }
1494
1495         if (NULL == plugin->handle) {
1496                 contact_adaptor_error("Plugin handle is null");
1497
1498                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
1499                                                         "Plugin handle is null");
1500
1501                 return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
1502         }
1503
1504         contact_error_code_t ret;
1505         plugin_req_enter();
1506         ret = plugin->handle->delete_me_profile_image_meta_with_push(context, user_data,
1507                                                 error, server_data);
1508         plugin_req_exit(ret, plugin, error);
1509
1510         return ret;
1511 }
1512
1513 /**
1514 * @brief Sets the level of privacy
1515 *
1516 * @param[in]    plugin          specifies contact adaptor plugin handle
1517 * @param[in]    context         specifies contact adaptor plugin context handle
1518 * @param[in]    request         specifies contact adaptor privacy API request handle
1519 * @param[in]    user_data       specifies user side arbitrary data
1520 * @param[out]   response        specifies contact adaptor privacy API response handle
1521 * @param[out]   error           specifies returned error code handle
1522 * @param[out]   server_data     specifies server side arbitrary data
1523 * @return       0 on success, otherwise a positive error value
1524 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
1525 */
1526 contact_error_code_t contact_adaptor_set_me_profile_privacy(contact_adaptor_plugin_h plugin,
1527                                                 contact_adaptor_plugin_context_h context,
1528                                                 contact_adaptor_privacy_req_h request,
1529                                                 void *user_data,
1530                                                 contact_adaptor_privacy_res_h *response,
1531                                                 contact_adaptor_error_code_h *error,
1532                                                 void **server_data)
1533 {
1534         contact_adaptor_warning("Set me profile privacy");
1535
1536         if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
1537                 contact_adaptor_error("Invalid argument");
1538
1539                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
1540                                                         "Invalid argument (plugin or context or request)");
1541
1542                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
1543         }
1544
1545         if (NULL == plugin->handle) {
1546                 contact_adaptor_error("Plugin handle is null");
1547
1548                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
1549                                                         "Plugin handle is null");
1550
1551                 return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
1552         }
1553
1554         contact_error_code_t ret;
1555         plugin_req_enter();
1556         ret = plugin->handle->set_me_profile_privacy(context, request, user_data,
1557                                                 response, error, server_data);
1558         plugin_req_exit(ret, plugin, error);
1559
1560         return ret;
1561 }
1562
1563 /**
1564 * @brief Gets my profile's privacy level
1565 *
1566 * @param[in]    plugin          specifies contact adaptor plugin handle
1567 * @param[in]    context         specifies contact adaptor plugin context handle
1568 * @param[in]    request         specifies contact adaptor privacy API request handle
1569 * @param[in]    user_data       specifies user side arbitrary data
1570 * @param[out]   response        specifies contact adaptor privacy API response handle
1571 * @param[out]   error           specifies returned error code handle
1572 * @param[out]   server_data     specifies server side arbitrary data
1573 * @return       0 on success, otherwise a positive error value
1574 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
1575 */
1576 contact_error_code_t contact_adaptor_get_me_profile_privacy(contact_adaptor_plugin_h plugin,
1577                                                 contact_adaptor_plugin_context_h context,
1578                                                 contact_adaptor_privacy_req_h request,
1579                                                 void *user_data,
1580                                                 contact_adaptor_privacy_res_h *response,
1581                                                 contact_adaptor_error_code_h *error,
1582                                                 void **server_data)
1583 {
1584         contact_adaptor_warning("Get me profile privacy");
1585
1586         if ((NULL == plugin) || (NULL == context)) {
1587                 contact_adaptor_error("Invalid argument");
1588
1589                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
1590                                                         "Invalid argument (plugin or context or request)");
1591
1592                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
1593         }
1594
1595         if (NULL == plugin->handle) {
1596                 contact_adaptor_error("Plugin handle is null");
1597
1598                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
1599                                                         "Plugin handle is null");
1600
1601                 return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
1602         }
1603
1604         contact_error_code_t ret;
1605         plugin_req_enter();
1606         ret = plugin->handle->get_me_profile_privacy(context, request, user_data,
1607                                                 response, error, server_data);
1608         plugin_req_exit(ret, plugin, error);
1609
1610         return ret;
1611 }
1612
1613 /**
1614 * @brief Sets my presence information
1615 *
1616 * @param[in]    plugin          specifies contact adaptor plugin handle
1617 * @param[in]    context         specifies contact adaptor plugin context handle
1618 * @param[in]    request         specifies contact adaptor presence API request handle
1619 * @param[in]    user_data       specifies user side arbitrary data
1620 * @param[out]   response        specifies contact adaptor presence API response handle
1621 * @param[out]   error           specifies returned error code handle
1622 * @param[out]   server_data     specifies server side arbitrary data
1623 * @return       0 on success, otherwise a positive error value
1624 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
1625 */
1626 contact_error_code_t contact_adaptor_set_me_presence_with_push(contact_adaptor_plugin_h plugin,
1627                                                 contact_adaptor_plugin_context_h context,
1628                                                 contact_adaptor_presence_info_h request,
1629                                                 void *user_data,
1630                                                 contact_adaptor_presence_info_h *response,
1631                                                 contact_adaptor_error_code_h *error,
1632                                                 void **server_data)
1633 {
1634         contact_adaptor_warning("Set me presence with push");
1635
1636         if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
1637                 contact_adaptor_error("Invalid argument");
1638
1639                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
1640                                                         "Invalid argument (plugin or context or request)");
1641
1642                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
1643         }
1644
1645         if (NULL == plugin->handle) {
1646                 contact_adaptor_error("Plugin handle is null");
1647
1648                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
1649                                                         "Plugin handle is null");
1650
1651                 return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
1652         }
1653
1654         contact_error_code_t ret;
1655         plugin_req_enter();
1656         ret = plugin->handle->set_me_presence_with_push(context, request, user_data,
1657                                                 response, error, server_data);
1658         plugin_req_exit(ret, plugin, error);
1659
1660         return ret;
1661 }
1662
1663 /**
1664 * @brief Sets my presence on/off information
1665 *
1666 * @param[in]    plugin          specifies contact adaptor plugin handle
1667 * @param[in]    context         specifies contact adaptor plugin context handle
1668 * @param[in]    request         specifies contact adaptor presence API request handle
1669 * @param[in]    user_data       specifies user side arbitrary data
1670 * @param[out]   response        specifies contact adaptor presence API response handle
1671 * @param[out]   error           specifies returned error code handle
1672 * @param[out]   server_data     specifies server side arbitrary data
1673 * @return       0 on success, otherwise a positive error value
1674 * @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
1675 */
1676 contact_error_code_t contact_adaptor_set_me_presence_on_off_with_push(contact_adaptor_plugin_h plugin,
1677                                                 contact_adaptor_plugin_context_h context,
1678                                                 contact_adaptor_presence_info_h request,
1679                                                 void *user_data,
1680                                                 contact_adaptor_presence_info_h *response,
1681                                                 contact_adaptor_error_code_h *error,
1682                                                 void **server_data)
1683 {
1684         contact_adaptor_warning("Set me presence on off with push");
1685
1686         if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
1687                 contact_adaptor_error("Invalid argument");
1688
1689                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
1690                                                         "Invalid argument (plugin or context or request)");
1691
1692                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
1693         }
1694
1695         if (NULL == plugin->handle) {
1696                 contact_adaptor_error("Plugin handle is null");
1697
1698                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
1699                                                         "Plugin handle is null");
1700
1701                 return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
1702         }
1703
1704         contact_error_code_t ret;
1705         plugin_req_enter();
1706         ret = plugin->handle->set_me_presence_on_off_with_push(context, request, user_data,
1707                                                                 response, error, server_data);
1708         plugin_req_exit(ret, plugin, error);
1709
1710         return ret;
1711 }
1712
1713 EXPORT_API
1714 contact_error_code_t contact_adaptor_set_me_profile_type(contact_adaptor_plugin_h plugin,
1715                                                 contact_adaptor_plugin_context_h context,
1716                                                 int req_type,
1717                                                 void *user_data,
1718                                                 char **url,
1719                                                 contact_adaptor_error_code_h *error,
1720                                                 void **server_data)
1721 {
1722         contact_adaptor_info("%s", __FUNCTION__);
1723
1724         if ((NULL == plugin) || (NULL == context)) {
1725                 contact_adaptor_error("Invalid argument");
1726
1727                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
1728                                                         "Invalid argument (plugin or context or request)");
1729
1730                 return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
1731         }
1732
1733         if (NULL == plugin->handle) {
1734                 contact_adaptor_error("Plugin handle is null");
1735
1736                 *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
1737                                                         "Plugin handle is null");
1738
1739                 return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
1740         }
1741
1742         char *_url = NULL;
1743         contact_error_code_t ret;
1744         plugin_req_enter();
1745         ret = plugin->handle->set_me_profile_type(context, req_type, user_data,
1746                                                                 &_url, error, server_data);
1747         plugin_req_exit(ret, plugin, error);
1748
1749         contact_adaptor_debug("url : %s", _url);
1750         if (NULL != url) {
1751                 *url = _url;
1752         } else {
1753                 free(_url);
1754         }
1755
1756         return ret;
1757 }
1758
1759