Fix Macro issue
[framework/telephony/libtcore.git] / src / server.c
1 /*
2  * libtcore
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Ja-young Gu <jygu@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <pthread.h>
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <time.h>
27 #include <dlfcn.h>
28
29 #include <glib.h>
30 #include <glib/gprintf.h>
31
32 #include "tcore.h"
33 #include "plugin.h"
34 #include "server.h"
35 #include "user_request.h"
36 #include "core_object.h"
37 #include "co_ps.h"
38 #include "communicator.h"
39 #include "storage.h"
40 #include "udev.h"
41 #include "util.h"
42
43 #define MODEMS_PATH "/usr/lib/telephony/plugins/modems"
44
45 struct tcore_server_type {
46         GMainLoop *mainloop;
47         GSList *plugins;
48         GSList *communicators;
49         GSList *storages;
50         GSList *modems;
51
52         GSList *template_co;
53
54         GSList *hook_list_request;
55         GSList *hook_list_notification;
56
57         TcorePlugin *default_plugin;
58         TcoreUdev *udev;
59 };
60
61 struct tcore_modem_type {
62         char *cp_name;
63         TcorePlugin *modem_iface_plugin;
64
65         TcorePlugin *modem_plugin;
66
67         void *mapping_tbl;
68 };
69
70 struct hook_request_type {
71         enum tcore_request_command command;
72         tcore_server_request_hook func;
73         void *user_data;
74 };
75
76 struct hook_notification_type {
77         enum tcore_notification_command command;
78         tcore_server_notification_hook func;
79         void *user_data;
80 };
81
82 static gint _compare_priority(gconstpointer a, gconstpointer b)
83 {
84         TcorePlugin *plugin1 = (TcorePlugin *)a;
85         TcorePlugin *plugin2 = (TcorePlugin *)b;
86
87         if (plugin2 == NULL)
88                 return 1;
89
90         return tcore_plugin_get_description(plugin1)->priority -
91                         tcore_plugin_get_description(plugin2)->priority;
92 }
93
94 static char *_server_enumerate_modem(TcorePlugin *plugin)
95 {
96         static unsigned int cp_counter = 0;
97         char *filename;
98
99         if (plugin == NULL)
100                 return NULL;
101
102         /*
103          * Presently enumeration is based on Modem Interface Plug-in descriptor name
104          * followed by an incremental Positive integer 'cp_count'.
105          *
106          * For example, if Modem Interface Plug-in descriptor name is 'imcmodem' then,
107          *      'name' would be enumerated as "imcmode_N", where N >= 0
108          */
109         filename = tcore_plugin_ref_plugin_name(plugin);
110         if (filename == NULL)
111                 return NULL;
112
113         dbg("%s", filename);
114
115         return g_strdup_printf("%s%d", filename, cp_counter++);
116 }
117
118 static TcoreModem *_server_find_modem(Server *s,
119                                 TcorePlugin *modem_iface_plugin, TcorePlugin *modem_plugin)
120 {
121         GSList *list;
122         TcoreModem *modem;
123
124         dbg("Modem Plug-in [0x%x][%s] Modem Interface Plug-in: [0x%x][%s]",
125                         modem_plugin, tcore_plugin_ref_plugin_name(modem_plugin),
126                         modem_iface_plugin, tcore_plugin_ref_plugin_name(modem_iface_plugin));
127
128         for (list = s->modems; list; list = list->next) {
129                 modem = list->data;
130                 if (modem == NULL)
131                         continue;
132
133                 /*
134                  * Specifically for Unregister, Add Modem Plug-in
135                  * and Add/Remove Mapping Table -
136                  *
137                  * MUST match Modem Interface Plug-in
138                  *                      AND
139                  * If passed Modem Interface Plug-in is NULL, then
140                  * Modem Interface Plug-in of 'modems' MUST be NULL
141                  */
142                 if ((modem_iface_plugin == modem->modem_iface_plugin)
143                         && ((modem_plugin == NULL) && (modem->modem_plugin == NULL))) {
144                         dbg("'modem' found!!!");
145                         return modem;
146                 }
147
148                 /*
149                  * Specifically for get Mapping Table -
150                  *
151                  * Modem Interface Plug-in MUST be NULL
152                  *                      AND
153                  * Passed Modem Plug-in MUST match Modem Plug-of 'modems'
154                  */
155                 if ((modem_iface_plugin == NULL)
156                         && (modem_plugin == modem->modem_plugin)) {
157                         dbg("'modem' found!!!");
158                         return modem;
159                 }
160
161                 /*
162                  * Specifically for get CP name -
163                  *
164                  * Passed Modem OR Modem Interface Plug-in MUST match
165                  *                      AND
166                  * MUST match either Modem OR Modem Interface Plug-in of 'modems'
167                  */
168                 if ((modem_iface_plugin == modem_plugin)
169                                 && ((modem_iface_plugin == modem->modem_iface_plugin)
170                                         || (modem_plugin == modem->modem_plugin))) {
171                         dbg("'modem' found!!!");
172                         return modem;
173                 }
174         }
175
176         err("Modem not found");
177
178         return NULL;
179 }
180
181 Server *tcore_server_new()
182 {
183         Server *s;
184
185         s = g_try_new0(struct tcore_server_type, 1);
186         if (s == NULL)
187                 return NULL;
188
189         s->mainloop = g_main_loop_new (NULL, FALSE);
190         if (s->mainloop == NULL) {
191                 free(s);
192                 return NULL;
193         }
194
195         s->plugins = NULL;
196         s->communicators = NULL;
197         s->storages = NULL;
198         s->template_co = NULL;
199         s->hook_list_request = NULL;
200         s->hook_list_notification = NULL;
201         s->default_plugin = NULL;
202
203         return s;
204 }
205
206 void tcore_server_free(Server *s)
207 {
208         GSList *list;
209         TcorePlugin *p;
210         const struct tcore_plugin_define_desc *desc;
211
212         if (s == NULL)
213                 return;
214
215         if (s->mainloop)
216                 g_main_loop_unref(s->mainloop);
217
218     for (list = s->plugins; list; list = list->next) {
219         p = list->data;
220         if (p == NULL)
221             continue;
222
223         desc = (struct tcore_plugin_define_desc *)tcore_plugin_get_description(p);
224                 if ((desc == NULL) || (desc->unload == NULL))
225                         continue;
226
227                 desc->unload(p);
228
229                 tcore_plugin_free(p);
230
231                 list->data = NULL;
232         }
233
234         if (s->hook_list_notification)
235                 g_slist_free_full(s->hook_list_notification, g_free);
236
237         if (s->hook_list_request)
238                 g_slist_free_full(s->hook_list_request, g_free);
239
240         if (s->template_co)
241                 g_slist_free(s->template_co);
242
243         if (s->storages)
244                 g_slist_free(s->storages);
245
246         if (s->communicators)
247                 g_slist_free(s->communicators);
248
249         if (s->plugins) {
250                 g_slist_free(s->plugins);
251                 s->plugins = NULL;
252         }
253
254         /* Freeing Server */
255         g_free(s);
256 }
257
258 TReturn tcore_server_run(Server *s)
259 {
260         char *version;
261
262         if ((s == NULL)|| (s->mainloop == NULL))
263                 return TCORE_RETURN_EINVAL;
264
265         version = tcore_util_get_version();
266         if (version) {
267                 dbg("libtcore version: %s", version);
268                 free(version);
269         }
270
271         tcore_server_send_notification(s, NULL, TNOTI_SERVER_RUN, 0, NULL);
272
273         g_main_loop_run(s->mainloop);
274
275         return TCORE_RETURN_SUCCESS;
276 }
277
278 TReturn tcore_server_exit(Server *s)
279 {
280         if ((s == NULL)|| (s->mainloop == NULL))
281                 return TCORE_RETURN_EINVAL;
282
283         g_main_loop_quit(s->mainloop);
284
285         return TCORE_RETURN_SUCCESS;
286 }
287
288 TReturn tcore_server_add_plugin(Server *s, TcorePlugin *plugin)
289 {
290         if ((s == NULL)|| (plugin == NULL))
291                 return TCORE_RETURN_EINVAL;
292
293         s->plugins = g_slist_insert_sorted(s->plugins, plugin, _compare_priority);
294
295         tcore_server_send_notification(s, NULL, TNOTI_SERVER_ADDED_PLUGIN, 0, NULL);
296
297         return TCORE_RETURN_SUCCESS;
298 }
299
300 TcorePlugin *tcore_server_find_plugin(Server *s, const char *name)
301 {
302         GSList *list;
303         TcoreModem *modem;
304
305         dbg("Name: [%s]", name);
306
307         for (list = s->modems; list; list = list->next) {
308                 modem = list->data;
309                 if (modem == NULL)
310                         continue;
311
312                 if (g_strcmp0(modem->cp_name, name) == 0)
313                         return modem->modem_plugin;
314         }
315
316         err("Modem plugin not found");
317
318         return NULL;
319 }
320
321 GSList *tcore_server_ref_plugins(Server *s)
322 {
323         if (s == NULL)
324                 return NULL;
325
326         return s->plugins;
327 }
328
329 TReturn tcore_server_add_communicator(Server *s, Communicator *comm)
330 {
331         if ((s == NULL)|| (comm == NULL))
332                 return TCORE_RETURN_EINVAL;
333
334         s->communicators = g_slist_insert(s->communicators, comm, 0);
335
336         tcore_server_send_notification(s, NULL, TNOTI_SERVER_ADDED_COMMUNICATOR, 0, NULL);
337
338         return TCORE_RETURN_SUCCESS;
339 }
340
341 GSList *tcore_server_ref_communicators(Server *s)
342 {
343         if (s == NULL)
344                 return NULL;
345
346         return s->communicators;
347 }
348
349 Communicator *tcore_server_find_communicator(Server *s, const char *name)
350 {
351         GSList *list;
352         Communicator *comm;
353
354         for (list = s->communicators; list; list = list->next) {
355                 comm = list->data;
356                 if (comm == NULL) {
357                         continue;
358                 }
359
360                 if (g_strcmp0(tcore_communicator_ref_name(comm), name) == 0) {
361                         return comm;
362                 }
363         }
364
365         return NULL;
366 }
367
368 TReturn tcore_server_add_storage(Server *s, Storage *strg)
369 {
370         if ((s == NULL)|| (strg == NULL))
371                 return TCORE_RETURN_EINVAL;
372
373         s->storages = g_slist_insert(s->storages, strg, 0);
374
375         tcore_server_send_notification(s, NULL, TNOTI_SERVER_ADDED_STORAGE, 0, NULL);
376
377         return TCORE_RETURN_SUCCESS;
378 }
379
380 GSList *tcore_server_ref_storages(Server *s)
381 {
382         if (s == NULL)
383                 return NULL;
384
385         return s->storages;
386 }
387
388 Storage *tcore_server_find_storage(Server *s, const char *name)
389 {
390         GSList *list;
391         Storage *strg;
392
393         for (list = s->storages; list; list = list->next) {
394                 strg = list->data;
395                 if (strg == NULL) {
396                         continue;
397                 }
398
399                 if (g_strcmp0(tcore_storage_ref_name(strg), name) == 0) {
400                         return strg;
401                 }
402         }
403
404         return NULL;
405 }
406
407 TReturn tcore_server_add_template_object(Server *s, CoreObject *template_co)
408 {
409         GSList *list;
410         CoreObject *temp;
411
412         if ((s == NULL)|| (template_co == NULL))
413                 return TCORE_RETURN_EINVAL;
414
415         for (list = s->template_co; list; list = list->next) {
416                 temp = list->data;
417                 if (temp == NULL) {
418                         continue;
419                 }
420
421                 if (tcore_object_get_type(temp) == tcore_object_get_type(template_co)) {
422                         return TCORE_RETURN_EALREADY;
423                 }
424         }
425
426         s->template_co = g_slist_insert(s->template_co, template_co, 0);
427
428         return TCORE_RETURN_SUCCESS;
429 }
430
431 GSList *tcore_server_ref_template_object(Server *s)
432 {
433         if (s == NULL)
434                 return NULL;
435
436         return s->template_co;
437 }
438
439 CoreObject *tcore_server_find_template_object(Server *s, unsigned int type)
440 {
441         GSList *list;
442         CoreObject *template_co;
443
444         for (list = s->template_co; list; list = list->next) {
445                 template_co = list->data;
446                 if (template_co == NULL)
447                         continue;
448
449                 if (type == tcore_object_get_type(template_co))
450                         return template_co;
451         }
452
453         return NULL;
454 }
455
456 TReturn tcore_server_link_udev(Server *s, TcoreUdev *udev)
457 {
458         if ((s == NULL)|| (udev == NULL))
459                 return TCORE_RETURN_EINVAL;
460
461         s->udev = udev;
462
463         return TCORE_RETURN_SUCCESS;
464 }
465
466 TcoreUdev *tcore_server_ref_udev(Server *s)
467 {
468         if (s == NULL)
469                 return NULL;
470
471         return s->udev;
472 }
473
474 TReturn tcore_server_dispatch_request(Server *s, UserRequest *ur)
475 {
476         char *modem = NULL;
477         TcorePlugin *p;
478         enum tcore_request_command command = 0;
479         GSList *list;
480         struct hook_request_type *hook;
481         int category;
482         CoreObject *co;
483         TReturn ret = TCORE_RETURN_ENOSYS;
484
485         if ((s == NULL)|| (ur == NULL))
486                 return TCORE_RETURN_EINVAL;
487
488         for (list = s->hook_list_request; list; list = list->next) {
489                 hook = list->data;
490                 if (hook == NULL)
491                         continue;
492
493                 if (hook->command == tcore_user_request_get_command(ur))
494                         if (hook->func(s, ur, hook->user_data)
495                                         == TCORE_HOOK_RETURN_STOP_PROPAGATION)
496                                 return TCORE_RETURN_SUCCESS;
497         }
498
499         modem = tcore_user_request_get_modem_name(ur);
500         if (modem == NULL)
501                 return TCORE_RETURN_EINVAL;
502
503         p = tcore_server_find_plugin(s, modem);
504         if (p == NULL) {
505                 free(modem);
506                 return TCORE_RETURN_SERVER_WRONG_PLUGIN;
507         }
508         free(modem);
509
510         command = tcore_user_request_get_command(ur);
511
512         category = CORE_OBJECT_TYPE_DEFAULT | (command & 0x0FF00000);
513         dbg("Category: [0x%x]", category);
514
515         co = tcore_plugin_ref_core_object(p, category);
516         if (co == NULL) {
517                 warn("can't find 0x%x core_object", category);
518                 return TCORE_RETURN_ENOSYS;
519         }
520
521         if (tcore_object_dispatch_request(co, ur) == TCORE_RETURN_SUCCESS)
522                         ret = TCORE_RETURN_SUCCESS;
523                 else
524                         dbg("failed...");
525
526         return ret;
527 }
528
529 TReturn tcore_server_send_notification(Server *s, CoreObject *source,
530                 enum tcore_notification_command command,
531                 unsigned int data_len, void *data)
532 {
533         GSList *list;
534         Communicator *comm;
535         struct hook_notification_type *hook;
536         dbg("Send Notification!!! Command: [0x%x]", command);
537
538         if (s == NULL)
539                 return TCORE_RETURN_EINVAL;
540
541         for (list = s->hook_list_notification; list; list = list->next) {
542                 hook = list->data;
543                 if (hook == NULL) {
544                         continue;
545                 }
546
547                 if (hook->command == command) {
548                         dbg("Invoking hook_func() for Command: [0x%x]", command);
549                         if (hook->func(s, source, command, data_len, data, hook->user_data)
550                                         == TCORE_HOOK_RETURN_STOP_PROPAGATION)
551                                 return TCORE_RETURN_SUCCESS;
552                 }
553         }
554
555         for (list = s->communicators; list; list = list->next) {
556                 comm = list->data;
557                 if (comm == NULL)
558                         continue;
559
560                 tcore_communicator_send_notification(comm, source, command, data_len, data);
561         }
562
563         return TCORE_RETURN_SUCCESS;
564 }
565
566 TReturn tcore_server_add_request_hook(Server *s,
567                 enum tcore_request_command command,
568                 tcore_server_request_hook func, void *user_data)
569 {
570         struct hook_request_type *hook;
571
572         if ((s == NULL)|| (func == NULL))
573                 return TCORE_RETURN_EINVAL;
574
575         hook = g_try_new0(struct hook_request_type, 1);
576         if (hook == NULL)
577                 return TCORE_RETURN_ENOMEM;
578
579         hook->command = command;
580         hook->func = func;
581         hook->user_data = user_data;
582
583         s->hook_list_request = g_slist_append(s->hook_list_request, hook);
584
585         return TCORE_RETURN_SUCCESS;
586 }
587
588 TReturn tcore_server_remove_request_hook(Server *s, tcore_server_request_hook func)
589 {
590         struct hook_request_type *hook;
591         GSList *list;
592
593         if (s == NULL)
594                 return TCORE_RETURN_EINVAL;
595
596         for (list = s->hook_list_request; list; list = list->next) {
597                 hook = list->data;
598                 if (hook == NULL) {
599                         continue;
600                 }
601
602                 if (hook->func == func) {
603                         s->hook_list_request = g_slist_remove(s->hook_list_request, hook);
604                         list = s->hook_list_request;
605                         g_free(hook);
606                 }
607         }
608
609         return TCORE_RETURN_SUCCESS;
610 }
611
612 TReturn tcore_server_add_notification_hook(Server *s,
613                 enum tcore_notification_command command,
614                 tcore_server_notification_hook func, void *user_data)
615 {
616         struct hook_notification_type *hook;
617
618         if ((s == NULL) || (func == NULL)) {
619                 err("server: [0x%x] func: [0x%x]", s, func);
620                 return TCORE_RETURN_EINVAL;
621         }
622
623         hook = g_try_new0(struct hook_notification_type, 1);
624         if (hook == NULL) {
625                 err("Failed to allocate memory");
626                 return TCORE_RETURN_ENOMEM;
627         }
628
629         hook->command = command;
630         hook->func = func;
631         hook->user_data = user_data;
632
633         s->hook_list_notification = g_slist_append(s->hook_list_notification, hook);
634         dbg("Added hook_func() for Command: [0x%x]", command);
635
636         return TCORE_RETURN_SUCCESS;
637 }
638
639 TReturn tcore_server_remove_notification_hook(Server *s,
640                 tcore_server_notification_hook func)
641 {
642         struct hook_notification_type *hook;
643         GSList *list;
644
645         if (s == NULL)
646                 return TCORE_RETURN_EINVAL;
647
648         for (list = s->hook_list_notification; list; list = list->next) {
649                 hook = list->data;
650                 if (hook == NULL) {
651                         continue;
652                 }
653
654                 if (hook->func == func) {
655                         s->hook_list_notification = g_slist_remove(s->hook_list_notification, hook);
656                         list = s->hook_list_notification;
657                         g_free(hook);
658                 }
659         }
660
661         return TCORE_RETURN_SUCCESS;
662 }
663
664 gboolean tcore_server_register_modem(Server *s, TcorePlugin *modem_iface_plugin)
665 {
666         TcoreModem *modem;
667
668         if ((s == NULL) || (modem_iface_plugin == NULL)) {
669                 err("server [0x%x] Modem Interface Plug-in: [0x%x]", s, modem_iface_plugin);
670                 return FALSE;
671         }
672
673         modem = g_try_new0(TcoreModem, 1);
674         if (modem == NULL) {
675                 err("Failed to allocate memory");
676                 return FALSE;
677         }
678
679         modem->cp_name = _server_enumerate_modem(modem_iface_plugin);
680         modem->modem_iface_plugin = modem_iface_plugin;
681
682         s->modems = g_slist_append(s->modems, modem);
683         dbg("Added to 'modems' entry - CP Name: [%s] Modem Interface Plug-in: [%s]",
684                                         modem->cp_name, tcore_plugin_ref_plugin_name(modem_iface_plugin));
685
686         return TRUE;
687 }
688
689 void tcore_server_unregister_modem(Server *s, TcorePlugin *modem_iface_plugin)
690 {
691         TcoreModem *modem;
692
693         if ((s == NULL) || (modem_iface_plugin == NULL)) {
694                 err("server [0x%x] Modem Interface Plug-in: [0x%x]", s, modem_iface_plugin);
695                 return;
696         }
697
698         modem = _server_find_modem(s, modem_iface_plugin, NULL);
699         if (modem == NULL) {
700                 err("Failed to find 'modem' for Modem Interface Plug-in: [%s]",
701                                         tcore_plugin_ref_plugin_name(modem_iface_plugin));
702                 return;
703         }
704
705         s->modems = g_slist_remove(s->modems, modem);
706
707         g_free(modem->cp_name);
708         g_free(modem);
709 }
710
711 gboolean tcore_server_update_modem_plugin(TcorePlugin *modem_iface_plugin,
712                                                         TcorePlugin *modem_plugin)
713 {
714         Server *s;
715         TcoreModem *modem;
716
717         if ((modem_iface_plugin == NULL) || (modem_plugin == NULL)) {
718                 err("Modem Plug-in [0x%x] Modem Interface Plug-in: [0x%x]",
719                                                                         modem_plugin, modem_iface_plugin);
720                 return FALSE;
721         }
722
723         s = tcore_plugin_ref_server(modem_iface_plugin);
724         if (s == NULL) {
725                 err("server is NULL");
726                 return FALSE;
727         }
728
729         modem = _server_find_modem(s, modem_iface_plugin, NULL);
730         if (modem == NULL) {
731                 err("Failed to find 'modem' for Modem Interface Plug-in: [%s]",
732                                         tcore_plugin_ref_plugin_name(modem_iface_plugin));
733                 return FALSE;
734         }
735
736         modem->modem_plugin = modem_plugin;
737         dbg("Added to 'modems' pair - Modem Plug-in [%s] <---> Modem Interface Plug-in: [%s]",
738                                         tcore_plugin_ref_plugin_name(modem_plugin),
739                                         tcore_plugin_ref_plugin_name(modem_iface_plugin));
740
741         return TRUE;
742 }
743
744 GSList *tcore_server_get_cp_name_list(Server *s)
745 {
746         GSList *cp_name_list = NULL;
747         GSList *list;
748         unsigned int list_count;
749         TcoreModem *modem;
750
751         int i = 0;
752
753         if (s == NULL) {
754                 err("server is NULL");
755                 return NULL;
756         }
757
758         list_count = g_slist_length(s->modems);
759         if (list_count == 0) {
760                 err("No entries in Modems list");
761                 return NULL;
762         }
763
764         for (list = s->modems; list; list = list->next) {
765                 modem = list->data;
766                 if (modem == NULL) {
767                         dbg("No modem - continue");
768                         continue;
769                 }
770
771                 dbg("[%d] CP Name: [%s]", i++, modem->cp_name);
772                 cp_name_list = g_slist_append(cp_name_list, g_strdup(modem->cp_name));
773         }
774
775         /* 'cp_name_list' would be freed by the calling function */
776         return cp_name_list;
777 }
778
779 const char *tcore_server_get_cp_name_by_plugin(TcorePlugin *plugin)
780 {
781         Server *s;
782         TcoreModem *modem;
783
784         if (plugin == NULL) {
785                 err("plugin is NULL");
786                 return NULL;
787         }
788
789         s = tcore_plugin_ref_server(plugin);
790         if (s == NULL) {
791                 err("server is NULL");
792                 return NULL;
793         }
794
795         modem = _server_find_modem(s, plugin, plugin);
796         if (modem == NULL) {
797                 err("Failed to find 'modem' for Plug-in: [%s]",
798                                         tcore_plugin_ref_plugin_name(plugin));
799                 return NULL;
800         }
801
802         return (const char *)modem->cp_name;
803 }
804
805 gboolean tcore_server_add_cp_mapping_tbl_entry(TcorePlugin *modem_iface_plugin,
806                                         unsigned int co_type, TcoreHal *hal)
807 {
808         Server *s;
809         TcoreModem *modem;
810
811         if (modem_iface_plugin == NULL) {
812                 err("Modem Interface is NULL");
813                 return FALSE;
814         }
815
816         s = tcore_plugin_ref_server(modem_iface_plugin);
817         if (s == NULL) {
818                 err("server is NULL");
819                 return FALSE;
820         }
821
822         modem = _server_find_modem(s, modem_iface_plugin, NULL);
823         if (modem == NULL) {
824                 err("Failed to find 'modem' for Modem Interface Plug-in: [%s]",
825                                         tcore_plugin_ref_plugin_name(modem_iface_plugin));
826                 return FALSE;
827         }
828
829         /*
830          * Set the Mapping Table to the Modems list
831          */
832         modem->mapping_tbl =
833                         tcore_object_add_mapping_tbl_entry(modem->mapping_tbl,
834                                                                 co_type, hal);
835
836         return TRUE;
837 }
838
839 void tcore_server_remove_cp_mapping_tbl(TcorePlugin *modem_iface_plugin)
840 {
841         Server *s;
842         TcoreModem *modem;
843
844         if (modem_iface_plugin == NULL) {
845                 err("Modem Interface is NULL");
846                 return;
847         }
848
849         s = tcore_plugin_ref_server(modem_iface_plugin);
850         if (s == NULL) {
851                 err("server is NULL");
852                 return;
853         }
854
855         modem = _server_find_modem(s, modem_iface_plugin, NULL);
856         if (modem == NULL) {
857                 err("Failed to find 'modem' for Modem Interface Plug-in: [%s]",
858                                         tcore_plugin_ref_plugin_name(modem_iface_plugin));
859                 return;
860         }
861
862         /* Removing the Mapping Table from the Modems list */
863         tcore_object_remove_mapping_tbl(modem->mapping_tbl);
864 }
865
866 void tcore_server_remove_cp_mapping_tbl_entry(TcorePlugin *modem_iface_plugin,
867                                         TcoreHal *hal)
868 {
869         Server *s;
870         TcoreModem *modem;
871
872         if (modem_iface_plugin == NULL) {
873                 err("Modem Interface is NULL");
874                 return;
875         }
876
877         s = tcore_plugin_ref_server(modem_iface_plugin);
878         if (s == NULL) {
879                 err("server is NULL");
880                 return;
881         }
882
883         modem = _server_find_modem(s, modem_iface_plugin, NULL);
884         if (modem == NULL) {
885                 err("Failed to find 'modem' for Modem Interface Plug-in: [%s]",
886                                         tcore_plugin_ref_plugin_name(modem_iface_plugin));
887                 return;
888         }
889
890         /* Removing the Mapping Table from the Modems list */
891         modem->mapping_tbl =
892                 tcore_object_remove_mapping_tbl_entry(modem->mapping_tbl, hal);
893 }
894
895 void *tcore_server_get_cp_mapping_tbl(TcorePlugin *modem_plugin)
896 {
897         Server *s;
898         TcoreModem *modem;
899
900         if (modem_plugin == NULL) {
901                 err("Modem Interface is NULL");
902                 return NULL;
903         }
904
905         s = tcore_plugin_ref_server(modem_plugin);
906         if (s == NULL) {
907                 err("server is NULL");
908                 return NULL;
909         }
910
911         modem = _server_find_modem(s, NULL, modem_plugin);
912         if (modem == NULL) {
913                 err("Failed to find 'modem' for Modem Plug-in: [%s]",
914                                         tcore_plugin_ref_plugin_name(modem_plugin));
915                 return NULL;
916         }
917
918         return modem->mapping_tbl;
919 }
920
921 void tcore_server_print_modems(TcorePlugin *plugin)
922 {
923         Server *s;
924         TcoreModem *modem;
925
926         if (plugin == NULL) {
927                 err("Modem Interface is NULL");
928                 return;
929         }
930
931         s = tcore_plugin_ref_server(plugin);
932         if (s == NULL) {
933                 err("server is NULL");
934                 return;
935         }
936
937         modem = _server_find_modem(s, plugin, plugin);
938         if (modem == NULL) {
939                 err("Failed to find 'modem' for Plug-in: [%s]",
940                                         tcore_plugin_ref_plugin_name(plugin));
941                 return;
942         }
943
944         msg("Modem Plug-in: [%s] Modem Interface Plug-in: [%s]",
945                         tcore_plugin_ref_plugin_name(modem->modem_plugin),
946                         tcore_plugin_ref_plugin_name(modem->modem_iface_plugin));
947         msg("CP Name: [%s]", modem->cp_name);
948
949         tcore_object_print_mapping_tbl(modem->mapping_tbl);
950 }
951
952 TReturn tcore_server_load_modem_plugin(Server *s,
953                                         TcorePlugin *modem_if_plugin,
954                                         const char *name)
955 {
956         struct tcore_plugin_define_desc *desc;
957         TcorePlugin *modem_plugin;
958         char *filename = NULL;
959         void *handle;
960         TReturn ret = TCORE_RETURN_FAILURE;
961
962         dbg("Enter");
963
964         if (s == NULL || name == NULL) {
965                 ret = TCORE_RETURN_EINVAL;
966                 goto out;
967         }
968
969         filename = g_build_filename(MODEMS_PATH, name, NULL);
970
971         handle = dlopen(filename, RTLD_NOW);
972         if (handle == NULL) {
973                 dbg("Failed to load '%s': %s", filename, dlerror());
974                 goto out;
975         }
976
977         desc = dlsym(handle, "plugin_define_desc");
978         if (desc == NULL) {
979                 dbg("Failed to load symbol: %s", dlerror());
980                 dlclose(handle);
981                 goto out;
982         }
983
984         dbg("Plugin %s found", desc->name);
985
986         if (desc->load != NULL) {
987                 if (desc->load() == FALSE) {
988                         err("Failed to load %s plugin", desc->name);
989                         dlclose(handle);
990                         goto out;
991                 }
992         }
993
994         modem_plugin = tcore_plugin_new(s, desc, filename, handle);
995         tcore_server_add_plugin(s, modem_plugin);
996
997         if (modem_if_plugin != NULL)
998                 tcore_server_update_modem_plugin(modem_if_plugin,
999                                                         modem_plugin);
1000
1001         dbg("Plugin %s loaded successfully", desc->name);
1002
1003         if (desc->init == NULL) {
1004                 err("Plugin %s has not initializer", desc->name);
1005                 dlclose(handle);
1006                 goto out;
1007         }
1008
1009         if (desc->init(modem_plugin) == FALSE) {
1010                 err("Plugin %s initialization failed", desc->name);
1011                 dlclose(handle);
1012                 goto out;
1013         }
1014
1015         dbg("Plugin %s initialization success", desc->name);
1016
1017         /* Notify addition of Plug-in to Upper Layers */
1018         tcore_server_send_notification(s, NULL, TNOTI_SERVER_ADDED_PLUGIN,
1019                                                                 0, modem_plugin);
1020
1021         ret = TCORE_RETURN_SUCCESS;
1022
1023 out:
1024         g_free(filename);
1025
1026         dbg("Exit");
1027
1028         return ret;
1029 }
1030
1031 void tcore_server_unload_modem_plugin(Server *s, TcorePlugin *modem_if_plugin)
1032 {
1033         TcoreModem *modem;
1034         TcorePlugin *modem_plugin;
1035         const struct tcore_plugin_define_desc *desc;
1036
1037         dbg("Enter");
1038
1039         if ((s == NULL) || (modem_if_plugin == NULL)) {
1040                 err("Invalid inputs");
1041                 return;
1042         }
1043
1044         /* Find modem from Server's Modem's list */
1045         modem = _server_find_modem(s, modem_if_plugin, modem_if_plugin);
1046         if (modem == NULL) {
1047                 err("Failed to find 'modem' for Plug-in: [%s]",
1048                                         tcore_plugin_ref_plugin_name(modem_if_plugin));
1049                 return;
1050         }
1051
1052         msg("Modem Plug-in: [%s] Modem Interface Plug-in: [%s]",
1053                         tcore_plugin_ref_plugin_name(modem->modem_plugin),
1054                         tcore_plugin_ref_plugin_name(modem->modem_iface_plugin));
1055         msg("CP Name: [%s]", modem->cp_name);
1056
1057         /* Extract Modem Plug-in */
1058         modem_plugin = modem->modem_plugin;
1059         if (modem_plugin == NULL) {
1060                 err("Modem Plug-in is NULL");
1061                 return;
1062         }
1063
1064         /* Notify deletion of Plug-in to Upper Layers */
1065         tcore_server_send_notification(s, NULL, TNOTI_SERVER_REMOVED_PLUGIN,
1066                                                         0, modem_plugin);
1067
1068         /* Extract descriptor of Modem Plug-in */
1069         desc = tcore_plugin_get_description(modem_plugin);
1070         if (desc != NULL) {
1071                 /* Unload Modem Plug-in */
1072                 if (desc->unload != NULL) {
1073                         dbg("Unloading Modem Plug-in: [%s]",
1074                                                 tcore_plugin_ref_plugin_name(modem_plugin));
1075                         desc->unload(modem_plugin);
1076                 }
1077         }
1078
1079         /* Free Modem Plug-in */
1080         tcore_plugin_free(modem_plugin);
1081
1082         dbg("Unloaded Modem Plug-in");
1083 }