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