c0c118bcf8b65fab6de7d9bc0f0bd285874f6638
[platform/core/convergence/service-adaptor.git] / adaptor / auth-adaptor / auth-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 <stdint.h>
20 #include <string.h>
21 #include <dirent.h>
22 #include <dlfcn.h>
23 #include <glib.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 #include <errno.h>
27
28 #include <plugin_message.h>
29
30 #include "auth-adaptor.h"
31 #include "auth-adaptor-log.h"
32
33 #define PLUGIN_MESSAGE_LISTENER_CMD_APPEND_FD           "append;"
34 #define PLUGIN_MESSAGE_LISTENER_CMD_STOP                "stop;"
35 #define PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE            8192
36
37 #define AUTH_PLUGIN_INTERFACE_CREATE_CONTEXT            "create_context"
38 #define AUTH_PLUGIN_INTERFACE_DESTROY_CONTEXT           "destroy_context"
39 #define AUTH_PLUGIN_INTERFACE_DESTROY_HANDLE            "destroy_handle"
40 #define AUTH_PLUGIN_INTERFACE_IS_AUTH                   "is_auth"
41 #define AUTH_PLUGIN_INTERFACE_JOIN                      "join"
42 #define AUTH_PLUGIN_INTERFACE_LOGIN                     "login"
43 #define AUTH_PLUGIN_INTERFACE_REFRESH_ACCESS_TOKEN      "refresh"
44
45
46 #define IF_IS_PLUGIN_THAN_RETURN_NULL()         do {if (!g_process_identity) return NULL; } while (0)
47
48 #define SAFE_ADD_STRING(x)      ((x) ? (x) : "")
49
50 typedef enum {
51         PLUGIN_TYPE_INHOUSE     = 0,
52         PLUGIN_TYPE_3RD_PARTY   = 1,
53 } auth_plugin_type_e;
54
55 /**
56  * @brief Describes Auth adaptor plugin
57  */
58 typedef struct auth_adaptor_plugin_s {
59         auth_adaptor_h                          adaptor;                /* Adaptor */
60         char                                    *path;                  /* Plugin library path */
61         auth_adaptor_plugin_handle_h            handle;                 /* Plugin handle */
62         void                                    *dl_handle;             /* Plugin library handle */
63         int                                     ref_counter;            /* Plugin reference counter */
64         GMutex                                  ref_counter_mutex;      /* Plugin reference counter mutex */
65         auth_adaptor_plugin_listener_h          plugin_listener;        /* Plugin callback listener */
66         GMutex                                  plugin_listener_mutex;  /* Plugin callback listener mutex */
67
68         GMutex                                  message_mutex;
69         auth_plugin_type_e                      type;
70         int                                     pid;
71         int                                     rd;
72         int                                     wd;
73         GList                                   *contexts;
74         GMutex                                  contexts_mutex;
75 /*      GQueue                                  sended; */
76 } auth_adaptor_plugin_t;
77
78 typedef struct _plugin_message_context_s {
79         int hooker;
80         char *message;
81 } plugin_message_context_t;
82
83 /**
84  * @brief Describes Auth adaptor
85  */
86 typedef struct auth_adaptor_s {
87         GMutex  auth_adaptor_mutex;             /* Adaptor mutex */
88         int     started;                        /* Started flag */
89         char    *plugins_dir;                   /* Plugins directory path */
90         GList   *plugins;                       /* List of loaded plugins */
91         GMutex  plugins_mutex;                  /* Plugin list mutex */
92         GList   *adaptor_listeners;             /* List of vservice channel listener (for now not effective) */
93         GMutex  adaptor_listeners_mutex;        /* Listener list mutex */
94
95         int     rd_cmd[2];
96         GList   *rd_list;
97         GMutex  rd_mutex;
98         pthread_t       plugin_listener;
99 } auth_adaptor_t;
100
101 static int g_process_identity = -1;
102
103 /**
104  * @brief Creates plugin
105  */
106 static auth_adaptor_plugin_h auth_adaptor_create_plugin(const char *plugin_path);
107
108 /**
109  * @brief Destroys plugin and deletes all resources associated with it
110  */
111 static void auth_adaptor_destroy_plugin(auth_adaptor_plugin_h plugin);
112
113 /**
114  * @brief Loads plugins from selected directory
115  */
116 static int auth_adaptor_load_plugins_from_directory(auth_adaptor_h adaptor,
117                                                 const char *dir_path);
118
119 /**
120  * @brief Checks if plugin is loaded by selected plugin adaptor
121  */
122 static int auth_adaptor_has_plugin(auth_adaptor_h adaptor,
123                                                 auth_adaptor_plugin_h plugin);
124
125 static auth_adaptor_error_code_h auth_adaptor_create_error_code(const int64_t code,
126                                                 const char *msg);
127 /**
128  * Increases adaptor's plugin references counter
129  */
130 static void auth_adaptor_plugin_ref(auth_adaptor_plugin_h);
131
132 /**
133  * @brief Decreases adaptor's plugin references counter
134  */
135 static void auth_adaptor_plugin_unref(auth_adaptor_plugin_h);
136
137 /*
138 void auth_adaptor_login_reply_cb(auth_adaptor_plugin_context_h context,
139                                                 auth_adaptor_error_code_h error_code,
140                                                 void *response)
141 {
142         if (_service_adaptor_login_reply != NULL)
143                 _service_adaptor_login_reply(imsi, plugin_uri, app_id, msisdn, response);
144 }
145 */
146
147 /* ////////////////////////////////////////////////////////////////////////////// */
148 /* ////////////  Internal function prototype (for forked plugin)  /////////////// */
149 /* ////////////////////////////////////////////////////////////////////////////// */
150
151
152 /* To be used by adaptor */
153 void *_auth_adaptor_plugin_message_collector(void *data);
154 void __auth_adaptor_transfer_message(const char *msg);
155 int __auth_adaptor_parse_message_cmd(auth_adaptor_h adaptor, char *msg);
156 void _auth_adaptor_send_cmd_add_fd(auth_adaptor_h adaptor, int fd);
157 void _auth_adaptor_send_cmd_stop_listen(auth_adaptor_h adaptor);
158
159 static int auth_adaptor_send_message_to_plugin_sync(auth_adaptor_plugin_h plugin,
160                                                 plugin_message_h send_message,
161                                                 plugin_message_h *receive_message);
162
163 /* To be used by adaptor (virtual plugin handle) */
164 auth_adaptor_plugin_handle_h __auth_adaptor_create_3rd_party_plugin_handle(const char *plugin_uri);
165
166 auth_error_code_t auth_plugin_send_create_context(auth_adaptor_plugin_context_h *context,
167                                                         const char *user_id,
168                                                         const char *user_password,
169                                                         const char *app_id,
170                                                         const char *app_secret,
171                                                         const char *service_name);
172
173 auth_error_code_t auth_plugin_send_destroy_context(auth_adaptor_plugin_context_h context);
174
175 auth_error_code_t auth_plugin_send_is_auth(auth_adaptor_plugin_context_h context,
176                                                         void *request,
177                                                         int *is_auth,
178                                                         auth_adaptor_error_code_h *error,
179                                                         void *response);
180
181 auth_error_code_t auth_plugin_send_join(auth_adaptor_plugin_context_h context,
182                                                         const char *device_id,
183                                                         void *request,
184                                                         auth_adaptor_error_code_h *error,
185                                                         void *response);
186
187 auth_error_code_t auth_plugin_send_login(auth_adaptor_plugin_context_h context,
188                                                         void *request,
189                                                         auth_adaptor_error_code_h *error,
190                                                         void *response);
191
192 auth_error_code_t auth_plugin_send_refresh_access_token(auth_adaptor_plugin_context_h context,
193                                                         void *request,
194                                                         auth_adaptor_error_code_h *error,
195                                                         void *response);
196
197
198 auth_error_code_t auth_plugin_send_set_service_status(auth_adaptor_plugin_context_h context,
199                                                         const int service_id,
200                                                         const int status,
201                                                         void *request,
202                                                         auth_adaptor_error_code_h *error,
203                                                         void *response);
204
205 auth_error_code_t auth_plugin_send_get_msisdn(auth_adaptor_plugin_context_h context,
206                                                         void *request,
207                                                         char **msisdn,
208                                                         auth_adaptor_error_code_h *error,
209                                                         void *response);
210
211 auth_error_code_t auth_plugin_send_get_service_status(auth_adaptor_plugin_context_h context,
212                 const int service_id,
213                 void *request,
214                 int *status,
215                 auth_adaptor_error_code_h *error,
216                 void *response);
217
218 auth_error_code_t auth_plugin_send_get_service_policy(auth_adaptor_plugin_context_h context,
219                 const int service_id,
220                 void *request,
221                 char **default_status,
222                 char **policy_feature,
223                 char **policy_version,
224                 char **policy_doc_url,
225                 auth_adaptor_error_code_h *error,
226                 void *response);
227
228 auth_error_code_t auth_plugin_send_get_server_info(auth_adaptor_plugin_context_h context,
229                 void *request,
230                 GHashTable **server_info,
231                 auth_adaptor_error_code_h *error,
232                 void *response);
233
234
235 /* To be used by forked plugin */
236 void *_auth_plugin_request_collector(void *data);
237 auth_adaptor_plugin_context_h __auth_plugin_get_context_by_context_id(auth_adaptor_plugin_h plugin, int context_id);
238 void __auth_plugin_progress_command(auth_adaptor_plugin_h plugin, char *order, char **result);
239
240
241 /* ------------------------------------------------------------------------
242 // Functions implementations
243 // ------------------------------------------------------------------------ */
244
245 /* ////////////////////////////////////////////////////// */
246 /* // Mandatory: External adaptor management function /// */
247 /* ////////////////////////////////////////////////////// */
248 auth_adaptor_h auth_adaptor_create(const char *plugins_dir)
249 {
250         if (NULL == plugins_dir) {
251                 auth_adaptor_error("Invalid argument""(plugins_dir: %s)", plugins_dir);
252                 return NULL;
253         }
254
255         auth_adaptor_h auth_adaptor = (auth_adaptor_h) calloc(1, sizeof(auth_adaptor_t));
256
257         if (NULL == auth_adaptor) {
258                 auth_adaptor_error("Critical : Memory allocation failed");
259                 return NULL;
260         }
261
262         /* for forked plugin */
263         if (pipe(auth_adaptor->rd_cmd) == -1) {
264                 free(auth_adaptor);
265                 auth_adaptor = NULL;
266                 return NULL;
267         }
268         g_mutex_init(&auth_adaptor->rd_mutex);
269         auth_adaptor->rd_list = NULL;
270 /*      auth_adaptor->rd_list = g_list_append(auth_adaptor->rd_list, (gpointer)auth_adaptor->rd_cmd[0]); */
271
272         auth_adaptor->started = 0;
273         auth_adaptor->plugins_dir = strdup(plugins_dir);
274
275         g_mutex_init(&auth_adaptor->auth_adaptor_mutex);
276         g_mutex_init(&auth_adaptor->plugins_mutex);
277         g_mutex_init(&auth_adaptor->adaptor_listeners_mutex);
278
279         g_mutex_lock(&auth_adaptor->adaptor_listeners_mutex);
280         auth_adaptor->adaptor_listeners = NULL;
281         g_mutex_unlock(&auth_adaptor->adaptor_listeners_mutex);
282
283         g_mutex_lock(&auth_adaptor->plugins_mutex);
284         auth_adaptor->plugins = NULL;
285         g_mutex_unlock(&auth_adaptor->plugins_mutex);
286
287
288         return auth_adaptor;
289 }
290
291 void auth_adaptor_destroy(auth_adaptor_h adaptor)
292 {
293         if (NULL == adaptor) {
294                 auth_adaptor_error("Invalid argument""(adaptor: %p)", adaptor);
295                 return;
296         }
297
298         g_mutex_lock(&adaptor->auth_adaptor_mutex);
299         if (adaptor->started) {
300                 auth_adaptor_error("Auth adaptor is running. Forcing stop before destroy");
301                 auth_adaptor_stop(adaptor);
302         }
303
304         g_mutex_lock(&adaptor->plugins_mutex);
305         if (NULL != adaptor->plugins) {
306                 g_list_free_full(adaptor->plugins, (GDestroyNotify) auth_adaptor_plugin_unref);
307                 adaptor->plugins = NULL;
308         }
309         g_mutex_unlock(&adaptor->plugins_mutex);
310
311         g_mutex_lock(&adaptor->adaptor_listeners_mutex);
312         if (NULL != adaptor->adaptor_listeners) {
313                 g_list_free(adaptor->adaptor_listeners);
314                 adaptor->adaptor_listeners = NULL;
315         }
316         g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
317 /*
318         _service_adaptor_login_reply = NULL;
319 */
320         free(adaptor->plugins_dir);
321         adaptor->plugins_dir = NULL;
322
323         /* For forked plugin */
324         g_list_free(adaptor->rd_list);
325         close(adaptor->rd_cmd[0]);
326         close(adaptor->rd_cmd[1]);
327
328         free(adaptor);
329 }
330
331 int auth_adaptor_start(auth_adaptor_h adaptor)
332 {
333         auth_adaptor_debug("Starting auth adaptor");
334         if (NULL == adaptor) {
335                 auth_adaptor_error("Invalid argument""(adaptor: %p)", adaptor);
336                 return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
337         }
338
339         g_mutex_lock(&adaptor->auth_adaptor_mutex);
340         int result = AUTH_ADAPTOR_ERROR_NONE;
341         if (adaptor->started) {
342                 auth_adaptor_error("Auth adaptor is already started");
343         } else {
344                 adaptor->started = 1;
345
346                 pthread_t pid;
347                 if (pthread_create(&pid, NULL, _auth_adaptor_plugin_message_collector, (void *)adaptor)) {
348                         adaptor->started = 0;
349                         auth_adaptor_error("Could not create 3rd party plugin listener");
350                         result = AUTH_ADAPTOR_ERROR_NOT_FOUND;
351                 } else if (AUTH_ADAPTOR_ERROR_NONE != (result = auth_adaptor_load_plugins_from_directory(adaptor, adaptor->plugins_dir))) {
352                         _auth_adaptor_send_cmd_stop_listen(adaptor);
353                         adaptor->started = 0;
354                         auth_adaptor_error("Could not load plugins from directory");
355                         result = AUTH_ADAPTOR_ERROR_NOT_FOUND;
356                 } else {
357                         adaptor->plugin_listener = pid;
358                         auth_adaptor_info("Auth adaptor started successfully");
359                 }
360         }
361         g_mutex_unlock(&adaptor->auth_adaptor_mutex);
362
363         return result;
364 }
365
366 int auth_adaptor_stop(auth_adaptor_h adaptor)
367 {
368         if (NULL == adaptor) {
369                 auth_adaptor_error("Invalid argument""(adaptor: %p)", adaptor);
370                 return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
371         }
372
373         g_mutex_lock(&adaptor->auth_adaptor_mutex);
374
375         auth_adaptor_debug("stop plugin listener");
376         _auth_adaptor_send_cmd_stop_listen(adaptor);
377         pthread_join(adaptor->plugin_listener, NULL);
378         int result = AUTH_ADAPTOR_ERROR_NONE;
379         if (0 == adaptor->started) {
380                 result = AUTH_ADAPTOR_ERROR_STOP;
381         } else {
382                 if (NULL != adaptor->plugins) {
383                         g_mutex_lock(&adaptor->plugins_mutex);
384                         g_list_free_full(adaptor->plugins, (GDestroyNotify) auth_adaptor_plugin_unref);
385                         adaptor->plugins = NULL;
386                         g_mutex_unlock(&adaptor->plugins_mutex);
387                 }
388                 adaptor->started = 0;
389                 auth_adaptor_debug("Auth adaptor stopped");
390         }
391
392         g_mutex_unlock(&adaptor->auth_adaptor_mutex);
393
394         return result;
395 }
396
397 int auth_adaptor_register_listener(auth_adaptor_h adaptor,
398                                                 auth_adaptor_listener_h listener)
399 {
400         if ((NULL == adaptor) || (NULL == listener)) {
401                 auth_adaptor_error("Invalid argument""(adaptor: %p, listener: %p)", adaptor, listener);
402                 return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
403         }
404
405         g_mutex_lock(&adaptor->adaptor_listeners_mutex);
406
407         adaptor->adaptor_listeners = g_list_append(adaptor->adaptor_listeners, listener);
408
409         g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
410 /*
411         _service_adaptor_login_reply =
412                         (auth_adaptor_service_login_reply_cb)listener->login_reply;
413 */
414         return AUTH_ADAPTOR_ERROR_NONE;
415 }
416
417 int auth_adaptor_unregister_listener(auth_adaptor_h adaptor,
418                                                 auth_adaptor_listener_h listener)
419 {
420         if ((NULL == adaptor) || (NULL == listener)) {
421                 auth_adaptor_error("Invalid argument""(adaptor: %p, listener: %p)", adaptor, listener);
422                 return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
423         }
424
425         g_mutex_lock(&adaptor->adaptor_listeners_mutex);
426
427         if (NULL == g_list_find(adaptor->adaptor_listeners, listener)) {
428                 g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
429                 auth_adaptor_error("Could not find listener");
430                 free(listener);
431                 return AUTH_ADAPTOR_ERROR_NOT_FOUND;
432         }
433
434         adaptor->adaptor_listeners = g_list_remove(adaptor->adaptor_listeners, listener);
435         free(listener);
436
437         g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
438 /*
439         _service_adaptor_login_reply = NULL;
440 */
441         return AUTH_ADAPTOR_ERROR_NONE;
442 }
443
444 /* /////////////////////////////////////////////////////////////
445    // Plugin create / destroy / ref. count / get plugin name
446    ///////////////////////////////////////////////////////////// */
447 static auth_adaptor_plugin_h auth_adaptor_create_plugin(const char *plugin_path)
448 {
449         if (NULL == plugin_path) {
450                 auth_adaptor_error("Invalid argument""(plugin_path: %p)", plugin_path);
451                 return NULL;
452
453         }
454
455         void *dl_handle = dlopen(plugin_path, RTLD_LAZY);
456         if (NULL == dl_handle) {
457                 auth_adaptor_error("Could not load plugin %s: %s", plugin_path, dlerror());
458                 return NULL;
459         }
460
461         auth_adaptor_plugin_handle_h (*get_adaptee_handle)(void) = NULL;
462
463         get_adaptee_handle = (auth_adaptor_plugin_handle_h (*)(void))(dlsym(dl_handle, "create_plugin_handle"));
464         if (NULL == get_adaptee_handle) {
465                 dlclose(dl_handle);
466                 auth_adaptor_error("Could not get function pointer to create_plugin_handle");
467                 return NULL;
468         }
469
470         plugin_req_enter();
471         auth_adaptor_plugin_handle_h handle = get_adaptee_handle();
472         plugin_req_exit_void();
473         if (NULL == handle) {
474                 dlclose(dl_handle);
475                 auth_adaptor_error("Could not get adaptee handle");
476                 return NULL;
477         }
478
479         auth_adaptor_plugin_h plugin = (auth_adaptor_plugin_h) calloc(1, sizeof(auth_adaptor_plugin_t));
480         if (NULL == plugin) {
481                 dlclose(dl_handle);
482                 auth_adaptor_error("Could not create plugin object");
483                 return NULL;
484         }
485
486         plugin->path = g_strdup(plugin_path);
487         plugin->handle = handle;
488         plugin->dl_handle = dl_handle;
489         plugin->ref_counter = 0;
490
491         plugin->type = PLUGIN_TYPE_INHOUSE;
492
493         g_mutex_init(&plugin->ref_counter_mutex);
494         g_mutex_init(&plugin->plugin_listener_mutex);
495         g_mutex_init(&plugin->contexts_mutex);
496         plugin->contexts = NULL;
497
498         auth_adaptor_plugin_listener_h listener =
499                 (auth_adaptor_plugin_listener_h) calloc(1, sizeof(auth_adaptor_plugin_listener_t));
500 /*
501         listener->auth_adaptor_login_reply              = auth_adaptor_login_reply_cb;
502 */
503         plugin_req_enter();
504         plugin->handle->set_listener(listener);
505         plugin_req_exit_void();
506
507         g_mutex_lock(&plugin->plugin_listener_mutex);
508         plugin->plugin_listener = listener;
509         g_mutex_unlock(&plugin->plugin_listener_mutex);
510
511         return plugin;
512 }
513
514 static void auth_adaptor_destroy_plugin(auth_adaptor_plugin_h plugin)
515 {
516         if (NULL == plugin) {
517                 auth_adaptor_error("Invalid argument""(plugin: %p)", plugin);
518                 return;
519         }
520
521         if (NULL != plugin->handle) {
522                 plugin->handle->destroy_handle(plugin->handle);
523
524                 g_mutex_lock(&plugin->plugin_listener_mutex);
525                 plugin_req_enter();
526                 plugin->handle->unset_listener();
527                 plugin_req_exit_void();
528                 g_mutex_unlock(&plugin->plugin_listener_mutex);
529
530                 plugin->handle = NULL;
531         }
532
533         if (NULL != plugin->dl_handle) {
534                 dlclose(plugin->dl_handle);
535                 plugin->dl_handle = NULL;
536         }
537
538         g_free(plugin->path);
539         plugin->path = NULL;
540
541         free(plugin);
542 }
543
544 static int auth_adaptor_load_plugins_from_directory(auth_adaptor_h adaptor,
545                                                 const char *dir_path)
546 {
547         char *plugin_path = NULL;
548         DIR *dir = NULL;
549         struct dirent dir_entry, *result = NULL;
550
551         auth_adaptor_debug("Starting load plugins from directory");
552
553         if ((NULL == adaptor) || (NULL == dir_path)) {
554                 auth_adaptor_error("Invalid argument""(adaptor: %p, dir_path: %p)", adaptor, dir_path);
555                 return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
556         }
557
558         dir = opendir(dir_path);
559         if (NULL == dir) {
560                 auth_adaptor_error("Could not open dir path (%s)", dir_path);
561                 return AUTH_ADAPTOR_ERROR_NOT_FOUND;
562         }
563
564         int ret = AUTH_ADAPTOR_ERROR_NONE;
565         while (0 == (readdir_r(dir, &dir_entry, &result))) {
566
567                 if (NULL == result) {
568                         auth_adaptor_error("Could not open directory %s", plugin_path);
569                         break;
570                 }
571
572                 if (dir_entry.d_type & DT_DIR) {
573                         continue;
574                 }
575
576                 plugin_path = g_strconcat(dir_path, "/", dir_entry.d_name, NULL);
577                 auth_adaptor_plugin_h plugin = auth_adaptor_create_plugin(plugin_path);
578
579                 if (NULL != plugin) {
580                         auth_adaptor_debug("Loaded plugin: %s", plugin_path);
581                         plugin->adaptor = adaptor;
582                         auth_adaptor_plugin_ref(plugin);
583                         g_mutex_lock(&adaptor->plugins_mutex);
584                         adaptor->plugins = g_list_append(adaptor->plugins, plugin);
585                         g_mutex_unlock(&adaptor->plugins_mutex);
586                 } else {
587                         auth_adaptor_error("Could not load plugin %s", plugin_path);
588                 }
589
590                 free(plugin_path);
591                 plugin_path = NULL;
592         }
593
594         auth_adaptor_debug("End load plugins from directory");
595         closedir(dir);
596         return ret;
597 }
598
599 static int auth_adaptor_has_plugin(auth_adaptor_h adaptor,
600                                                 auth_adaptor_plugin_h plugin)
601 {
602         if ((NULL == adaptor) || (NULL == plugin)) {
603                 auth_adaptor_error("Invalid argument""(adaptor: %p, plugin: %p)", adaptor, plugin);
604                 return 0;
605         }
606
607         int result = 0;
608
609         g_mutex_lock(&adaptor->plugins_mutex);
610         if (NULL != g_list_find(adaptor->plugins, plugin)) {
611                 result = 1;
612         }
613         g_mutex_unlock(&adaptor->plugins_mutex);
614
615         return result;
616 }
617
618 static void auth_adaptor_plugin_ref(auth_adaptor_plugin_h plugin)
619 {
620         if (NULL == plugin) {
621                 auth_adaptor_error("Invalid argument""(plugin: %p)", plugin);
622                 return;
623         }
624
625         g_mutex_lock(&plugin->ref_counter_mutex);
626         plugin->ref_counter = plugin->ref_counter + 1;
627         if (NULL != plugin->handle) {
628                 auth_adaptor_info("plugin name: %s, ref_counter: %d",
629                                 plugin->handle->plugin_uri, plugin->ref_counter);
630         } else {
631                 auth_adaptor_info("ref_counter: %d", plugin->ref_counter);
632         }
633         g_mutex_unlock(&plugin->ref_counter_mutex);
634 }
635
636 static void auth_adaptor_plugin_unref(auth_adaptor_plugin_h plugin)
637 {
638         if (NULL == plugin) {
639                 auth_adaptor_error("Invalid argument""(plugin: %p)", plugin);
640                 return;
641         }
642
643         int should_destroy = 0;
644
645         g_mutex_lock(&plugin->ref_counter_mutex);
646         plugin->ref_counter = plugin->ref_counter - 1;
647         if (NULL != plugin->handle) {
648                 auth_adaptor_info("plugin name: %s, ref_counter: %d",
649                                 plugin->handle->plugin_uri, plugin->ref_counter);
650         } else {
651                 auth_adaptor_info("ref_counter: %d", plugin->ref_counter);
652         }
653         if (0 >= plugin->ref_counter) {
654                 should_destroy = 1;
655         }
656         g_mutex_unlock(&plugin->ref_counter_mutex);
657
658         if (should_destroy) {
659                 auth_adaptor_debug("Plugin is being destroyed");
660                 auth_adaptor_destroy_plugin(plugin);
661         }
662 }
663
664 /* For 3rd party plugin packages */
665 int auth_adaptor_load_plugin_from_package(auth_adaptor_h adaptor,
666                                                 const char *package_id,
667                                                 const char *plugin_path)
668 {
669         int adaptor_fd[2];
670         int plugin_fd[2];
671
672         if (pipe(adaptor_fd) == -1) {
673                 auth_adaptor_debug("pipe creation error, can not load plugin package");
674         } else if (pipe(plugin_fd) == -1) {
675                 close(adaptor_fd[0]);
676                 close(adaptor_fd[1]);
677                 auth_adaptor_debug("pipe creation error[2], can not load plugin package");
678         } else {
679                 g_process_identity = fork();
680                 if (0 == g_process_identity) {  /* child */
681                         auth_adaptor_debug_func("[CHILD PROCESS] forked success (PID : %d, id : %d)", (int)getpid());
682
683                         auth_adaptor_plugin_h plugin = NULL;
684                         plugin = auth_adaptor_create_plugin(plugin_path);
685
686                         if (NULL == plugin) {
687                                 auth_adaptor_error("[CHILD PROCESS] Load plugin failed");
688                                 exit(1);
689                         }
690
691                         plugin->rd = plugin_fd[0];
692                         close(plugin_fd[1]);
693                         plugin->wd = adaptor_fd[1];
694                         close(adaptor_fd[0]);
695                         void *temp = _auth_plugin_request_collector((void *)plugin);
696                         auth_adaptor_debug_func("[CHILD PROCESS] exit %p", temp);
697                         exit(0);
698                 } else if (0 < g_process_identity) {    /* parent */
699                         auth_adaptor_debug_func("[PARENT PROCESS] forked success (PID : %d)", (int)getpid());
700                         auth_adaptor_plugin_h _plugin = (auth_adaptor_plugin_h) calloc(1, sizeof(auth_adaptor_plugin_t));
701                         if (NULL != _plugin) {
702                                 _plugin->ref_counter = 0;
703                                 g_mutex_init(&_plugin->ref_counter_mutex);
704                                 g_mutex_init(&_plugin->message_mutex);
705
706                                 _plugin->handle = __auth_adaptor_create_3rd_party_plugin_handle(package_id);
707
708                                 _plugin->type = PLUGIN_TYPE_3RD_PARTY;
709                                 _plugin->pid = g_process_identity;
710                                 _plugin->rd = adaptor_fd[0];
711                                 close(adaptor_fd[1]);
712                                 _plugin->wd = plugin_fd[1];
713                                 close(plugin_fd[0]);
714
715                                 _auth_adaptor_send_cmd_add_fd(adaptor, _plugin->rd);
716
717                                 _plugin->adaptor = adaptor;
718                                 auth_adaptor_plugin_ref(_plugin);
719                                 g_mutex_lock(&adaptor->plugins_mutex);
720                                 adaptor->plugins = g_list_append(adaptor->plugins, _plugin);
721                                 g_mutex_unlock(&adaptor->plugins_mutex);
722                         }
723                 } else {
724                         close(adaptor_fd[0]);
725                         close(adaptor_fd[1]);
726                         close(plugin_fd[0]);
727                         close(plugin_fd[1]);
728                         auth_adaptor_debug("fork error, can not load plugin package");
729                 }
730         }
731
732         return 0;
733 }
734
735 /* //////////////////////////////////////////////////////
736    // Get plugin name by plugin
737    ////////////////////////////////////////////////////// */
738 void auth_adaptor_get_plugin_uri(auth_adaptor_plugin_h plugin,
739                                                 char **plugin_uri)
740 {
741         if ((NULL == plugin) || (NULL == plugin_uri)) {
742                 auth_adaptor_error("Invalid argument""(plugin: %p, uri: %p)", plugin, plugin_uri);
743                 return;
744         }
745         if (NULL != plugin->handle) {
746                 *plugin_uri = strdup(plugin->handle->plugin_uri);
747         }
748 }
749
750 /* //////////////////////////////////////////////////////
751    // Create / Destroy error code
752    ////////////////////////////////////////////////////// */
753 static auth_adaptor_error_code_h auth_adaptor_create_error_code(const int64_t code,
754                                                 const char *msg)
755 {
756         if (NULL == msg) {
757                 return NULL;
758         }
759
760         auth_adaptor_error_code_h error_code =
761                         (auth_adaptor_error_code_h) malloc(sizeof(auth_adaptor_error_code_t));
762
763         if (NULL != error_code) {
764                 error_code->code = code;
765                 error_code->msg = strdup(msg);
766         }
767
768         return error_code;
769 }
770
771 void auth_adaptor_destroy_error_code(auth_adaptor_error_code_h *error_code)
772 {
773         if ((NULL != error_code) && (NULL != (*error_code))) {
774                 free((*error_code)->msg);
775                 (*error_code)->msg = NULL;
776                 free(*error_code);
777                 *error_code = NULL;
778         }
779 }
780
781 /* //////////////////////////////////////////////////////
782    // Plugin context create / destroy
783    ////////////////////////////////////////////////////// */
784 auth_adaptor_plugin_context_h auth_adaptor_create_plugin_context(auth_adaptor_plugin_h plugin,
785                                                 const char *user_id,
786                                                 const char *user_password,
787                                                 const char *app_id,
788                                                 const char *app_secret,
789                                                 const char *imsi,
790                                                 const char *service_name)
791 {
792         auth_adaptor_debug("Starting auth_adaptor_create_plugin_context");
793
794         if ((NULL == plugin) || (NULL == service_name)) {
795                 auth_adaptor_error("Invalid argument""(plugin: %p, service_name: %s)",
796                                 plugin, service_name);
797                 return NULL;
798         }
799
800         if (NULL != plugin->handle) {
801                 auth_adaptor_plugin_context_h plugin_context = NULL;
802                 if (plugin->type == PLUGIN_TYPE_3RD_PARTY) {
803                         plugin_context = (auth_adaptor_plugin_context_h) calloc(1, sizeof(auth_adaptor_plugin_context_t));
804                         if (NULL == plugin_context) {
805                                 auth_adaptor_error("Create context failed");
806                                 return NULL;
807                         } else {
808                                 plugin_context->plugin_handle = plugin;
809                         }
810                 }
811
812                 plugin_req_enter();
813                 plugin->handle->create_context(&plugin_context, SAFE_ADD_STRING(user_id), SAFE_ADD_STRING(user_password), SAFE_ADD_STRING(app_id), SAFE_ADD_STRING(app_secret), SAFE_ADD_STRING(imsi));
814                 plugin_req_exit_void();
815
816                 if (NULL == plugin_context) {
817                         auth_adaptor_error("Create context failed");
818                         return NULL;
819                 } else {
820                         plugin_context->plugin_uri = strdup(plugin->handle->plugin_uri);
821                         plugin_context->service_name = strdup(service_name);
822                 }
823
824                 /* For forked plugin */
825                 g_mutex_lock(&plugin->contexts_mutex);
826                 plugin->contexts = g_list_append(plugin->contexts, (gpointer)plugin_context);
827                 g_mutex_unlock(&plugin->contexts_mutex);
828
829                 return plugin_context;
830         } else {
831                 auth_adaptor_error("Plugin handle is null");
832         }
833
834         auth_adaptor_debug("End auth_adaptor_create_plugin_context");
835         return NULL;
836 }
837
838 void auth_adaptor_destroy_plugin_context(auth_adaptor_plugin_h plugin,
839                                                 auth_adaptor_plugin_context_h plugin_context)
840 {
841         if ((NULL == plugin) || (NULL == plugin_context)) {
842                 auth_adaptor_error("Invalid argument""(plugin: %p, plugin_context: %p)", plugin, plugin_context);
843                 return;
844         }
845
846         if (NULL != plugin->handle) {
847                 /* For forked plugin */
848                 g_mutex_lock(&plugin->contexts_mutex);
849                 plugin->contexts = g_list_remove(plugin->contexts, (gpointer)plugin_context);
850                 g_mutex_unlock(&plugin->contexts_mutex);
851
852                 plugin_req_enter();
853                 plugin->handle->destroy_context(plugin_context);
854                 plugin_req_exit_void();
855         } else {
856                 auth_adaptor_error("Plugin handle is null");
857         }
858
859         return;
860 }
861
862 /* //////////////////////////////////////////////////////
863    // Get plugin by plugin name
864    ////////////////////////////////////////////////////// */
865 auth_adaptor_plugin_h auth_adaptor_get_plugin_by_name(auth_adaptor_h adaptor,
866                                                 const char *plugin_uri)
867 {
868         auth_adaptor_debug("Starting auth_adaptor_get_plugin_by_name");
869
870         if ((NULL == adaptor) || (NULL == plugin_uri)) {
871                 auth_adaptor_error("Invalid argument""(adaptor: %p, plugin_uri: %p)", adaptor, plugin_uri);
872                 return NULL;
873         }
874
875         auth_adaptor_plugin_h plugin = NULL;
876         g_mutex_lock(&adaptor->plugins_mutex);
877
878         int count = g_list_length(adaptor->plugins);
879         int i = 0;
880         for (i = 0; i < count; i++) {
881                 auth_adaptor_plugin_h temp_plugin = g_list_nth_data(adaptor->plugins, i);
882                 if (NULL != temp_plugin) {
883                         if (0 == strcmp(temp_plugin->handle->plugin_uri, plugin_uri)) {
884                                 auth_adaptor_plugin_ref(temp_plugin);
885                                 plugin = temp_plugin;
886                                 g_mutex_unlock(&adaptor->plugins_mutex);
887                                 return plugin;
888                         }
889                 }
890         }
891         g_mutex_unlock(&adaptor->plugins_mutex);
892
893         return plugin;
894 }
895
896 /* //////////////////////////////////////////////////////
897    // Plugin load / unload / get plugin list
898    ////////////////////////////////////////////////////// */
899 int auth_adaptor_load_plugin(auth_adaptor_h adaptor,
900                                                 const char *plugin_path)
901 {
902         if ((NULL == adaptor) || (NULL == plugin_path)) {
903                 auth_adaptor_error("Invalid argument""(adaptor: %p, plugin_path: %p)", adaptor, plugin_path);
904                 return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
905         }
906
907         if (0 == adaptor->started) {
908                 auth_adaptor_error("Auth adaptor is not started");
909                 return AUTH_ADAPTOR_ERROR_START;
910         }
911
912         auth_adaptor_plugin_h plugin = auth_adaptor_create_plugin(plugin_path);
913         if (NULL == plugin) {
914                 auth_adaptor_error("Could not load plugin %s", plugin_path);
915                 return AUTH_ADAPTOR_ERROR_CREATE;
916         }
917
918         plugin->adaptor = adaptor;
919         auth_adaptor_plugin_ref(plugin);
920
921         g_mutex_lock(&adaptor->plugins_mutex);
922         adaptor->plugins = g_list_append(adaptor->plugins, plugin);
923         g_mutex_unlock(&adaptor->plugins_mutex);
924
925         return AUTH_ADAPTOR_ERROR_NONE;
926 }
927
928 int auth_adaptor_unload_plugin(auth_adaptor_h adaptor,
929                                                 auth_adaptor_plugin_h plugin)
930 {
931         if ((NULL == adaptor) || (NULL == plugin)) {
932                 auth_adaptor_error("Invalid argument""(adaptor: %p, plugin: %p)", adaptor, plugin);
933                 return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
934         }
935
936         if (0 == adaptor->started) {
937                 auth_adaptor_error("Auth adaptor is not started");
938                 return AUTH_ADAPTOR_ERROR_START;
939         }
940
941         if (0 == auth_adaptor_has_plugin(adaptor, plugin)) {
942                 auth_adaptor_error("Auth adaptor has no plugin");
943                 return AUTH_ADAPTOR_ERROR_NOT_FOUND;
944         }
945
946         plugin->adaptor = NULL;
947
948         g_mutex_lock(&adaptor->plugins_mutex);
949         adaptor->plugins = g_list_remove(adaptor->plugins, plugin);
950         g_mutex_unlock(&adaptor->plugins_mutex);
951
952         auth_adaptor_plugin_unref(plugin);
953
954         return AUTH_ADAPTOR_ERROR_NONE;
955 }
956
957 GList *auth_adaptor_get_plugins(auth_adaptor_h adaptor)
958 {
959         if (NULL == adaptor) {
960                 auth_adaptor_error("Invalid argument""(adaptor: %p)", adaptor);
961                 return NULL;
962         }
963
964         GList *plugins = NULL;
965
966         g_mutex_lock(&adaptor->plugins_mutex);
967         int plugins_count = g_list_length(adaptor->plugins);
968         int i;
969         for (i = 0; i < plugins_count; i++) {
970                 auth_adaptor_plugin_h plugin = g_list_nth_data(adaptor->plugins, i);
971                 if (NULL != plugin) {
972                         auth_adaptor_plugin_ref(plugin);
973                         plugins = g_list_append(plugins, plugin);
974                 }
975         }
976         g_mutex_unlock(&adaptor->plugins_mutex);
977
978         return plugins;
979 }
980
981 /* ////////////////////////////////////////////////////////////
982    // Adaptor get Element Functions
983    //////////////////////////////////////////////////////////// */
984
985 /*
986  * @return : Need free
987  */
988 EXPORT_API
989 char *auth_adaptor_get_access_token_dup(auth_adaptor_plugin_context_h context)
990 {
991         if (NULL == context) {
992                 auth_adaptor_warning("Invalid argument""(context: %p", context);
993                 return NULL;
994         }
995
996         if (NULL == context->access_token) {
997                 auth_adaptor_warning("Invalid argument""(context->access_token: %p", context->access_token);
998                 return NULL;
999         }
1000
1001         if (0 >= strlen(context->access_token)) {
1002                 auth_adaptor_warning("Invalid argument""(context->access_token length: %d", strlen(context->access_token));
1003                 return NULL;
1004         }
1005
1006         return strdup(context->access_token);
1007 }
1008
1009 /*
1010  * @return : Need free
1011  */
1012 EXPORT_API
1013 char *auth_adaptor_get_uid_dup(auth_adaptor_plugin_context_h context)
1014 {
1015         if (NULL == context) {
1016                 auth_adaptor_warning("Invalid argument""(context: %p", context);
1017                 return NULL;
1018         }
1019
1020         if (NULL == context->uid) {
1021                 auth_adaptor_warning("Invalid argument""(context->uid: %p", context->uid);
1022                 return NULL;
1023         }
1024
1025         if (0 >= strlen(context->uid)) {
1026                 auth_adaptor_warning("Invalid argument""(context->uid length: %d", strlen(context->uid));
1027                 return NULL;
1028         }
1029
1030         return strdup(context->uid);
1031 }
1032
1033 /*
1034  * @return : Need free
1035  */
1036 EXPORT_API
1037 char *auth_adaptor_get_msisdn_dup(auth_adaptor_plugin_context_h context)
1038 {
1039         if (NULL == context) {
1040                 auth_adaptor_warning("Invalid argument""(context: %p", context);
1041                 return NULL;
1042         }
1043
1044         if (NULL == context->msisdn) {
1045                 auth_adaptor_warning("Invalid argument""(context->msisdn: %p", context->msisdn);
1046                 return NULL;
1047         }
1048
1049         if (0 >= strlen(context->msisdn)) {
1050                 auth_adaptor_warning("Invalid argument""(context->msisdn length: %d", strlen(context->msisdn));
1051                 return NULL;
1052         }
1053
1054         return strdup(context->msisdn);
1055 }
1056
1057 /* ////////////////////////////////////////////////////////////
1058    // Adaptor Plugin call Functions
1059    //////////////////////////////////////////////////////////// */
1060
1061 auth_error_code_t _auth_adaptor_mandatory_param_check(auth_adaptor_plugin_h plugin,
1062                                                 auth_adaptor_plugin_context_h context,
1063                                                 auth_adaptor_error_code_h *error_code)
1064 {
1065         auth_error_code_t ret = AUTH_ADAPTOR_ERROR_NONE;
1066
1067         if ((NULL == plugin) || (NULL == context)) {
1068                 auth_adaptor_error("Invalid argument""(plugin: %p, context: %p)", plugin, context);
1069                 if (NULL != error_code) {
1070                         *error_code = auth_adaptor_create_error_code(
1071                                         (int64_t) AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT,
1072                                         "Invalid argument (plugin or context)");
1073                 }
1074
1075                 return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
1076         }
1077
1078         if (NULL == plugin->handle) {
1079                 auth_adaptor_error("Plugin handle is null");
1080
1081                 if (NULL != error_code) {
1082                         *error_code = auth_adaptor_create_error_code(
1083                                         (int64_t) AUTH_ADAPTOR_ERROR_INVALID_HANDLE,
1084                                         "Plugin handle is null");
1085                 }
1086
1087                 return AUTH_ADAPTOR_ERROR_INVALID_HANDLE;
1088         }
1089
1090         return ret;
1091 }
1092
1093 /**
1094 * @brief Check Account Registration [Sync API]
1095 *
1096 * @param[in]    plugin          specifies Auth-adaptor Plugin handle
1097 * @param[in]    context         specifies Auth-adaptor Plugin context
1098 * @param[in]    request         specifies Optional value for specific Plugin (Recommend Json Object format)
1099 * @param[out]   is_auth         specifies Registered Flag (Registered : 1, Not registered : 0)
1100 * @param[out]   error_code      specifies Error code
1101 * @param[out]   response        specifies Optional value from specific Plugin (Recommend Json Object format)
1102 * @return 0 on success, otherwise a positive error value
1103 * @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
1104 */
1105 auth_error_code_t auth_adaptor_is_auth(auth_adaptor_plugin_h plugin,
1106                                                 auth_adaptor_plugin_context_h context,
1107                                                 void *request,
1108                                                 int *is_auth,
1109                                                 auth_adaptor_error_code_h *error_code, void *response)
1110 {
1111         auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
1112         if (AUTH_ADAPTOR_ERROR_NONE != ret) {
1113                 return ret;
1114         }
1115
1116         if ((NULL == is_auth)) {
1117                 auth_adaptor_error("Invalid argument""(is_auth: %p)", is_auth);
1118                 if (NULL != error_code) {
1119                         *error_code = auth_adaptor_create_error_code(
1120                                         (int64_t) AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT,
1121                                         "Invalid argument (is_auth pointer is null)");
1122                 }
1123
1124                 return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
1125         }
1126
1127         if (NULL == plugin->handle->is_auth) {
1128                 auth_adaptor_error("Plugin does not support this API");
1129                 if (NULL != error_code) {
1130                         *error_code = auth_adaptor_create_error_code(
1131                                         (int64_t) AUTH_ADAPTOR_ERROR_UNSUPPORTED,
1132                                         "Plugin does not support this API (is_auth)");
1133                 }
1134                 return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
1135         }
1136
1137         plugin_req_enter();
1138         ret = plugin->handle->is_auth(context, request, is_auth, error_code, response);
1139         plugin_req_exit(ret, plugin, error_code);
1140
1141         return ret;
1142 }
1143
1144 /**
1145 * @brief Request Access Token (included auth_adaptor_context) [Sync API]
1146 *
1147 * @param[in]    plugin          specifies Auth-adaptor Plugin handle
1148 * @param[in]    context         specifies Auth-adaptor Plugin context
1149 * @param[in]    is_auth         specifies Registration Flag (Must be issued from "auth_adaptor_is_auth" Function)
1150 * @param[in]    request         specifies Optional value for specific Plugin (Recommend Json Object format)
1151 * @param[out]   error_code      specifies Error code
1152 * @param[out]   response        specifies Optional value from specific Plugin (Recommend Json Object format)
1153 * @return 0 on success, otherwise a positive error value
1154 * @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
1155 */
1156 auth_error_code_t auth_adaptor_login(auth_adaptor_plugin_h plugin,
1157                                                 auth_adaptor_plugin_context_h context,
1158                                                 int is_auth,
1159                                                 void *request,
1160                                                 auth_adaptor_error_code_h *error_code,
1161                                                 void *response)
1162 {
1163         auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
1164         if (AUTH_ADAPTOR_ERROR_NONE != ret) {
1165                 return ret;
1166         }
1167
1168         if ((0 > is_auth) || (1 < is_auth)) {
1169                 auth_adaptor_error("\"is_auth\" value must be issued from \"auth_adaptor_is_auth\"");
1170
1171                 if (NULL != error_code) {
1172                         *error_code = auth_adaptor_create_error_code(
1173                                         (int64_t) AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT,
1174                                         "Invalid argument (is_auth)");
1175                 }
1176
1177                 return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
1178         }
1179
1180         if (0 == is_auth) {
1181                 auth_adaptor_error("Device is not joined. Please register to ESU");
1182
1183                 if (NULL != error_code) {
1184                         *error_code = auth_adaptor_create_error_code(
1185                                         (int64_t) AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL,
1186                                         "Device is not joined");
1187                 }
1188
1189                 return AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
1190         }
1191
1192
1193         char *old_access_token = auth_adaptor_get_access_token_dup(context);
1194         char *old_uid = auth_adaptor_get_uid_dup(context);
1195         free(context->uid);
1196         free(context->access_token);
1197         context->access_token = NULL;
1198         context->uid = NULL;
1199
1200         plugin_req_enter();
1201         ret = plugin->handle->login(context, request, error_code, response);
1202         plugin_req_exit(ret, plugin, error_code);
1203
1204         if (AUTH_ADAPTOR_ERROR_NONE == ret) {
1205                 auth_adaptor_info("Login Successed");
1206
1207                 if (NULL == context->access_token)
1208                 /* || (NULL == context->uid)) */
1209                 {
1210                         auth_adaptor_error("Critical missmatching Error!!\n");
1211                         auth_adaptor_error("Login returns success but access_token is NULL");
1212                         ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
1213
1214                         if (NULL != error_code) {
1215                                 *error_code = auth_adaptor_create_error_code((int64_t) AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL,
1216                                                 "Plugin returns Login success but access_token is Empty");
1217                         }
1218                 }
1219
1220         }
1221         if (NULL != context->access_token) {
1222                 free(old_access_token);
1223         } else {
1224                 auth_adaptor_error("Fill old access token by error");
1225                 context->access_token = old_access_token;
1226         }
1227         if (NULL != context->uid) {
1228                 free(old_uid);
1229         } else {
1230                 auth_adaptor_error("Fill old uid by error");
1231                 context->uid = old_uid;
1232         }
1233
1234         return ret;
1235 }
1236
1237 /**
1238 * @brief Request for Refreshing Access Token (included auth_adaptor_context) [Sync API]
1239 *
1240 * @param[in]    plugin          specifies Auth-adaptor Plugin handle
1241 * @param[in]    context         specifies Auth-adaptor Plugin context
1242 * @param[in]    request         specifies Optional value for specific Plugin (Recommend Json Object format)
1243 * @param[out]   error_code      specifies Error code
1244 * @param[out]   response        specifies Optional value from specific Plugin (Recommend Json Object format)
1245 * @return 0 on success, otherwise a positive error value
1246 * @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
1247 */
1248 auth_error_code_t auth_adaptor_login_refresh(auth_adaptor_plugin_h plugin,
1249                                                 auth_adaptor_plugin_context_h context,
1250                                                 void *request,
1251                                                 auth_adaptor_error_code_h *error_code,
1252                                                 void *response)
1253 {
1254         auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
1255         if (AUTH_ADAPTOR_ERROR_NONE != ret) {
1256                 return ret;
1257         }
1258
1259         if ((NULL == context->access_token) || (0 >= strlen(context->access_token))) {
1260                 auth_adaptor_error("Access_token is empty. Please login first");
1261
1262                 if (NULL != error_code) {
1263                         *error_code = auth_adaptor_create_error_code(
1264                                         (int64_t) AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT,
1265                                         "Invalid argument (context->access_token)");
1266                 }
1267
1268                 return AUTH_ADAPTOR_ERROR_NOT_AUTHORIZED;
1269         }
1270
1271         char *old_access_token = auth_adaptor_get_access_token_dup(context);
1272         char *old_uid = auth_adaptor_get_uid_dup(context);
1273 /*      free(context->uid); */
1274 /*      free(context->access_token); */
1275 /*      context->access_token = NULL; */
1276 /*      context->uid = NULL; */
1277         plugin_req_enter();
1278         ret = plugin->handle->refresh_access_token(context, request, error_code, response);
1279         plugin_req_exit(ret, plugin, error_code);
1280
1281         if (AUTH_ADAPTOR_ERROR_NONE == ret) {
1282                 auth_adaptor_info("Login refresh Successed");
1283 /*
1284                 if ((NULL == context->access_token) || (NULL == context->uid))
1285                 {
1286                         auth_adaptor_error("Critical missmatching Error!!\n");
1287                         auth_adaptor_error("Login_refresh returns success but access_token or uid is NULL");
1288                         ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
1289
1290                         if (NULL != error_code)
1291                         {
1292                                 *error_code = auth_adaptor_create_error_code((int64_t) AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL,
1293                                                 "Plugin returns Login_refresh success but access_token or uid is Empty");
1294                         }
1295                 }
1296 */
1297         }
1298
1299         if (NULL != context->access_token) {
1300                 free(old_access_token);
1301         } else {
1302                 auth_adaptor_error("Fill old access token by error");
1303                 context->access_token = old_access_token;
1304         }
1305         if (NULL != context->uid) {
1306                 free(old_uid);
1307         } else {
1308                 auth_adaptor_error("Fill old uid by error");
1309                 context->uid = old_uid;
1310         }
1311
1312         return ret;
1313 }
1314
1315 /**
1316 * @brief Request Account Registration [Sync API]
1317 *
1318 * @param[in]    plugin          specifies Auth-adaptor Plugin handle
1319 * @param[in]    context         specifies Auth-adaptor Plugin context
1320 * @param[in]    device_id       specifies Device Unique ID
1321 * @param[in]    request         specifies Optional value for specific Plugin (Recommend Json Object format)
1322 * @param[out]   error_code      specifies Error code
1323 * @param[out]   response        specifies Optional value from specific Plugin (Recommend Json Object format)
1324 * @return 0 on success, otherwise a positive error value
1325 * @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
1326 */
1327 auth_error_code_t auth_adaptor_join(auth_adaptor_plugin_h plugin,
1328                                                 auth_adaptor_plugin_context_h context,
1329                                                 const char *device_id,
1330                                                 void *request,
1331                                                 auth_adaptor_error_code_h *error_code,
1332                                                 void *response)
1333 {
1334         auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
1335         if (AUTH_ADAPTOR_ERROR_NONE != ret) {
1336                 return ret;
1337         }
1338
1339         if (NULL == plugin->handle->join) {
1340                 auth_adaptor_error("Plugin does not support this API");
1341                 if (NULL != error_code) {
1342                         *error_code = auth_adaptor_create_error_code(
1343                                         (int64_t) AUTH_ADAPTOR_ERROR_UNSUPPORTED,
1344                                         "Plugin does not support this API (is_auth)");
1345                 }
1346                 return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
1347         }
1348
1349         plugin_req_enter();
1350         ret = plugin->handle->join(context, device_id, request, error_code, response);
1351         plugin_req_exit(ret, plugin, error_code);
1352
1353         return ret;
1354 }
1355
1356 /**
1357 * @brief Request Account Information (MSISDN) [Sync API]
1358 *
1359 * @param[in]    plugin          specifies Auth-adaptor Plugin handle
1360 * @param[in]    context         specifies Auth-adaptor Plugin context
1361 * @param[in]    request         specifies Optional value for specific Plugin (Recommend Json Object format)
1362 * @param[out]   msisdn          specifies MSISDN
1363 * @param[out]   error_code      specifies Error code
1364 * @param[out]   response        specifies Optional value from specific Plugin (Recommend Json Object format)
1365 * @return 0 on success, otherwise a positive error value
1366 * @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
1367 */
1368 auth_error_code_t auth_adaptor_get_msisdn(auth_adaptor_plugin_h plugin,
1369                                                 auth_adaptor_plugin_context_h context,
1370                                                 void *request,
1371                                                 char **msisdn,
1372                                                 auth_adaptor_error_code_h *error_code,
1373                                                 void *response)
1374 {
1375         auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
1376         if (AUTH_ADAPTOR_ERROR_NONE != ret) {
1377                 return ret;
1378         }
1379
1380         plugin_req_enter();
1381         ret = plugin->handle->get_msisdn(context, request, msisdn, error_code, response);
1382         plugin_req_exit(ret, plugin, error_code);
1383
1384         return ret;
1385 }
1386
1387 /**
1388 * @brief Request Changing Service Status (Enable, Disable or etc...) [Sync API]
1389 *
1390 * @param[in]    plugin          specifies Auth-adaptor Plugin handle
1391 * @param[in]    context         specifies Auth-adaptor Plugin context
1392 * @param[in]    service_id      specifies Service ID (The value is depended by Server)
1393 * @param[in]    status          specifies Service Status (The value is depended by Server)
1394 * @param[in]    request         specifies Optional value for specific Plugin (Recommend Json Object format)
1395 * @param[out]   error_code      specifies Error code
1396 * @param[out]   response        specifies Optional value from specific Plugin (Recommend Json Object format)
1397 * @return 0 on success, otherwise a positive error value
1398 * @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
1399 */
1400 auth_error_code_t auth_adaptor_set_service_status(auth_adaptor_plugin_h plugin,
1401                                                 auth_adaptor_plugin_context_h context,
1402                                                 const int service_id,
1403                                                 const int status,
1404                                                 void *request,
1405                                                 auth_adaptor_error_code_h *error_code,
1406                                                 void *response)
1407 {
1408         auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
1409         if (AUTH_ADAPTOR_ERROR_NONE != ret) {
1410                 return ret;
1411         }
1412
1413         plugin_req_enter();
1414         ret = plugin->handle->set_service_status(context, service_id, status, request, error_code, response);
1415         plugin_req_exit(ret, plugin, error_code);
1416
1417         return ret;
1418 }
1419
1420 /**
1421 * @brief Request Service Status [Sync API]
1422 *
1423 * @param[in]    plugin          specifies Auth-adaptor Plugin handle
1424 * @param[in]    context         specifies Auth-adaptor Plugin context
1425 * @param[in]    service_id      specifies Service ID (The value is depended by Server)
1426 * @param[in]    request         specifies Optional value for specific Plugin (Recommend Json Object format)
1427 * @param[out]   status          specifies Service Status (The value is depended by Server)
1428 * @param[out]   error_code      specifies Error code
1429 * @param[out]   response        specifies Optional value from specific Plugin (Recommend Json Object format)
1430 * @return 0 on success, otherwise a positive error value
1431 * @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
1432 */
1433 auth_error_code_t auth_adaptor_get_service_status(auth_adaptor_plugin_h plugin,
1434                                                 auth_adaptor_plugin_context_h context,
1435                                                 const int service_id,
1436                                                 void *request,
1437                                                 int *status,
1438                                                 auth_adaptor_error_code_h *error_code,
1439                                                 void *response)
1440 {
1441         auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
1442         if (AUTH_ADAPTOR_ERROR_NONE != ret) {
1443                 return ret;
1444         }
1445
1446         plugin_req_enter();
1447         ret = plugin->handle->get_service_status(context, service_id, request, status, error_code, response);
1448         plugin_req_exit(ret, plugin, error_code);
1449
1450         return ret;
1451 }
1452
1453 /**
1454 * @brief Request Service Policy [Sync API]
1455 *
1456 * @param[in]    plugin          specifies Auth-adaptor Plugin handle
1457 * @param[in]    context         specifies Auth-adaptor Plugin context
1458 * @param[in]    service_id      specifies Service ID (The value is depended by Server)
1459 * @param[in]    request         specifies Optional value for specific Plugin (Recommend Json Object format)
1460 * @param[in]    default_status  specifies Service default Status Policy
1461 * @param[in]    policy_feature  specifies Service Policy Feature
1462 * @param[in]    policy_version  specifies Service Policy Version
1463 * @param[in]    policy_doc_url  specifies Service Policy Document URL
1464 * @param[out]   error_code      specifies Error code
1465 * @param[out]   response        specifies Optional value from specific Plugin (Recommend Json Object format)
1466 * @return 0 on success, otherwise a positive error value
1467 * @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
1468 */
1469 auth_error_code_t auth_adaptor_get_service_policy(auth_adaptor_plugin_h plugin,
1470                                                 auth_adaptor_plugin_context_h context,
1471                                                 const int service_id,
1472                                                 void *request,
1473                                                 char **default_status,
1474                                                 char **policy_feature,
1475                                                 char **policy_version,
1476                                                 char **policy_doc_url,
1477                                                 auth_adaptor_error_code_h *error_code,
1478                                                 void *response)
1479 {
1480         auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
1481         if (AUTH_ADAPTOR_ERROR_NONE != ret) {
1482                 return ret;
1483         }
1484
1485         plugin_req_enter();
1486         ret = plugin->handle->get_service_policy(context, service_id, request, default_status,
1487                         policy_feature, policy_version, policy_doc_url, error_code, response);
1488         plugin_req_exit(ret, plugin, error_code);
1489
1490         return ret;
1491 }
1492
1493 /**
1494 * @brief Request Permitted Server information for Account [Sync API]
1495 *
1496 * @param[in]    plugin          specifies Auth-adaptor Plugin handle
1497 * @param[in]    context         specifies Auth-adaptor Plugin context
1498 * @param[in]    request         specifies Optional value for specific Plugin (Recommend Json Object format)
1499 * @param[out]   server_info     specifies server information (URL, Scheme, Port)
1500 * @param[out]   error_code      specifies Error code
1501 * @param[out]   response        specifies Optional value from specific Plugin (Recommend Json Object format)
1502 * @return 0 on success, otherwise a positive error value
1503 * @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
1504 */
1505 EXPORT_API
1506 auth_error_code_t auth_adaptor_get_server_info(auth_adaptor_plugin_h plugin,
1507                                                 auth_adaptor_plugin_context_h context,
1508                                                 void *request,
1509                                                 GHashTable **server_info,
1510                                                 auth_adaptor_error_code_h *error_code,
1511                                                 void *response)
1512 {
1513         auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
1514         if (AUTH_ADAPTOR_ERROR_NONE != ret) {
1515                 return ret;
1516         }
1517
1518         plugin_req_enter();
1519         ret = plugin->handle->get_server_info(context, request, server_info, error_code, response);
1520         plugin_req_exit(ret, plugin, error_code);
1521
1522         return ret;
1523 }
1524
1525 EXPORT_API
1526 auth_error_code_t auth_adaptor_external_request(auth_adaptor_plugin_h plugin,
1527                                                 auth_adaptor_plugin_context_h context,
1528                                                 const char *api_uri,
1529                                                 const unsigned char *req_bundle_raw,
1530                                                 int req_len,
1531                                                 unsigned char **res_bundle_raw,
1532                                                 int *res_len,
1533                                                 auth_adaptor_error_code_h *error_code)
1534 {
1535         auth_error_code_t ret = AUTH_ADAPTOR_ERROR_NONE;
1536
1537         if (NULL == plugin) {
1538                 auth_adaptor_error("Invalid argument""(plugin: %p)", plugin);
1539                 if (NULL != error_code) {
1540                         *error_code = auth_adaptor_create_error_code(
1541                                         (int64_t) AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT,
1542                                         "Invalid argument (plugin)");
1543                 }
1544
1545                 return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
1546         }
1547
1548         if (NULL == plugin->handle) {
1549                 auth_adaptor_error("Plugin handle is null");
1550
1551                 if (NULL != error_code) {
1552                         *error_code = auth_adaptor_create_error_code(
1553                                         (int64_t) AUTH_ADAPTOR_ERROR_INVALID_HANDLE,
1554                                         "Plugin handle is null");
1555                 }
1556
1557                 return AUTH_ADAPTOR_ERROR_INVALID_HANDLE;
1558         }
1559
1560         if (NULL ==  plugin->handle->external_request) {
1561                 if (NULL != error_code) {
1562                         *error_code = auth_adaptor_create_error_code(AUTH_ADAPTOR_ERROR_UNSUPPORTED,
1563                                         "API does not supported by plugin");
1564                 }
1565                 return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
1566         }
1567
1568         plugin_req_enter();
1569         ret = plugin->handle->external_request(context, api_uri,
1570                         req_bundle_raw, req_len,
1571                         res_bundle_raw, res_len, error_code);
1572         plugin_req_exit(ret, plugin, error_code);
1573
1574         return ret;
1575 }
1576
1577 /* ///////////////////////////////////////////////////////////////////////////////
1578 ///////////////////////////////////////////////////////////////////////////////
1579 ////////////  Internal function description (for forked plugin)  //////////////
1580 ///////////////////////////////////////////////////////////////////////////////
1581 /////////////////////////////////////////////////////////////////////////////// */
1582
1583 void *_auth_adaptor_plugin_message_collector(void *data)
1584 {
1585         auth_adaptor_h adaptor = (auth_adaptor_h) data;
1586
1587         auth_adaptor_info("3rd party plugin listener run");
1588         int i, lagest_fd = -1;
1589         fd_set read_set;
1590         struct timeval tv;
1591         tv.tv_sec = 10L;                /* TODO change to define or meaningful value */
1592         char msg_buf[PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE] = {0, };
1593         int buf_size, rcv_len;
1594         GList *dead_list = NULL;
1595
1596         while (1) {
1597                 /* Clears and sets fds for select */
1598                 FD_ZERO(&read_set);
1599                 FD_SET(adaptor->rd_cmd[0], &read_set);
1600                 lagest_fd = adaptor->rd_cmd[0];
1601
1602                 /* Sets plugin fds for select */
1603                 for (i = 0; i < g_list_length(adaptor->rd_list); i++) {
1604                         int fd = (int) g_list_nth_data(adaptor->rd_list, i);
1605                         FD_SET(fd, &read_set);
1606                         if (lagest_fd < fd) {
1607                                 lagest_fd = fd;
1608                         }
1609                 }
1610
1611                 /* Select with timeout (for avoid blocking issue) */
1612                 int stmt = select((lagest_fd + 1), &read_set, NULL, NULL, &tv);
1613                 IF_IS_PLUGIN_THAN_RETURN_NULL();
1614                 if (stmt == 0) {
1615 /*                      auth_adaptor_debug("select refrech by timeout(%ld sec) [id : %d]", tv.tv_sec, g_process_identity); */
1616                         if (0L >= tv.tv_sec) {
1617 /*                              auth_adaptor_debug("Resets selector timeout sec"); */
1618                                 tv.tv_sec = 10L;
1619                         }
1620                         IF_IS_PLUGIN_THAN_RETURN_NULL();
1621                 } else if (stmt > 0) {
1622                         /* Checking message queue with Plugin processes. */
1623                         for (i = 0; i < g_list_length(adaptor->rd_list); i++) {
1624                                 IF_IS_PLUGIN_THAN_RETURN_NULL();
1625                                 int fd = (int) g_list_nth_data(adaptor->rd_list, i);
1626                                 if (FD_ISSET(fd, &read_set)) {
1627                                         IF_IS_PLUGIN_THAN_RETURN_NULL();
1628                                         /* pre-read buf size */
1629                                         rcv_len = read(fd, &buf_size, sizeof(int));
1630                                         if (0 >= rcv_len) {
1631                                                 auth_adaptor_debug("Child process dead (Remove from listening queue)");
1632                                                 dead_list = g_list_append(dead_list, (gpointer)fd);
1633                                                 continue;
1634                                         }
1635                                         /* allocates and read buf data */
1636                                         memset(msg_buf, 0, PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE);
1637                                         buf_size %= PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE - 1;
1638                                         rcv_len = read(fd, msg_buf, buf_size);
1639                                         auth_adaptor_debug("read message [%s][%d]", msg_buf, rcv_len);
1640
1641                                         if (0 < rcv_len) {
1642                                                 /* transfer data to adaptor */
1643                                                 __auth_adaptor_transfer_message(msg_buf);
1644                                         } else {
1645                                                 auth_adaptor_debug("Child process dead (Remove from listening queue)");
1646                                                 dead_list = g_list_append(dead_list, (gpointer)fd);
1647                                         }
1648                                 }
1649                         }
1650
1651                         /* Checking message queue with Adaptor internal command. */
1652                         IF_IS_PLUGIN_THAN_RETURN_NULL();
1653                         if (FD_ISSET(adaptor->rd_cmd[0], &read_set)) {
1654                                 int fd = adaptor->rd_cmd[0];
1655                                 IF_IS_PLUGIN_THAN_RETURN_NULL();
1656                                 /* pre-read buf size */
1657                                 rcv_len = read(fd, &buf_size, sizeof(int));
1658
1659                                 if (0 >= rcv_len) {
1660                                         auth_adaptor_debug("Parent process dead : Listener break");
1661                                         break;
1662                                 }
1663
1664                                 /* allocates and read buf data */
1665                                 memset(msg_buf, 0, PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE);
1666                                 buf_size %= PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE - 1;
1667                                 rcv_len = read(fd, msg_buf, buf_size);
1668                                 auth_adaptor_debug("read message [%s][%d]", msg_buf, rcv_len);
1669
1670                                 if (0 >= rcv_len) {
1671                                         auth_adaptor_debug("Parent process dead : Listener break");
1672                                         break;
1673                                 }
1674
1675                                 /* parse cmd message (e.g. append read_fd / change timeout sec / stop listener) */
1676                                 int cmd_ret = __auth_adaptor_parse_message_cmd(adaptor, msg_buf);
1677                                 if (0 > cmd_ret) {
1678                                         auth_adaptor_info("3rd party plugin listener stopped by adaptor cmd");
1679                                         break;
1680                                 }
1681                         }
1682
1683                         /* Remove fd with disconnected plugin. */
1684                         for (i = 0; i < g_list_length(dead_list); i++) {
1685                                 adaptor->rd_list = g_list_remove(adaptor->rd_list, (gpointer) g_list_nth_data(dead_list, i));
1686                         }
1687                         g_list_free(dead_list);
1688                         dead_list = NULL;
1689                 } else {
1690                         auth_adaptor_error("plugin message listener error (errno : %d)", errno);
1691                 }
1692         }
1693         auth_adaptor_info("3rd party plugin listener stopped");
1694
1695         return data;
1696 }
1697
1698 void __auth_adaptor_transfer_message(const char *msg)
1699 {
1700         plugin_message_h t_msg = NULL;
1701         int ret = 0;
1702         ret = plugin_message_deserialize(msg, &t_msg);
1703         if (!ret) {
1704                 pmnumber req_type, req_id;
1705                 ret = plugin_message_get_value_number(t_msg, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, &req_type);
1706
1707                 if (!ret && (PLUGIN_MESSAGE_TYPE_FUNCTION == req_type)) {
1708                         auth_adaptor_debug("MEssage function type : function");
1709                         ret = plugin_message_get_value_number(t_msg, PLUGIN_MESSAGE_ELEMENT_REQUEST_ID, &req_id);
1710                         if (!ret) {
1711                                 auth_adaptor_debug("Send plugin data to requester");
1712                                 int hooked_fd = (int) req_id;
1713                                 int len = strlen(msg);
1714                                 ret = write(hooked_fd, &len, sizeof(int));
1715                                 if (0 < len) {
1716                                         ret = write(hooked_fd, msg, sizeof(char) * len);
1717                                 }
1718                         } else {
1719                                 auth_adaptor_debug("Couldn't get request id");
1720                         }
1721                 } else if (!ret && (PLUGIN_MESSAGE_TYPE_CALLBACK == req_type)) {
1722                         auth_adaptor_warning("Auth adaptor unsupport callback yet");
1723                 } else {
1724                         auth_adaptor_warning("Received message parsing fail.");
1725                 }
1726                 plugin_message_destroy(t_msg);
1727         }
1728 }
1729
1730 int __auth_adaptor_parse_message_cmd(auth_adaptor_h adaptor, char *msg)
1731 {
1732         char *cmd_data = NULL;
1733         if (0 == strncmp(PLUGIN_MESSAGE_LISTENER_CMD_APPEND_FD, msg, strlen(PLUGIN_MESSAGE_LISTENER_CMD_APPEND_FD))) {
1734                 cmd_data = msg + strlen(PLUGIN_MESSAGE_LISTENER_CMD_APPEND_FD);
1735                 int fd = atoi(cmd_data);
1736
1737                 adaptor->rd_list = g_list_append(adaptor->rd_list, (gpointer)fd);
1738         } else if (0 == strncmp(PLUGIN_MESSAGE_LISTENER_CMD_STOP, msg, strlen(PLUGIN_MESSAGE_LISTENER_CMD_STOP))) {
1739                 return -1;
1740         }
1741
1742         return 0;
1743 }
1744
1745
1746 void _auth_adaptor_send_cmd_add_fd(auth_adaptor_h adaptor, int fd)
1747 {
1748         char cmd_buf[256] = {0, };
1749         snprintf(cmd_buf, 255, "%s%d", PLUGIN_MESSAGE_LISTENER_CMD_APPEND_FD, fd);
1750         int len = strlen(cmd_buf);
1751         int wr_ret;
1752
1753         g_mutex_lock(&adaptor->rd_mutex);
1754         wr_ret = write(adaptor->rd_cmd[1], &len, sizeof(int));
1755         wr_ret = write(adaptor->rd_cmd[1], cmd_buf, sizeof(char) * len);
1756         g_mutex_unlock(&adaptor->rd_mutex);
1757         auth_adaptor_debug("writed (%d)(%s)", wr_ret, cmd_buf);
1758 }
1759
1760 void _auth_adaptor_send_cmd_stop_listen(auth_adaptor_h adaptor)
1761 {
1762         char cmd_buf[256] = {0, };
1763         snprintf(cmd_buf, 255, "%s", PLUGIN_MESSAGE_LISTENER_CMD_STOP);
1764         int len = strlen(cmd_buf);
1765         int wr_ret;
1766
1767         g_mutex_lock(&adaptor->rd_mutex);
1768         wr_ret = write(adaptor->rd_cmd[1], &len, sizeof(int));
1769         wr_ret = write(adaptor->rd_cmd[1], cmd_buf, sizeof(char) * len);
1770         g_mutex_unlock(&adaptor->rd_mutex);
1771         auth_adaptor_debug("writed (%d)(%s)", wr_ret, cmd_buf);
1772 }
1773
1774 static int auth_adaptor_send_message_to_plugin_sync(auth_adaptor_plugin_h plugin,
1775                                                 plugin_message_h send_message,
1776                                                 plugin_message_h *receive_message)
1777 {
1778         int io_ret = 0;
1779         int wfd = plugin->wd;
1780         int sync_hook[2];
1781
1782         if (pipe(sync_hook) != -1) {
1783                 char read_buf[PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE] = {0, };
1784
1785                 plugin_message_set_value_number(send_message, PLUGIN_MESSAGE_ELEMENT_REQUEST_ID, (pmnumber) sync_hook[1]);
1786                 char *stream = NULL;
1787                 io_ret = plugin_message_serialize(send_message, &stream);
1788                 int len = strlen(stream);
1789
1790                 g_mutex_lock(&plugin->message_mutex);
1791                 io_ret = write(wfd, &len, sizeof(len));
1792                 io_ret = write(wfd, stream, sizeof(char) * len);
1793                 g_mutex_unlock(&plugin->message_mutex);
1794                 free(stream);
1795                 stream = NULL;
1796                 len = 0;
1797
1798                 io_ret = read(sync_hook[0], &len, sizeof(len));
1799
1800                 if (0 < len) {
1801                         memset(read_buf, 0, PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE);
1802                         len %= PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE - 1;
1803                         io_ret = read(sync_hook[0], read_buf, len);
1804                 }
1805                 auth_adaptor_debug("io ret : %d", io_ret);
1806                 close(sync_hook[0]);
1807                 close(sync_hook[1]);
1808
1809                 plugin_message_h _rcv;
1810                 if (0 < strlen(read_buf)) {
1811                         io_ret = plugin_message_deserialize(read_buf, &_rcv);
1812                         if (!io_ret) {
1813                                 *receive_message = _rcv;
1814                         }
1815                 }
1816         } else {
1817                 io_ret = -1;
1818         }
1819
1820         return io_ret;
1821 }
1822
1823 auth_adaptor_plugin_handle_h __auth_adaptor_create_3rd_party_plugin_handle(const char *plugin_uri)
1824 {
1825         auth_adaptor_plugin_handle_h handle = (auth_adaptor_plugin_handle_h) calloc(1, sizeof(auth_adaptor_plugin_handle_t));
1826
1827         if (NULL != handle) {
1828                 handle->create_context = auth_plugin_send_create_context;
1829                 handle->destroy_context = auth_plugin_send_destroy_context;
1830                 handle->is_auth = auth_plugin_send_is_auth;
1831                 handle->login = auth_plugin_send_login;
1832                 handle->refresh_access_token = auth_plugin_send_refresh_access_token;
1833
1834                 handle->set_service_status = auth_plugin_send_set_service_status;
1835                 handle->get_msisdn = auth_plugin_send_get_msisdn;
1836                 handle->get_service_status = auth_plugin_send_get_service_status;
1837                 handle->get_service_policy = auth_plugin_send_get_service_policy;
1838                 handle->get_server_info = auth_plugin_send_get_server_info;
1839
1840
1841                 handle->plugin_uri = strdup(plugin_uri);
1842         }
1843
1844         return handle;
1845 }
1846
1847 auth_error_code_t auth_plugin_send_create_context(auth_adaptor_plugin_context_h *context,
1848                                                         const char *user_id,
1849                                                         const char *user_password,
1850                                                         const char *app_id,
1851                                                         const char *app_secret,
1852                                                         const char *imsi)
1853 {
1854         auth_adaptor_plugin_h plugin = NULL;
1855         plugin = (*context)->plugin_handle;
1856
1857         int ret = 0;
1858         plugin_message_h message = NULL;
1859         ret = plugin_message_create(&message);
1860
1861         if (ret == 0) {
1862                 (*context)->context_id = (int) (intptr_t)(*context);
1863
1864                 plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
1865                                 (pmnumber) (*context)->context_id);
1866                 plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
1867                                 AUTH_PLUGIN_INTERFACE_CREATE_CONTEXT);
1868
1869                 plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
1870                                 (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
1871
1872                 int param_index = 1;
1873                 plugin_message_set_param_string(message, param_index++, user_id);
1874                 plugin_message_set_param_string(message, param_index++, user_password);
1875                 plugin_message_set_param_string(message, param_index++, app_id);
1876                 plugin_message_set_param_string(message, param_index++, app_secret);
1877                 plugin_message_set_param_string(message, param_index++, imsi);
1878
1879                 plugin_message_h result_message = NULL;
1880                 ret = auth_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
1881
1882                 if (0 == ret) {
1883                         pmnumber ret_code;
1884                         plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
1885
1886                         ret = (int) ret_code;
1887
1888                         char *ret_msg = NULL;
1889                         if (AUTH_ADAPTOR_ERROR_NONE == ret) {
1890                                 auth_adaptor_debug("Create context successed");
1891                         } else {
1892                                 plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
1893                                 auth_adaptor_debug("Create context failed (%d)(%s)", ret, ret_msg);
1894                                 free(ret_msg);
1895                                 ret_msg = NULL;
1896
1897                                 free(*context);
1898                                 (*context) = NULL;
1899                         }
1900                         plugin_message_destroy(result_message);
1901                 }
1902         } else {
1903                 ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
1904         }
1905         plugin_message_destroy(message);
1906
1907         return ret;
1908
1909
1910 }
1911
1912 auth_error_code_t auth_plugin_send_destroy_context(auth_adaptor_plugin_context_h context)
1913 {
1914         auth_adaptor_plugin_h plugin = NULL;
1915         plugin = context->plugin_handle;
1916
1917         int ret = 0;
1918         plugin_message_h message = NULL;
1919         ret = plugin_message_create(&message);
1920
1921         if (ret == 0) {
1922                 plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
1923                                 (pmnumber) context->context_id);
1924                 plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
1925                                 AUTH_PLUGIN_INTERFACE_DESTROY_CONTEXT);
1926
1927                 plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
1928                                 (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
1929
1930                 plugin_message_h result_message = NULL;
1931                 ret = auth_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
1932
1933                 if (0 == ret) {
1934                         pmnumber ret_code;
1935                         plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
1936
1937                         ret = (int) ret_code;
1938
1939                         char *ret_msg = NULL;
1940                         if (AUTH_ADAPTOR_ERROR_NONE == ret) {
1941                                 auth_adaptor_debug("Destroy context successed");
1942                         } else {
1943                                 plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
1944                                 auth_adaptor_debug("Destroy context failed (%d)(%s)", ret, ret_msg);
1945                                 free(ret_msg);
1946                                 ret_msg = NULL;
1947
1948                                 auth_adaptor_debug("Force release memory by adaptor process");
1949                                 free(context->access_token);
1950                                 free(context);
1951                                 context = NULL;
1952                         }
1953                         plugin_message_destroy(result_message);
1954                 }
1955         } else {
1956                 ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
1957         }
1958         plugin_message_destroy(message);
1959
1960         return ret;
1961
1962
1963 }
1964
1965
1966
1967
1968 auth_error_code_t auth_plugin_send_is_auth(auth_adaptor_plugin_context_h context,
1969                                                         void *request,
1970                                                         int *is_auth,
1971                                                         auth_adaptor_error_code_h *error,
1972                                                         void *response)
1973 {
1974         auth_adaptor_plugin_h plugin = NULL;
1975         plugin = context->plugin_handle;
1976
1977         int ret = 0;
1978         plugin_message_h message = NULL;
1979         ret = plugin_message_create(&message);
1980
1981         if (ret == 0) {
1982                 plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID, (pmnumber) context->context_id);
1983                 plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME, AUTH_PLUGIN_INTERFACE_IS_AUTH);
1984
1985                 plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
1986
1987                 plugin_message_h result_message = NULL;
1988                 ret = auth_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
1989
1990                 if (0 == ret) {
1991                         pmnumber _is_auth, ret_code;
1992                         plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
1993
1994                         ret = (int) ret_code;
1995
1996                         char *ret_msg = NULL;
1997                         if (AUTH_ADAPTOR_ERROR_NONE == ret) {
1998                                 auth_adaptor_debug("Is_auth successed");
1999                                 plugin_message_get_param_number(result_message, 1, &_is_auth);
2000                                 *is_auth = (int)_is_auth;
2001                         } else {
2002                                 plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
2003                                 auth_adaptor_debug("Is_auth failed (%d)(%s)", ret, ret_msg);
2004                                 if (NULL != error) {
2005                                         auth_adaptor_error_code_h error_code = auth_adaptor_create_error_code(ret, ret_msg);
2006                                         *error = error_code;
2007                                 }
2008                                 free(ret_msg);
2009                                 ret_msg = NULL;
2010                         }
2011
2012                         plugin_message_destroy(result_message);
2013                 }
2014         } else {
2015                 ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
2016         }
2017         plugin_message_destroy(message);
2018
2019         return ret;
2020 }
2021
2022 auth_error_code_t auth_plugin_send_join(auth_adaptor_plugin_context_h context,
2023                                                         const char *device_id,
2024                                                         void *request,
2025                                                         auth_adaptor_error_code_h *error,
2026                                                         void *response)
2027 {
2028         auth_adaptor_plugin_h plugin = NULL;
2029         plugin = context->plugin_handle;
2030
2031         int ret = 0;
2032         plugin_message_h message = NULL;
2033         ret = plugin_message_create(&message);
2034
2035         if (ret == 0) {
2036                 plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID, (pmnumber) context->context_id);
2037                 plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME, AUTH_PLUGIN_INTERFACE_JOIN);
2038
2039                 plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
2040
2041                 plugin_message_h result_message = NULL;
2042                 ret = auth_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
2043
2044                 if (0 == ret) {
2045                         pmnumber ret_code;
2046                         plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
2047
2048                         ret = (int) ret_code;
2049
2050                         char *ret_msg = NULL;
2051                         if (AUTH_ADAPTOR_ERROR_NONE == ret) {
2052                                 auth_adaptor_debug("Join successed");
2053                         } else {
2054                                 plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
2055                                 auth_adaptor_debug("Join failed (%d)(%s)", ret, ret_msg);
2056                                 if (NULL != error) {
2057                                         auth_adaptor_error_code_h error_code = auth_adaptor_create_error_code(ret, ret_msg);
2058                                         *error = error_code;
2059                                 }
2060                                 free(ret_msg);
2061                                 ret_msg = NULL;
2062                         }
2063
2064                         plugin_message_destroy(result_message);
2065                 }
2066         } else {
2067                 ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
2068         }
2069         plugin_message_destroy(message);
2070
2071         return ret;
2072 }
2073
2074
2075
2076 auth_error_code_t auth_plugin_send_login(auth_adaptor_plugin_context_h context,
2077                                                         void *request,
2078                                                         auth_adaptor_error_code_h *error,
2079                                                         void *response)
2080 {
2081         auth_adaptor_plugin_h plugin = NULL;
2082         plugin = context->plugin_handle;
2083
2084         int ret = 0;
2085         plugin_message_h message = NULL;
2086         ret = plugin_message_create(&message);
2087
2088         if (ret == 0) {
2089                 plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
2090                                 (pmnumber) context->context_id);
2091                 plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
2092                                 AUTH_PLUGIN_INTERFACE_LOGIN);
2093
2094                 plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
2095                                 (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
2096
2097                 plugin_message_h result_message = NULL;
2098                 ret = auth_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
2099
2100                 if (0 == ret) {
2101                         pmnumber ret_code;
2102                         plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
2103
2104                         ret = (int) ret_code;
2105                         char *ret_msg = NULL;
2106                         if (AUTH_ADAPTOR_ERROR_NONE == ret) {
2107                                 auth_adaptor_debug("Login successed");
2108                                 char *access_token = NULL;
2109                                 char *uid = NULL;
2110                                 int param_idx = 1;
2111                                 plugin_message_get_param_string(result_message, param_idx++, &access_token);
2112                                 plugin_message_get_param_string(result_message, param_idx++, &uid);
2113                                 auth_adaptor_debug("access token : %s", access_token);
2114                                 auth_adaptor_debug("uid : %s", uid);
2115
2116                                 context->access_token = access_token;
2117                                 context->uid = uid;
2118                         } else {
2119                                 plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
2120                                 auth_adaptor_debug("Login failed (%d)(%s)", ret, ret_msg);
2121                                 if (NULL != error) {
2122                                         auth_adaptor_error_code_h error_code = auth_adaptor_create_error_code(ret, ret_msg);
2123                                         *error = error_code;
2124                                 }
2125                                 free(ret_msg);
2126                                 ret_msg = NULL;
2127                         }
2128                         plugin_message_destroy(result_message);
2129                 }
2130         } else {
2131                 ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
2132         }
2133         plugin_message_destroy(message);
2134
2135         return ret;
2136
2137 }
2138
2139 auth_error_code_t auth_plugin_send_refresh_access_token(auth_adaptor_plugin_context_h context,
2140                                                         void *request,
2141                                                         auth_adaptor_error_code_h *error,
2142                                                         void *response)
2143 {
2144         auth_adaptor_plugin_h plugin = NULL;
2145         plugin = context->plugin_handle;
2146
2147         int ret = 0;
2148         plugin_message_h message = NULL;
2149         ret = plugin_message_create(&message);
2150
2151         if (ret == 0) {
2152                 plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
2153                                 (pmnumber) context->context_id);
2154                 plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
2155                                 AUTH_PLUGIN_INTERFACE_REFRESH_ACCESS_TOKEN);
2156
2157                 plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
2158                                 (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
2159
2160                 plugin_message_h result_message = NULL;
2161                 ret = auth_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
2162
2163                 if (0 == ret) {
2164                         pmnumber ret_code;
2165                         plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
2166
2167                         ret = (int) ret_code;
2168                         char *ret_msg = NULL;
2169                         if (AUTH_ADAPTOR_ERROR_NONE == ret) {
2170                                 auth_adaptor_debug("Login refresh successed");
2171                                 char *access_token = NULL;
2172                                 char *uid = NULL;
2173                                 int param_idx = 1;
2174                                 plugin_message_get_param_string(result_message, param_idx++, &access_token);
2175                                 plugin_message_get_param_string(result_message, param_idx++, &uid);
2176                                 auth_adaptor_debug("access token : %s", access_token);
2177                                 auth_adaptor_debug("uid : %s", uid);
2178
2179                                 context->access_token = access_token;
2180                                 context->uid = uid;
2181                         } else {
2182                                 plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
2183                                 auth_adaptor_debug("Login refresh failed (%d)(%s)", ret, ret_msg);
2184                                 if (NULL != error) {
2185                                         auth_adaptor_error_code_h error_code = auth_adaptor_create_error_code(ret, ret_msg);
2186                                         *error = error_code;
2187                                 }
2188                                 free(ret_msg);
2189                                 ret_msg = NULL;
2190                         }
2191                         plugin_message_destroy(result_message);
2192                 }
2193         } else {
2194                 ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
2195         }
2196         plugin_message_destroy(message);
2197
2198         return ret;
2199
2200 }
2201 /*
2202 auth_error_code_t auth_plugin_send_get_server_info(auth_adaptor_plugin_context_h context,
2203                 void *request,
2204                 GHashTable **server_info,
2205                 auth_adaptor_error_code_h *error,
2206                 void *response)
2207
2208 {
2209         auth_adaptor_plugin_h plugin = NULL;
2210         plugin = context->plugin_handle;
2211
2212         int ret = 0;
2213         plugin_message_h message = NULL;
2214         ret = plugin_message_create(&message);
2215
2216         if (ret == 0)
2217         {
2218                 plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
2219                                 (pmnumber) context->context_id);
2220                 plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
2221                                 AUTH_PLUGIN_INTERFACE_LOGIN);
2222
2223                 plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
2224                                 (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
2225
2226                 plugin_message_h result_message = NULL;
2227                 ret = auth_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
2228
2229                 if (0 == ret)
2230                 {
2231                         pmnumber ret_code;
2232                         plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
2233
2234                         ret = (int) ret_code;
2235                         char *ret_msg = NULL;
2236                         if (AUTH_ADAPTOR_ERROR_NONE == ret)
2237                         {
2238                                 auth_adaptor_debug("Get server info successed");
2239                                 char *server_info_raw = NULL;
2240                                 int param_idx = 1;
2241                                 plugin_message_get_param_string(result_message, param_idx++, &server_info_raw);
2242
2243                                 if ((NULL != server_info) && (NULL != server_info_raw))
2244                                 {
2245                                         bundle *info_data = bundle_decode((bundle_raw)server_info_raw, strlen(server_info_raw));
2246                                         if (NULL != info_data)
2247                                         {
2248                                                 GHashTable *ht = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
2249                                                 bundle_foreach(info_data, server_info_iter, (void *) ht);
2250                                                 *server_info = ht;
2251                                         }
2252                                 }
2253
2254                                 free(server_info_raw);
2255                         }
2256                         else
2257                         {
2258                                 plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
2259                                 auth_adaptor_debug("Login failed (%d)(%s)", ret, ret_msg);
2260                                 if (NULL != error)
2261                                 {
2262                                         auth_adaptor_error_code_h error_code = auth_adaptor_create_error_code(ret, ret_msg);
2263                                         *error = error_code;
2264                                 }
2265                                 free(ret_msg);
2266                                 ret_msg = NULL;
2267                         }
2268                         plugin_message_destroy(result_message);
2269                 }
2270         }
2271         else
2272         {
2273                 ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
2274         }
2275         plugin_message_destroy(message);
2276
2277         return ret;
2278
2279 }
2280 */
2281
2282
2283 auth_error_code_t auth_plugin_send_set_service_status(auth_adaptor_plugin_context_h context,
2284                                                         const int service_id,
2285                                                         const int status,
2286                                                         void *request,
2287                                                         auth_adaptor_error_code_h *error,
2288                                                         void *response)
2289 {
2290         return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
2291 }
2292
2293 auth_error_code_t auth_plugin_send_get_msisdn(auth_adaptor_plugin_context_h context,
2294                                                         void *request,
2295                                                         char **msisdn,
2296                                                         auth_adaptor_error_code_h *error,
2297                                                         void *response)
2298 {
2299         return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
2300 }
2301
2302 auth_error_code_t auth_plugin_send_get_service_status(auth_adaptor_plugin_context_h context,
2303                 const int service_id,
2304                 void *request,
2305                 int *status,
2306                 auth_adaptor_error_code_h *error,
2307                 void *response)
2308 {
2309         return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
2310 }
2311
2312 auth_error_code_t auth_plugin_send_get_service_policy(auth_adaptor_plugin_context_h context,
2313                 const int service_id,
2314                 void *request,
2315                 char **default_status,
2316                 char **policy_feature,
2317                 char **policy_version,
2318                 char **policy_doc_url,
2319                 auth_adaptor_error_code_h *error,
2320                 void *response)
2321 {
2322         return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
2323 }
2324
2325 auth_error_code_t auth_plugin_send_get_server_info(auth_adaptor_plugin_context_h context,
2326                 void *request,
2327                 GHashTable **server_info,
2328                 auth_adaptor_error_code_h *error,
2329                 void *response)
2330 {
2331         return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
2332 }
2333
2334
2335 /* For forked plugin */
2336 void *_auth_plugin_request_collector(void *data)
2337 {
2338         auth_adaptor_plugin_h plugin = (auth_adaptor_plugin_h) data;
2339
2340         int rcv_len, buf_size;
2341         char msg_buf[PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE] = {0, };
2342
2343         while (1) {
2344                 /* pre-read buf size */
2345                 rcv_len = read(plugin->rd, &buf_size, sizeof(int));
2346
2347                 if (rcv_len <= 0) {
2348                         LOGD("shutdown by adaptor disconnected");
2349                         return NULL;
2350                 }
2351
2352                 /* allocates and read buf data */
2353                 memset(msg_buf, 0, PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE);
2354                 buf_size %= PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE - 1;
2355                 rcv_len = read(plugin->rd, msg_buf, buf_size);
2356                 LOGD("read message [%s][len: %d]", msg_buf, rcv_len);
2357
2358                 if (rcv_len <= 0) {
2359                         LOGD("shutdown by adaptor disconnected");
2360                         return NULL;
2361                 }
2362
2363                 char *result = NULL;
2364                 __auth_plugin_progress_command(plugin, msg_buf, &result);
2365
2366                 if (NULL != result) {
2367                         int res_len = strlen(result);
2368                         rcv_len = write(plugin->wd, &res_len, sizeof(int));
2369                         rcv_len = write(plugin->wd, result, sizeof(char) * res_len);
2370                 }
2371                 /* transfer data to adaptor */
2372                 /*              __auth_adaptor_transfer_message(adaptor, msg_buf); */
2373         }
2374         return data;
2375 }
2376
2377 auth_adaptor_plugin_context_h __auth_plugin_get_context_by_context_id(auth_adaptor_plugin_h plugin, int context_id)
2378 {
2379         if (NULL == plugin) {
2380                 return NULL;
2381         }
2382
2383         /* For forked plugin */
2384         auth_adaptor_plugin_context_h ctx = NULL;
2385         int i, len;
2386         len = g_list_length(plugin->contexts);
2387
2388         for (i = 0; i < len; i++) {
2389                 ctx = (auth_adaptor_plugin_context_h) g_list_nth_data(plugin->contexts, i);
2390
2391                 if (context_id == ctx->context_id) {
2392                         return ctx;
2393                 }
2394         }
2395         return NULL;
2396 }
2397
2398 void __auth_plugin_progress_command(auth_adaptor_plugin_h plugin, char *order, char **result)
2399 {
2400         int ret = 0;
2401         plugin_message_h m_order = NULL;
2402         plugin_message_h m_result = NULL;
2403
2404         if ((NULL == order) || (plugin_message_deserialize(order, &m_order))) {
2405                 LOGE("[%s/%d] Message parse error", __FUNCTION__, __LINE__);
2406                 return;
2407         } else if (plugin_message_create(&m_result)) {
2408                 plugin_message_destroy(m_order);
2409                 m_order = NULL;
2410
2411                 LOGE("[%s/%d] Message parse error", __FUNCTION__, __LINE__);
2412                 return;
2413         }
2414
2415         char *func_name = NULL;
2416         int context_id = 0;
2417
2418         pmnumber ctx, req, type;
2419
2420         plugin_message_get_value_number(m_order, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID, &ctx);
2421         plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID, ctx);
2422         plugin_message_get_value_number(m_order, PLUGIN_MESSAGE_ELEMENT_REQUEST_ID, &req);
2423         plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_REQUEST_ID, req);
2424         plugin_message_get_value_string(m_order, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME, &func_name);
2425         plugin_message_set_value_string(m_result, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME, func_name);
2426         plugin_message_get_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, &type);
2427         plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, type);
2428         plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)AUTH_ADAPTOR_ERROR_NONE);
2429         context_id = (int) ctx;
2430         auth_adaptor_plugin_context_h context = __auth_plugin_get_context_by_context_id(plugin, context_id);
2431
2432         auth_adaptor_error_code_h error_code = NULL;
2433
2434         if (0 == strncmp(AUTH_PLUGIN_INTERFACE_CREATE_CONTEXT,
2435                         func_name, strlen(AUTH_PLUGIN_INTERFACE_CREATE_CONTEXT))) {
2436                 LOGD(">>>>>> %s func start", func_name);
2437                 char *user_id = NULL;
2438                 char *user_password = NULL;
2439                 char *app_id = NULL;
2440                 char *app_secret = NULL;
2441                 char *service_name = NULL;
2442                 char *imsi = NULL;
2443
2444                 int param_idx = 1;
2445                 plugin_message_get_param_string(m_order, param_idx++, &user_id);
2446                 plugin_message_get_param_string(m_order, param_idx++, &user_password);
2447                 plugin_message_get_param_string(m_order, param_idx++, &app_id);
2448                 plugin_message_get_param_string(m_order, param_idx++, &app_secret);
2449                 plugin_message_get_param_string(m_order, param_idx++, &imsi);
2450
2451                 LOGD("Call library function");
2452                 context = auth_adaptor_create_plugin_context(plugin,
2453                                 user_id, user_password, app_id, app_secret, imsi, "");
2454                 if (NULL == context) {
2455                         LOGE("[%s<%s>/%d] Could not create context", __FUNCTION__, func_name, __LINE__);
2456                         plugin_message_set_value_number(m_result,
2457                                         PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
2458                                         (pmnumber)AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL);
2459                         plugin_message_set_value_string(m_result,
2460                                         PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
2461                                         "Could not create context");
2462                 } else {
2463                         LOGD("[%s<%s>/%d] Created context successfuly", __FUNCTION__, func_name, __LINE__);
2464                         context->context_id = context_id;
2465
2466                         plugin_message_set_value_number(m_result,
2467                                         PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
2468                                         (pmnumber)AUTH_ADAPTOR_ERROR_NONE);
2469                 }
2470
2471                 free(user_id);
2472                 free(user_password);
2473                 free(app_id);
2474                 free(app_secret);
2475                 free(service_name);
2476                 LOGD("<<<<<< %s func end", func_name);
2477         } else if (0 == strncmp(AUTH_PLUGIN_INTERFACE_DESTROY_CONTEXT,
2478                         func_name, strlen(AUTH_PLUGIN_INTERFACE_DESTROY_CONTEXT))) {
2479                 LOGD(">>>>>> %s func start", func_name);
2480                 if (NULL == context) {
2481                         LOGE("[%s<%s>/%d] Could not found context", __FUNCTION__, func_name, __LINE__);
2482                         plugin_message_set_value_number(m_result,
2483                                         PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
2484                                         (pmnumber)AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT);
2485                         plugin_message_set_value_string(m_result,
2486                                         PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
2487                                         "Invalid argument (context is NULL)");
2488                 } else {
2489                         LOGD("[%s<%s>/%d] function success", __FUNCTION__, func_name, __LINE__);
2490                         auth_adaptor_destroy_plugin_context(plugin, context);
2491
2492                         plugin_message_set_value_number(m_result,
2493                                         PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
2494                                         (pmnumber)AUTH_ADAPTOR_ERROR_NONE);
2495                 }
2496                 LOGD("<<<<<< %s func end", func_name);
2497         } else if (0 == strncmp(AUTH_PLUGIN_INTERFACE_IS_AUTH,
2498                         func_name, strlen(AUTH_PLUGIN_INTERFACE_IS_AUTH))) {
2499                 LOGD(">>>>>> %s func start", func_name);
2500                 int is_auth = 0;
2501                 LOGD("Call library function");
2502                 if (NULL == context) {
2503                         LOGE("[%s<%s>/%d] Could not found context", __FUNCTION__, func_name, __LINE__);
2504                         plugin_message_set_value_number(m_result,
2505                                         PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
2506                                         (pmnumber)AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT);
2507                         plugin_message_set_value_string(m_result,
2508                                         PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
2509                                         "Invalid argument (context is NULL)");
2510                 } else {
2511                         ret = plugin->handle->is_auth(context, NULL, &is_auth, &error_code, NULL);
2512                         if (AUTH_ADAPTOR_ERROR_NONE == ret) {
2513                                 int param_idx = 1;
2514                                 plugin_message_set_param_number(m_result, param_idx++, (pmnumber)is_auth);
2515                                 plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
2516                         } else if (NULL != error_code) {
2517                                 plugin_message_set_value_number(m_result,
2518                                                 PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
2519                                                 (pmnumber)error_code->code);
2520                                 plugin_message_set_value_string(m_result,
2521                                                 PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
2522                                                 error_code->msg ? error_code->msg : "");
2523                                 free(error_code->msg);
2524                                 free(error_code);
2525                         } else {
2526                                 plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
2527                         }
2528                 }
2529                 LOGD("<<<<<< %s func end", func_name);
2530         } else if (0 == strncmp(AUTH_PLUGIN_INTERFACE_LOGIN,
2531                         func_name, strlen(AUTH_PLUGIN_INTERFACE_LOGIN))) {
2532                 LOGD(">>>>>> %s func start", func_name);
2533                 LOGD("Call library function");
2534                 if (NULL == context) {
2535                         LOGE("[%s<%s>/%d] Could not found context", __FUNCTION__, func_name, __LINE__);
2536                         plugin_message_set_value_number(m_result,
2537                                         PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
2538                                         (pmnumber)AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT);
2539                         plugin_message_set_value_string(m_result,
2540                                         PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
2541                                         "Invalid argument (context is NULL)");
2542                 } else {
2543                         ret = plugin->handle->login(context, NULL, &error_code, NULL);
2544                         if (AUTH_ADAPTOR_ERROR_NONE == ret) {
2545                                 int param_idx = 1;
2546                                 plugin_message_set_param_string(m_result, param_idx++, context->access_token ? context->access_token : "");
2547                                 plugin_message_set_param_string(m_result, param_idx++, context->uid ? context->uid : "");
2548                                 plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
2549                         } else if (NULL != error_code) {
2550                                 plugin_message_set_value_number(m_result,
2551                                                 PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
2552                                                 (pmnumber)error_code->code);
2553                                 plugin_message_set_value_string(m_result,
2554                                                 PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
2555                                                 error_code->msg ? error_code->msg : "");
2556                                 free(error_code->msg);
2557                                 free(error_code);
2558                         } else {
2559                                 plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
2560                         }
2561                 }
2562                 LOGD("<<<<<< %s func end", func_name);
2563         } else if (0 == strncmp(AUTH_PLUGIN_INTERFACE_REFRESH_ACCESS_TOKEN,
2564                         func_name, strlen(AUTH_PLUGIN_INTERFACE_REFRESH_ACCESS_TOKEN))) {
2565                 LOGD(">>>>>> %s func start", func_name);
2566                 LOGD("Call library function");
2567                 if (NULL == context) {
2568                         LOGE("[%s<%s>/%d] Could not found context", __FUNCTION__, func_name, __LINE__);
2569                         plugin_message_set_value_number(m_result,
2570                                         PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
2571                                         (pmnumber)AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT);
2572                         plugin_message_set_value_string(m_result,
2573                                         PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
2574                                         "Invalid argument (context is NULL)");
2575                 } else {
2576                         ret = plugin->handle->refresh_access_token(context, NULL, &error_code, NULL);
2577                         if (AUTH_ADAPTOR_ERROR_NONE == ret) {
2578                                 int param_idx = 1;
2579                                 plugin_message_set_param_string(m_result, param_idx++, context->access_token ? context->access_token : "");
2580                                 plugin_message_set_param_string(m_result, param_idx++, context->uid ? context->uid : "");
2581                                 plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
2582                         } else if (NULL != error_code) {
2583                                 plugin_message_set_value_number(m_result,
2584                                                 PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
2585                                                 (pmnumber)error_code->code);
2586                                 plugin_message_set_value_string(m_result,
2587                                                 PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
2588                                                 error_code->msg ? error_code->msg : "");
2589                                 free(error_code->msg);
2590                                 free(error_code);
2591                         } else {
2592                                 plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
2593                         }
2594                 }
2595                 LOGD("<<<<<< %s func end", func_name);
2596         } else {
2597                 plugin_message_set_value_number(m_result,
2598                                 PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
2599                                 (pmnumber)AUTH_ADAPTOR_ERROR_UNSUPPORTED);
2600                 plugin_message_set_value_string(m_result,
2601                                 PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
2602                                 "Unsupported operation");
2603         }
2604
2605         free(func_name);
2606
2607         char *result_data = NULL;
2608         plugin_message_serialize(m_result, &result_data);
2609         plugin_message_destroy(m_result);
2610         plugin_message_destroy(m_order);
2611
2612         *result = result_data;
2613 }
2614
2615