tizen 2.3.1 release
[framework/telephony/libtcore.git] / src / core_object.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 <stdlib.h>
23 #include <string.h>
24
25 #include <glib.h>
26
27 #include "tcore.h"
28 #include "server.h"
29 #include "plugin.h"
30 #include "core_object.h"
31 #include "hal.h"
32 #include "at.h"
33
34 #include "co_call.h"
35 #include "co_modem.h"
36 #include "co_ps.h"
37 #include "co_network.h"
38 #include "co_ss.h"
39 #include "co_sim.h"
40 #include "co_sat.h"
41 #include "co_sap.h"
42 #include "co_sms.h"
43 #include "co_phonebook.h"
44 #include "co_gps.h"
45
46 struct callback_type {
47         CoreObject *co;
48         char *event;
49         CoreObjectCallback callback;
50         void *user_data;
51 };
52
53 struct tcore_object_type {
54         unsigned int type;
55         char *name;
56
57         TcorePlugin *parent_plugin;
58
59         void *object;
60         void *user_data;
61
62         CoreObjectFreeHook free_hook;
63         CoreObjectCloneHook clone_hook;
64         CoreObjectDispatcher dispatcher;
65         GSList *callbacks;
66         GHashTable *property;
67
68         TcoreHal *hal;
69 };
70
71
72 /* Mapping Table */
73 struct tcore_object_mapping_tbl {
74         TcoreHal *hal;
75         GSList *object_type;
76 };
77
78 static void _util_print_mapping_tbl_entry(object_mapping_table_t *tbl_entry)
79 {
80         GSList *co_list;
81
82         msg("------> Table Entry - HAL: [0x%x]", tbl_entry->hal);
83
84         co_list = tbl_entry->object_type;
85         if (co_list == NULL) {
86                 err("No Core Objects defined for this Mapping Table Entry");
87                 return;
88         }
89
90         /* Search all the Table entries with matching 'type' */
91         for ( ; co_list ; co_list = co_list->next) {
92                 if (co_list->data == NULL)
93                         continue;
94
95                 msg("           Core Object type: [0x%x]", co_list->data);
96         }
97 }
98
99 static void _free_tbl_entry(gpointer data)
100 {
101         object_mapping_table_t *tbl_entry;
102
103         if (data == NULL)
104                 return;
105
106         tbl_entry = data;
107
108         dbg("Removing Mapping Table Entry - HAL: [0x%x]", tbl_entry->hal);
109         _util_print_mapping_tbl_entry(tbl_entry);
110
111         /* Free Core Object types list */
112         g_slist_free(tbl_entry->object_type);
113
114         /* Free Table entry */
115         g_free(tbl_entry);
116 }
117 static CoreObject *_object_new(TcorePlugin *plugin, unsigned int type)
118 {
119         CoreObject *co;
120
121         co = calloc(1, sizeof(struct tcore_object_type));
122         if (!co)
123                 return NULL;
124
125         co->parent_plugin = plugin;
126
127         co->type = type;
128         co->property = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
129
130         return co;
131 }
132
133 static gboolean _on_at_event(TcoreAT *at, const GSList *lines, void *user_data)
134 {
135         gboolean ret;
136
137         struct callback_type *cb = user_data;
138
139         ret = cb->callback(cb->co, lines, cb->user_data);
140         if (ret == FALSE) {
141
142         }
143
144         return ret;
145 }
146
147 static void _remove_at_callback(TcoreAT *at, struct callback_type *cb)
148 {
149         tcore_at_remove_notification_full(at, cb->event, _on_at_event, cb);
150 }
151
152 static object_mapping_table_t *_object_search_mapping_tbl_entry(GSList *mapping_tbl_list,
153                                                                                                                 TcoreHal *hal)
154 {
155         GSList *list;
156         object_mapping_table_t *tbl_entry = NULL;
157
158         for (list = mapping_tbl_list; list ; list = list->next) {
159                 tbl_entry = list->data;
160                 if (tbl_entry == NULL)
161                         continue;
162
163                 /* Search for Table entry with matching 'hal' */
164                 if (tbl_entry->hal == hal) {
165                         return tbl_entry;
166                 }
167         }
168
169         return NULL;
170 }
171
172 static object_mapping_table_t *_object_search_mapping_tbl_entry_by_type(
173                                                                 GSList *mapping_tbl_list, unsigned int type)
174 {
175         GSList *list;
176         GSList *co_list;
177         object_mapping_table_t *tbl_entry = NULL;
178
179         for (list = mapping_tbl_list; list ; list = list->next) {
180                 tbl_entry = list->data;
181                 if (tbl_entry == NULL)
182                         continue;
183
184                 /* Search all the Table entries with matching 'type' */
185                 for (co_list = tbl_entry->object_type ; co_list ; co_list = co_list->next) {
186                         if (co_list->data == NULL)
187                                 continue;
188
189                         if (type == (unsigned int)co_list->data) {
190                                 return tbl_entry;
191                         }
192                 }
193         }
194
195         return tbl_entry;
196 }
197
198 static CoreObject *_create_core_object_by_type(guint type,
199         TcorePlugin *plugin, TcoreHal *hal)
200 {
201         CoreObject *co = NULL;
202
203         switch (type) {
204         case CORE_OBJECT_TYPE_MODEM:
205                 /* Create Core Object */
206                 co = tcore_modem_new(plugin, "modem", NULL, hal);
207         break;
208
209         case CORE_OBJECT_TYPE_CALL:
210                 /* Create Core Object */
211                 co = tcore_call_new(plugin, "call", NULL, hal);
212         break;
213
214         case CORE_OBJECT_TYPE_SS:
215                 /* Create Core Object */
216                 co = tcore_ss_new(plugin, "ss", NULL, hal);
217         break;
218
219         case CORE_OBJECT_TYPE_NETWORK:
220                 /* Create Core Object */
221                 co = tcore_network_new(plugin, "network", NULL, hal);
222         break;
223
224         case CORE_OBJECT_TYPE_PS:
225                 /* Create Core Object */
226                 co = tcore_ps_new(plugin, "ps", NULL, hal);
227         break;
228
229         case CORE_OBJECT_TYPE_SIM:
230                 /* Create Core Object */
231                 co = tcore_sim_new(plugin, "sim", NULL, hal);
232         break;
233
234         case CORE_OBJECT_TYPE_SAT:
235                 /* Create Core Object */
236                 co = tcore_sat_new(plugin, "sat", NULL, hal);
237         break;
238
239         case CORE_OBJECT_TYPE_SAP:
240                 /* Create Core Object */
241                 co = tcore_sap_new(plugin, "sap", NULL, hal);
242         break;
243
244         case CORE_OBJECT_TYPE_SMS:
245                 /* Create Core Object */
246                 co = tcore_sms_new(plugin, "sms", NULL, hal);
247         break;
248
249         case CORE_OBJECT_TYPE_PHONEBOOK:
250                 /* Create Core Object */
251                 co = tcore_phonebook_new(plugin, "phonebook", NULL, hal);
252         break;
253
254         case CORE_OBJECT_TYPE_GPS:
255                 /* Create Core Object */
256                 co = tcore_gps_new(plugin, "gps", NULL, hal);
257         break;
258
259         case CORE_OBJECT_TYPE_CUSTOM:           /* Fall through */
260         default:
261                 err("Unsupport/Invalid Core Object Type [0x%x]", type);
262         }
263
264         return co;
265 }
266
267
268 static gboolean _init_core_object_by_type(unsigned int type,
269         TcorePlugin *plugin, struct object_initializer *initializer_list)
270 {
271         gboolean ret = FALSE;
272         CoreObject *co = tcore_plugin_ref_core_object(plugin, type);
273         if (co == NULL) {
274                 err("No Core Object of type: [0x%x]", type);
275                 return FALSE;
276         }
277
278         switch (type) {
279         case CORE_OBJECT_TYPE_MODEM: {
280                 /* Invoke initializer */
281                 if (initializer_list->modem_init)
282                         ret = initializer_list->modem_init(plugin, co);
283         } break;
284
285         case CORE_OBJECT_TYPE_CALL: {
286                 /* Invoke initializer */
287                 if (initializer_list->call_init)
288                         ret = initializer_list->call_init(plugin, co);
289         } break;
290
291         case CORE_OBJECT_TYPE_SS: {
292                 /* Invoke initializer */
293                 if (initializer_list->ss_init)
294                         ret = initializer_list->ss_init(plugin, co);
295         } break;
296
297         case CORE_OBJECT_TYPE_NETWORK: {
298                 /* Invoke initializer */
299                 if (initializer_list->network_init)
300                         ret = initializer_list->network_init(plugin, co);
301         } break;
302
303         case CORE_OBJECT_TYPE_PS: {
304                 /* Invoke initializer */
305                 if (initializer_list->ps_init)
306                         ret = initializer_list->ps_init(plugin, co);
307         } break;
308
309         case CORE_OBJECT_TYPE_SIM: {
310                 /* Invoke initializer */
311                 if (initializer_list->sim_init)
312                         ret = initializer_list->sim_init(plugin, co);
313         } break;
314
315         case CORE_OBJECT_TYPE_SAT: {
316                 /* Invoke initializer */
317                 if (initializer_list->sat_init)
318                         ret = initializer_list->sat_init(plugin, co);
319         } break;
320
321         case CORE_OBJECT_TYPE_SAP: {
322                 /* Invoke initializer */
323                 if (initializer_list->sap_init)
324                         ret = initializer_list->sap_init(plugin, co);
325         } break;
326
327         case CORE_OBJECT_TYPE_SMS:{
328                 /* Invoke initializer */
329                 if (initializer_list->sms_init)
330                         ret = initializer_list->sms_init(plugin, co);
331         } break;
332
333         case CORE_OBJECT_TYPE_PHONEBOOK: {
334                 /* Invoke initializer */
335                 if (initializer_list->phonebook_init)
336                         ret = initializer_list->phonebook_init(plugin, co);
337         } break;
338
339         case CORE_OBJECT_TYPE_GPS:{
340                 /* Invoke initializer */
341                 if (initializer_list->gps_init)
342                         ret = initializer_list->gps_init(plugin, co);
343         } break;
344
345         case CORE_OBJECT_TYPE_CUSTOM:           /* Fall through */
346         default:
347                 dbg("Unsupport/Invalid Core Object Type [0x%x]", type);
348         }
349
350         return ret;
351 }
352
353
354 static void _deinit_core_object_by_type(unsigned int type,
355                         TcorePlugin *plugin, struct object_deinitializer *deinitializer_list)
356 {
357         CoreObject *co;
358
359         co = tcore_plugin_ref_core_object(plugin, type);
360         if (co == NULL) {
361                 err("No Core Object of type: [0x%x]", type);
362                 return;
363         }
364
365         switch (type) {
366         case CORE_OBJECT_TYPE_MODEM: {
367                 if (deinitializer_list->modem_deinit) {
368                         /* Invoke deinitializer */
369                         deinitializer_list->modem_deinit(plugin, co);
370                 }
371         } break;
372
373         case CORE_OBJECT_TYPE_CALL: {
374                 if (deinitializer_list->call_deinit) {
375                         /* Invoke deinitializer */
376                         deinitializer_list->call_deinit(plugin, co);
377                 }
378         } break;
379
380         case CORE_OBJECT_TYPE_SS: {
381                 if (deinitializer_list->ss_deinit) {
382                         /* Invoke deinitializer */
383                         deinitializer_list->ss_deinit(plugin, co);
384                 }
385         } break;
386
387         case CORE_OBJECT_TYPE_NETWORK: {
388                 if (deinitializer_list->network_deinit) {
389                         /* Invoke deinitializer */
390                         deinitializer_list->network_deinit(plugin, co);
391                 }
392         } break;
393
394         case CORE_OBJECT_TYPE_PS: {
395                 if (deinitializer_list->ps_deinit) {
396                         /* Invoke deinitializer */
397                         deinitializer_list->ps_deinit(plugin, co);
398                 }
399         } break;
400
401         case CORE_OBJECT_TYPE_SIM: {
402                 if (deinitializer_list->sim_deinit) {
403                         /* Invoke deinitializer */
404                         deinitializer_list->sim_deinit(plugin, co);
405                 }
406         } break;
407
408         case CORE_OBJECT_TYPE_SAT: {
409                 if (deinitializer_list->sat_deinit) {
410                         /* Invoke deinitializer */
411                         deinitializer_list->sat_deinit(plugin, co);
412                 }
413         } break;
414
415         case CORE_OBJECT_TYPE_SAP: {
416                 if (deinitializer_list->sap_deinit) {
417                         /* Invoke deinitializer */
418                         deinitializer_list->sap_deinit(plugin, co);
419                 }
420         } break;
421
422         case CORE_OBJECT_TYPE_SMS:{
423                 if (deinitializer_list->sms_deinit) {
424                         /* Invoke deinitializer */
425                         deinitializer_list->sms_deinit(plugin, co);
426                 }
427         } break;
428
429         case CORE_OBJECT_TYPE_PHONEBOOK: {
430                 if (deinitializer_list->phonebook_deinit) {
431                         /* Invoke deinitializer */
432                         deinitializer_list->phonebook_deinit(plugin, co);
433                 }
434         } break;
435
436         case CORE_OBJECT_TYPE_GPS:{
437                 if (deinitializer_list->gps_deinit) {
438                         /* Invoke deinitializer */
439                         deinitializer_list->gps_deinit(plugin, co);
440                 }
441         } break;
442
443         case CORE_OBJECT_TYPE_CUSTOM:           /* Fall through */
444         default:
445                 dbg("Unsupport/Invalid Core Object Type [0x%x]", type);
446                 return;
447         }
448
449         /* Free Core Object */
450         tcore_object_free(co);
451 }
452
453
454 CoreObject *tcore_object_new(TcorePlugin *plugin,
455                 const char *name, TcoreHal *hal)
456 {
457         CoreObject *co;
458
459         co = _object_new(plugin, CORE_OBJECT_TYPE_DEFAULT);
460         if (!co)
461                 return NULL;
462
463         tcore_object_set_hal(co, hal);
464         tcore_object_set_name(co, name);
465
466         if (plugin)
467                 tcore_plugin_add_core_object(plugin, co);
468
469         return co;
470 }
471
472 void tcore_object_free(CoreObject *co)
473 {
474         GSList *l = NULL;
475         struct callback_type *cb = NULL;
476
477         if (!co)
478                 return;
479
480         dbg("co_name=%s", co->name);
481
482         if (co->free_hook)
483                 co->free_hook(co);
484         else {
485                 if (co->object)
486                         warn("free_hook is null, private-object couldn't be freed!!");
487         }
488
489         if (co->property) {
490                 g_hash_table_destroy(co->property);
491         }
492
493         if (co->callbacks) {
494                 for (l = co->callbacks; l; l = l->next) {
495                         cb = l->data;
496                         if (!cb)
497                                 continue;
498
499                         if (cb->event)
500                                 free(cb->event);
501
502                         free(cb);
503                 }
504
505                 g_slist_free(co->callbacks);
506                 co->callbacks = NULL;
507         }
508
509         if (co->parent_plugin)
510                 tcore_plugin_remove_core_object(co->parent_plugin, co);
511
512         if (co->name)
513                 free(co->name);
514
515         memset(co, 0, sizeof(CoreObject));
516         free(co);
517 }
518
519 CoreObject *tcore_object_clone(CoreObject *src, TcorePlugin *new_parent)
520 {
521         CoreObject *dest;
522         TcorePlugin *p;
523
524         GSList *l = NULL;
525         struct callback_type *cb = NULL;
526
527         if (!src)
528                 return NULL;
529
530         if (new_parent)
531                 p = new_parent;
532         else
533                 p = src->parent_plugin;
534
535         dest = _object_new(p, src->type);
536         if (!dest)
537                 return NULL;
538
539         dest->object = src->object;
540         dest->user_data = src->user_data;
541         dest->free_hook = src->free_hook;
542         dest->clone_hook = src->clone_hook;
543         dest->dispatcher = src->dispatcher;
544         dest->hal = src->hal;
545
546         for (l = src->callbacks; l; l = l->next) {
547                 cb = l->data;
548                 if (!cb)
549                         continue;
550
551                 tcore_object_add_callback(dest, cb->event, cb->callback, cb->user_data);
552         }
553
554         tcore_plugin_add_core_object(p, dest);
555
556         if (src->clone_hook)
557                 src->clone_hook(src, dest);
558
559         return dest;
560 }
561
562 CoreObject *tcore_object_clone_template_object(TcorePlugin *p,
563                                 unsigned int co_type)
564 {
565         CoreObject *template_co;
566
567         template_co = tcore_server_find_template_object(tcore_plugin_ref_server(p), co_type);
568         if(template_co == NULL)
569                 return NULL;
570
571         return tcore_object_clone(template_co, p);
572
573 }
574
575 const char *tcore_object_ref_name(CoreObject *co)
576 {
577         if (!co)
578                 return NULL;
579
580         return co->name;
581 }
582
583 TReturn tcore_object_set_free_hook(CoreObject *co,
584                 CoreObjectFreeHook free_hook)
585 {
586         if (!co)
587                 return TCORE_RETURN_EINVAL;
588
589         co->free_hook = free_hook;
590
591         return TCORE_RETURN_SUCCESS;
592 }
593
594
595 TReturn tcore_object_set_clone_hook(CoreObject *co,
596                 CoreObjectCloneHook clone_hook)
597 {
598         if (!co)
599                 return TCORE_RETURN_EINVAL;
600
601         co->clone_hook = clone_hook;
602
603         return TCORE_RETURN_SUCCESS;
604 }
605
606 TReturn tcore_object_set_name(CoreObject *co, const char *name)
607 {
608         if (!co)
609                 return TCORE_RETURN_EINVAL;
610
611         if (co->name) {
612                 free(co->name);
613                 co->name = NULL;
614         }
615
616         if (name)
617                 co->name = strdup(name);
618
619         return TCORE_RETURN_SUCCESS;
620 }
621
622 TcorePlugin *tcore_object_ref_plugin(CoreObject *co)
623 {
624         if (!co)
625                 return NULL;
626
627         return co->parent_plugin;
628 }
629
630 TReturn tcore_object_link_object(CoreObject *co, void *object)
631 {
632         if (!co)
633                 return TCORE_RETURN_EINVAL;
634
635         co->object = object;
636
637         return TCORE_RETURN_SUCCESS;
638 }
639
640 void *tcore_object_ref_object(CoreObject *co)
641 {
642         if (!co)
643                 return NULL;
644
645         return co->object;
646 }
647
648 TReturn tcore_object_set_type(CoreObject *co, unsigned int type)
649 {
650         if (!co)
651                 return TCORE_RETURN_EINVAL;
652
653         co->type = type;
654
655         return TCORE_RETURN_SUCCESS;
656 }
657
658 unsigned int tcore_object_get_type(CoreObject *co)
659 {
660         if (!co)
661                 return 0;
662
663         return co->type;
664 }
665
666 TReturn tcore_object_set_hal(CoreObject *co, TcoreHal *hal)
667 {
668         TcoreAT *at;
669         struct callback_type *cb = NULL;
670         GSList *l = NULL;
671
672         if (!co)
673                 return TCORE_RETURN_EINVAL;
674
675         if (co->hal) {
676                 // remove unsolicited callbacks
677                 if (tcore_hal_get_mode(co->hal) == TCORE_HAL_MODE_AT) {
678                         at = tcore_hal_get_at(co->hal);
679                         for (l = co->callbacks; l; l = l->next) {
680                                 cb = l->data;
681                                 if (!cb)
682                                         continue;
683
684                                 tcore_at_remove_notification_full(at, cb->event, _on_at_event, cb);
685                         }
686                 }
687         }
688
689         co->hal = hal;
690         if (!hal)
691                 return TCORE_RETURN_SUCCESS;
692
693         // register unsolicited callbacks
694         if (tcore_hal_get_mode(hal) == TCORE_HAL_MODE_AT) {
695                 at = tcore_hal_get_at(hal);
696                 for (l = co->callbacks; l; l = l->next) {
697                         cb = l->data;
698                         if (!cb)
699                                 continue;
700
701                         if (cb->event[0] == 27)
702                                 tcore_at_add_notification(at, cb->event + 1, TRUE, _on_at_event, cb);
703                         else
704                                 tcore_at_add_notification(at, cb->event, FALSE, _on_at_event, cb);
705                 }
706         }
707
708         return TCORE_RETURN_SUCCESS;
709 }
710
711 TcoreHal *tcore_object_get_hal(CoreObject *co)
712 {
713         if (!co)
714                 return NULL;
715
716         return co->hal;
717 }
718
719 TReturn tcore_object_link_user_data(CoreObject *co,
720                 void *user_data)
721 {
722         if (!co)
723                 return TCORE_RETURN_EINVAL;
724
725         co->user_data = user_data;
726
727         return TCORE_RETURN_SUCCESS;
728 }
729
730 void *tcore_object_ref_user_data(CoreObject *co)
731 {
732         if (!co)
733                 return NULL;
734
735         return co->user_data;
736 }
737
738 TReturn tcore_object_dispatch_request(CoreObject *co,
739                 UserRequest *ur)
740 {
741         if (!co || !ur)
742                 return TCORE_RETURN_EINVAL;
743
744         if (!co->dispatcher)
745                 return TCORE_RETURN_ENOSYS;
746
747         return co->dispatcher(co, ur);
748 }
749
750 TReturn tcore_object_set_dispatcher(CoreObject *co,
751                 CoreObjectDispatcher func)
752 {
753         if (!co || !func)
754                 return TCORE_RETURN_EINVAL;
755
756         co->dispatcher = func;
757
758         return TCORE_RETURN_SUCCESS;
759 }
760
761 TReturn tcore_object_override_callback(CoreObject *co,
762                 const char *event, tcore_object_callback callback, void *user_data)
763 {
764         struct callback_type *cb = NULL;
765         GSList *l = NULL;
766         TcoreAT *at = NULL;
767
768         if ((co == NULL) || (event == NULL) || (callback == NULL))
769                 return TCORE_RETURN_EINVAL;
770
771         if (strlen(event) < 1)
772                 return TCORE_RETURN_EINVAL;
773
774         if (co->hal) {
775                 if (tcore_hal_get_mode(co->hal) == TCORE_HAL_MODE_AT)
776                         at = tcore_hal_get_at(co->hal);
777         }
778
779         for (l = co->callbacks; l; l = l->next) {
780                 cb = l->data;
781                 if (cb == NULL)
782                         continue;
783
784                 if (g_strcmp0(cb->event, event) != 0)
785                         continue;
786
787                 if (at)
788                         _remove_at_callback(at, cb);
789
790                 g_free(cb->event);
791                 co->callbacks = g_slist_remove(co->callbacks, cb);
792                 g_free(cb);
793         }
794
795         return tcore_object_add_callback(co, event, callback, user_data);
796 }
797
798 TReturn tcore_object_add_callback(CoreObject *co,
799                 const char *event,
800                 CoreObjectCallback callback, void *user_data)
801 {
802         struct callback_type *cb = NULL;
803         TcoreAT *at = NULL;
804
805         if (!co || !event || !callback)
806                 return TCORE_RETURN_EINVAL;
807
808         if (strlen(event) < 1)
809                 return TCORE_RETURN_EINVAL;
810
811         cb = calloc(1, sizeof(struct callback_type));
812         if (!cb)
813                 return TCORE_RETURN_ENOMEM;
814
815         cb->co = co;
816         cb->event = strdup(event);
817         cb->callback = callback;
818         cb->user_data = user_data;
819
820         co->callbacks = g_slist_append(co->callbacks, cb);
821
822         if (co->hal) {
823                 if (tcore_hal_get_mode(co->hal) == TCORE_HAL_MODE_AT) {
824                         at = tcore_hal_get_at(co->hal);
825                         if (event[0] == 27)
826                                 tcore_at_add_notification(at, cb->event + 1, TRUE, _on_at_event, cb);
827                         else
828                                 tcore_at_add_notification(at, cb->event, FALSE, _on_at_event, cb);
829
830                 }
831         }
832
833         return TCORE_RETURN_SUCCESS;
834 }
835
836 TReturn tcore_object_del_callback(CoreObject *co,
837                 const char *event, CoreObjectCallback callback)
838 {
839         struct callback_type *cb = NULL;
840         GSList *l = NULL;
841         TcoreAT *at = NULL;
842
843         if (!co || !event || !callback || !co->callbacks)
844                 return TCORE_RETURN_EINVAL;
845
846         if (strlen(event) == 0)
847                 return TCORE_RETURN_EINVAL;
848
849         if (co->hal) {
850                 if (tcore_hal_get_mode(co->hal) == TCORE_HAL_MODE_AT)
851                         at = tcore_hal_get_at(co->hal);
852         }
853
854         l = co->callbacks;
855         while (l) {
856                 cb = l->data;
857                 if (!cb) {
858                         l = l->next;
859                         continue;
860                 }
861
862                 if (cb->callback != callback) {
863                         l = l->next;
864                         continue;
865                 }
866
867                 if (g_strcmp0(cb->event, event) != 0) {
868                         l = l->next;
869                         continue;
870                 }
871
872                 if (at)
873                         _remove_at_callback(at, cb);
874
875                 l = l->next;
876                 co->callbacks = g_slist_remove(co->callbacks, cb);
877                 free(cb->event);
878                 free(cb);
879         }
880
881         return TCORE_RETURN_SUCCESS;
882 }
883
884 TReturn tcore_object_emit_callback(CoreObject *co,
885                 const char *event, const void *event_info)
886 {
887         struct callback_type *cb = NULL;
888         GSList *l = NULL;
889         TReturn ret;
890
891         if (!co || !event)
892                 return TCORE_RETURN_EINVAL;
893
894         l = co->callbacks;
895         while (l) {
896                 cb = l->data;
897                 if (!cb) {
898                         l = l->next;
899                         continue;
900                 }
901
902                 if (g_strcmp0(cb->event, event) != 0) {
903                         l = l->next;
904                         continue;
905                 }
906
907                 if (cb->callback) {
908                         ret = cb->callback(co, event_info, cb->user_data);
909                         if (ret == FALSE) {
910                                 l = l->next;
911                                 co->callbacks = g_slist_remove(co->callbacks, cb);
912                                 continue;
913                         }
914                 }
915
916                 l = l->next;
917         }
918
919         return TCORE_RETURN_SUCCESS;
920 }
921
922 static GSList *_set_property_real (CoreObject *co, const char *key,
923                 const char *value, GSList *list)
924 {
925         char *prev;
926
927         if (!co || !key)
928                 return list;
929
930         if (!value) {
931                 g_hash_table_remove (co->property, key);
932                 return g_slist_append (list, (char *)key);
933         }
934
935         prev = g_hash_table_lookup(co->property, key);
936         if (prev != NULL) {
937                 /*
938                  * If same data, no change & no callback emit
939                  */
940                 if (strcmp (prev, value) == 0)
941                         return list;
942
943                 g_hash_table_replace(co->property, strdup(key), strdup(value));
944         }
945         else {
946                 g_hash_table_insert(co->property, strdup(key), strdup(value));
947         }
948
949         return g_slist_append (list, (char *)key);
950 }
951
952 TReturn tcore_object_set_property_full(CoreObject *co, const char *first_property, ...)
953 {
954         va_list argptr;
955         GSList *list = NULL;
956         const char *k;
957         const char *v;
958
959         if (!co || !first_property)
960                 return TCORE_RETURN_EINVAL;
961
962         va_start (argptr, first_property);
963
964         k = first_property;
965         v = va_arg (argptr, char *);
966         list = _set_property_real (co, k, v, list);
967
968         while (1) {
969                 k = va_arg (argptr, char *);
970                 if (!k)
971                         break;
972
973                 v = va_arg (argptr, char *);
974                 list = _set_property_real (co, k, v, list);
975         }
976
977         va_end (argptr);
978
979         if (!list)
980                 return TCORE_RETURN_SUCCESS;
981
982         if (g_slist_length(list) > 0)
983                 tcore_object_emit_callback (co,
984                                 CORE_OBJECT_EVENT_PROPERTY_CHANGED, list);
985
986         g_slist_free (list);
987
988         return TCORE_RETURN_SUCCESS;
989 }
990
991 const char *tcore_object_ref_property(CoreObject *co, const char *key)
992 {
993         if (!co || !key)
994                 return NULL;
995
996         return g_hash_table_lookup(co->property, key);
997 }
998
999 GHashTable *tcore_object_ref_property_hash(CoreObject *co)
1000 {
1001         if (!co)
1002                 return NULL;
1003
1004         return co->property;
1005 }
1006 void *tcore_object_add_mapping_tbl_entry(void *mapping_tbl,
1007                                                 unsigned int object_type, TcoreHal *hal)
1008 {
1009         GSList *mapping_tbl_list = mapping_tbl;
1010         object_mapping_table_t *tbl_entry;
1011
1012         if (hal == NULL) {
1013                 err("Mapping Table: [0x%x] HAL: [0x%x]", mapping_tbl, hal);
1014                 return mapping_tbl;
1015         }
1016
1017         /*
1018          * Search 'hal' across all the Table entries of the Mapping Table
1019          *
1020          * Table entry MAY NOT be found as -
1021          *      1. Mapping Table is NOT yet created
1022          *      2. Table entry for corresponding 'hal' is NOT present
1023          *
1024          * In each of the above cases, the new Mapping Table entry should be added
1025          * to the Mapping Table.
1026          */
1027         tbl_entry = _object_search_mapping_tbl_entry(mapping_tbl_list, hal);
1028         if (tbl_entry == NULL) {
1029                 dbg("Creating New Table entry for HAL: [0x%x]", hal);
1030                 /*
1031                  * If there is NO previously added Table entry for the 'hal' then
1032                  * new Table entry is created
1033                  */
1034
1035                 tbl_entry = g_try_new0(object_mapping_table_t, 1);
1036                 if (tbl_entry != NULL)
1037                         tbl_entry->hal = hal;
1038                 else {
1039                         err("Failed to allocate memory");
1040                         return mapping_tbl_list;
1041                 }
1042
1043                 /* Add the Mapping Table entry to Mapping Table */
1044                 mapping_tbl_list = g_slist_append(mapping_tbl_list, tbl_entry);
1045         }
1046
1047         /*
1048          * Appending the Core Object type to the list of Core Objects types
1049          */
1050         tbl_entry->object_type = g_slist_append(tbl_entry->object_type, (gpointer)object_type);
1051         dbg("Added Mapping Table entry - HAL: [0x%x] Object type: [0x%x]", hal, object_type);
1052
1053         return mapping_tbl_list;
1054 }
1055
1056 void tcore_object_remove_mapping_tbl(void *mapping_tbl)
1057 {
1058         GSList *mapping_tbl_list = mapping_tbl;
1059
1060         if (mapping_tbl_list == NULL) {
1061                 err("Mapping Table is NULL");
1062                 return;
1063         }
1064
1065         /* Freeing Mapping Table */
1066         g_slist_free_full(mapping_tbl_list, _free_tbl_entry);
1067 }
1068
1069 void *tcore_object_remove_mapping_tbl_entry(void *mapping_tbl, TcoreHal *hal)
1070 {
1071         GSList *mapping_tbl_list = mapping_tbl;
1072         object_mapping_table_t *tbl_entry;
1073
1074         if (mapping_tbl_list == NULL) {
1075                 err("Mapping Table is NULL");
1076                 return mapping_tbl;
1077         }
1078
1079         tbl_entry = _object_search_mapping_tbl_entry(mapping_tbl_list, hal);
1080         if (tbl_entry == NULL) {
1081                 err("Table entry is NOT available");
1082                 return mapping_tbl_list;
1083         }
1084
1085         dbg("Removing Mapping Table Entry - HAL: [0x%x]", hal);
1086         _util_print_mapping_tbl_entry(tbl_entry);
1087
1088         /* Free Core Object types list */
1089         g_slist_free(tbl_entry->object_type);
1090
1091         /* Remove mapping Table entry */
1092         mapping_tbl_list = g_slist_remove(mapping_tbl_list, tbl_entry);
1093
1094         /* Free Table entry */
1095         g_free(tbl_entry);
1096
1097         return mapping_tbl_list;
1098 }
1099
1100 void tcore_object_remove_mapping_tbl_entry_by_type(void *mapping_tbl,
1101                                                         unsigned int co_type)
1102 {
1103         GSList *mapping_tbl_list;
1104         object_mapping_table_t *tbl_entry;
1105
1106         if (mapping_tbl == NULL) {
1107                 err("Mapping Table is NULL");
1108                 return;
1109         }
1110
1111         mapping_tbl_list = mapping_tbl;
1112
1113         tbl_entry =
1114                 _object_search_mapping_tbl_entry_by_type(mapping_tbl_list, co_type);
1115         if (tbl_entry == NULL) {
1116                 err("Table entry is NOT available");
1117                 return;
1118         }
1119
1120         /* Remove the Core Object type from the list */
1121         tbl_entry->object_type = g_slist_remove(tbl_entry->object_type, (gconstpointer)co_type);
1122 }
1123
1124 void tcore_object_print_mapping_tbl(void *mapping_tbl)
1125 {
1126         GSList *mapping_tbl_list;
1127         object_mapping_table_t *tbl_entry = NULL;
1128
1129
1130         if (mapping_tbl == NULL) {
1131                 err("Mapping Table is NULL");
1132                 return;
1133         }
1134
1135         mapping_tbl_list = mapping_tbl;
1136
1137         for ( ; mapping_tbl_list ; mapping_tbl_list = mapping_tbl_list->next) {
1138                 tbl_entry = mapping_tbl_list->data;
1139                 if (tbl_entry == NULL)
1140                         continue;
1141
1142                 _util_print_mapping_tbl_entry(tbl_entry);
1143         }
1144 }
1145
1146 /* Initialize Core Objects */
1147 TReturn tcore_object_init_objects(TcorePlugin *plugin,
1148                                                 struct object_initializer *initializer_list)
1149 {
1150         GSList *mapping_tbl_list;
1151         gboolean ret = FALSE;
1152
1153         /* Refer mapping_tbl from Server's Modem list */
1154         mapping_tbl_list = tcore_server_get_cp_mapping_tbl(plugin);
1155
1156         /*
1157          * Mapping Table is a MUST
1158          * If Mapping Table is NOT NULL, then initialization would be guided by the
1159          * Mapping Table entries,
1160          * else, it is treated as a Failure.
1161          */
1162         if (mapping_tbl_list != NULL) {
1163                 object_mapping_table_t *tbl_entry;
1164                 GSList *mtbl_list;
1165                 GSList *object_type_list;
1166                 unsigned int type;
1167
1168                 /* Create each Core Object based on the Mapping Table entries */
1169                 mtbl_list = mapping_tbl_list;
1170                 for ( ; mtbl_list ; mtbl_list = mtbl_list->next) {
1171                         tbl_entry = mtbl_list->data;
1172                         if (tbl_entry != NULL) {
1173                                 CoreObject *co;
1174
1175                                 object_type_list = tbl_entry->object_type;
1176                                 for ( ; object_type_list ; object_type_list = object_type_list->next) {
1177                                         type = (guint)object_type_list->data;
1178
1179                                         co = _create_core_object_by_type(type, plugin, tbl_entry->hal);
1180                                         if (co == NULL) {
1181                                                 err("Failed to create Core Object - Type: [0x%x]", type);
1182                                                 return TCORE_RETURN_FAILURE;
1183                                         }
1184                                         dbg("Created Core Object - Type: [0x%x]", type);
1185                                 }
1186                         }
1187                 }
1188
1189
1190                 /* Initialize each Core Object based on the Mapping Table entries */
1191                 mtbl_list = mapping_tbl_list;
1192                 for ( ; mtbl_list ; mtbl_list = mtbl_list->next) {
1193                         tbl_entry = mtbl_list->data;
1194                         if (tbl_entry != NULL) {
1195                                 /* To handle NULL 'init' function case */
1196                                 ret = FALSE;
1197
1198                                 object_type_list = tbl_entry->object_type;
1199
1200                                 for ( ; object_type_list ; object_type_list = object_type_list->next) {
1201                                         type = (unsigned int)object_type_list->data;
1202                                         dbg("Core Object type: [0x%x]", type);
1203
1204                                         ret = _init_core_object_by_type(type, plugin, initializer_list);
1205                                         if (ret == FALSE) {
1206                                                 err("Failed to initialize Core Object Type [0x%x]", type);
1207                                                 return TCORE_RETURN_FAILURE;
1208                                         }
1209                                         dbg("Initialized Core Object - Type: [0x%x]", type);
1210                                 }
1211                         }
1212                 }
1213         } else {
1214                 err("Mapping Table is NOT present");
1215         }
1216         if (ret == FALSE) {
1217                 err("Failed to create/initialize Core Objects");
1218                 return TCORE_RETURN_FAILURE;
1219         }
1220
1221         dbg("Successfully initialized Core Objects");
1222         return TCORE_RETURN_SUCCESS;
1223 }
1224
1225 /* De-initialize Core Objects */
1226 void tcore_object_deinit_objects(TcorePlugin *plugin,
1227                                                 struct object_deinitializer *deinitializer_list)
1228 {
1229         GSList *mapping_tbl_list;
1230
1231         /* Refer mapping_tbl from Server's Modem list */
1232         mapping_tbl_list = tcore_server_get_cp_mapping_tbl(plugin);
1233
1234         /*
1235          * Mapping Table is a MUST
1236          * If Mapping Table is NOT NULL, then de-initialization would be guided by the
1237          * Mapping Table entries,
1238          * else,
1239          * just return with an Error log.
1240          */
1241         if (mapping_tbl_list != NULL) {
1242                 object_mapping_table_t *tbl_entry;
1243                 GSList *object_type_list;
1244                 unsigned int type;
1245
1246                 /* De-initialize each Core Object based on the Mapping Table entries */
1247                 for ( ; mapping_tbl_list ; mapping_tbl_list = mapping_tbl_list->next) {
1248                         tbl_entry = mapping_tbl_list->data;
1249                         if (tbl_entry == NULL)
1250                                 continue;
1251
1252                         object_type_list = tbl_entry->object_type;
1253
1254                         for ( ; object_type_list ; object_type_list = object_type_list->next) {
1255                                 type = (unsigned int)object_type_list->data;
1256                                 dbg("Core Object type: [0x%x]", type);
1257
1258                                 _deinit_core_object_by_type(type, plugin, deinitializer_list);
1259                         }
1260                 }
1261                 dbg("Successfully de-initialized Core Objects");
1262         } else
1263                 err("Mapping Table is NOT present");
1264 }