4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Ja-young Gu <jygu@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
30 #include <glib/gprintf.h>
35 #include "user_request.h"
36 #include "core_object.h"
38 #include "communicator.h"
43 #define MODEMS_PATH "/usr/lib/telephony/plugins/modems"
45 struct tcore_server_type {
48 GSList *communicators;
54 GSList *hook_list_request;
55 GSList *hook_list_notification;
57 TcorePlugin *default_plugin;
61 struct tcore_modem_type {
63 TcorePlugin *modem_iface_plugin;
65 TcorePlugin *modem_plugin;
70 struct hook_request_type {
71 enum tcore_request_command command;
72 tcore_server_request_hook func;
76 struct hook_notification_type {
77 enum tcore_notification_command command;
78 tcore_server_notification_hook func;
82 static gint _compare_priority(gconstpointer a, gconstpointer b)
84 TcorePlugin *plugin1 = (TcorePlugin *)a;
85 TcorePlugin *plugin2 = (TcorePlugin *)b;
90 return tcore_plugin_get_description(plugin1)->priority -
91 tcore_plugin_get_description(plugin2)->priority;
94 static char *_server_enumerate_modem(TcorePlugin *plugin)
96 static unsigned int cp_counter = 0;
103 * Presently enumeration is based on Modem Interface Plug-in descriptor name
104 * followed by an incremental Positive integer 'cp_count'.
106 * For example, if Modem Interface Plug-in descriptor name is 'imcmodem' then,
107 * 'name' would be enumerated as "imcmode_N", where N >= 0
109 filename = tcore_plugin_ref_plugin_name(plugin);
110 if (filename == NULL)
115 return g_strdup_printf("%s%d", filename, cp_counter++);
118 static TcoreModem *_server_find_modem(Server *s,
119 TcorePlugin *modem_iface_plugin, TcorePlugin *modem_plugin)
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));
128 for (list = s->modems; list; list = list->next) {
134 * Specifically for Unregister, Add Modem Plug-in
135 * and Add/Remove Mapping Table -
137 * MUST match Modem Interface Plug-in
139 * If passed Modem Interface Plug-in is NULL, then
140 * Modem Interface Plug-in of 'modems' MUST be NULL
142 if ((modem_iface_plugin == modem->modem_iface_plugin)
143 && ((modem_plugin == NULL) && (modem->modem_plugin == NULL))) {
144 dbg("'modem' found!!!");
149 * Specifically for get Mapping Table -
151 * Modem Interface Plug-in MUST be NULL
153 * Passed Modem Plug-in MUST match Modem Plug-of 'modems'
155 if ((modem_iface_plugin == NULL)
156 && (modem_plugin == modem->modem_plugin)) {
157 dbg("'modem' found!!!");
162 * Specifically for get CP name -
164 * Passed Modem OR Modem Interface Plug-in MUST match
166 * MUST match either Modem OR Modem Interface Plug-in of 'modems'
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!!!");
176 err("Modem not found");
181 Server *tcore_server_new()
185 s = g_try_new0(struct tcore_server_type, 1);
189 s->mainloop = g_main_loop_new (NULL, FALSE);
190 if (s->mainloop == NULL) {
196 s->communicators = NULL;
198 s->template_co = NULL;
199 s->hook_list_request = NULL;
200 s->hook_list_notification = NULL;
201 s->default_plugin = NULL;
206 void tcore_server_free(Server *s)
210 const struct tcore_plugin_define_desc *desc;
216 g_main_loop_unref(s->mainloop);
218 for (list = s->plugins; list; list = list->next) {
223 desc = (struct tcore_plugin_define_desc *)tcore_plugin_get_description(p);
224 if ((desc == NULL) || (desc->unload == NULL))
229 tcore_plugin_free(p);
234 if (s->hook_list_notification)
235 g_slist_free_full(s->hook_list_notification, g_free);
237 if (s->hook_list_request)
238 g_slist_free_full(s->hook_list_request, g_free);
241 g_slist_free(s->template_co);
244 g_slist_free(s->storages);
246 if (s->communicators)
247 g_slist_free(s->communicators);
250 g_slist_free(s->plugins);
258 TReturn tcore_server_run(Server *s)
262 if ((s == NULL)|| (s->mainloop == NULL))
263 return TCORE_RETURN_EINVAL;
265 version = tcore_util_get_version();
267 dbg("libtcore version: %s", version);
271 tcore_server_send_notification(s, NULL, TNOTI_SERVER_RUN, 0, NULL);
273 g_main_loop_run(s->mainloop);
275 return TCORE_RETURN_SUCCESS;
278 TReturn tcore_server_exit(Server *s)
280 if ((s == NULL)|| (s->mainloop == NULL))
281 return TCORE_RETURN_EINVAL;
283 g_main_loop_quit(s->mainloop);
285 return TCORE_RETURN_SUCCESS;
288 TReturn tcore_server_add_plugin(Server *s, TcorePlugin *plugin)
290 if ((s == NULL)|| (plugin == NULL))
291 return TCORE_RETURN_EINVAL;
293 s->plugins = g_slist_insert_sorted(s->plugins, plugin, _compare_priority);
295 tcore_server_send_notification(s, NULL, TNOTI_SERVER_ADDED_PLUGIN, 0, NULL);
297 return TCORE_RETURN_SUCCESS;
300 TcorePlugin *tcore_server_find_plugin(Server *s, const char *name)
305 dbg("Name: [%s]", name);
307 for (list = s->modems; list; list = list->next) {
312 if (g_strcmp0(modem->cp_name, name) == 0)
313 return modem->modem_plugin;
316 err("Modem plugin not found");
321 GSList *tcore_server_ref_plugins(Server *s)
329 TReturn tcore_server_add_communicator(Server *s, Communicator *comm)
331 if ((s == NULL)|| (comm == NULL))
332 return TCORE_RETURN_EINVAL;
334 s->communicators = g_slist_insert(s->communicators, comm, 0);
336 tcore_server_send_notification(s, NULL, TNOTI_SERVER_ADDED_COMMUNICATOR, 0, NULL);
338 return TCORE_RETURN_SUCCESS;
341 GSList *tcore_server_ref_communicators(Server *s)
346 return s->communicators;
349 Communicator *tcore_server_find_communicator(Server *s, const char *name)
354 for (list = s->communicators; list; list = list->next) {
360 if (g_strcmp0(tcore_communicator_ref_name(comm), name) == 0) {
368 TReturn tcore_server_add_storage(Server *s, Storage *strg)
370 if ((s == NULL)|| (strg == NULL))
371 return TCORE_RETURN_EINVAL;
373 s->storages = g_slist_insert(s->storages, strg, 0);
375 tcore_server_send_notification(s, NULL, TNOTI_SERVER_ADDED_STORAGE, 0, NULL);
377 return TCORE_RETURN_SUCCESS;
380 GSList *tcore_server_ref_storages(Server *s)
388 Storage *tcore_server_find_storage(Server *s, const char *name)
393 for (list = s->storages; list; list = list->next) {
399 if (g_strcmp0(tcore_storage_ref_name(strg), name) == 0) {
407 TReturn tcore_server_add_template_object(Server *s, CoreObject *template_co)
412 if ((s == NULL)|| (template_co == NULL))
413 return TCORE_RETURN_EINVAL;
415 for (list = s->template_co; list; list = list->next) {
421 if (tcore_object_get_type(temp) == tcore_object_get_type(template_co)) {
422 return TCORE_RETURN_EALREADY;
426 s->template_co = g_slist_insert(s->template_co, template_co, 0);
428 return TCORE_RETURN_SUCCESS;
431 GSList *tcore_server_ref_template_object(Server *s)
436 return s->template_co;
439 CoreObject *tcore_server_find_template_object(Server *s, unsigned int type)
442 CoreObject *template_co;
444 for (list = s->template_co; list; list = list->next) {
445 template_co = list->data;
446 if (template_co == NULL)
449 if (type == tcore_object_get_type(template_co))
456 TReturn tcore_server_link_udev(Server *s, TcoreUdev *udev)
458 if ((s == NULL)|| (udev == NULL))
459 return TCORE_RETURN_EINVAL;
463 return TCORE_RETURN_SUCCESS;
466 TcoreUdev *tcore_server_ref_udev(Server *s)
474 TReturn tcore_server_dispatch_request(Server *s, UserRequest *ur)
478 enum tcore_request_command command = 0;
480 struct hook_request_type *hook;
483 TReturn ret = TCORE_RETURN_ENOSYS;
485 if ((s == NULL)|| (ur == NULL))
486 return TCORE_RETURN_EINVAL;
488 for (list = s->hook_list_request; list; list = list->next) {
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;
499 modem = tcore_user_request_get_modem_name(ur);
501 return TCORE_RETURN_EINVAL;
503 p = tcore_server_find_plugin(s, modem);
506 return TCORE_RETURN_SERVER_WRONG_PLUGIN;
510 command = tcore_user_request_get_command(ur);
512 category = CORE_OBJECT_TYPE_DEFAULT | (command & 0x0FF00000);
513 dbg("Category: [0x%x]", category);
515 co = tcore_plugin_ref_core_object(p, category);
517 warn("can't find 0x%x core_object", category);
518 return TCORE_RETURN_ENOSYS;
521 if (tcore_object_dispatch_request(co, ur) == TCORE_RETURN_SUCCESS)
522 ret = TCORE_RETURN_SUCCESS;
529 TReturn tcore_server_send_notification(Server *s, CoreObject *source,
530 enum tcore_notification_command command,
531 unsigned int data_len, void *data)
535 struct hook_notification_type *hook;
536 dbg("Send Notification!!! Command: [0x%x]", command);
539 return TCORE_RETURN_EINVAL;
541 for (list = s->hook_list_notification; list; list = list->next) {
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;
555 for (list = s->communicators; list; list = list->next) {
560 tcore_communicator_send_notification(comm, source, command, data_len, data);
563 return TCORE_RETURN_SUCCESS;
566 TReturn tcore_server_add_request_hook(Server *s,
567 enum tcore_request_command command,
568 tcore_server_request_hook func, void *user_data)
570 struct hook_request_type *hook;
572 if ((s == NULL)|| (func == NULL))
573 return TCORE_RETURN_EINVAL;
575 hook = g_try_new0(struct hook_request_type, 1);
577 return TCORE_RETURN_ENOMEM;
579 hook->command = command;
581 hook->user_data = user_data;
583 s->hook_list_request = g_slist_append(s->hook_list_request, hook);
585 return TCORE_RETURN_SUCCESS;
588 TReturn tcore_server_remove_request_hook(Server *s, tcore_server_request_hook func)
590 struct hook_request_type *hook;
594 return TCORE_RETURN_EINVAL;
596 for (list = s->hook_list_request; list; list = list->next) {
602 if (hook->func == func) {
603 s->hook_list_request = g_slist_remove(s->hook_list_request, hook);
604 list = s->hook_list_request;
609 return TCORE_RETURN_SUCCESS;
612 TReturn tcore_server_add_notification_hook(Server *s,
613 enum tcore_notification_command command,
614 tcore_server_notification_hook func, void *user_data)
616 struct hook_notification_type *hook;
618 if ((s == NULL) || (func == NULL)) {
619 err("server: [0x%x] func: [0x%x]", s, func);
620 return TCORE_RETURN_EINVAL;
623 hook = g_try_new0(struct hook_notification_type, 1);
625 err("Failed to allocate memory");
626 return TCORE_RETURN_ENOMEM;
629 hook->command = command;
631 hook->user_data = user_data;
633 s->hook_list_notification = g_slist_append(s->hook_list_notification, hook);
634 dbg("Added hook_func() for Command: [0x%x]", command);
636 return TCORE_RETURN_SUCCESS;
639 TReturn tcore_server_remove_notification_hook(Server *s,
640 tcore_server_notification_hook func)
642 struct hook_notification_type *hook;
646 return TCORE_RETURN_EINVAL;
648 for (list = s->hook_list_notification; list; list = list->next) {
654 if (hook->func == func) {
655 s->hook_list_notification = g_slist_remove(s->hook_list_notification, hook);
656 list = s->hook_list_notification;
661 return TCORE_RETURN_SUCCESS;
664 gboolean tcore_server_register_modem(Server *s, TcorePlugin *modem_iface_plugin)
668 if ((s == NULL) || (modem_iface_plugin == NULL)) {
669 err("server [0x%x] Modem Interface Plug-in: [0x%x]", s, modem_iface_plugin);
673 modem = g_try_new0(TcoreModem, 1);
675 err("Failed to allocate memory");
679 modem->cp_name = _server_enumerate_modem(modem_iface_plugin);
680 modem->modem_iface_plugin = modem_iface_plugin;
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));
689 void tcore_server_unregister_modem(Server *s, TcorePlugin *modem_iface_plugin)
693 if ((s == NULL) || (modem_iface_plugin == NULL)) {
694 err("server [0x%x] Modem Interface Plug-in: [0x%x]", s, modem_iface_plugin);
698 modem = _server_find_modem(s, modem_iface_plugin, NULL);
700 err("Failed to find 'modem' for Modem Interface Plug-in: [%s]",
701 tcore_plugin_ref_plugin_name(modem_iface_plugin));
705 s->modems = g_slist_remove(s->modems, modem);
707 g_free(modem->cp_name);
711 gboolean tcore_server_update_modem_plugin(TcorePlugin *modem_iface_plugin,
712 TcorePlugin *modem_plugin)
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);
723 s = tcore_plugin_ref_server(modem_iface_plugin);
725 err("server is NULL");
729 modem = _server_find_modem(s, modem_iface_plugin, NULL);
731 err("Failed to find 'modem' for Modem Interface Plug-in: [%s]",
732 tcore_plugin_ref_plugin_name(modem_iface_plugin));
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));
744 GSList *tcore_server_get_cp_name_list(Server *s)
746 GSList *cp_name_list = NULL;
748 unsigned int list_count;
754 err("server is NULL");
758 list_count = g_slist_length(s->modems);
759 if (list_count == 0) {
760 err("No entries in Modems list");
764 for (list = s->modems; list; list = list->next) {
767 dbg("No modem - continue");
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));
775 /* 'cp_name_list' would be freed by the calling function */
779 const char *tcore_server_get_cp_name_by_plugin(TcorePlugin *plugin)
784 if (plugin == NULL) {
785 err("plugin is NULL");
789 s = tcore_plugin_ref_server(plugin);
791 err("server is NULL");
795 modem = _server_find_modem(s, plugin, plugin);
797 err("Failed to find 'modem' for Plug-in: [%s]",
798 tcore_plugin_ref_plugin_name(plugin));
802 return (const char *)modem->cp_name;
805 gboolean tcore_server_add_cp_mapping_tbl_entry(TcorePlugin *modem_iface_plugin,
806 unsigned int co_type, TcoreHal *hal)
811 if (modem_iface_plugin == NULL) {
812 err("Modem Interface is NULL");
816 s = tcore_plugin_ref_server(modem_iface_plugin);
818 err("server is NULL");
822 modem = _server_find_modem(s, modem_iface_plugin, NULL);
824 err("Failed to find 'modem' for Modem Interface Plug-in: [%s]",
825 tcore_plugin_ref_plugin_name(modem_iface_plugin));
830 * Set the Mapping Table to the Modems list
833 tcore_object_add_mapping_tbl_entry(modem->mapping_tbl,
839 void tcore_server_remove_cp_mapping_tbl(TcorePlugin *modem_iface_plugin)
844 if (modem_iface_plugin == NULL) {
845 err("Modem Interface is NULL");
849 s = tcore_plugin_ref_server(modem_iface_plugin);
851 err("server is NULL");
855 modem = _server_find_modem(s, modem_iface_plugin, NULL);
857 err("Failed to find 'modem' for Modem Interface Plug-in: [%s]",
858 tcore_plugin_ref_plugin_name(modem_iface_plugin));
862 /* Removing the Mapping Table from the Modems list */
863 tcore_object_remove_mapping_tbl(modem->mapping_tbl);
866 void tcore_server_remove_cp_mapping_tbl_entry(TcorePlugin *modem_iface_plugin,
872 if (modem_iface_plugin == NULL) {
873 err("Modem Interface is NULL");
877 s = tcore_plugin_ref_server(modem_iface_plugin);
879 err("server is NULL");
883 modem = _server_find_modem(s, modem_iface_plugin, NULL);
885 err("Failed to find 'modem' for Modem Interface Plug-in: [%s]",
886 tcore_plugin_ref_plugin_name(modem_iface_plugin));
890 /* Removing the Mapping Table from the Modems list */
892 tcore_object_remove_mapping_tbl_entry(modem->mapping_tbl, hal);
895 void *tcore_server_get_cp_mapping_tbl(TcorePlugin *modem_plugin)
900 if (modem_plugin == NULL) {
901 err("Modem Interface is NULL");
905 s = tcore_plugin_ref_server(modem_plugin);
907 err("server is NULL");
911 modem = _server_find_modem(s, NULL, modem_plugin);
913 err("Failed to find 'modem' for Modem Plug-in: [%s]",
914 tcore_plugin_ref_plugin_name(modem_plugin));
918 return modem->mapping_tbl;
921 void tcore_server_print_modems(TcorePlugin *plugin)
926 if (plugin == NULL) {
927 err("Modem Interface is NULL");
931 s = tcore_plugin_ref_server(plugin);
933 err("server is NULL");
937 modem = _server_find_modem(s, plugin, plugin);
939 err("Failed to find 'modem' for Plug-in: [%s]",
940 tcore_plugin_ref_plugin_name(plugin));
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);
949 tcore_object_print_mapping_tbl(modem->mapping_tbl);
952 TReturn tcore_server_load_modem_plugin(Server *s,
953 TcorePlugin *modem_if_plugin,
956 struct tcore_plugin_define_desc *desc;
957 TcorePlugin *modem_plugin;
958 char *filename = NULL;
960 TReturn ret = TCORE_RETURN_FAILURE;
964 if (s == NULL || name == NULL) {
965 ret = TCORE_RETURN_EINVAL;
969 filename = g_build_filename(MODEMS_PATH, name, NULL);
971 handle = dlopen(filename, RTLD_NOW);
972 if (handle == NULL) {
973 dbg("Failed to load '%s': %s", filename, dlerror());
977 desc = dlsym(handle, "plugin_define_desc");
979 dbg("Failed to load symbol: %s", dlerror());
984 dbg("Plugin %s found", desc->name);
986 if (desc->load != NULL) {
987 if (desc->load() == FALSE) {
988 err("Failed to load %s plugin", desc->name);
994 modem_plugin = tcore_plugin_new(s, desc, filename, handle);
995 tcore_server_add_plugin(s, modem_plugin);
997 if (modem_if_plugin != NULL)
998 tcore_server_update_modem_plugin(modem_if_plugin,
1001 dbg("Plugin %s loaded successfully", desc->name);
1003 if (desc->init == NULL) {
1004 err("Plugin %s has not initializer", desc->name);
1009 if (desc->init(modem_plugin) == FALSE) {
1010 err("Plugin %s initialization failed", desc->name);
1015 dbg("Plugin %s initialization success", desc->name);
1017 /* Notify addition of Plug-in to Upper Layers */
1018 tcore_server_send_notification(s, NULL, TNOTI_SERVER_ADDED_PLUGIN,
1021 ret = TCORE_RETURN_SUCCESS;
1031 void tcore_server_unload_modem_plugin(Server *s, TcorePlugin *modem_if_plugin)
1034 TcorePlugin *modem_plugin;
1035 const struct tcore_plugin_define_desc *desc;
1039 if ((s == NULL) || (modem_if_plugin == NULL)) {
1040 err("Invalid inputs");
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));
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);
1057 /* Extract Modem Plug-in */
1058 modem_plugin = modem->modem_plugin;
1059 if (modem_plugin == NULL) {
1060 err("Modem Plug-in is NULL");
1064 /* Notify deletion of Plug-in to Upper Layers */
1065 tcore_server_send_notification(s, NULL, TNOTI_SERVER_REMOVED_PLUGIN,
1068 /* Extract descriptor of Modem Plug-in */
1069 desc = tcore_plugin_get_description(modem_plugin);
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);
1079 /* Free Modem Plug-in */
1080 tcore_plugin_free(modem_plugin);
1082 dbg("Unloaded Modem Plug-in");