fd9f617dcd06301e3e61fab57c8e34b7969f9117
[platform/core/convergence/service-adaptor.git] / adaptor / message-adaptor / message-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
25 #include "message-adaptor.h"
26 #include "message-adaptor-log.h"
27
28
29 /**
30  * Message adaptor plugin
31  */
32 typedef struct message_adaptor_plugin_s {
33         message_adaptor_h                       adaptor;                /* Adaptor */
34         char                                    *path;                  /* Plugin library path */
35         message_adaptor_plugin_handle_h         handle;                 /* Plugin handle */
36         void                                    *dl_handle;             /* Plugin library handle */
37         int                                     ref_counter;            /* Plugin reference counter */
38         GMutex                                  ref_counter_mutex;      /* Plugin reference counter mutex */
39         message_adaptor_plugin_listener_h       plugin_listener;        /* Plugin callback listener */
40         GMutex                                  plugin_listener_mutex;  /* Plugin callback listener mutex */
41         int                                     connected;              /* connected flag */
42         GMutex                                  plugin_connect_mutex;
43         GCond                                   plugin_connect_cond;
44 } message_adaptor_plugin_t;
45
46 /**
47  * Message adaptor
48  */
49 typedef struct message_adaptor_s {
50         GMutex  message_adaptor_mutex;          /* Adaptor mutex */
51         int     started;                        /* Started flag */
52         char    *plugins_dir;                   /* Plugins directory path */
53         GList   *plugins;                       /* List of loaded plugins */
54         GMutex  plugins_mutex;                  /* Plugin list mutex */
55         GList   *adaptor_listeners;             /* List of vservice channel listener (for now not effective) */
56         GMutex  adaptor_listeners_mutex;        /* Listener list mutex */
57 } message_adaptor_t;
58
59 /**
60  * Creates plugin
61  */
62 static message_adaptor_plugin_h message_adaptor_create_plugin(const char *plugin_path);
63
64 /**
65  * Destroys plugin and deletes all resources associated with it
66  */
67 static void message_adaptor_destroy_plugin(message_adaptor_plugin_h plugin);
68
69 /**
70  * Loads plugins from selected directory
71  */
72 static int message_adaptor_load_plugins_from_directory(message_adaptor_h adaptor, const char *dir_path);
73
74 /**
75  * Checks if plugin is loaded by selected plugin adaptor
76  */
77 static int message_adaptor_has_plugin(message_adaptor_h adaptor, message_adaptor_plugin_h plugin);
78
79 /**
80  * Increases adaptor's plugin references counter
81  */
82 static void message_adaptor_plugin_ref(message_adaptor_plugin_h);
83
84 /**
85  * Decreases adaptor's plugin references counter
86  */
87 static void message_adaptor_plugin_unref(message_adaptor_plugin_h);
88
89
90 /**
91  * Definition of callback function variables for service adaptor
92  */
93
94 message_adaptor_service_client_echo_cb _service_adaptor_service_client_echo_cb = NULL;
95 message_adaptor_service_create_chatroom_reply_cb _service_adaptor_service_create_chatroom_reply_cb = NULL;
96 message_adaptor_service_change_chatroom_meta_reply_cb _service_adaptor_service_change_chatroom_meta_reply_cb = NULL;
97 message_adaptor_service_chat_reply_cb _service_adaptor_service_chat_reply_cb = NULL;
98 message_adaptor_service_allow_chat_reply_cb _service_adaptor_service_allow_chat_reply_cb = NULL;
99 message_adaptor_service_get_all_unread_message_reply_cb _service_adaptor_service_get_all_unread_message_reply_cb = NULL;
100 message_adaptor_service_forward_online_message_request_cb _service_adaptor_service_forward_online_message_request_cb = NULL;
101 message_adaptor_service_forward_unread_message_request_cb _service_adaptor_service_forward_unread_message_request_cb = NULL;
102 message_adaptor_service_read_message_reply_cb _service_adaptor_service_read_message_reply_cb = NULL;
103 message_adaptor_service_invite_chat_reply_cb _service_adaptor_service_invite_chat_reply_cb = NULL;
104 message_adaptor_service_end_chat_reply_cb _service_adaptor_service_end_chat_reply_cb = NULL;
105 message_adaptor_service_unseal_message_reply_cb _service_adaptor_service_unseal_message_reply_cb = NULL;
106 message_adaptor_service_save_call_log_reply_cb _service_adaptor_service_save_call_log_reply_cb = NULL;
107 message_adaptor_service_current_time_reply_cb _service_adaptor_service_current_time_reply_cb = NULL;
108 message_adaptor_service_typing_updated_cb _service_adaptor_service_typing_updated_cb = NULL;
109 message_adaptor_service_completion_cb _service_adaptor_service_completion_cb = NULL;
110 /*
111  * Required function for sample callback functions
112  */
113
114 void
115 message_adaptor_client_echo_cb(message_adaptor_plugin_context_h context,
116                                                 long long int request_id,
117                                                 message_adaptor_error_code_t **error_code,
118                                                 void *server_data)
119 {
120         plugin_req_id_print();
121         if (_service_adaptor_service_client_echo_cb) {
122                 _service_adaptor_service_client_echo_cb(context, request_id, error_code, server_data);
123         }
124 }
125
126 void
127 message_adaptor_create_chatroom_reply_cb(message_adaptor_plugin_context_h context,
128                                                 long long int request_id,
129                                                 long long int chatroom_id,
130                                                 int default_message_ttl,
131                                                 message_adaptor_wrong_receiver_s *wrong_receiver,
132                                                 message_adaptor_error_code_t **error_code,
133                                                 void *server_data)
134 {
135         plugin_req_id_print();
136         if (_service_adaptor_service_create_chatroom_reply_cb) {
137                 _service_adaptor_service_create_chatroom_reply_cb(context, request_id,
138                                 chatroom_id, default_message_ttl, wrong_receiver, error_code, server_data);
139         }
140 }
141
142 void
143 message_adaptor_change_chatroom_meta_reply_cb(message_adaptor_plugin_context_h context,
144                                                 long long int request_id,
145                                                 long long int chatroom_id,
146                                                 message_adaptor_error_code_t **error_code,
147                                                 void *server_data)
148
149 {
150         plugin_req_id_print();
151         if (_service_adaptor_service_change_chatroom_meta_reply_cb) {
152                 _service_adaptor_service_change_chatroom_meta_reply_cb(context, request_id,
153                                 chatroom_id, error_code, server_data);
154         }
155 }
156
157 void
158 message_adaptor_chat_reply_cb(message_adaptor_plugin_context_h context,
159                                                 long long int request_id,
160                                                 long long int chatroom_id,
161                                                 message_adaptor_processed_msg_s **processed_msgs,
162                                                 unsigned int processed_msgs_len,
163                                                 message_adaptor_error_code_t **error_code,
164                                                 void *server_data)
165 {
166         plugin_req_id_print();
167         if (_service_adaptor_service_chat_reply_cb) {
168                 _service_adaptor_service_chat_reply_cb(context,
169                                 request_id, chatroom_id, processed_msgs,
170                                 processed_msgs_len, error_code, server_data);
171         }
172 }
173
174
175 void
176 message_adaptor_allow_chat_reply_cb(message_adaptor_plugin_context_h context,
177                                                 long long int request_id,
178                                                 long long int chatroom_id,
179                                                 message_adaptor_delivery_ack_s **deliveryacks,
180                                                 unsigned int deliveryacks_len,
181                                                 unsigned long long last_delivery_ack_timestamp,
182                                                 message_adaptor_read_ack_s **read_acks,
183                                                 unsigned int read_acks_len,
184                                                 unsigned long long last_read_ack_timestamp,
185                                                 message_adaptor_ordered_chat_member_s **ordered_chat_members,
186                                                 unsigned int ordered_chat_members_len,
187                                                 const char *chatroom_title,
188                                                 int default_message_ttl,
189                                                 message_adaptor_error_code_t **error_code,
190                                                 void *server_data)
191 {
192         plugin_req_id_print();
193         if (_service_adaptor_service_allow_chat_reply_cb) {
194                 _service_adaptor_service_allow_chat_reply_cb(context,
195                                 request_id, chatroom_id,
196                                 deliveryacks, deliveryacks_len, last_delivery_ack_timestamp,
197                                 read_acks, read_acks_len, last_read_ack_timestamp,
198                                 ordered_chat_members, ordered_chat_members_len,
199                                 chatroom_title, default_message_ttl,
200                                 error_code, server_data);
201         }
202 }
203
204 void
205 message_adaptor_get_all_unread_message_reply_cb(message_adaptor_plugin_context_h context,
206                                                 long long int request_id,
207                                                 message_adaptor_error_code_t **error_code,
208                                                 void *server_data)
209 {
210         plugin_req_id_print();
211         if (_service_adaptor_service_get_all_unread_message_reply_cb) {
212                 _service_adaptor_service_get_all_unread_message_reply_cb(context,
213                                 request_id, error_code, server_data);
214         }
215 }
216
217 void
218 message_adaptor_forward_online_message_request_cb(message_adaptor_plugin_context_h context,
219                                                 long long int request_id,
220                                                 long long int chatroom_id, int chat_type,
221                                                 message_inboxentry_t *inbox_msg,
222                                                 bool skip_reply,
223                                                 message_adaptor_error_code_t **error_code,
224                                                 void *server_data)
225 {
226         plugin_req_id_print();
227         if (_service_adaptor_service_forward_online_message_request_cb) {
228                 _service_adaptor_service_forward_online_message_request_cb(context,
229                                 request_id, chatroom_id, chat_type,
230                                 inbox_msg, skip_reply, error_code, server_data);
231         }
232 }
233
234 void
235 message_adaptor_forward_unread_message_request_cb(message_adaptor_plugin_context_h context,
236                                                 long long int request_id,
237                                                 message_inboxentry_t ***inbox_msgs,
238                                                 unsigned int inbox_msgs_len,
239                                                 char **next_pagination_key,
240                                                 message_adaptor_error_code_t **error_code,
241                                                 void *server_data)
242 {
243         plugin_req_id_print();
244         if (_service_adaptor_service_forward_unread_message_request_cb) {
245                 _service_adaptor_service_forward_unread_message_request_cb(context,
246                                 request_id, inbox_msgs, inbox_msgs_len,
247                                 next_pagination_key, error_code, server_data);
248         }
249 }
250
251 void
252 message_adaptor_read_message_reply_cb(message_adaptor_plugin_context_h context,
253                                                 long long int request_id,
254                                                 long long int chatroom_id,
255                                                 message_adaptor_error_code_t **error_code,
256                                                 void *server_data)
257 {
258         plugin_req_id_print();
259         if (_service_adaptor_service_read_message_reply_cb) {
260                 _service_adaptor_service_read_message_reply_cb(context,
261                                 request_id, chatroom_id, error_code, server_data);
262         }
263 }
264
265 void
266 message_adaptor_invite_chat_reply_cb(message_adaptor_plugin_context_h context,
267                                                 long long int request_id,
268                                                 long long int chatroom_id,
269                                                 long long int sent_time,
270                                                 message_adaptor_wrong_receiver_s *wrong_receiver,
271                                                 message_adaptor_error_code_t **error_code,
272                                                 void *server_data)
273 {
274         plugin_req_id_print();
275         if (_service_adaptor_service_invite_chat_reply_cb) {
276                 _service_adaptor_service_invite_chat_reply_cb(context,
277                                 request_id, chatroom_id, sent_time,
278                                 wrong_receiver, error_code, server_data);
279         }
280 }
281
282 void
283 message_adaptor_end_chat_reply_cb(message_adaptor_plugin_context_h context,
284                                                 long long int request_id,
285                                                 message_adaptor_error_code_t **error_code,
286                                                 void *server_data)
287 {
288         plugin_req_id_print();
289         if (_service_adaptor_service_end_chat_reply_cb) {
290                 _service_adaptor_service_end_chat_reply_cb(context,
291                                 request_id, error_code, server_data);
292         }
293 }
294
295 void
296 message_adaptor_unseal_message_reply_cb(message_adaptor_plugin_context_h context,
297                                                 long long int request_id,
298                                                 long long int chatroom_id,
299                                                 message_adaptor_error_code_t **error_code,
300                                                 void *server_data)
301 {
302         plugin_req_id_print();
303         if (_service_adaptor_service_unseal_message_reply_cb) {
304                 _service_adaptor_service_unseal_message_reply_cb(context,
305                                 request_id, chatroom_id, error_code, server_data);
306         }
307 }
308
309 void
310 message_adaptor_save_call_log_reply_cb(message_adaptor_plugin_context_h context,
311                                                 long long int request_id,
312                                                 message_adaptor_error_code_t **error_code,
313                                                 void *server_data)
314 {
315         plugin_req_id_print();
316         if (_service_adaptor_service_save_call_log_reply_cb) {
317                 _service_adaptor_service_save_call_log_reply_cb(context,
318                                 request_id, error_code, server_data);
319         }
320 }
321
322 void
323 message_adaptor_current_time_reply_cb(message_adaptor_plugin_context_h context,
324                                                 long long int request_id,
325                                                 long long int current_time_millis,
326                                                 message_adaptor_error_code_t **error_code,
327                                                 void *server_data)
328 {
329         plugin_req_id_print();
330         if (_service_adaptor_service_current_time_reply_cb) {
331                 _service_adaptor_service_current_time_reply_cb(context,
332                                 request_id, current_time_millis, error_code, server_data);
333         }
334 }
335
336 void
337 message_adaptor_typing_updated_cb(message_adaptor_plugin_context_h context,
338                                                 long long int request_id,
339                                                 long long int chatroom_id,
340                                                 long long int *sender,
341                                                 char **state,
342                                                 int *contentType,
343                                                 int *refreshTime,
344                                                 message_adaptor_error_code_t **error_code,
345                                                 void *server_data)
346 {
347         plugin_req_id_print();
348         if (_service_adaptor_service_typing_updated_cb) {
349                 _service_adaptor_service_typing_updated_cb(context,
350                                 request_id, chatroom_id, sender,
351                                 state, contentType, refreshTime,
352                                 error_code, server_data);
353         }
354 }
355
356 void
357 message_adaptor_completion_cb(message_adaptor_plugin_context_h context,
358                                                 message_connection_state_t state,
359                                                 message_adaptor_error_code_t **error_code,
360                                                 void *server_data)
361 {
362         if (_service_adaptor_service_completion_cb) {
363                 _service_adaptor_service_completion_cb(context,
364                                 state, error_code, server_data);
365         }
366 }
367
368
369 /* //------------------------------------------------------------------------
370    // Functions implementations
371    //------------------------------------------------------------------------ */
372
373 /* //////////////////////////////////////////////////////
374    // Mandatory: External adaptor management function
375    ////////////////////////////////////////////////////// */
376
377 EXPORT_API
378 message_adaptor_h message_adaptor_create(const char *plugins_dir)
379 {
380         message_adaptor_h message_adaptor = (message_adaptor_h) malloc(sizeof(message_adaptor_t));
381         if (NULL == message_adaptor) {
382                 return NULL;
383         }
384
385         message_adaptor->started = 0;
386         message_adaptor->plugins_dir = strdup(plugins_dir);
387
388         g_mutex_init(&message_adaptor->message_adaptor_mutex);
389         g_mutex_init(&message_adaptor->plugins_mutex);
390         g_mutex_init(&message_adaptor->adaptor_listeners_mutex);
391
392         g_mutex_lock(&message_adaptor->adaptor_listeners_mutex);
393         message_adaptor->adaptor_listeners = NULL;
394         g_mutex_unlock(&message_adaptor->adaptor_listeners_mutex);
395
396         g_mutex_lock(&message_adaptor->plugins_mutex);
397         message_adaptor->plugins = NULL;
398         g_mutex_unlock(&message_adaptor->plugins_mutex);
399
400         return message_adaptor;
401
402 }
403
404 EXPORT_API
405 void message_adaptor_destroy(message_adaptor_h adaptor)
406 {
407         if (NULL == adaptor) {
408                 message_adaptor_error("Invalid argument");
409                 return ;
410         }
411
412         g_mutex_lock(&adaptor->message_adaptor_mutex);
413         if (adaptor->started) {
414                 message_adaptor_error("Message adaptor is running. Forcing stop before destroy");
415                 message_adaptor_stop(adaptor);
416         }
417
418         g_mutex_lock(&adaptor->plugins_mutex);
419         if (NULL != adaptor->plugins) {
420                 g_list_free_full(adaptor->plugins, (GDestroyNotify) message_adaptor_plugin_unref);
421                 adaptor->plugins = NULL;
422         }
423         g_mutex_unlock(&adaptor->plugins_mutex);
424
425         g_mutex_lock(&adaptor->adaptor_listeners_mutex);
426         if (NULL != adaptor->adaptor_listeners) {
427                 g_list_free(adaptor->adaptor_listeners);
428                 adaptor->adaptor_listeners = NULL;
429         }
430         g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
431
432         free(adaptor->plugins_dir);
433         adaptor->plugins_dir = NULL;
434
435         g_mutex_unlock(&adaptor->message_adaptor_mutex);
436
437         free(adaptor);
438 }
439
440 EXPORT_API
441 int message_adaptor_start(message_adaptor_h adaptor)
442 {
443         message_adaptor_debug("Starting message adaptor");
444         if (NULL == adaptor) {
445                 message_adaptor_error("Invalid argument");
446                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
447         }
448
449         g_mutex_lock(&adaptor->message_adaptor_mutex);
450         int result = MESSAGE_ADAPTOR_ERROR_NONE;
451         if (adaptor->started) {
452                 message_adaptor_error("Message adaptor is already started");
453                 result = MESSAGE_ADAPTOR_ERROR_START;
454         } else {
455                 adaptor->started = 1;
456                 result = message_adaptor_load_plugins_from_directory(adaptor, adaptor->plugins_dir);
457                 if (MESSAGE_ADAPTOR_ERROR_NONE != result) {
458                         adaptor->started = 0;
459                         message_adaptor_error("Could not load plugins from directory");
460                 } else {
461                         message_adaptor_debug("Message adaptor started successfully");
462                 }
463         }
464         g_mutex_unlock(&adaptor->message_adaptor_mutex);
465
466         return result;
467 }
468
469 /**
470  * Stops message adaptor.
471  */
472 EXPORT_API
473 int message_adaptor_stop(message_adaptor_h adaptor)
474 {
475         if (NULL == adaptor) {
476                 message_adaptor_error("Invalid argument");
477                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
478         }
479
480         g_mutex_lock(&adaptor->message_adaptor_mutex);
481         int result = MESSAGE_ADAPTOR_ERROR_NONE;
482         if (!adaptor->started) {
483                 result = MESSAGE_ADAPTOR_ERROR_START;
484         } else {
485                 if (NULL != adaptor->plugins) {
486                         g_mutex_lock(&adaptor->plugins_mutex);
487                         g_list_free_full(adaptor->plugins, (GDestroyNotify) message_adaptor_plugin_unref);
488                         adaptor->plugins = NULL;
489                         g_mutex_unlock(&adaptor->plugins_mutex);
490                 }
491                 adaptor->started = 0;
492                 message_adaptor_debug("Message adaptor stopped");
493         }
494
495         g_mutex_unlock(&adaptor->message_adaptor_mutex);
496         return result;
497 }
498
499 /**
500  * Registers plugin state listener
501  */
502         EXPORT_API
503 int message_adaptor_register_listener(message_adaptor_h adaptor, message_adaptor_listener_h listener)
504 {
505         if ((NULL == adaptor) || (NULL == listener)) {
506                 message_adaptor_error("Invalid argument");
507                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
508         }
509
510         g_mutex_lock(&adaptor->adaptor_listeners_mutex);
511
512         adaptor->adaptor_listeners = g_list_append(adaptor->adaptor_listeners, listener);
513
514         g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
515
516         _service_adaptor_service_client_echo_cb =
517                 (message_adaptor_service_client_echo_cb)listener->client_echo_cb;
518         _service_adaptor_service_create_chatroom_reply_cb =
519                 (message_adaptor_service_create_chatroom_reply_cb)listener->create_chatroom_reply_cb;
520         _service_adaptor_service_change_chatroom_meta_reply_cb =
521                 (message_adaptor_service_change_chatroom_meta_reply_cb)listener->change_chatroom_meta_reply_cb;
522         _service_adaptor_service_chat_reply_cb =
523                 (message_adaptor_service_chat_reply_cb)listener->chat_reply_cb;
524         _service_adaptor_service_allow_chat_reply_cb =
525                 (message_adaptor_service_allow_chat_reply_cb)listener->allow_chat_reply_cb;
526         _service_adaptor_service_get_all_unread_message_reply_cb =
527                 (message_adaptor_service_get_all_unread_message_reply_cb)listener->get_all_unread_message_reply_cb;
528         _service_adaptor_service_forward_online_message_request_cb =
529                 (message_adaptor_service_forward_online_message_request_cb)listener->forward_online_message_request_cb;
530         _service_adaptor_service_forward_unread_message_request_cb =
531                 (message_adaptor_service_forward_unread_message_request_cb)listener->forward_unread_message_request_cb;
532         _service_adaptor_service_read_message_reply_cb =
533                 (message_adaptor_service_read_message_reply_cb)listener->read_message_reply_cb;
534         _service_adaptor_service_invite_chat_reply_cb =
535                 (message_adaptor_service_invite_chat_reply_cb)listener->invite_chat_reply_cb;
536         _service_adaptor_service_end_chat_reply_cb =
537                 (message_adaptor_service_end_chat_reply_cb)listener->end_chat_reply_cb;
538         _service_adaptor_service_unseal_message_reply_cb =
539                 (message_adaptor_service_unseal_message_reply_cb)listener->unseal_message_reply_cb;
540         _service_adaptor_service_save_call_log_reply_cb =
541                 (message_adaptor_service_save_call_log_reply_cb)listener->save_call_log_reply_cb;
542         _service_adaptor_service_current_time_reply_cb =
543                 (message_adaptor_service_current_time_reply_cb)listener->current_time_reply_cb;
544         _service_adaptor_service_typing_updated_cb =
545                 (message_adaptor_service_typing_updated_cb)listener->typing_updated_cb;
546         _service_adaptor_service_completion_cb =
547                 (message_adaptor_service_completion_cb)listener->completion_cb;
548
549         return MESSAGE_ADAPTOR_ERROR_NONE;
550 }
551
552 /**
553  * Unregisters plugin state listener
554  */
555 EXPORT_API
556 int message_adaptor_unregister_listener(message_adaptor_h adaptor, message_adaptor_listener_h listener)
557 {
558         if ((NULL == adaptor) || (NULL == listener)) {
559                 message_adaptor_error("Invalid argument");
560                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
561         }
562
563         g_mutex_lock(&adaptor->adaptor_listeners_mutex);
564
565         if (NULL == g_list_find(adaptor->adaptor_listeners, listener)) {
566                 g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
567                 message_adaptor_error("Could not find listener");
568                 free(listener);
569                 return MESSAGE_ADAPTOR_ERROR_NOT_FOUND;
570         }
571
572         adaptor->adaptor_listeners = g_list_remove(adaptor->adaptor_listeners, listener);
573         free(listener);
574
575         g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
576
577         _service_adaptor_service_client_echo_cb = NULL;
578         _service_adaptor_service_create_chatroom_reply_cb = NULL;
579         _service_adaptor_service_change_chatroom_meta_reply_cb = NULL;
580         _service_adaptor_service_chat_reply_cb = NULL;
581         _service_adaptor_service_allow_chat_reply_cb = NULL;
582         _service_adaptor_service_get_all_unread_message_reply_cb = NULL;
583         _service_adaptor_service_forward_online_message_request_cb = NULL;
584         _service_adaptor_service_forward_unread_message_request_cb = NULL;
585         _service_adaptor_service_read_message_reply_cb = NULL;
586         _service_adaptor_service_invite_chat_reply_cb = NULL;
587         _service_adaptor_service_end_chat_reply_cb = NULL;
588         _service_adaptor_service_unseal_message_reply_cb = NULL;
589         _service_adaptor_service_save_call_log_reply_cb = NULL;
590         _service_adaptor_service_current_time_reply_cb = NULL;
591         _service_adaptor_service_typing_updated_cb = NULL;
592         _service_adaptor_service_completion_cb = NULL;
593
594         return MESSAGE_ADAPTOR_ERROR_NONE;
595 }
596
597 /* /////////////////////////////////////////////////////////////
598    // Plugin create / destroy / ref. count / get plugin name
599    ///////////////////////////////////////////////////////////// */
600 static message_adaptor_plugin_h message_adaptor_create_plugin(const char *plugin_path)
601 {
602         if (NULL == plugin_path) {
603                 message_adaptor_error("Invalid argument");
604                 return NULL;
605         }
606
607         void *dl_handle = dlopen(plugin_path, RTLD_LAZY);
608         if (NULL == dl_handle) {
609                 message_adaptor_error("Could not load plugin %s: %s", plugin_path, dlerror());
610                 return NULL;
611         }
612
613         message_adaptor_plugin_handle_h (*get_adaptee_handle)(void) = NULL;
614
615         get_adaptee_handle = (message_adaptor_plugin_handle_h (*)(void))(dlsym(dl_handle, "create_plugin_handle"));
616         if (NULL == get_adaptee_handle) {
617                 dlclose(dl_handle);
618                 message_adaptor_error("Could not get function pointer to create_plugin_handle");
619                 return NULL;
620         }
621
622         plugin_req_enter();
623         message_adaptor_plugin_handle_h handle = get_adaptee_handle();
624         plugin_req_exit_void();
625         if (NULL == handle) {
626                 dlclose(dl_handle);
627                 message_adaptor_error("Could not get adaptee handle");
628                 return NULL;
629         }
630
631         message_adaptor_plugin_h plugin = (message_adaptor_plugin_h) calloc(1, sizeof(message_adaptor_plugin_t));
632         if (NULL == plugin) {
633                 dlclose(dl_handle);
634                 message_adaptor_error("Could not create plugin object");
635                 return NULL;
636         }
637
638         message_adaptor_plugin_listener_h listener =
639                 (message_adaptor_plugin_listener_h) calloc(1, sizeof(message_adaptor_plugin_listener_t));
640         if (NULL == listener) {
641                 free(plugin);
642                 dlclose(dl_handle);
643                 message_adaptor_error("Could not create listener object");
644                 return NULL;
645         }
646
647         plugin->path = g_strdup(plugin_path);
648         plugin->handle = handle;
649         plugin->dl_handle = dl_handle;
650         plugin->ref_counter = 0;
651
652         g_mutex_init(&plugin->ref_counter_mutex);
653         g_mutex_init(&plugin->plugin_listener_mutex);
654
655         plugin->connected = 0;
656
657         g_mutex_init(&plugin->plugin_connect_mutex);
658         g_cond_init(&plugin->plugin_connect_cond);
659
660         listener->message_adaptor_client_echo = message_adaptor_client_echo_cb;
661         listener->message_adaptor_create_chatroom_reply = message_adaptor_create_chatroom_reply_cb;
662         listener->message_adaptor_change_chatroom_meta_reply = message_adaptor_change_chatroom_meta_reply_cb;
663         listener->message_adaptor_chat_reply = message_adaptor_chat_reply_cb;
664         listener->message_adaptor_allow_chat_reply = message_adaptor_allow_chat_reply_cb;
665         listener->message_adaptor_get_all_unread_message_reply = message_adaptor_get_all_unread_message_reply_cb;
666         listener->message_adaptor_forward_online_message_request = message_adaptor_forward_online_message_request_cb;
667         listener->message_adaptor_forward_unread_message_request = message_adaptor_forward_unread_message_request_cb;
668         listener->message_adaptor_read_message_reply = message_adaptor_read_message_reply_cb;
669         listener->message_adaptor_invite_chat_reply = message_adaptor_invite_chat_reply_cb;
670         listener->message_adaptor_end_chat_reply = message_adaptor_end_chat_reply_cb;
671         listener->message_adaptor_unseal_message_reply = message_adaptor_unseal_message_reply_cb;
672         listener->message_adaptor_save_call_log_reply = message_adaptor_save_call_log_reply_cb;
673         listener->message_adaptor_current_time_reply = message_adaptor_current_time_reply_cb;
674         listener->message_adaptor_typing_updated = message_adaptor_typing_updated_cb;
675         listener->message_adaptor_completion = message_adaptor_completion_cb;
676
677         plugin_req_enter();
678         plugin->handle->set_listener(listener);
679         plugin_req_exit_void();
680
681         g_mutex_lock(&plugin->plugin_listener_mutex);
682         plugin->plugin_listener = listener;
683         g_mutex_unlock(&plugin->plugin_listener_mutex);
684
685         return plugin;
686 }
687
688 static void message_adaptor_destroy_plugin(message_adaptor_plugin_h plugin)
689 {
690         if (NULL == plugin) {
691                 message_adaptor_error("Invalid argument");
692                 return;
693         }
694
695         if (NULL != plugin->handle) {
696                 plugin->handle->destroy_handle(plugin->handle);
697
698                 g_mutex_lock(&plugin->plugin_listener_mutex);
699                 plugin_req_enter();
700                 plugin->handle->unset_listener();
701                 plugin_req_exit_void();
702                 g_mutex_unlock(&plugin->plugin_listener_mutex);
703
704                 plugin->handle = NULL;
705         }
706
707         if (NULL != plugin->dl_handle) {
708                 dlclose(plugin->dl_handle);
709                 plugin->dl_handle = NULL;
710         }
711
712         free(plugin->path);
713         plugin->path = NULL;
714
715         free(plugin);
716 }
717
718 static int message_adaptor_load_plugins_from_directory(message_adaptor_h adaptor, const char *dir_path)
719 {
720         char *plugin_path = NULL;
721         DIR *dir = NULL;
722         struct dirent dir_entry, *result = NULL;
723
724         message_adaptor_debug("Starting load plugins from directory");
725
726         if ((NULL == adaptor) || (NULL == dir_path)) {
727                 message_adaptor_error("Invalid argument");
728                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
729         }
730
731         dir = opendir(dir_path);
732         if (NULL == dir) {
733                 message_adaptor_error("Could not open dir path (%s)", dir_path);
734                 return MESSAGE_ADAPTOR_ERROR_NOT_FOUND;
735         }
736
737         int ret = MESSAGE_ADAPTOR_ERROR_NONE;
738         while (0 == (readdir_r(dir, &dir_entry, &result))) {
739
740                 if (NULL == result) {
741                         message_adaptor_error("Could not open directory %s", plugin_path);
742                         break;
743                 }
744
745                 if (dir_entry.d_type & DT_DIR) {
746                         continue;
747                 }
748
749                 plugin_path = g_strconcat(dir_path, "/", dir_entry.d_name, NULL);
750                 message_adaptor_plugin_h plugin = message_adaptor_create_plugin(plugin_path);
751
752                 if (NULL != plugin) {
753                         message_adaptor_debug("Loaded plugin: %s", plugin_path);
754                         plugin->adaptor = adaptor;
755                         message_adaptor_plugin_ref(plugin);
756                         g_mutex_lock(&adaptor->plugins_mutex);
757                         adaptor->plugins = g_list_append(adaptor->plugins, plugin);
758                         g_mutex_unlock(&adaptor->plugins_mutex);
759                 } else {
760                         message_adaptor_error("Could not load plugin %s", plugin_path);
761                 }
762
763                 free(plugin_path);
764                 plugin_path = NULL;
765         }
766
767         message_adaptor_debug("End load plugins from directory");
768         closedir(dir);
769         return ret;
770 }
771
772
773 static int message_adaptor_has_plugin(message_adaptor_h adaptor, message_adaptor_plugin_h plugin)
774 {
775         if ((NULL == adaptor) || (NULL == plugin)) {
776                 message_adaptor_error("Invalid argument");
777                 return 0;
778         }
779
780         int result = 0;
781
782         g_mutex_lock(&adaptor->plugins_mutex);
783         if (NULL != g_list_find(adaptor->plugins, plugin)) {
784                 result = 1;
785         }
786         g_mutex_unlock(&adaptor->plugins_mutex);
787
788         return result;
789 }
790
791 static void message_adaptor_plugin_ref(message_adaptor_plugin_h plugin)
792 {
793         if (NULL == plugin) {
794                 message_adaptor_error("Invalid argument");
795                 return;
796         }
797
798         g_mutex_lock(&plugin->ref_counter_mutex);
799         plugin->ref_counter = plugin->ref_counter + 1;
800         if (NULL != plugin->handle) {
801                 message_adaptor_info("plugin name : %s, ref_counter: %d", plugin->handle->plugin_uri, plugin->ref_counter);
802         } else {
803                 message_adaptor_info("ref_counter : %d", plugin->ref_counter);
804         }
805         g_mutex_unlock(&plugin->ref_counter_mutex);
806 }
807
808 static void message_adaptor_plugin_unref(message_adaptor_plugin_h plugin)
809 {
810         if (NULL == plugin) {
811                 message_adaptor_error("Invalid argument");
812                 return ;
813         }
814
815         int should_destroy = 0;
816
817         g_mutex_lock(&plugin->ref_counter_mutex);
818         plugin->ref_counter = plugin->ref_counter - 1;
819
820         if (NULL != plugin->handle) {
821                 message_adaptor_info("plugin name : %s, ref_counter: %d", plugin->handle->plugin_uri, plugin->ref_counter);
822         } else {
823                 message_adaptor_info("ref_counter : %d", plugin->ref_counter);
824         }
825
826         if (0 >= plugin->ref_counter) {
827                 should_destroy = 1;
828         }
829         g_mutex_unlock(&plugin->ref_counter_mutex);
830
831         if (should_destroy) {
832                 message_adaptor_debug("Plugin is being destroyed");
833                 message_adaptor_destroy_plugin(plugin);
834         }
835 }
836
837
838 /**
839  * Refresh access token
840  */
841 EXPORT_API
842 message_error_code_t message_adaptor_refresh_access_token(message_adaptor_plugin_context_h context,
843                                                 const char *new_access_token)
844 {
845         if ((NULL == context) || (NULL == new_access_token) || (0 >= strlen(new_access_token))) {
846                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
847         }
848         if ((NULL == context->access_token) || (0 >= strlen(context->access_token))) {
849                 return MESSAGE_ADAPTOR_ERROR_NOT_AUTHORIZED;
850         }
851
852         free(context->access_token);
853         context->access_token = NULL;
854         context->access_token = strdup(new_access_token);
855
856         return MESSAGE_ADAPTOR_ERROR_NONE;
857 }
858
859 EXPORT_API
860 message_error_code_t message_adaptor_refresh_uid(message_adaptor_plugin_context_h context,
861                                                 const char *new_uid)
862 {
863         if ((NULL == context) || (NULL == new_uid) || (0 >= strlen(new_uid))) {
864                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
865         }
866         message_adaptor_debug("New uid : %s", new_uid);
867
868         free(context->uid);
869         context->uid = NULL;
870         context->uid = strdup(new_uid);
871
872         char *pend = NULL;
873         context->duid = (long long int) strtoll(new_uid, &pend, 10);
874
875         return MESSAGE_ADAPTOR_ERROR_NONE;
876 }
877
878 /* //////////////////////////////////////////////////////
879    // Create / Destroy error code
880    ////////////////////////////////////////////////////// */
881 message_adaptor_error_code_h message_adaptor_create_error_code(const char *code, const char *msg)
882 {
883         if (NULL == code || NULL == msg) {
884                 return NULL;
885         }
886
887         message_adaptor_error_code_h error_code = (message_adaptor_error_code_h) malloc(sizeof(message_adaptor_error_code_t));
888
889         if (NULL != error_code) {
890                 error_code->code = strdup(code);
891                 error_code->msg = strdup(msg);
892         }
893
894         return error_code;
895 }
896
897 void message_adaptor_destroy_error_code(message_adaptor_error_code_h *error_code)
898 {
899         if ((NULL != error_code) && (NULL != (*error_code))) {
900                 free((*error_code)->msg);
901                 (*error_code)->msg = NULL;
902                 free(*error_code);
903                 *error_code = NULL;
904         }
905 }
906
907 void _set_error_code(message_adaptor_error_code_h *error, const char *code, const char *msg)
908 {
909         if (NULL == error) {
910                 return;
911         }
912
913         message_adaptor_error_code_h error_code = (message_adaptor_error_code_h) calloc(1, sizeof(message_adaptor_error_code_t));
914
915         if (NULL != error_code) {
916                 error_code->code = strdup(code);
917                 error_code->msg = strdup(msg);
918         }
919
920         *error = error_code;
921 }
922
923 void message_adaptor_destroy_chat_msg_s(message_adaptor_chat_msg_s *msg)
924 {
925         if (NULL == msg) {
926                 return;
927         }
928         free(msg->chatmsg);
929         free(msg);
930 }
931 void message_adaptor_destroy_processed_msg_s(message_adaptor_processed_msg_s *msg)
932 {
933         if (NULL == msg) {
934                 return;
935         }
936         free(msg);
937 }
938 void message_adaptor_destroy_delivery_ack_s(message_adaptor_delivery_ack_s *ack)
939 {
940         if (NULL == ack) {
941                 return;
942         }
943         free(ack);
944 }
945 void message_adaptor_destroy_read_ack_s(message_adaptor_read_ack_s *ack)
946 {
947         if (NULL == ack) {
948                 return;
949         }
950         free(ack);
951 }
952 void message_adaptor_destroy_ordered_chat_member_s(message_adaptor_ordered_chat_member_s *member)
953 {
954         if (NULL == member) {
955                 return;
956         }
957         free(member->name);
958         free(member);
959 }
960 void message_adaptor_destroy_inbox_message_s(message_adaptor_inbox_message_s *msg)
961 {
962         if (NULL == msg) {
963                 return;
964         }
965         free(msg->chatMsg);
966         free(msg);
967 }
968 void message_adaptor_destroy_phone_number_s(message_adaptor_phone_number_s *num)
969 {
970         if (NULL == num) {
971                 return;
972         }
973         free(num->phonenumber);
974         free(num->ccc);
975         free(num);
976 }
977 void message_adaptor_destroy_chat_id_s(message_adaptor_chat_id_s *id)
978 {
979         if (NULL == id) {
980                 return;
981         }
982         free(id->msisdn);
983         free(id);
984 }
985 void message_adaptor_destroy_end_chat_s(message_adaptor_end_chat_s *msg)
986 {
987         if (NULL == msg) {
988                 return;
989         }
990         free(msg);
991 }
992
993
994 /* //////////////////////////////////////////////////////
995    // Plugin context create / destroy
996    ////////////////////////////////////////////////////// */
997
998 message_adaptor_plugin_context_h message_adaptor_create_plugin_context(message_adaptor_plugin_h plugin,
999                                                 char *plugin_uri,
1000                                                 char *duid,
1001                                                 char *access_token,
1002                                                 char *app_id,
1003                                                 int service_id)
1004 {
1005         message_adaptor_debug("Starting message_adaptor_create_plugin_context");
1006
1007         if (NULL == plugin) {
1008                 message_adaptor_error("Invalid argument");
1009                 return NULL;
1010         }
1011
1012         if (NULL != plugin->handle) {
1013                 message_adaptor_plugin_context_h plugin_context = NULL;
1014
1015                 plugin_req_enter();
1016                 plugin->handle->create_context(&plugin_context, duid, access_token, app_id, service_id);
1017                 plugin_req_exit_void();
1018
1019                 if (NULL != plugin_context) {
1020                         plugin_context->plugin_uri = strdup(plugin->handle->plugin_uri);
1021                         plugin_context->connection_policy = MESSAGE_CONNECTION_POLICY_AUTO;
1022                 } else {
1023                         message_adaptor_error("plugin context info message_context set error");
1024                         message_adaptor_error("plugin context info message_plugin set error");
1025                 }
1026                 return plugin_context;
1027         } else {
1028                 message_adaptor_error("Plugin handle is null");
1029         }
1030
1031         message_adaptor_debug("End message_adaptor_create_plugin_context");
1032         return NULL;
1033 }
1034
1035 void message_adaptor_destroy_plugin_context(message_adaptor_plugin_h plugin, message_adaptor_plugin_context_h plugin_context)
1036 {
1037         message_adaptor_warning("Destroy plugin context");
1038
1039         if ((NULL == plugin) || (NULL == plugin_context)) {
1040                 message_adaptor_error("Invalid argument");
1041                 return;
1042         }
1043
1044         if (NULL != plugin->handle) {
1045                 plugin_req_enter();
1046                 plugin->handle->destroy_context(plugin_context);
1047                 plugin_req_exit_void();
1048         } else {
1049                 message_adaptor_error("Plugin handle is null");
1050         }
1051 }
1052
1053 message_error_code_t message_adaptor_set_connected(message_adaptor_plugin_h plugin, int connected)
1054 {
1055         if (NULL == plugin) {
1056                 message_adaptor_error("plugin is NULL");
1057                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1058         }
1059
1060         g_mutex_lock(&plugin->plugin_connect_mutex);
1061         plugin->connected = connected;
1062         g_cond_signal(&plugin->plugin_connect_cond);
1063         g_mutex_unlock(&plugin->plugin_connect_mutex);
1064
1065         return MESSAGE_ADAPTOR_ERROR_NONE;
1066 }
1067
1068 message_error_code_t message_adaptor_wait_connected(message_adaptor_plugin_h plugin)
1069 {
1070         if (NULL == plugin) {
1071                 message_adaptor_error("plugin is NULL");
1072                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1073         }
1074
1075         gint64 timeout = g_get_monotonic_time() + 10 * G_TIME_SPAN_SECOND;
1076         g_mutex_lock(&plugin->plugin_connect_mutex);
1077
1078         while (0 == plugin->connected) {
1079                 if (!g_cond_wait_until(&plugin->plugin_connect_cond, &plugin->plugin_connect_mutex, timeout)) {
1080                         g_mutex_unlock(&plugin->plugin_connect_mutex);
1081                         return MESSAGE_ADAPTOR_ERROR_CONNECT;
1082                 }
1083         }
1084
1085         g_mutex_unlock(&plugin->plugin_connect_mutex);
1086
1087         return MESSAGE_ADAPTOR_ERROR_NONE;
1088 }
1089
1090 /* //////////////////////////////////////////////////////
1091    // Get plugin by plugin name
1092    ////////////////////////////////////////////////////// */
1093 message_adaptor_plugin_h message_adaptor_get_plugin_by_name(message_adaptor_h adaptor, const char *plugin_uri)
1094 {
1095         message_adaptor_warning("Starting message_adaptor_get_plugin_by_name");
1096
1097         if ((NULL == adaptor)) {
1098                 message_adaptor_error("adaptor is NULL");
1099         }
1100
1101         if ((NULL == plugin_uri)) {
1102                 message_adaptor_error("adaptor is NULL");
1103         } else {
1104                 message_adaptor_error("plugin name : %s", plugin_uri);
1105         }
1106
1107         if ((NULL == adaptor) || (NULL == plugin_uri)) {
1108                 message_adaptor_error("Invalid argument");
1109                 return NULL;
1110         }
1111
1112         message_adaptor_plugin_h plugin = NULL;
1113         g_mutex_lock(&adaptor->plugins_mutex);
1114         int count = g_list_length(adaptor->plugins);
1115         int i = 0;
1116         message_adaptor_error("count : %d", count);
1117         for (i = 0; i < count; i++) {
1118                 message_adaptor_plugin_h temp_plugin = (message_adaptor_plugin_h)g_list_nth_data(adaptor->plugins, i);
1119                 if (NULL != temp_plugin) {
1120                         message_adaptor_error("temp_plugin name : %s", temp_plugin->handle->plugin_uri);
1121                         if (0 == strcmp(temp_plugin->handle->plugin_uri, plugin_uri)) {
1122                                 message_adaptor_plugin_ref(temp_plugin);
1123                                 plugin = temp_plugin;
1124                                 g_mutex_unlock(&adaptor->plugins_mutex);
1125                                 return plugin;
1126                         }
1127                 } else {
1128                         message_adaptor_error("NULL != temp_plugin");
1129                 }
1130         }
1131         g_mutex_unlock(&adaptor->plugins_mutex);
1132
1133         if (NULL == plugin) {
1134                 message_adaptor_debug("Plugin is not found by name");
1135         }
1136
1137         return plugin;
1138 }
1139
1140 /* //////////////////////////////////////////////////////
1141    // Plugin load / unload / get plugin list
1142    ////////////////////////////////////////////////////// */
1143 int message_adaptor_load_plugin(message_adaptor_h adaptor, const char *plugin_path)
1144 {
1145         if ((NULL == adaptor) || (NULL == plugin_path)) {
1146                 message_adaptor_error("Invalid argument");
1147                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1148         }
1149
1150         if (!adaptor->started) {
1151                 message_adaptor_error("Storage adaptor is not started");
1152                 return MESSAGE_ADAPTOR_ERROR_START;
1153         }
1154
1155         message_adaptor_plugin_h plugin = message_adaptor_create_plugin(plugin_path);
1156         if (NULL == plugin) {
1157                 message_adaptor_error("Could not load plugin %s", plugin_path);
1158                 return MESSAGE_ADAPTOR_ERROR_CREATE;
1159         }
1160
1161         plugin->adaptor = adaptor;
1162         message_adaptor_plugin_ref(plugin);
1163
1164         g_mutex_lock(&adaptor->plugins_mutex);
1165         adaptor->plugins = g_list_append(adaptor->plugins, plugin);
1166         g_mutex_unlock(&adaptor->plugins_mutex);
1167
1168         return MESSAGE_ADAPTOR_ERROR_NONE;
1169 }
1170
1171 int message_adaptor_unload_plugin(message_adaptor_h adaptor, message_adaptor_plugin_h plugin)
1172 {
1173         if ((NULL == adaptor) || (NULL == plugin)) {
1174                 message_adaptor_error("Invalid argument");
1175                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1176         }
1177
1178         if (!adaptor->started) {
1179                 message_adaptor_error("Storage adaptor is not started");
1180                 return MESSAGE_ADAPTOR_ERROR_START;
1181         }
1182
1183         if (!message_adaptor_has_plugin(adaptor, plugin)) {
1184                 message_adaptor_error("Storage adaptor has no plugin");
1185                 return MESSAGE_ADAPTOR_ERROR_NOT_FOUND;
1186         }
1187
1188         plugin->adaptor = NULL;
1189
1190         g_mutex_lock(&adaptor->plugins_mutex);
1191         adaptor->plugins = g_list_remove(adaptor->plugins, plugin);
1192         g_mutex_unlock(&adaptor->plugins_mutex);
1193         message_adaptor_plugin_unref(plugin);
1194
1195         return MESSAGE_ADAPTOR_ERROR_NONE;
1196 }
1197
1198 GList *message_adaptor_get_plugins(message_adaptor_h adaptor)
1199 {
1200         if (NULL == adaptor) {
1201                 message_adaptor_error("Invalid argument");
1202                 return NULL;
1203         }
1204
1205         GList *plugins = NULL;
1206         g_mutex_lock(&adaptor->plugins_mutex);
1207         int plugins_count = g_list_length(adaptor->plugins);
1208         int i;
1209         for (i = 0; i < plugins_count; i++) {
1210                 message_adaptor_plugin_h plugin = (message_adaptor_plugin_h) g_list_nth_data(adaptor->plugins, i);
1211                 if (NULL != plugin) {
1212                         message_adaptor_plugin_ref(plugin);
1213                         plugins = g_list_append(plugins, plugin);
1214                 }
1215         }
1216         g_mutex_unlock(&adaptor->plugins_mutex);
1217
1218         return plugins;
1219
1220 }
1221
1222 /* ////////////////////////////////////////////////////////////
1223    // Adaptor Plugin call Functions
1224    //////////////////////////////////////////////////////////// */
1225
1226 /**
1227 * @brief Set server information for Message Plugin
1228 *
1229 * @param[in]    plugin                          specifies Message Adaptor Plugin handle
1230 * @param[in]    context                         specifies Message Adaptor Plugin Context handle
1231 * @param[in]    server_info                     specifies server information for Message Plugin
1232 * @param[in]    request                         specifies optional parameter
1233 * @param[out]   error                           specifies error code
1234 * @param[out]   response                        specifies optional parameter
1235 * @return 0 on success, otherwise a positive error value
1236 * @retval error code defined in message_error_code_t - MESSAGE_ADAPTOR_ERROR_NONE if Successful
1237 */
1238 EXPORT_API
1239 message_error_code_t message_adaptor_set_server_info(message_adaptor_plugin_h plugin,
1240                                                 message_adaptor_plugin_context_h context,
1241                                                 GHashTable *server_info,
1242                                                 void *request,
1243                                                 message_adaptor_error_code_h *error_code,
1244                                                 void *response)
1245 {
1246         if ((NULL == plugin) || (NULL == context)) {
1247                 message_adaptor_error("Invalid argument""(plugin: %p, context: %p)", plugin, context);
1248
1249                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1250
1251                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1252         }
1253
1254         if (NULL == plugin->handle) {
1255                 message_adaptor_error("Plugin handle is null");
1256                 _set_error_code(error_code, "13", "Plugin handle is null");
1257
1258                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1259         }
1260
1261         message_error_code_t ret;
1262         plugin_req_enter();
1263         ret = plugin->handle->set_server_info(context, server_info, request, error_code, response);
1264         plugin_req_exit(ret, plugin, error_code);
1265
1266         return ret;
1267 }
1268
1269
1270 /*TODO fill this area */
1271 EXPORT_API
1272 message_error_code_t message_adaptor_get_key(message_adaptor_plugin_h plugin,
1273                                                 message_adaptor_plugin_context_h context,
1274                                                 char **in_gcmid,
1275                                                 char **in_del_gcm_id,
1276                                                 char **key,
1277                                                 char **expiredkey,
1278                                                 char **gpbauthkey,
1279                                                 message_adaptor_error_code_t **error_code,
1280                                                 void **server_data)
1281 {
1282         if ((NULL == plugin) || (NULL == context)) {
1283                 message_adaptor_error("Invalid argument");
1284
1285                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1286
1287                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1288         }
1289
1290         if (NULL == plugin->handle) {
1291                 message_adaptor_error("Plugin handle is null");
1292
1293                 _set_error_code(error_code, "13", "Plugin handle is null");
1294
1295                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1296         }
1297
1298         if (NULL == context->uid) {
1299                 message_adaptor_error("UID is null");
1300
1301                 _set_error_code(error_code, "14", "Invalid argument (uid)");
1302
1303                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1304         }
1305
1306         message_error_code_t ret;
1307         plugin_req_enter();
1308         ret = plugin->handle->get_key(context, &(context->uid), in_gcmid, in_del_gcm_id, key, expiredkey, gpbauthkey, error_code, server_data);
1309         plugin_req_exit(ret, plugin, error_code);
1310
1311         return ret;
1312 }
1313
1314 EXPORT_API
1315 message_error_code_t message_adaptor_request_chat_id(message_adaptor_plugin_h plugin,
1316                                                 message_adaptor_plugin_context_h context,
1317                                                 message_adaptor_phone_number_s **phone_numbers,
1318                                                 unsigned int phone_numbers_len,
1319                                                 void *user_data,
1320                                                 message_adaptor_chat_id_s ***chat_ids,
1321                                                 unsigned int *chat_ids_len,
1322                                                 message_adaptor_error_code_t **error_code,
1323                                                 void **server_data)
1324 {
1325         message_adaptor_info("%s() Start!!!", __FUNCTION__);
1326
1327         if ((NULL == plugin) || (NULL == context)) {
1328                 message_adaptor_error("Invalid argument");
1329
1330                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1331
1332                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1333         }
1334
1335         if (NULL == plugin->handle) {
1336                 message_adaptor_error("Plugin handle is null");
1337
1338                 _set_error_code(error_code, "13", "Plugin handle is null");
1339
1340                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1341         }
1342
1343         if (NULL == context->uid) {
1344                 message_adaptor_error("UID is null");
1345
1346                 _set_error_code(error_code, "14", "Invalid argument (uid)");
1347
1348                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1349         }
1350
1351         message_error_code_t ret;
1352         plugin_req_enter();
1353         ret = plugin->handle->request_chat_id(context, context->uid, phone_numbers, phone_numbers_len, user_data, chat_ids, chat_ids_len, error_code, server_data);
1354         plugin_req_exit(ret, plugin, error_code);
1355
1356         return ret;
1357 }
1358
1359 EXPORT_API
1360 message_error_code_t message_adaptor_request_msisdn(message_adaptor_plugin_h plugin,
1361                                                 message_adaptor_plugin_context_h context,
1362                                                 long long int *chat_ids,
1363                                                 unsigned int chat_ids_len,
1364                                                 void *user_data,
1365                                                 message_adaptor_chat_id_s ***msisdns,
1366                                                 unsigned int *msisdns_len,
1367                                                 message_adaptor_error_code_t **error_code,
1368                                                 void **server_data)
1369 {
1370         message_adaptor_info("%s() Start!!!", __FUNCTION__);
1371
1372         if ((NULL == plugin) || (NULL == context)) {
1373                 message_adaptor_error("Invalid argument");
1374
1375                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1376
1377                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1378         }
1379
1380         if (NULL == plugin->handle) {
1381                 message_adaptor_error("Plugin handle is null");
1382
1383                 _set_error_code(error_code, "13", "Plugin handle is null");
1384
1385                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1386         }
1387
1388         if (NULL == context->uid) {
1389                 message_adaptor_error("UID is null");
1390
1391                 _set_error_code(error_code, "14", "Invalid argument (uid)");
1392
1393                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1394         }
1395
1396         message_error_code_t ret;
1397         plugin_req_enter();
1398         ret = plugin->handle->request_msisdn(context, context->uid, chat_ids, chat_ids_len, user_data, msisdns, msisdns_len, error_code, server_data);
1399         plugin_req_exit(ret, plugin, error_code);
1400
1401         return ret;
1402 }
1403
1404 /*TODO fill this area */
1405 EXPORT_API
1406 message_error_code_t message_adaptor_channel_auth_request(message_adaptor_plugin_h plugin,
1407                                                 message_adaptor_plugin_context_h context,
1408                                                 long long int request_id,
1409                                                 const int timeout_second,
1410                                                 void *user_data,
1411                                                 message_adaptor_error_code_t **error_code,
1412                                                 void *server_data)
1413 {
1414         if ((NULL == plugin) || (NULL == context)) {
1415                 message_adaptor_error("Invalid argument");
1416
1417                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1418
1419                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1420         }
1421
1422         if (NULL == plugin->handle) {
1423                 message_adaptor_error("Plugin handle is null");
1424
1425                 _set_error_code(error_code, "13", "Plugin handle is null");
1426
1427                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1428         }
1429         plugin_req_id_print();
1430
1431         message_error_code_t ret;
1432         plugin_req_enter();
1433         ret = plugin->handle->channel_auth_request(context, request_id, context->uid,
1434                         context->duid, context->app_id, context->access_token,
1435                         timeout_second, user_data, error_code, server_data);
1436         plugin_req_exit(ret, plugin, error_code);
1437
1438         return ret;
1439 }
1440
1441 EXPORT_API
1442 message_error_code_t message_adaptor_client_echo_reply(message_adaptor_plugin_h plugin,
1443                                                 message_adaptor_plugin_context_h context,
1444                                                 long long int request_id,
1445                                                 message_adaptor_error_code_t **error_code,
1446                                                 void *server_data)
1447 {
1448         if ((NULL == plugin) || (NULL == context)) {
1449                 message_adaptor_error("Invalid argument");
1450
1451                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1452
1453                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1454         }
1455
1456         if (NULL == plugin->handle) {
1457                 message_adaptor_error("Plugin handle is null");
1458
1459                 _set_error_code(error_code, "13", "Plugin handle is null");
1460
1461                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1462         }
1463         plugin_req_id_print();
1464
1465         message_error_code_t ret;
1466         plugin_req_enter();
1467         ret = plugin->handle->client_echo_reply(context, &request_id, error_code, server_data);
1468         plugin_req_exit(ret, plugin, error_code);
1469
1470         return ret;
1471 }
1472
1473 EXPORT_API
1474 message_error_code_t message_adaptor_create_chatroom_request(message_adaptor_plugin_h plugin,
1475                                                 message_adaptor_plugin_context_h context,
1476                                                 long long int request_id,
1477                                                 int chat_type,
1478                                                 long long int **receivers,
1479                                                 unsigned int receivers_len,
1480                                                 const char *chatroom_title,
1481                                                 message_adaptor_error_code_t **error_code,
1482                                                 void *user_data)
1483 {
1484         if ((NULL == plugin) || (NULL == context)) {
1485                 message_adaptor_error("Invalid argument");
1486
1487                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1488
1489                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1490         }
1491
1492         if (NULL == plugin->handle) {
1493                 message_adaptor_error("Plugin handle is null");
1494
1495                 _set_error_code(error_code, "13", "Plugin handle is null");
1496
1497                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1498         }
1499         plugin_req_id_print();
1500
1501         message_error_code_t ret;
1502         plugin_req_enter();
1503         ret = plugin->handle->create_chatroom_request(context, &request_id, &chat_type, receivers,
1504                         (int *)&receivers_len, chatroom_title, error_code, user_data);
1505         plugin_req_exit(ret, plugin, error_code);
1506
1507         return ret;
1508 }
1509
1510 EXPORT_API
1511 message_error_code_t message_adaptor_change_chatroom_meta_request(message_adaptor_plugin_h plugin,
1512                                                 message_adaptor_plugin_context_h context,
1513                                                 long long int request_id,
1514                                                 long long int chatroom_id,
1515                                                 const char *chatroom_title,
1516                                                 int default_message_ttl,
1517                                                 message_adaptor_error_code_t **error_code,
1518                                                 void *user_data)
1519 {
1520         if ((NULL == plugin) || (NULL == context)) {
1521                 message_adaptor_error("Invalid argument");
1522
1523                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1524
1525                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1526         }
1527
1528         if (NULL == plugin->handle) {
1529                 message_adaptor_error("Plugin handle is null");
1530
1531                 _set_error_code(error_code, "13", "Plugin handle is null");
1532
1533                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1534         }
1535         plugin_req_id_print();
1536
1537         message_error_code_t ret;
1538         plugin_req_enter();
1539         ret = plugin->handle->change_chatroom_meta_request(context, request_id, chatroom_id, chatroom_title,
1540                         default_message_ttl, error_code, user_data);
1541         plugin_req_exit(ret, plugin, error_code);
1542
1543         return ret;
1544 }
1545
1546
1547 EXPORT_API
1548 message_error_code_t message_adaptor_chat_request(message_adaptor_plugin_h plugin,
1549                                                 message_adaptor_plugin_context_h context,
1550                                                 long long int request_id,
1551                                                 long long int chatroom_id,
1552                                                 message_adaptor_chat_msg_s **chat_msgs,
1553                                                 unsigned int chat_msgs_len,
1554                                                 message_adaptor_error_code_t **error_code,
1555                                                 void *user_data)
1556 {
1557         if ((NULL == plugin) || (NULL == context)) {
1558                 message_adaptor_error("Invalid argument");
1559
1560                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1561
1562                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1563         }
1564
1565         if (NULL == plugin->handle) {
1566                 message_adaptor_error("Plugin handle is null");
1567
1568                 _set_error_code(error_code, "13", "Plugin handle is null");
1569
1570                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1571         }
1572         plugin_req_id_print();
1573
1574         message_error_code_t ret;
1575         plugin_req_enter();
1576         ret = plugin->handle->chat_request(context, &request_id, &chatroom_id, chat_msgs[0], error_code, user_data);
1577         plugin_req_exit(ret, plugin, error_code);
1578
1579         return ret;
1580 }
1581
1582 EXPORT_API
1583 message_error_code_t message_adaptor_allow_chat_request(message_adaptor_plugin_h plugin,
1584                                                 message_adaptor_plugin_context_h context,
1585                                                 long long int request_id,
1586                                                 long long int chatroom_id,
1587                                                 bool is_auto_allow,
1588                                                 int max_count,
1589                                                 bool need_delivery_ack,
1590                                                 long long int delivery_ack_timestamp,
1591                                                 bool need_read_ack,
1592                                                 long long int last_read_ack_timestamp,
1593                                                 bool need_ordered_chat_member_list,
1594                                                 message_adaptor_error_code_t **error_code,
1595                                                 void *user_data)
1596 {
1597         if ((NULL == plugin) || (NULL == context)) {
1598                 message_adaptor_error("Invalid argument");
1599
1600                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1601
1602                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1603         }
1604
1605         if (NULL == plugin->handle) {
1606                 message_adaptor_error("Plugin handle is null");
1607
1608                 _set_error_code(error_code, "13", "Plugin handle is null");
1609
1610                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1611         }
1612         plugin_req_id_print();
1613
1614         message_error_code_t ret;
1615         plugin_req_enter();
1616         ret = plugin->handle->allow_chat_request(context,
1617                         &request_id, &chatroom_id, is_auto_allow, max_count,
1618                         need_delivery_ack, delivery_ack_timestamp,
1619                         need_read_ack, last_read_ack_timestamp,
1620                         need_ordered_chat_member_list,
1621                         error_code, user_data);
1622         plugin_req_exit(ret, plugin, error_code);
1623
1624         return ret;
1625 }
1626
1627
1628 EXPORT_API
1629 message_error_code_t message_adaptor_get_all_unread_message_request(message_adaptor_plugin_h plugin,
1630                                                 message_adaptor_plugin_context_h context,
1631                                                 long long int request_id,
1632                                                 int max_count,
1633                                                 message_adaptor_error_code_t **error_code,
1634                                                 void *user_data)
1635 {
1636         if ((NULL == plugin) || (NULL == context)) {
1637                 message_adaptor_error("Invalid argument");
1638
1639                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1640
1641                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1642         }
1643
1644         if (NULL == plugin->handle) {
1645                 message_adaptor_error("Plugin handle is null");
1646
1647                 _set_error_code(error_code, "13", "Plugin handle is null");
1648
1649                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1650         }
1651         plugin_req_id_print();
1652
1653         message_error_code_t ret;
1654         plugin_req_enter();
1655         ret = plugin->handle->get_all_unread_message_request(context, &request_id, &max_count, error_code, user_data);
1656         plugin_req_exit(ret, plugin, error_code);
1657
1658         return ret;
1659 }
1660
1661
1662 EXPORT_API
1663 message_error_code_t message_adaptor_forward_online_message_reply(message_adaptor_plugin_h plugin,
1664                                                 message_adaptor_plugin_context_h context,
1665                                                 long long int request_id,
1666                                                 long long int chatroom_id,
1667                                                 bool mark_as_read,
1668                                                 message_adaptor_error_code_t **error_code,
1669                                                 void *user_data)
1670 {
1671         if ((NULL == plugin) || (NULL == context)) {
1672                 message_adaptor_error("Invalid argument");
1673
1674                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1675
1676                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1677         }
1678
1679         if (NULL == plugin->handle) {
1680                 message_adaptor_error("Plugin handle is null");
1681
1682                 _set_error_code(error_code, "13", "Plugin handle is null");
1683
1684                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1685         }
1686         plugin_req_id_print();
1687
1688         message_error_code_t ret;
1689         plugin_req_enter();
1690         ret = plugin->handle->forward_online_message_reply(context, &request_id, &chatroom_id, &mark_as_read, error_code, user_data);
1691         plugin_req_exit(ret, plugin, error_code);
1692
1693         return ret;
1694 }
1695
1696 EXPORT_API
1697 message_error_code_t message_adaptor_forward_unread_message_reply(message_adaptor_plugin_h plugin,
1698                                                 message_adaptor_plugin_context_h context,
1699                                                 long long int request_id,
1700                                                 const char *next_pagination_key,
1701                                                 int max_count,
1702                                                 message_adaptor_error_code_t **error_code,
1703                                                 void *user_data)
1704 {
1705         if ((NULL == plugin) || (NULL == context)) {
1706                 message_adaptor_error("Invalid argument");
1707
1708                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1709
1710                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1711         }
1712
1713         if (NULL == plugin->handle) {
1714                 message_adaptor_error("Plugin handle is null");
1715
1716                 _set_error_code(error_code, "13", "Plugin handle is null");
1717
1718                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1719         }
1720         plugin_req_id_print();
1721
1722         message_error_code_t ret;
1723         plugin_req_enter();
1724         ret = plugin->handle->forward_unread_message_reply(context, &request_id, &next_pagination_key, &max_count, error_code, user_data);
1725         plugin_req_exit(ret, plugin, error_code);
1726
1727         return ret;
1728 }
1729
1730 EXPORT_API
1731 message_error_code_t message_adaptor_read_message_request(message_adaptor_plugin_h plugin,
1732                                                 message_adaptor_plugin_context_h context,
1733                                                 long long int request_id,
1734                                                 long long int chatroom_id,
1735                                                 message_inboxentry_t *inbox_msg,
1736                                                 message_adaptor_error_code_t **error_code,
1737                                                 void *user_data)
1738 {
1739         if ((NULL == plugin) || (NULL == context)) {
1740                 message_adaptor_error("Invalid argument");
1741
1742                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1743
1744                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1745         }
1746
1747         if (NULL == plugin->handle) {
1748                 message_adaptor_error("Plugin handle is null");
1749
1750                 _set_error_code(error_code, "13", "Plugin handle is null");
1751
1752                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1753         }
1754         plugin_req_id_print();
1755
1756         message_error_code_t ret;
1757         plugin_req_enter();
1758         ret = plugin->handle->read_message_request(context, &request_id, &chatroom_id,
1759                         inbox_msg, error_code, user_data);
1760         plugin_req_exit(ret, plugin, error_code);
1761
1762         return ret;
1763 }
1764
1765 EXPORT_API
1766 message_error_code_t message_adaptor_invite_chat_request(message_adaptor_plugin_h plugin,
1767                                                 message_adaptor_plugin_context_h context,
1768                                                 long long int request_id,
1769                                                 long long int chatroom_id,
1770                                                 long long int *inviting_members,
1771                                                 unsigned int inviting_members_len,
1772                                                 message_adaptor_error_code_t **error_code,
1773                                                 void *user_data)
1774 {
1775         if ((NULL == plugin) || (NULL == context)) {
1776                 message_adaptor_error("Invalid argument");
1777
1778                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1779
1780                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1781         }
1782
1783         if (NULL == plugin->handle) {
1784                 message_adaptor_error("Plugin handle is null");
1785
1786                 _set_error_code(error_code, "13", "Plugin handle is null");
1787
1788                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1789         }
1790         plugin_req_id_print();
1791
1792         message_error_code_t ret;
1793         plugin_req_enter();
1794         ret = plugin->handle->invite_request(context, &request_id, &chatroom_id,
1795                         inviting_members, (int *)&inviting_members_len, error_code, user_data);
1796         plugin_req_exit(ret, plugin, error_code);
1797
1798         return ret;
1799 }
1800
1801 EXPORT_API
1802 message_error_code_t message_adaptor_end_chat_request(message_adaptor_plugin_h plugin,
1803                                                 message_adaptor_plugin_context_h context,
1804                                                 long long int request_id,
1805                                                 message_adaptor_end_chat_s **end_chats,
1806                                                 unsigned int end_chats_len,
1807                                                 message_adaptor_error_code_t **error_code,
1808                                                 void *user_data)
1809 {
1810         if ((NULL == plugin) || (NULL == context)) {
1811                 message_adaptor_error("Invalid argument");
1812
1813                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1814
1815                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1816         }
1817
1818         if (NULL == plugin->handle) {
1819                 message_adaptor_error("Plugin handle is null");
1820
1821                 _set_error_code(error_code, "13", "Plugin handle is null");
1822
1823                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1824         }
1825         plugin_req_id_print();
1826
1827         message_error_code_t ret;
1828         plugin_req_enter();
1829         ret = plugin->handle->end_chat_request(context, &request_id, end_chats, (int *)&end_chats_len, error_code, user_data);
1830         plugin_req_exit(ret, plugin, error_code);
1831
1832         return ret;
1833 }
1834
1835 EXPORT_API
1836 message_error_code_t message_adaptor_unseal_message_request(message_adaptor_plugin_h plugin,
1837                                                 message_adaptor_plugin_context_h context,
1838                                                 long long int request_id,
1839                                                 long long int chatroom_id,
1840                                                 long long int sender_id,
1841                                                 long long int message_id,
1842                                                 const char *message_detail,
1843                                                 message_adaptor_error_code_t **error_code,
1844                                                 void *user_data)
1845 {
1846         if ((NULL == plugin) || (NULL == context)) {
1847                 message_adaptor_error("Invalid argument");
1848                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1849
1850                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1851         }
1852
1853         if (NULL == plugin->handle) {
1854                 message_adaptor_error("Plugin handle is null");
1855
1856                 _set_error_code(error_code, "13", "Plugin handle is null");
1857
1858                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1859         }
1860         plugin_req_id_print();
1861
1862         message_error_code_t ret;
1863         plugin_req_enter();
1864         ret = plugin->handle->unseal_message_request(context, &request_id,
1865                         &chatroom_id, &sender_id, &message_id, message_detail, error_code, user_data);
1866         plugin_req_exit(ret, plugin, error_code);
1867
1868         return ret;
1869 }
1870
1871 EXPORT_API
1872 message_error_code_t message_adaptor_save_call_log_request(message_adaptor_plugin_h plugin,
1873                                                 message_adaptor_plugin_context_h context,
1874                                                 long long int request_id,
1875                                                 long long int chatroom_id,
1876                                                 const char *call_id,
1877                                                 const char *call_log_type,
1878                                                 long long int call_sender_id,
1879                                                 long long int call_receiver_id,
1880                                                 int conversaction_second,
1881                                                 message_adaptor_error_code_t **error_code,
1882                                                 void *user_data)
1883 {
1884         if ((NULL == plugin) || (NULL == context)) {
1885                 message_adaptor_error("Invalid argument");
1886                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1887
1888                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1889         }
1890
1891         if (NULL == plugin->handle) {
1892                 message_adaptor_error("Plugin handle is null");
1893                 _set_error_code(error_code, "13", "Plugin handle is null");
1894
1895                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1896         }
1897         plugin_req_id_print();
1898
1899         message_error_code_t ret;
1900         plugin_req_enter();
1901         ret = plugin->handle->save_call_log_request(context, &request_id, &chatroom_id, &call_id, &call_log_type, &call_sender_id, &call_receiver_id, &conversaction_second, error_code, user_data);
1902         plugin_req_exit(ret, plugin, error_code);
1903
1904         return ret;
1905 }
1906
1907 EXPORT_API
1908 message_error_code_t message_adaptor_current_time_request(message_adaptor_plugin_h plugin,
1909                                                 message_adaptor_plugin_context_h context,
1910                                                 long long int request_id,
1911                                                 message_adaptor_error_code_t **error_code,
1912                                                 void *user_data)
1913 {
1914         if ((NULL == plugin) || (NULL == context)) {
1915                 message_adaptor_error("Invalid argument");
1916
1917                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1918
1919                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1920         }
1921
1922         if (NULL == plugin->handle) {
1923                 message_adaptor_error("Plugin handle is null");
1924
1925                 _set_error_code(error_code, "13", "Plugin handle is null");
1926
1927                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1928         }
1929         plugin_req_id_print();
1930
1931         message_error_code_t ret;
1932         plugin_req_enter();
1933         ret = plugin->handle->current_time_request(context, &request_id, error_code, user_data);
1934         plugin_req_exit(ret, plugin, error_code);
1935
1936         return ret;
1937 }
1938
1939 EXPORT_API
1940 message_error_code_t message_adaptor_is_typing(message_adaptor_plugin_h plugin,
1941                                                 message_adaptor_plugin_context_h context,
1942                                                 long long int *request_id,
1943                                                 long long int *chatroom_id,
1944                                                 char **state,
1945                                                 int *chat_type,
1946                                                 int *refreshtime,
1947                                                 message_adaptor_error_code_t **error_code,
1948                                                 void *user_data)
1949 {
1950         if ((NULL == plugin) || (NULL == context)) {
1951                 message_adaptor_error("Invalid argument");
1952
1953                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1954
1955                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1956         }
1957
1958         if (NULL == plugin->handle) {
1959                 message_adaptor_error("Plugin handle is null");
1960
1961                 _set_error_code(error_code, "13", "Plugin handle is null");
1962
1963                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1964         }
1965
1966         message_error_code_t ret;
1967         plugin_req_enter();
1968         ret = plugin->handle->is_typing(context, request_id, chatroom_id,
1969                         state, chat_type, refreshtime, error_code, user_data);
1970         plugin_req_exit(ret, plugin, error_code);
1971
1972         return ret;
1973 }
1974
1975 message_error_code_t message_adaptor_connect(message_adaptor_plugin_h plugin,
1976                                                 message_adaptor_plugin_context_h context,
1977                                                 message_adaptor_error_code_h *error_code)
1978 {
1979         if ((NULL == plugin) || (NULL == context)) {
1980                 message_adaptor_error("Invalid argument");
1981
1982                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
1983
1984                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
1985         }
1986
1987         if (NULL == plugin->handle) {
1988                 message_adaptor_error("Plugin handle is null");
1989
1990                 _set_error_code(error_code, "13", "Plugin handle is null");
1991
1992                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
1993         }
1994
1995         message_error_code_t ret;
1996         plugin_req_enter();
1997         ret = plugin->handle->connect_to_server(context);
1998         plugin_req_exit(ret, plugin, error_code);
1999
2000         return ret;
2001 }
2002
2003 message_error_code_t message_adaptor_disconnect(message_adaptor_plugin_h plugin,
2004                                                 message_adaptor_plugin_context_h context,
2005                                                 message_adaptor_error_code_h *error_code)
2006 {
2007         if ((NULL == plugin) || (NULL == context)) {
2008                 message_adaptor_error("Invalid argument");
2009
2010                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
2011
2012                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
2013         }
2014
2015         if (NULL == plugin->handle) {
2016                 message_adaptor_error("Plugin handle is null");
2017
2018                 _set_error_code(error_code, "13", "Plugin handle is null");
2019
2020                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
2021         }
2022
2023         message_error_code_t ret;
2024         plugin_req_enter();
2025         ret = plugin->handle->disconnect_to_server(context);
2026         plugin_req_exit(ret, plugin, error_code);
2027
2028         return ret;
2029 }
2030
2031
2032 message_error_code_t message_adaptor_get_connection_state(message_adaptor_plugin_h plugin,
2033                                                 message_adaptor_plugin_context_h context,
2034                                                 message_connection_state_t *state,
2035                                                 message_adaptor_error_code_h *error_code)
2036 {
2037         if ((NULL == plugin) || (NULL == context)) {
2038                 message_adaptor_error("Invalid argument");
2039
2040                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
2041
2042                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
2043         }
2044
2045         if (NULL == plugin->handle) {
2046                 message_adaptor_error("Plugin handle is null");
2047
2048                 _set_error_code(error_code, "13", "Plugin handle is null");
2049
2050                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
2051         }
2052
2053         message_error_code_t ret;
2054         plugin_req_enter();
2055         ret = plugin->handle->get_connection_state(context, state);
2056         plugin_req_exit(ret, plugin, error_code);
2057
2058         return ret;
2059 }
2060
2061 message_error_code_t message_adaptor_decode_push_message(message_adaptor_plugin_h plugin,
2062                                                 message_adaptor_plugin_context_h context,
2063                                                 char *in_msg,
2064                                                 char **out_msg,
2065                                                 message_adaptor_error_code_h *error_code)
2066 {
2067         if ((NULL == plugin) || (NULL == context)) {
2068                 message_adaptor_error("Invalid argument");
2069
2070                 _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
2071
2072                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
2073         }
2074
2075         if (NULL == plugin->handle) {
2076                 message_adaptor_error("Plugin handle is null");
2077
2078                 _set_error_code(error_code, "13", "Plugin handle is null");
2079
2080                 return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
2081         }
2082
2083         if (NULL == in_msg || NULL == out_msg) {
2084                 message_adaptor_error("invalid argument : input/output message");
2085
2086                 _set_error_code(error_code, "14", "Invalid argument (in_msg or out_msg)");
2087
2088                 return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
2089         }
2090
2091         message_error_code_t ret;
2092         plugin_req_enter();
2093         ret = plugin->handle->decode_push_message(context, in_msg, out_msg);
2094         plugin_req_exit(ret, plugin, error_code);
2095
2096         return ret;
2097 }