Change access denied check string
[platform/core/telephony/libtapi.git] / src / tapi_common.c
1 /*
2  * libslp-tapi
3  *
4  * Copyright (c) 2014 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 #define _GNU_SOURCE
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include <glib.h>
28 #include <gio/gio.h>
29 #include <vconf.h>
30
31 #include "tapi_common.h"
32 #include "TapiUtility.h"
33
34 #include "TelNetwork.h"
35 #include "TelSms.h"
36 #include "TelSat.h"
37 #include "TelSs.h"
38 #include "TelCall.h"
39 #include "TelOem.h"
40
41 #include "common.h"
42 #include "tapi_log.h"
43
44 TelSatEventDownloadType_t g_event_list[TAPI_SAT_EVENT_LIST_MAX_COUNT] = {-1};
45 static GSList *state_callback_list = NULL;
46 static gboolean registered_vconf_cb = FALSE;
47 G_LOCK_DEFINE_STATIC(state_mutex);
48
49 typedef struct {
50         tapi_state_cb callback;
51         void *user_data;
52 } TelReadyStateCallback_t;
53
54 static void _process_sms_event(const gchar *sig, GVariant *param,
55         TapiHandle *handle, char *noti_id, struct tapi_evt_cb *evt_cb_data)
56 {
57         TAPI_RETURN_IF_FAIL(evt_cb_data);
58
59         if (!g_strcmp0(sig, "IncommingMsg")) {
60                 struct tel_noti_sms_incomming_msg noti;
61                 guchar *decoded_sca = NULL;
62                 guchar *decoded_tpdu = NULL;
63
64                 gchar *sca = NULL;
65                 gchar *tpdu = NULL;
66                 int msg_len = 0;
67
68                 gsize decoded_sca_len = 0;
69                 gsize decoded_tpdu_len = 0;
70
71                 memset(&noti, 0, sizeof(struct tel_noti_sms_incomming_msg));
72
73                 g_variant_get(param, "(isis)", &noti.format, &sca, &msg_len, &tpdu);
74
75                 decoded_sca = g_base64_decode((const gchar *)sca, &decoded_sca_len);
76                 decoded_tpdu = g_base64_decode((const gchar *)tpdu, &decoded_tpdu_len);
77                 if (NULL == decoded_tpdu) {
78                         err("g_base64_decode: Failed to decode tpdu");
79                         return;
80                 }
81                 dbg("ds :%d, dt : %d, ml :%d", decoded_sca_len, decoded_tpdu_len, msg_len);
82                 if (TAPI_SIM_SMSP_ADDRESS_LEN < decoded_sca_len)
83                         decoded_sca_len = TAPI_SIM_SMSP_ADDRESS_LEN;
84
85                 if (TAPI_NETTEXT_SMDATA_SIZE_MAX+1 < decoded_tpdu_len)
86                         decoded_tpdu_len = TAPI_NETTEXT_SMDATA_SIZE_MAX+1;
87
88                 if (decoded_sca)
89                         memcpy(noti.Sca, decoded_sca, decoded_sca_len);
90
91                 memcpy(noti.szData, decoded_tpdu, decoded_tpdu_len);
92
93                 noti.MsgLength = msg_len;
94
95                 g_free(sca);
96                 g_free(tpdu);
97                 g_free(decoded_sca);
98                 g_free(decoded_tpdu);
99
100                 TAPI_INVOKE_NOTI_CALLBACK(&noti);
101         } else if (!g_strcmp0(sig, "IncommingCbMsg")) {
102                 struct tel_noti_sms_incomming_cb_msg noti = {0};
103                 gchar *cb_msg = NULL;
104
105                 guchar *decoded_cbmsg = NULL;
106                 gsize decoded_cbmsg_len = 0;
107                 int cb_msg_len = 0;
108
109                 g_variant_get(param, "(iis)", &noti.CbMsgType, &cb_msg_len, &cb_msg);
110
111                 decoded_cbmsg = g_base64_decode(cb_msg, &decoded_cbmsg_len);
112                 if (NULL == decoded_cbmsg) {
113                         err("g_base64_decode: Failed to decode cbmsg");
114                         return;
115                 }
116
117                 dbg("dt : %d, ml :%d", decoded_cbmsg_len, cb_msg_len);
118
119                 if (TAPI_NETTEXT_CB_SIZE_MAX+1 < decoded_cbmsg_len)
120                         decoded_cbmsg_len = TAPI_NETTEXT_CB_SIZE_MAX+1;
121
122                 memcpy(&(noti.szMsgData[0]), decoded_cbmsg, decoded_cbmsg_len);
123
124                 noti.Length = cb_msg_len;
125
126                 g_free(cb_msg);
127                 g_free(decoded_cbmsg);
128
129                 TAPI_INVOKE_NOTI_CALLBACK(&noti);
130         } else if (!g_strcmp0(sig, "IncommingEtwsMsg")) {
131                 struct tel_noti_sms_incomming_etws_msg noti;
132
133                 GVariant *etwsMsg = NULL;
134                 int i = 0;
135                 GVariantIter *iter = 0;
136                 GVariant *inner_gv = 0;
137
138
139                 memset(&noti, 0, sizeof(struct tel_noti_sms_incomming_etws_msg));
140                 g_variant_get(param, "(ii@v)", &noti.EtwsMsgType, &noti.Length, &etwsMsg);
141
142                 inner_gv = g_variant_get_variant(etwsMsg);
143                 g_variant_get(inner_gv, "ay", &iter);
144                 while (g_variant_iter_loop(iter, "y", &noti.szMsgData[i])) {
145                          i++;
146                          if (i >= TAPI_NETTEXT_ETWS_SIZE_MAX + 1)
147                                  break;
148                 }
149                 g_variant_iter_free(iter);
150                 g_variant_unref(etwsMsg);
151                 g_variant_unref(inner_gv);
152
153                 TAPI_INVOKE_NOTI_CALLBACK(&noti);
154         } else if (!g_strcmp0(sig, "MemoryStatus")) {
155                 int noti = 0;
156
157                 g_variant_get(param, "(i)", &noti);
158                 TAPI_INVOKE_NOTI_CALLBACK(&noti);
159         } else if (!g_strcmp0(sig, "SmsReady")) {
160                 gint noti = 0;
161
162                 g_variant_get(param, "(i)", &noti);
163                 TAPI_INVOKE_NOTI_CALLBACK(&noti);
164         } else {
165                 dbg("not handled Sms noti[%s]", sig);
166         }
167 }
168
169 static void _process_call_event(const gchar *sig, GVariant *param,
170         TapiHandle *handle, char *noti_id, struct tapi_evt_cb *evt_cb_data)
171 {
172         TAPI_RETURN_IF_FAIL(evt_cb_data);
173
174         if (!g_strcmp0(sig, "VoiceCallStatusIdle") || !g_strcmp0(sig, "VideoCallStatusIdle")) {
175                 TelCallStatusIdleNoti_t data;
176                 int start_time = 0, end_time = 0;
177                 g_variant_get(param, "(iiii)", &data.id, &data.cause, &start_time, &end_time);
178                 msg("[ check ] (%s) %s : call_handle(%d), end_cause(0x%x)", handle->cp_name, "Status Idle noti", data.id, data.cause);
179                 TAPI_INVOKE_NOTI_CALLBACK(&data);
180         } else if (!g_strcmp0(sig, "VoiceCallStatusDialing") || !g_strcmp0(sig, "VideoCallStatusDialing")) {
181                 TelCallStatusDialingNoti_t data;
182                 g_variant_get(param, "(i)", &data.id);
183                 msg("[ check ] (%s) %s : call_handle(%d)", handle->cp_name, "Status Dialing noti", data.id);
184                 TAPI_INVOKE_NOTI_CALLBACK(&data);
185         } else if (!g_strcmp0(sig, "VoiceCallStatusAlert") || !g_strcmp0(sig, "VideoCallStatusAlert")) {
186                 TelCallStatusAlertNoti_t data;
187                 g_variant_get(param, "(i)", &data.id);
188                 msg("[ check ] (%s) %s : call_handle(%d)", handle->cp_name, "Status Alert noti", data.id);
189                 TAPI_INVOKE_NOTI_CALLBACK(&data);
190         } else if (!g_strcmp0(sig, "VoiceCallStatusActive") || !g_strcmp0(sig, "VideoCallStatusActive")) {
191                 TelCallStatusActiveNoti_t data;
192                 g_variant_get(param, "(i)", &data.id);
193                 msg("[ check ] (%s) %s : call_handle(%d)", handle->cp_name, "Status Active noti", data.id);
194                 TAPI_INVOKE_NOTI_CALLBACK(&data);
195         } else if (!g_strcmp0(sig, "VoiceCallStatusHeld")) {
196                 TelCallStatusHeldNoti_t data;
197                 g_variant_get(param, "(i)", &data.id);
198                 msg("[ check ] (%s) %s : call_handle(%d)", handle->cp_name, "Status Held noti", data.id);
199                 TAPI_INVOKE_NOTI_CALLBACK(&data);
200         } else if (!g_strcmp0(sig, "VoiceCallStatusIncoming") || !g_strcmp0(sig, "VideoCallStatusIncoming")) {
201                 TelCallIncomingCallInfo_t data;
202                 gchar *number = NULL;
203                 gchar *name = NULL;
204
205                 memset((void *)&data, 0, sizeof(TelCallIncomingCallInfo_t));
206                 g_variant_get(param, "(iiisbis)",
207                                 &data.CallHandle,
208                                 &data.CliMode,
209                                 &data.CliCause,
210                                 &number,
211                                 &data.fwded,
212                                 &data.ActiveLine,
213                                 &name);
214                 if (number) {
215                         memcpy(data.szCallingPartyNumber, number, strlen(number));
216                         g_free(number);
217                 }
218                 if (name) {
219                         memcpy(data.CallingNameInfo.szNameData, name, strlen(name));
220                         g_free(name);
221                 }
222                 msg("[ check ] %s : call_handle(%d)", "Status Incoming noti", data.CallHandle);
223                 msg("[ check ] %s : cli_mode(%d)", "Status Incoming noti", data.CliMode);
224                 msg("[ check ] %s : cli_cause(%d)", "Status Incoming noti", data.CliCause);
225                 msg("[ check ] %s : cli_number(%s)", "Status Incoming noti", data.szCallingPartyNumber);
226                 msg("[ check ] %s : is_forwarded(%d)", "Status Incoming noti", data.fwded);
227                 msg("[ check ] %s : active_line(%d)", "Status Incoming noti", data.ActiveLine);
228                 msg("[ check ] %s : call_name(%s)", "Status Incoming noti", data.CallingNameInfo.szNameData);
229
230                 TAPI_INVOKE_NOTI_CALLBACK(&data);
231         } else if (!g_strcmp0(sig, "Waiting")) {
232                 TelCallInfoWaitingNoti_t data;
233                 g_variant_get(param, "(i)", &data.id);
234                 msg("[ check ] (%s) %s : data.id(%d)", handle->cp_name, "Call Info Waiting noti", data.id);
235                 TAPI_INVOKE_NOTI_CALLBACK(&data);
236         } else if (!g_strcmp0(sig, "Forwarded")) {
237                 TelCallInfoForwardedNoti_t data;
238                 g_variant_get(param, "(i)", &data.id);
239                 msg("[ check ] (%s) %s : data.id(%d)", handle->cp_name, "Call Info Forwarded noti", data.id);
240                 TAPI_INVOKE_NOTI_CALLBACK(&data);
241         } else if (!g_strcmp0(sig, "ForwardedCall")) {
242                 TelCallInfoForwardedCallNoti_t data;
243                 g_variant_get(param, "(i)", &data.id);
244                 dbg("[ check ] (%s) %s : data.id(%d)", handle->cp_name, "Call Info Forwarded Call noti", data.id);
245                 TAPI_INVOKE_NOTI_CALLBACK(&data);
246         } else if (!g_strcmp0(sig, "BarredIncoming")) {
247                 TelCallInfoBarredIncomingNoti_t data;
248                 g_variant_get(param, "(i)", &data.id);
249                 msg("[ check ] (%s) %s : data.id(%d)", handle->cp_name, "Call Info Barred Incoming noti", data.id);
250                 TAPI_INVOKE_NOTI_CALLBACK(&data);
251         } else if (!g_strcmp0(sig, "BarredOutgoing")) {
252                 TelCallInfoBarredOutgoingNoti_t data;
253                 g_variant_get(param, "(i)", &data.id);
254                 msg("[ check ] (%s) %s : data.id(%d)", handle->cp_name, "Call Info Barred Outgoing noti", data.id);
255                 TAPI_INVOKE_NOTI_CALLBACK(&data);
256         } else if (!g_strcmp0(sig, "ForwardConditional")) {
257                 TelCallInfoForwardConditionalNoti_t data;
258                 g_variant_get(param, "(i)", &data.id);
259                 msg("[ check ] (%s) %s : data.id(%d)", handle->cp_name, "Call Info Forward Conditional noti", data.id);
260                 TAPI_INVOKE_NOTI_CALLBACK(&data);
261         } else if (!g_strcmp0(sig, "ForwardUnconditional")) {
262                 TelCallInfoForwardUnconditionalNoti_t data;
263                 g_variant_get(param, "(i)", &data.id);
264                 msg("[ check ] (%s) %s : data.id(%d)", handle->cp_name, "Call Info Forward Unconditional noti", data.id);
265                 TAPI_INVOKE_NOTI_CALLBACK(&data);
266         } else if (!g_strcmp0(sig, "CallActive")) {
267                 TelCallInfoActiveNoti_t data;
268                 g_variant_get(param, "(i)", &data.id);
269                 msg("[ check ] (%s) %s : data.id(%d)", handle->cp_name, "Call Info Call Active noti", data.id);
270                 TAPI_INVOKE_NOTI_CALLBACK(&data);
271         } else if (!g_strcmp0(sig, "CallHeld")) {
272                 TelCallInfoHeldNoti_t data;
273                 g_variant_get(param, "(i)", &data.id);
274                 msg("[ check ] (%s) %s : data.id(%d)", handle->cp_name, "Call Info Call Held noti", data.id);
275                 TAPI_INVOKE_NOTI_CALLBACK(&data);
276         } else if (!g_strcmp0(sig, "CallJoined")) {
277                 TelCallInfoJoinedNoti_t data;
278                 g_variant_get(param, "(i)", &data.id);
279                 msg("[ check ] (%s) %s : data.id(%d)", handle->cp_name, "Call Info Call Joined noti", data.id);
280                 TAPI_INVOKE_NOTI_CALLBACK(&data);
281         } else if (!g_strcmp0(sig, "CallPrivacyMode")) {
282                 TelCallVoicePrivacyNoti_t data;
283                 g_variant_get(param, "(i)", &data.privacy_mode);
284                 msg("[ check ] %s (%s): data.privacy_mode(%d) ", "Call Privacy Info noti", handle->cp_name, data.privacy_mode);
285                 TAPI_INVOKE_NOTI_CALLBACK(&data);
286         } else if (!g_strcmp0(sig, "CallOtaspStatus")) {
287                 TelCallOtaspStatusNoti_t otasp;
288                 g_variant_get(param, "(i)", &otasp.otasp_status);
289                 msg("[ check ] %s (%s): otasp_status(%d)", "Call OTASP Status ", handle->cp_name, otasp.otasp_status);
290                 TAPI_INVOKE_NOTI_CALLBACK(&otasp);
291         } else if (!g_strcmp0(sig, "CallOtapaStatus")) {
292                 TelCallOtapaStatusNoti_t otapa;
293                 g_variant_get(param, "(i)", &otapa.otapa_status);
294                 msg("[ check ] %s : otapa_status(%d)", "Call OTAPA Status ", otapa.otapa_status);
295                 TAPI_INVOKE_NOTI_CALLBACK(&otapa);
296         } else if (!g_strcmp0(sig, "CallSignalInfo")) {
297                 TelCallSignalInfoNoti_t signal_info;
298                 unsigned int signal;
299                 g_variant_get(param, "(iii)", &signal_info.signal_type, &signal_info.pitch_type, &signal);
300                 msg("[ check ] %s (%s): Signal type(%d) Pitch type(%d)  Signal (%d)", "Call Alert Signal Info ", handle->cp_name, signal_info.signal_type, signal_info.pitch_type, signal);
301                  if (signal_info.signal_type == TAPI_CALL_SIGNAL_TYPE_TONE) {
302                         signal_info.signal.sig_tone_type = signal;
303                 } else if (signal_info.signal_type == TAPI_CALL_SIGNAL_TYPE_ISDN_ALERTING) {
304                         signal_info.signal.sig_isdn_alert_type = signal;
305                 } else if (signal_info.signal_type == TAPI_CALL_SIGNAL_TYPE_IS54B_ALERTING) {
306                         signal_info.signal.sig_is54b_alert_type = signal;
307                 } else {
308                         err("Unknown Signal type");
309                         return;
310                 }
311                 TAPI_INVOKE_NOTI_CALLBACK(&signal_info);
312         } else if (!g_strcmp0(sig, "CallInfoRec")) {
313                 TelCallRecordInfoNoti_t noti;
314                 gchar *data = NULL;
315
316                 memset(&noti, '\0', sizeof(TelCallRecordInfoNoti_t));
317                 g_variant_get(param, "(iis)", &noti.info.id, &noti.info.type, &data);
318                 if (noti.info.type == TAPI_CALL_REC_INFO_TYPE_NAME) {
319                         strncpy(noti.info.data.name, data, TAPI_CALLING_NAME_SIZE_MAX);
320                         msg("[ check ] %s (%s): id(%d) type(%d) name(%s)", "CallInfoRec", handle->cp_name,
321                                 noti.info.id, noti.info.type, noti.info.data.name);
322                 } else if (noti.info.type == TAPI_CALL_REC_INFO_TYPE_NUMBER) {
323                         strncpy(noti.info.data.number, data, TAPI_CALL_DIAL_NUMBER_LEN_MAX);
324                         msg("[ check ] %s (%s): id(%d) type(%d) number(%s)", "CallInfoRec", handle->cp_name,
325                                 noti.info.id, noti.info.type, noti.info.data.number);
326                 }
327
328                 TAPI_INVOKE_NOTI_CALLBACK(&noti);
329                 g_free(data);
330         } else if (!g_strcmp0(sig, "CallSoundPath")) {
331                 TelCallSoundPathNoti_t data;
332                 g_variant_get(param, "(i)", &data.path);
333                 msg("[ check ] (%s) %s : path(%d)", handle->cp_name, "Call Sound Path noti", data.path);
334                 TAPI_INVOKE_NOTI_CALLBACK(&data);
335         } else if (!g_strcmp0(sig, "CallSoundRingbackTone")) {
336                 TelCallSoundRingbackToneNoti_t status;
337                 g_variant_get(param, "(i)", &status);
338                 msg("[ check ] (%s) %s : status(%d)", handle->cp_name, "Call Sound Ringbacktone noti", status);
339                 TAPI_INVOKE_NOTI_CALLBACK(&status);
340         } else if (!g_strcmp0(sig, "CallSoundWbamr")) {
341                 TelCallSoundWbamrNoti_t status;
342                 g_variant_get(param, "(i)", &status);
343                 msg("[ check ] (%s) %s : status(%d)", handle->cp_name, "Call Sound Wbamr noti", status);
344                 TAPI_INVOKE_NOTI_CALLBACK(&status);
345         } else if (!g_strcmp0(sig, "CallSoundNoiseReduction")) {
346                 TelCallSoundNoiseReductionNoti_t data;
347                 g_variant_get(param, "(i)", &data.status);
348                 msg("[ check ] (%s) %s : status(%d)", handle->cp_name, "Call Sound Noise Reduction noti", data.status);
349                 TAPI_INVOKE_NOTI_CALLBACK(&data);
350         } else if (!g_strcmp0(sig, "CallSoundClockStatus")) {
351                 gboolean data;
352                 g_variant_get(param, "(b)", &data);
353                 msg("[ check ] (%s) %s : status(%d)", handle->cp_name, "Call Sound Clock Status noti", data);
354                 TAPI_INVOKE_NOTI_CALLBACK(&data);
355         } else if (!g_strcmp0(sig, "CallPreferredVoiceSubscription")) {
356                 TelCallPreferredVoiceSubsNoti_t data;
357                 g_variant_get(param, "(i)", &data.preferred_subs);
358                 dbg("[ check ] %s : Voice preferred_subs(%d)", "Call Preferred Voice Subscription noti", data.preferred_subs);
359                 TAPI_INVOKE_NOTI_CALLBACK(&data);
360         } else {
361                 dbg("not handled Call noti[%s]", sig);
362         }
363 }
364
365 static void _process_sat_event(const gchar *sig, GVariant *param,
366         TapiHandle *handle, char *noti_id, struct tapi_evt_cb *evt_cb_data)
367 {
368         TAPI_RETURN_IF_FAIL(evt_cb_data);
369
370         if (!g_strcmp0(sig, "SetupMenu")) {
371                 TelSatSetupMenuInfo_t setup_menu;
372
373                 gchar *title = NULL;
374                 gint command_id, item_cnt;
375                 gboolean b_present, b_helpinfo, b_updated;
376                 GVariant *items = NULL;
377                 int sat_index = 0;
378                 GVariant *unbox;
379                 GVariantIter *iter;
380
381                 memset(&setup_menu, 0, sizeof(TelSatSetupMenuInfo_t));
382
383                 g_variant_get(param, "(ibs@vibb)", &command_id, &b_present, &title, &items, &item_cnt,
384                         &b_helpinfo, &b_updated);
385
386                 setup_menu.commandId = command_id;
387                 setup_menu.bIsMainMenuPresent = (b_present ? 1 : 0);
388                 memcpy(setup_menu.satMainTitle, title, TAPI_SAT_DEF_TITLE_LEN_MAX+1);
389                 g_free(title);
390                 setup_menu.satMainMenuNum = item_cnt;
391                 if (items && item_cnt > 0) {
392                         gchar *item_str;
393                         gint item_id;
394                         unbox = g_variant_get_variant(items);
395                         dbg("items(%p) items type_format(%s)", items, g_variant_get_type_string(unbox));
396
397                         g_variant_get(unbox, "a(si)", &iter);
398                         while (g_variant_iter_loop(iter, "(si)", &item_str, &item_id)) {
399                                 setup_menu.satMainMenuItem[sat_index].itemId = item_id;
400                                 memcpy(setup_menu.satMainMenuItem[sat_index].itemString,
401                                         item_str, TAPI_SAT_DEF_ITEM_STR_LEN_MAX + 6);
402                                 dbg("item index(%d) id(%d) str(%s)", sat_index,
403                                         setup_menu.satMainMenuItem[sat_index].itemId,
404                                         setup_menu.satMainMenuItem[sat_index].itemString);
405                                 sat_index++;
406                         }
407                         g_variant_iter_free(iter);
408                 }
409                 setup_menu.bIsSatMainMenuHelpInfo = (b_helpinfo ? 1 : 0);
410                 setup_menu.bIsUpdatedSatMainMenu = (b_updated ? 1 : 0);
411
412                 dbg("command id (%d)", setup_menu.commandId);
413                 dbg("menu present (%d)", setup_menu.bIsMainMenuPresent);
414                 dbg("menu title (%s)", setup_menu.satMainTitle);
415                 dbg("item cnt (%d)", setup_menu.satMainMenuNum);
416                 dbg("menu help info (%d)", setup_menu.bIsSatMainMenuHelpInfo);
417                 dbg("menu updated (%d)", setup_menu.bIsUpdatedSatMainMenu);
418
419                 dbg("icon exist(%d), icon_quali: (%d), icon_id: (%d), width: (%d), height: (%d), ics: (%d), icon_data_len: (%d)", setup_menu.iconId.bIsPresent, setup_menu.iconId.iconQualifier, setup_menu.iconId.iconIdentifier, setup_menu.iconId.iconInfo.width,
420                         setup_menu.iconId.iconInfo.height, setup_menu.iconId.iconInfo.ics, setup_menu.iconId.iconInfo.iconDataLen);
421
422                 TAPI_INVOKE_NOTI_CALLBACK(&setup_menu);
423         } else if (!g_strcmp0(sig, "DisplayText")) {
424                 TelSatDisplayTextInd_t display_text;
425                 gchar *text;
426                 gint command_id, text_len, duration;
427                 gboolean high_priority, user_rsp_required, immediately_rsp;
428
429                 memset(&display_text, 0, sizeof(TelSatDisplayTextInd_t));
430
431                 g_variant_get(param, "(isiibbb)", &command_id, &text, &text_len, &duration,
432                         &high_priority, &user_rsp_required, &immediately_rsp);
433
434                 display_text.commandId = command_id;
435                 memcpy(display_text.text.string, text, TAPI_SAT_DEF_TEXT_STRING_LEN_MAX+1);
436                 g_free(text);
437                 display_text.text.stringLen = text_len;
438                 display_text.duration = duration;
439                 display_text.bIsPriorityHigh = (high_priority ? 1 : 0);
440                 display_text.bIsUserRespRequired = (user_rsp_required ? 1 : 0);
441                 display_text.b_immediately_resp = (immediately_rsp ? 1 : 0);
442
443                 dbg("command id (%d)", display_text.commandId);
444                 dbg("display text (%s)", display_text.text.string);
445                 dbg("string len(%d)", display_text.text.stringLen);
446                 dbg("duration (%d)", display_text.duration);
447                 dbg("high priority (%d)", display_text.bIsPriorityHigh);
448                 dbg("user response required(%d)", display_text.bIsUserRespRequired);
449                 dbg("immediately response (%d)", display_text.b_immediately_resp);
450
451                 TAPI_INVOKE_NOTI_CALLBACK(&display_text);
452         } else if (!g_strcmp0(sig, "SelectItem")) {
453                 TelSatSelectItemInd_t select_item;
454
455                 gboolean help_info ;
456                 gchar *selected_text;
457                 gint command_id, default_item_id, menu_cnt, text_len = 0;
458                 GVariant *menu_items;
459                 int select_item_index = 0;
460                 GVariant *unbox;
461                 GVariantIter *iter;
462
463                 memset(&select_item, 0, sizeof(TelSatSelectItemInd_t));
464
465                 g_variant_get(param, "(ibsiii@v)", &command_id, &help_info, &selected_text,
466                         &text_len, &default_item_id, &menu_cnt, &menu_items);
467
468                 select_item.commandId = command_id;
469                 select_item.bIsHelpInfoAvailable = (help_info ? 1 : 0);
470                 memcpy(select_item.text.string, selected_text, TAPI_SAT_DEF_TITLE_LEN_MAX+1);
471                 g_free(selected_text);
472                 select_item.text.stringLen = text_len;
473                 select_item.defaultItemIndex = default_item_id;
474                 select_item.menuItemCount = menu_cnt;
475                 if (menu_items && menu_cnt > 0) {
476                         gchar *item_str;
477                         gint item_id, item_len;
478                         unbox = g_variant_get_variant(menu_items);
479                         dbg("items(%p) items type_format(%s)", menu_items, g_variant_get_type_string(unbox));
480
481                         g_variant_get(unbox, "a(iis)", &iter);
482                         while (g_variant_iter_loop(iter, "(iis)", &item_id, &item_len, &item_str)) {
483                                 select_item.menuItem[select_item_index].itemId = item_id;
484                                 select_item.menuItem[select_item_index].textLen = item_len;
485                                 memcpy(select_item.menuItem[select_item_index].text, item_str, TAPI_SAT_ITEM_TEXT_LEN_MAX + 1);
486                                 dbg("item index(%d) id(%d) len(%d) str(%s)", select_item_index,
487                                                 select_item.menuItem[select_item_index].itemId, select_item.menuItem[select_item_index].textLen, select_item.menuItem[select_item_index].text);
488                                 select_item_index++;
489                         }
490                         g_variant_iter_free(iter);
491                 }
492
493                 dbg("command id (%d)", select_item.commandId);
494                 dbg("help info(%d)", select_item.bIsHelpInfoAvailable);
495                 dbg("selected item string(%s)", select_item.text.string);
496                 dbg("string len(%d)", select_item.text.stringLen);
497                 dbg("default item index(%d)", select_item.defaultItemIndex);
498                 dbg("item count(%d)", select_item.menuItemCount);
499
500                 TAPI_INVOKE_NOTI_CALLBACK(&select_item);
501         } else if (!g_strcmp0(sig, "GetInkey")) {
502                 TelSatGetInkeyInd_t get_inkey;
503
504                 gint command_id, key_type, input_character_mode;
505                 gint text_len, duration;
506                 gboolean b_numeric, b_help_info;
507                 gchar *text = NULL;
508
509                 memset(&get_inkey, 0, sizeof(TelSatGetInkeyInd_t));
510
511                 g_variant_get(param, "(iiibbsii)", &command_id, &key_type, &input_character_mode,
512                         &b_numeric, &b_help_info, &text, &text_len, &duration);
513
514                 get_inkey.commandId = command_id;
515                 get_inkey.keyType = key_type;
516                 get_inkey.inputCharMode = input_character_mode;
517                 get_inkey.bIsNumeric = (b_numeric ? 1 : 0);
518                 get_inkey.bIsHelpInfoAvailable = (b_help_info ? 1 : 0);
519                 memcpy(get_inkey.text.string, text, TAPI_SAT_DEF_TEXT_STRING_LEN_MAX+1);
520                 g_free(text);
521                 get_inkey.text.stringLen = text_len;
522                 get_inkey.duration = duration;
523
524                 dbg("command id(%d)", get_inkey.commandId);
525                 dbg("key type(%d)", get_inkey.keyType);
526                 dbg("input character mode(%d)", get_inkey.inputCharMode);
527                 dbg("numeric(%d)", get_inkey.bIsNumeric);
528                 dbg("help info available(%d)", get_inkey.bIsHelpInfoAvailable);
529                 dbg("text (%s)", get_inkey.text.string);
530                 dbg("text length", get_inkey.text.stringLen);
531                 dbg("duration", get_inkey.duration);
532
533                 TAPI_INVOKE_NOTI_CALLBACK(&get_inkey);
534         } else if (!g_strcmp0(sig, "GetInput")) {
535                 TelSatGetInputInd_t get_input;
536
537                 gint command_id, input_character_mode;
538                 gint text_len, def_text_len, rsp_len_min, rsp_len_max;
539                 gboolean b_numeric, b_help_info, b_echo_input;
540                 gchar *text = NULL, *def_text = NULL;
541
542                 memset(&get_input, 0, sizeof(TelSatGetInputInd_t));
543
544                 g_variant_get(param, "(iibbbsiiisi)", &command_id, &input_character_mode, &b_numeric, &b_help_info, &b_echo_input,
545                         &text, &text_len, &rsp_len_max, &rsp_len_min, &def_text, &def_text_len);
546
547                 get_input.commandId = command_id;
548                 get_input.inputCharMode = input_character_mode;
549                 get_input.bIsNumeric = (b_numeric ? 1 : 0);
550                 get_input.bIsHelpInfoAvailable = (b_help_info ? 1 : 0);
551                 get_input.bIsEchoInput = (b_echo_input ? 1 : 0);
552                 memcpy(get_input.text.string, text, TAPI_SAT_DEF_TEXT_STRING_LEN_MAX+1);
553                 g_free(text);
554                 get_input.text.stringLen = text_len;
555                 get_input.respLen.max = rsp_len_max;
556                 get_input.respLen.min = rsp_len_min;
557                 memcpy(get_input.defaultText.string, def_text, TAPI_SAT_DEF_TEXT_STRING_LEN_MAX+1);
558                 g_free(def_text);
559                 get_input.defaultText.stringLen = def_text_len;
560
561                 dbg("command id(%d)", get_input.commandId);
562                 dbg("input character mode(%d)", get_input.inputCharMode);
563                 dbg("numeric(%d)", get_input.bIsNumeric);
564                 dbg("help info avaiable(%d)", get_input.bIsHelpInfoAvailable);
565                 dbg("echo input(%d)", get_input.bIsEchoInput);
566                 dbg("text(%s)", get_input.text.string);
567                 dbg("text length(%d)", get_input.text.stringLen);
568                 dbg("response length max(%d)", get_input.respLen.max);
569                 dbg("response length min(%d)", get_input.respLen.min);
570                 dbg("default text(%s)", get_input.defaultText.string);
571                 dbg("default text length(%d)", get_input.defaultText.stringLen);
572
573                 TAPI_INVOKE_NOTI_CALLBACK(&get_input);
574         } else if (!g_strcmp0(sig, "SendSMS")) {
575                 TelSatSendSmsIndSmsData_t send_sms;
576
577                 gint command_id, ton, npi, tpdu_type;
578                 gboolean b_packing_required;
579                 gint text_len, number_len, tpdu_data_len;
580                 gchar *text = NULL, *dialling_number = NULL;
581                 GVariant *tpdu_data;
582
583                 memset(&send_sms, 0, sizeof(TelSatSendSmsIndSmsData_t));
584
585                 g_variant_get(param, "(isibiisii@vi)", &command_id, &text, &text_len, &b_packing_required, &ton, &npi,
586                                         &dialling_number, &number_len, &tpdu_type, &tpdu_data, &tpdu_data_len);
587
588                 send_sms.commandId = command_id;
589                 send_sms.bIsPackingRequired = (b_packing_required ? 1 : 0);
590
591                 send_sms.address.ton = ton;
592                 send_sms.address.npi = npi;
593                 send_sms.address.diallingNumberLen = number_len;
594                 memcpy(send_sms.address.diallingNumber, dialling_number, TAPI_SAT_DIALLING_NUMBER_LEN_MAX);
595                 g_free(dialling_number);
596                 g_free(text);
597
598                 send_sms.smsTpdu.tpduType = tpdu_type;
599                 send_sms.smsTpdu.dataLen = tpdu_data_len;
600
601                 if (tpdu_data) {
602                         int send_sms_index = 0;
603                         guchar data;
604                         GVariantIter *iter = NULL;
605                         GVariant *inner_gv = NULL;
606
607                         inner_gv = g_variant_get_variant(tpdu_data);
608                         dbg("tpdu data exist type_format(%s)", g_variant_get_type_string(inner_gv));
609
610                         g_variant_get(inner_gv, "ay", &iter);
611                         while (g_variant_iter_loop(iter, "y", &data)) {
612                                 dbg("index(%d) data(%c)", send_sms_index, data);
613                                 send_sms.smsTpdu.data[send_sms_index] = data;
614                                 send_sms_index++;
615                         }
616                         g_variant_iter_free(iter);
617                         g_variant_unref(inner_gv);
618                 }
619
620                 dbg("command id(%d)", send_sms.commandId);
621                 dbg("packing required(%d)", send_sms.bIsPackingRequired);
622                 dbg("address ton(%d)", send_sms.address.ton);
623                 dbg("address npi(%d)", send_sms.address.npi);
624                 dbg("address dialing number (%s)", send_sms.address.diallingNumber);
625                 dbg("address number length (%d)", send_sms.address.diallingNumberLen);
626                 dbg("tpdu type (%d)", send_sms.smsTpdu.tpduType);
627                 dbg("tpdu length (%d)", send_sms.smsTpdu.dataLen);
628
629                 TAPI_INVOKE_NOTI_CALLBACK(&send_sms);
630         } else if (!g_strcmp0(sig, "SetupEventList")) {
631                 int g_index = 0;
632                 gint event_cnt;
633                 GVariant *evt_list;
634                 TelSatEventListData_t event_list;
635
636                 memset(&event_list, 0, sizeof(TelSatEventListData_t));
637
638                 g_variant_get(param, "(i@v)", &event_cnt, &evt_list);
639
640                 if (evt_list) {
641                         guchar data;
642                         GVariantIter *iter = NULL;
643                         GVariant *inner_gv = NULL;
644
645                         inner_gv = g_variant_get_variant(evt_list);
646                         dbg("event list exist type_format(%s)", g_variant_get_type_string(inner_gv));
647
648                         g_variant_get(inner_gv, "ai", &iter);
649                         while (g_variant_iter_loop(iter, "i", &data)) {
650                                 dbg("g_index(%d) event(%d)", g_index, data);
651                                 g_event_list[g_index] = data;
652
653                                 if (data == TAPI_EVENT_SAT_DW_TYPE_IDLE_SCREEN_AVAILABLE)
654                                         event_list.bIsIdleScreenAvailable = 1;
655                                 else if (data == TAPI_EVENT_SAT_DW_TYPE_LANGUAGE_SELECTION)
656                                         event_list.bIsLanguageSelection = 1;
657                                 else if (data == TAPI_EVENT_SAT_DW_TYPE_BROWSER_TERMINATION)
658                                         event_list.bIsBrowserTermination = 1;
659                                 else if (data == TAPI_EVENT_SAT_DW_TYPE_DATA_AVAILABLE)
660                                         event_list.bIsDataAvailable = 1;
661                                 else if (data == TAPI_EVENT_SAT_DW_TYPE_CHANNEL_STATUS)
662                                         event_list.bIsChannelStatus = 1;
663
664                                 g_index++;
665                         } /* while end */
666                         g_variant_iter_free(iter);
667                         g_variant_unref(inner_gv);
668                 }
669
670                 dbg("event list cnt(%d)", event_cnt);
671
672                 TAPI_INVOKE_NOTI_CALLBACK(&event_list);
673         } else if (!g_strcmp0(sig, "Refresh")) {
674                 TelSatRefreshInd_t refresh_info;
675
676                 gint command_id = 0;
677                 gint refresh_type = 0;
678                 gint file_cnt = 0;
679                 GVariant *file_list = NULL;
680
681                 memset(&refresh_info, 0, sizeof(TelSatRefreshInd_t));
682
683                 g_variant_get(param, "(ii@v)", &command_id, &refresh_type, &file_list);
684
685                 refresh_info.commandId = command_id;
686                 refresh_info.refreshMode = refresh_type;
687
688                 if (file_list) {
689                         int g_index = 0;
690                         guchar data;
691                         GVariantIter *iter = NULL;
692                         GVariant *inner_gv = NULL;
693
694                         inner_gv = g_variant_get_variant(file_list);
695                         dbg("file list exist type_format(%s)", g_variant_get_type_string(inner_gv));
696
697                         g_variant_get(inner_gv, "ai", &iter);
698                         while (g_variant_iter_loop(iter, "i", &data)) {
699                                 dbg("g_index(%d) file id(%d)", g_index, data);
700                                 refresh_info.fileId[g_index] = data;
701                                 g_index++;
702                         }
703                         file_cnt = g_index;
704
705                         /* while end */
706                         g_variant_iter_free(iter);
707                         g_variant_unref(inner_gv);
708                 }
709                 refresh_info.fileCount = file_cnt;
710
711                 dbg("refresh event/file cnt(%d)", refresh_info.fileCount);
712
713                 TAPI_INVOKE_NOTI_CALLBACK(&refresh_info);
714         } else if (!g_strcmp0(sig, "SendDtmf")) {
715                 TelSatSendDtmfIndDtmfData_t send_dtmf;
716
717                 gint command_id = 0;
718                 gint text_len = 0, dtmf_str_len = 0;
719                 gchar *text = NULL;
720                 gchar *dtmf_str = NULL;
721
722                 memset(&send_dtmf, 0, sizeof(TelSatSendDtmfIndDtmfData_t));
723
724                 g_variant_get(param, "(isisi)", &command_id, &text, &text_len, &dtmf_str, &dtmf_str_len);
725
726                 send_dtmf.commandId = command_id;
727                 send_dtmf.bIsHiddenMode = 1;
728
729                 send_dtmf.dtmfString.stringLen = dtmf_str_len;
730                 memcpy(send_dtmf.dtmfString.string, dtmf_str, TAPI_SAT_DEF_TEXT_STRING_LEN_MAX+1);
731                 g_free(dtmf_str);
732                 g_free(text);
733
734                 dbg("dtmf event command id(%d)", send_dtmf.commandId);
735                 dbg("dtmf event dtmf(%s)", send_dtmf.dtmfString.string);
736
737                 TAPI_INVOKE_NOTI_CALLBACK(&send_dtmf);
738         } else if (!g_strcmp0(sig, "EndProactiveSession")) {
739                 int command_type = 0;
740
741                 g_variant_get(param, "(i)", &command_type);
742                 dbg("end session evt : command type(%d)", command_type);
743                 TAPI_INVOKE_NOTI_CALLBACK(&command_type);
744         } else if (!g_strcmp0(sig, "CallControlResult")) {
745                 TelSatCallCtrlIndData_t call_ctrl_result_ind;
746                 gint call_ctrl_result = 0, disp_len = 0;
747                 gint bc_repeat_indicator = 0, ton = 0x0F, npi = 0X0F;
748                 gchar *text = NULL, *call_num = NULL, *ss_string = NULL, *sub_addr = NULL, *ccp1 = NULL, *ccp2 = NULL;
749
750                 memset(&call_ctrl_result_ind, 0x00, sizeof(TelSatCallCtrlIndData_t));
751
752                 g_variant_get(param, "(isiisssssi)", &call_ctrl_result, &text, &ton, &npi, &call_num,
753                         &ss_string, &sub_addr, &ccp1, &ccp2, &bc_repeat_indicator);
754
755                 call_ctrl_result_ind.callCtrlResult = call_ctrl_result;
756                 disp_len = strlen(text); /* alpha id */
757                 if (disp_len > 1) {
758                         call_ctrl_result_ind.dispData.stringLen = disp_len;
759                         memcpy(&call_ctrl_result_ind.dispData.string, text, disp_len);
760                         call_ctrl_result_ind.bIsUserInfoDisplayEnabled = 1;
761                 }
762                 g_free(text);
763
764                 if (strlen(call_num) > 1 && (g_strcmp0(call_num, "") != 0)) {
765                         /* Call number exist */
766                         call_ctrl_result_ind.callCtrlCnfType = TAPI_SAT_CALL_TYPE_MO_VOICE;
767                         call_ctrl_result_ind.u.callCtrlCnfCallData.address.stringLen = strlen(call_num);
768                         memcpy(&call_ctrl_result_ind.u.callCtrlCnfCallData.address.string, call_num, strlen(call_num));
769                         call_ctrl_result_ind.u.callCtrlCnfCallData.subAddress.stringLen = strlen(sub_addr);
770                         memcpy(&call_ctrl_result_ind.u.callCtrlCnfCallData.subAddress.string, sub_addr, strlen(sub_addr));
771                         call_ctrl_result_ind.u.callCtrlCnfCallData.ccp1.stringLen = strlen(ccp1);
772                         memcpy(&call_ctrl_result_ind.u.callCtrlCnfCallData.ccp1.string, ccp1, strlen(ccp1));
773                         call_ctrl_result_ind.u.callCtrlCnfCallData.ccp1.stringLen = strlen(ccp2);
774                         memcpy(&call_ctrl_result_ind.u.callCtrlCnfCallData.ccp1.string, ccp2, strlen(ccp2));
775                         call_ctrl_result_ind.u.callCtrlCnfCallData.bcRepeatIndicator = bc_repeat_indicator;
776                 } else if (strlen(ss_string) > 1 && (g_strcmp0(ss_string, "") != 0)) {
777                         /* SS string exist */
778                         call_ctrl_result_ind.callCtrlCnfType = TAPI_SAT_CALL_TYPE_SS;
779                         call_ctrl_result_ind.u.callCtrlCnfSsData.ssString.stringLen = strlen(ss_string);
780                         memcpy(&call_ctrl_result_ind.u.callCtrlCnfSsData.ssString.string, ss_string, strlen(ss_string));
781                         call_ctrl_result_ind.u.callCtrlCnfSsData.subAddress.stringLen = strlen(sub_addr);
782                         memcpy(&call_ctrl_result_ind.u.callCtrlCnfSsData.subAddress.string, sub_addr, strlen(sub_addr));
783                         call_ctrl_result_ind.u.callCtrlCnfSsData.ccp1.stringLen = strlen(ccp1);
784                         memcpy(&call_ctrl_result_ind.u.callCtrlCnfSsData.ccp1.string, ccp1, strlen(ccp1));
785                         call_ctrl_result_ind.u.callCtrlCnfSsData.ccp1.stringLen = strlen(ccp2);
786                         memcpy(&call_ctrl_result_ind.u.callCtrlCnfSsData.ccp1.string, ccp2, strlen(ccp2));
787                         call_ctrl_result_ind.u.callCtrlCnfSsData.bcRepeatIndicator = bc_repeat_indicator;
788                 } else {
789                         dbg("not matched call control");
790                         goto EXIT;
791                 }
792
793                 TAPI_INVOKE_NOTI_CALLBACK(&call_ctrl_result_ind);
794
795 EXIT:
796                 g_free(call_num);
797                 g_free(sub_addr);
798                 g_free(ccp1);
799                 g_free(ccp2);
800                 g_free(ss_string);
801         } else if (!g_strcmp0(sig, "MoSmControlResult")) {
802                 TelSatMoSmCtrlIndData_t mo_sm_ctrl_result_ind;
803                 gint call_ctrl_result = 0 , disp_len = 0;
804                 gint rp_dst_ton = 0x0F, rp_dst_npi = 0X0F, tp_dst_ton = 0x0F, tp_dst_npi = 0X0F;
805                 gchar *text = NULL, *rp_dst_call_num = NULL, *tp_dst_call_num = NULL;
806
807                 memset(&mo_sm_ctrl_result_ind, 0x00, sizeof(TelSatMoSmCtrlIndData_t));
808
809                 g_variant_get(param, "(isiisiis)", &call_ctrl_result, &text,
810                         &rp_dst_ton, &rp_dst_npi, &rp_dst_call_num, &tp_dst_ton, &tp_dst_npi, &tp_dst_call_num);
811
812                 mo_sm_ctrl_result_ind.moSmsCtrlResult = call_ctrl_result;
813                 disp_len = strlen(text); /* alpha id */
814                 if (disp_len > 1) {
815                         mo_sm_ctrl_result_ind.dispData.stringLen = disp_len;
816                         memcpy(&mo_sm_ctrl_result_ind.dispData.string, text, disp_len);
817                         mo_sm_ctrl_result_ind.bIsUserInfoDisplayEnabled = 1;
818                 }
819
820                 if (strlen(rp_dst_call_num) > 1 && (g_strcmp0(rp_dst_call_num, "") != 0)) {
821                         /* RP DST Call number exist */
822                         mo_sm_ctrl_result_ind.tpDestAddr.bIsDigitOnly = 1;
823                         mo_sm_ctrl_result_ind.rpDestAddr.stringLen = strlen(rp_dst_call_num);
824                         memcpy(&mo_sm_ctrl_result_ind.rpDestAddr.string, rp_dst_call_num, strlen(rp_dst_call_num));
825                 } else if (strlen(tp_dst_call_num) > 1 && (g_strcmp0(tp_dst_call_num, "") != 0)) {
826                         /* TP DST Call number exist */
827                         mo_sm_ctrl_result_ind.tpDestAddr.bIsDigitOnly = 1;
828                         mo_sm_ctrl_result_ind.tpDestAddr.stringLen = strlen(tp_dst_call_num);
829                         memcpy(&mo_sm_ctrl_result_ind.tpDestAddr.string, tp_dst_call_num, strlen(tp_dst_call_num));
830                 } else {
831                         dbg("Any destination address are not provided, use default one.");
832                 }
833                 g_free(text);
834                 g_free(rp_dst_call_num);
835                 g_free(tp_dst_call_num);
836
837                 TAPI_INVOKE_NOTI_CALLBACK(&mo_sm_ctrl_result_ind);
838         } else if (!g_strcmp0(sig, "SetupCall")) {
839                 TelSatSetupCallIndCallData_t setup_call_data;
840                 gint command_type = 0, confirm_text_len = 0;
841                 gint text_len = 0, call_type = 0, duration = 0;
842                 gchar *confirm_text = NULL, *text = NULL, *call_number = NULL;
843
844                 dbg("setupcall event");
845                 memset(&setup_call_data, 0x00, sizeof(TelSatSetupCallIndCallData_t));
846
847                 g_variant_get(param, "(isisiisi)", &command_type, &confirm_text,
848                         &confirm_text_len, &text, &text_len, &call_type, &call_number, &duration);
849
850
851                 setup_call_data.commandId = command_type;
852                 setup_call_data.calltype = call_type;
853                 memcpy(&setup_call_data.dispText.string, text, strlen(text));
854                 setup_call_data.dispText.stringLen = text_len;
855                 memcpy(&setup_call_data.callNumber.string, call_number, strlen(call_number));
856                 setup_call_data.callNumber.stringLen = strlen(call_number); /* Number length */
857                 setup_call_data.duration = duration;
858
859                 g_free(confirm_text);
860                 g_free(text);
861                 g_free(call_number);
862
863                 TAPI_INVOKE_NOTI_CALLBACK(&setup_call_data);
864         } else {
865                 dbg("not handled Sat noti[%s]", sig);
866         }
867 }
868
869 static void _process_sim_event(const gchar *sig, GVariant *param,
870         TapiHandle *handle, char *noti_id, struct tapi_evt_cb *evt_cb_data)
871 {
872         TAPI_RETURN_IF_FAIL(evt_cb_data);
873
874         if (!g_strcmp0(sig, "Status")) {
875                 int status = 0;
876                 g_variant_get(param, "(i)", &status);
877                 TAPI_INVOKE_NOTI_CALLBACK(&status);
878         } else if (!g_strcmp0(sig, "Refreshed")) {
879                 int type = 0;
880                 g_variant_get(param, "(i)", &type);
881                 TAPI_INVOKE_NOTI_CALLBACK(&type);
882         } else {
883                 dbg("not handled SIM noti[%s]", sig);
884         }
885 }
886
887 static void _process_pb_event(const gchar *sig, GVariant *param,
888         TapiHandle *handle, char *noti_id, struct tapi_evt_cb *evt_cb_data)
889 {
890         TAPI_RETURN_IF_FAIL(evt_cb_data);
891
892         if (!g_strcmp0(sig, "Status")) {
893                 TelSimPbStatus_t status;
894                 g_variant_get(param, "(ibbbbbb)",
895                         &status.init_completed,
896                         &status.pb_list.b_fdn,
897                         &status.pb_list.b_adn,
898                         &status.pb_list.b_sdn,
899                         &status.pb_list.b_3g,
900                         &status.pb_list.b_aas,
901                         &status.pb_list.b_gas);
902
903                 msg("(%s) init[%d] fdn[%d] adn[%d] sdn[%d] usim[%d] aas[%d] gas[%d]",
904                         handle->cp_name, status.init_completed, status.pb_list.b_fdn, status.pb_list.b_adn, status.pb_list.b_sdn, status.pb_list.b_3g, status.pb_list.b_aas, status.pb_list.b_gas);
905                 TAPI_INVOKE_NOTI_CALLBACK(&status);
906         } else if (!g_strcmp0(sig, "ContactChange")) {
907                 TelSimPbContactChangeInfo_t ContactChange;
908                 g_variant_get(param, "(iqi)",
909                         &ContactChange.pb_type,
910                         &ContactChange.index,
911                         &ContactChange.operation);
912
913                 msg("(%s) type[%d] index[%d] operation[%d]",
914                         handle->cp_name, ContactChange.pb_type, ContactChange.index, ContactChange.operation);
915                 TAPI_INVOKE_NOTI_CALLBACK(&ContactChange);
916         } else {
917                 dbg("not handled Phonebook noti[%s]", sig);
918         }
919 }
920
921 static void _process_sap_event(const gchar *sig, GVariant *param,
922         TapiHandle *handle, char *noti_id, struct tapi_evt_cb *evt_cb_data)
923 {
924         TAPI_RETURN_IF_FAIL(evt_cb_data);
925
926         if (!g_strcmp0(sig, "Status")) {
927                 int noti = 0;
928                 g_variant_get(param, "(i)", &noti);
929                 TAPI_INVOKE_NOTI_CALLBACK(&noti);
930         } else if (!g_strcmp0(sig, "Disconnect")) {
931                 int disconnect = 0;
932                 g_variant_get(param, "(i)", &disconnect);
933                 TAPI_INVOKE_NOTI_CALLBACK(&disconnect);
934         } else {
935                 dbg("not handled SAP noti[%s]", sig);
936         }
937 }
938
939 static void _process_modem_event(const gchar *sig, GVariant *param,
940         TapiHandle *handle, char *noti_id, struct tapi_evt_cb *evt_cb_data)
941 {
942         TAPI_RETURN_IF_FAIL(evt_cb_data);
943
944         if (!g_strcmp0(sig, "Power")) {
945                 int noti = 0;
946
947                 g_variant_get(param, "(i)", &noti);
948
949                 TAPI_INVOKE_NOTI_CALLBACK(&noti);
950         } else {
951                 dbg("not handled Modem noti[%s]", sig);
952         }
953
954         return;
955 }
956
957 static void _process_ss_event(const gchar *sig, GVariant *param,
958         TapiHandle *handle, char *noti_id, struct tapi_evt_cb *evt_cb_data)
959 {
960         GVariant *value = 0;
961         GVariantIter *iter = 0;
962         GVariantIter *iter_row = 0;
963         const gchar *key = 0;
964         int i = 0;
965
966         TAPI_RETURN_IF_FAIL(evt_cb_data);
967
968         if (!g_strcmp0(sig, "NotifyUSSD")) {
969                 TelSsUssdMsgInfo_t noti;
970                 char *str = NULL;
971                 memset(&noti, 0, sizeof(TelSsUssdMsgInfo_t));
972
973                 g_variant_get(param, "(iiis)", &noti.Type, &noti.Dcs, &noti.Length, &str);
974
975                 if (str) {
976                         g_strlcpy((char *)noti.szString, str, TAPI_SS_USSD_DATA_SIZE_MAX);
977                         g_free(str);
978                 }
979
980                 TAPI_INVOKE_NOTI_CALLBACK(&noti);
981         } else if (!g_strcmp0(sig, "NotifySsInfo")) {
982                 TelSsInfo_t noti;
983                 memset(&noti, 0, sizeof(TelSsInfo_t));
984
985                 g_variant_get(param, "(ii)", &noti.Cause, &noti.SsType);
986
987                 TAPI_INVOKE_NOTI_CALLBACK(&noti);
988         } else if (!g_strcmp0(sig, "ReleaseComplete")) {
989                 TelSsRelCompMsgInfo_t noti;
990                 GVariant *msg = 0;
991                 int len = 0;
992
993                 memset(&noti, 0, sizeof(TelSsRelCompMsgInfo_t));
994
995                 g_variant_get(param, "(i@v)", &len, &msg);
996
997                 noti.RelCompMsgLen = (unsigned char)len;
998
999                 if (msg) {
1000                         int count = 0;
1001                         guchar data;
1002                         GVariantIter *msg_iter = NULL;
1003                         GVariant *inner_gv = NULL;
1004
1005                         inner_gv = g_variant_get_variant(msg);
1006                         msg("[ check ] data exist type_format(%s)", g_variant_get_type_string(inner_gv));
1007
1008                         g_variant_get(inner_gv, "ay", &msg_iter);
1009                         while (g_variant_iter_loop(msg_iter, "y", &data)) {
1010                                 msg("index(%d) data(%c)", count, data);
1011                                 noti.szRelCompMsg[count] = data;
1012                                 count++;
1013                         }
1014                         g_variant_iter_free(msg_iter);
1015                         g_variant_unref(msg);
1016                         g_variant_unref(inner_gv);
1017                 }
1018
1019                 TAPI_INVOKE_NOTI_CALLBACK(&noti);
1020         } else if (!g_strcmp0(sig, "NotifyForwarding")) {
1021                 TelSsForwardNoti_t noti;
1022                 memset(&noti, 0, sizeof(TelSsForwardNoti_t));
1023
1024                 g_variant_get(param, "(aa{sv})", &iter);
1025
1026                 noti.record_num = g_variant_iter_n_children(iter);
1027
1028                 if (TAPI_SS_RECORD_NUM_MAX < noti.record_num)
1029                         noti.record_num = TAPI_SS_RECORD_NUM_MAX;
1030
1031                 while (g_variant_iter_next(iter, "a{sv}", &iter_row) && (i < noti.record_num)) {
1032                         while (g_variant_iter_loop(iter_row, "{sv}", &key, &value)) {
1033                                 if (!g_strcmp0(key, "ss_class"))
1034                                         noti.record[i].Class = g_variant_get_int32(value);
1035                                 else if (!g_strcmp0(key, "ss_status"))
1036                                         noti.record[i].Status = g_variant_get_int32(value);
1037                                 else if (!g_strcmp0(key, "forwarding_mode"))
1038                                         noti.record[i].ForwardCondition = g_variant_get_int32(value);
1039                                 else  if (!g_strcmp0(key, "number_present"))
1040                                         noti.record[i].bCallForwardingNumberPresent = g_variant_get_int32(value);
1041                                 else if (!g_strcmp0(key, "no_reply_time"))
1042                                         noti.record[i].NoReplyWaitTime = g_variant_get_int32(value);
1043                                 else if (!g_strcmp0(key, "type_of_number"))
1044                                         noti.record[i].Ton = g_variant_get_int32(value);
1045                                 else if (!g_strcmp0(key, "numbering_plan_identity"))
1046                                         noti.record[i].Npi = g_variant_get_int32(value);
1047                                 else if (!g_strcmp0(key, "forwarding_number"))
1048                                         strncpy((char *)noti.record[i].szCallForwardingNumber,
1049                                                 g_variant_get_string(value, 0), TAPI_CALL_DIALDIGIT_LEN_MAX);
1050                         }
1051                         i++;
1052                         g_variant_iter_free(iter_row);
1053                 }
1054                 g_variant_iter_free(iter);
1055
1056                 TAPI_INVOKE_NOTI_CALLBACK(&noti);
1057
1058         } else if (!g_strcmp0(sig, "NotifyWaiting")) {
1059
1060                 TelSsWaitingNoti_t noti;
1061                 memset(&noti, '\0', sizeof(TelSsWaitingNoti_t));
1062
1063                 g_variant_get(param, "(aa{sv})", &iter);
1064
1065                 noti.record_num = g_variant_iter_n_children(iter);
1066
1067                 if (TAPI_SS_RECORD_NUM_MAX < noti.record_num)
1068                         noti.record_num = TAPI_SS_RECORD_NUM_MAX;
1069
1070                 while (g_variant_iter_next(iter, "a{sv}", &iter_row) && (i < noti.record_num)) {
1071                         while (g_variant_iter_loop(iter_row, "{sv}", &key, &value)) {
1072
1073                                 if (!g_strcmp0(key, "ss_class"))
1074                                         noti.record[i].Class = g_variant_get_int32(value);
1075                                 else if (!g_strcmp0(key, "ss_status"))
1076                                         noti.record[i].Status = g_variant_get_int32(value);
1077                         }
1078                         i++;
1079                         g_variant_iter_free(iter_row);
1080                 }
1081                 g_variant_iter_free(iter);
1082
1083                 TAPI_INVOKE_NOTI_CALLBACK(&noti);
1084
1085         } else if (!g_strcmp0(sig, "NotifyBarring")) {
1086                 TelSsBarringNoti_t noti;
1087                 memset(&noti, '\0', sizeof(TelSsBarringNoti_t));
1088
1089                 g_variant_get(param, "(aa{sv})", &iter);
1090
1091                 noti.record_num = g_variant_iter_n_children(iter);
1092
1093                 if (TAPI_SS_RECORD_NUM_MAX < noti.record_num)
1094                         noti.record_num = TAPI_SS_RECORD_NUM_MAX;
1095
1096                 while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
1097                         while (g_variant_iter_loop(iter_row, "{sv}", &key, &value) && (i < noti.record_num)) {
1098                                 if (!g_strcmp0(key, "ss_class"))
1099                                         noti.record[i].Class = g_variant_get_int32(value);
1100                                 else if (!g_strcmp0(key, "ss_status"))
1101                                         noti.record[i].Status = g_variant_get_int32(value);
1102                                 else if (!g_strcmp0(key, "barring_mode"))
1103                                         noti.record[i].Flavour = g_variant_get_int32(value);
1104                         }
1105                         i++;
1106                         g_variant_iter_free(iter_row);
1107                 }
1108                 g_variant_iter_free(iter);
1109
1110                 TAPI_INVOKE_NOTI_CALLBACK(&noti);
1111
1112         } else {
1113                 dbg("not handled SS noti[%s]", sig);
1114         }
1115
1116         return;
1117 }
1118
1119 static void _process_oem_event(const gchar *sig, GVariant *param,
1120         TapiHandle *handle, char *noti_id, struct tapi_evt_cb *evt_cb_data)
1121 {
1122         TAPI_RETURN_IF_FAIL(evt_cb_data);
1123
1124         if (!g_strcmp0(sig, "OemData")) {
1125                 TelOemNotiData_t oem_data = {0};
1126                 gchar *data = NULL;
1127
1128                 g_variant_get(param, "(is)", &oem_data.oem_id, &data);
1129                 oem_data.data = g_base64_decode((const gchar *)data, (gsize *)&oem_data.data_len);
1130                 if (oem_data.data) {
1131                         msg("[%s] id:[%d] len:[%d]", handle->cp_name, oem_data.oem_id, oem_data.data_len);
1132                         TAPI_INVOKE_NOTI_CALLBACK(&oem_data);
1133
1134                         g_free(oem_data.data);
1135                 }
1136
1137                 g_free(data);
1138         }
1139 }
1140
1141 static void on_prop_callback(GDBusConnection *conn, const gchar *name, const gchar *path, const gchar *interface,
1142                 const gchar *sig, GVariant *param, gpointer user_data)
1143 {
1144         TapiHandle *handle = user_data;
1145         struct tapi_evt_cb *evt_cb_data = NULL;
1146         const gchar *interface_name_for_signal;
1147         GVariant *changed_properties = NULL;
1148         gchar **invalidated_properties = NULL;
1149         GVariantIter iter;
1150         gchar *key;
1151         GVariant *value;
1152         gchar *prev_value;
1153         char noti_id[256];
1154         char *data;
1155
1156         TAPI_RETURN_IF_FAIL(handle);
1157
1158         if (!g_variant_is_of_type(param, G_VARIANT_TYPE("(sa{sv}as)"))) {
1159                 err("PropertiesChanged parameter type mismatch ('%s')", g_variant_get_type_string(param));
1160                 return;
1161         }
1162
1163         g_variant_get(param, "(&s@a{sv}^a&s)", &interface_name_for_signal,
1164                         &changed_properties, &invalidated_properties);
1165
1166         if (!changed_properties) {
1167                 err("Cannot get changed_properties");
1168                 goto fail;
1169         }
1170
1171         g_variant_iter_init(&iter, changed_properties);
1172         while (g_variant_iter_next(&iter, "{sv}", &key, &value)) {
1173                 memset(noti_id, 0, 256);
1174                 snprintf(noti_id, 255, "%s:%s", interface_name_for_signal, key);
1175
1176                 evt_cb_data = g_hash_table_lookup(handle->evt_list, noti_id);
1177                 if (!evt_cb_data) {
1178                         g_variant_unref(value);
1179                         g_free((gchar *)key);
1180                         /* ignore un-registered property change callback */
1181                         continue;
1182
1183                 }
1184
1185                 if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1186                         data = g_try_malloc0(g_variant_get_size(value) + 3);
1187                         if (!data) {
1188                                 warn("g_try_malloc0 failed");
1189                                 g_variant_unref(value);
1190                                 g_free((gchar *)key);
1191                                 continue;
1192                         }
1193                         data[0] = 's';
1194                         data[1] = ':';
1195                         memcpy(data + 2, g_variant_get_data(value),
1196                                         g_variant_get_size(value));
1197                 } else if (g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
1198                         data = g_strdup_printf("b:%d",
1199                                         *(guchar *) g_variant_get_data(value));
1200                 } else {
1201                         data = g_strdup_printf("i:%d", *(int *) g_variant_get_data(value));
1202                 }
1203
1204                 prev_value = g_hash_table_lookup(handle->cache_property, noti_id);
1205                 if (prev_value) {
1206                         if (g_strcmp0(data, prev_value) == 0) {
1207                                 g_free(data);
1208                                 g_variant_unref(value);
1209                                 g_free((gchar *)key);
1210                                 continue;
1211                         }
1212                 }
1213
1214                 msg("[%s] save prop: [%s] - [%s]", handle->cp_name, noti_id, data);
1215                 g_hash_table_replace(handle->cache_property, g_strdup(noti_id), data);
1216
1217                 {
1218                         int param_i = 0;
1219                         if (data[0] == 's') {
1220                                 TAPI_INVOKE_NOTI_CALLBACK((void *) (data + 2));
1221                         } else {
1222                                 param_i = atoi(data + 2);
1223                                 TAPI_INVOKE_NOTI_CALLBACK((void *)&param_i);
1224                         }
1225                 }
1226                 g_variant_unref(value);
1227                 g_free((gchar *)key);
1228         }
1229
1230         if (changed_properties != NULL)
1231                 g_variant_unref(changed_properties);
1232
1233 fail:
1234         if (invalidated_properties)
1235                 g_free(invalidated_properties);
1236 }
1237
1238 static void on_signal_callback(GDBusConnection *conn,
1239         const gchar *name, const gchar *path, const gchar *interface,
1240         const gchar *sig, GVariant *param, gpointer user_data)
1241 {
1242         TapiHandle *handle = user_data;
1243         struct tapi_evt_cb *evt_cb_data = NULL;
1244         char *noti_id;
1245
1246         TAPI_RETURN_IF_FAIL(handle);
1247
1248         noti_id = g_strdup_printf("%s:%s", interface, sig);
1249
1250         evt_cb_data = g_hash_table_lookup(handle->evt_list, noti_id);
1251         if (!evt_cb_data) {
1252                 dbg("can't find noti_id(%s) callback info", noti_id);
1253                 g_free(noti_id);
1254                 return;
1255         }
1256
1257         if (!g_strcmp0(interface, DBUS_TELEPHONY_SMS_INTERFACE))
1258                 _process_sms_event(sig, param, handle, noti_id, evt_cb_data);
1259         else if (!g_strcmp0(interface, DBUS_TELEPHONY_CALL_INTERFACE))
1260                 _process_call_event(sig, param, handle, noti_id, evt_cb_data);
1261         else if (!g_strcmp0(interface, DBUS_TELEPHONY_SAT_INTERFACE))
1262                 _process_sat_event(sig, param, handle, noti_id, evt_cb_data);
1263         else if (!g_strcmp0(interface, DBUS_TELEPHONY_SIM_INTERFACE))
1264                 _process_sim_event(sig, param, handle, noti_id, evt_cb_data);
1265         else if (!g_strcmp0(interface, DBUS_TELEPHONY_PB_INTERFACE))
1266                 _process_pb_event(sig, param, handle, noti_id, evt_cb_data);
1267         else if (!g_strcmp0(interface, DBUS_TELEPHONY_SAP_INTERFACE))
1268                 _process_sap_event(sig, param, handle, noti_id, evt_cb_data);
1269         else if (!g_strcmp0(interface, DBUS_TELEPHONY_MODEM_INTERFACE))
1270                 _process_modem_event(sig, param, handle, noti_id, evt_cb_data);
1271         else if (!g_strcmp0(interface, DBUS_TELEPHONY_SS_INTERFACE))
1272                 _process_ss_event(sig, param, handle, noti_id, evt_cb_data);
1273         else if (!g_strcmp0(interface, DBUS_TELEPHONY_NETWORK_INTERFACE))
1274                 _process_network_event(sig, param, handle, noti_id, evt_cb_data);
1275         else if (!g_strcmp0(interface, DBUS_TELEPHONY_OEM_INTERFACE))
1276                 _process_oem_event(sig, param, handle, noti_id, evt_cb_data);
1277
1278         g_free(noti_id);
1279 }
1280
1281 EXPORT_API char **tel_get_cp_name_list(void)
1282 {
1283         gpointer d_conn = NULL;
1284         GError *error = NULL;
1285
1286         GVariantIter *iter = NULL;
1287         GVariant *rst = NULL;
1288
1289         gchar *modem_path = NULL;
1290         GSList *list = NULL;
1291         GSList *l = NULL;
1292
1293         int i = 0, element_cnt = 0;
1294         gchar **cp_list = NULL;
1295
1296         d_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1297         if (!d_conn) {
1298                 err("Error creating dbus connection: %s\n", error->message);
1299                 g_error_free(error);
1300                 return NULL;
1301         }
1302
1303         rst = g_dbus_connection_call_sync(d_conn, DBUS_TELEPHONY_SERVICE , "/org/tizen/telephony",
1304                         "org.tizen.telephony.Manager", "GetModems", NULL, NULL,
1305                         G_DBUS_CALL_FLAGS_NONE, TAPI_DEFAULT_TIMEOUT, NULL, &error);
1306         if (!rst) {
1307                 err("GetModems() failed. (%s)", error->message);
1308                 g_error_free(error);
1309                 goto OUT;
1310         }
1311
1312         g_variant_get(rst, "(as)", &iter);
1313         while (g_variant_iter_next(iter, "s", &modem_path))
1314                 list = g_slist_append(list, modem_path);
1315         g_variant_iter_free(iter);
1316
1317         if (!list) {
1318                 err("No CP name");
1319                 goto OUT;
1320         }
1321
1322         element_cnt = g_slist_length(list);
1323         cp_list = g_new0(char *, element_cnt + 1);
1324         if (!cp_list)
1325                 goto OUT;
1326
1327         for (l = list; l; l = l->next, i++) {
1328                 cp_list[i] = g_strdup(l->data);
1329                 g_free(l->data);
1330
1331                 dbg("cp name[%d] = %s", i, cp_list[i]);
1332         }
1333         cp_list[element_cnt] = NULL;
1334
1335         g_slist_free(list);
1336
1337 OUT:
1338         if (d_conn)
1339                 g_object_unref(d_conn);
1340
1341         if (rst)
1342                 g_variant_unref(rst);
1343
1344         return cp_list;
1345 }
1346
1347 static char *get_property(TapiHandle *handle, const char *property,
1348         const GVariantType *type)
1349 {
1350         char **dbus_info;
1351         GVariant *value = NULL;
1352         GVariant *value_container = NULL;
1353         GError *error = NULL;
1354         char *data = NULL;
1355
1356         dbus_info = g_strsplit(property, ":", 2);
1357         if (!dbus_info) {
1358                 dbg("invalid property");
1359                 return NULL ;
1360         }
1361
1362         if (!dbus_info[0] || !dbus_info[1]) {
1363                 dbg("invalid property");
1364                 goto OUT;
1365         }
1366
1367         value_container = g_dbus_connection_call_sync(handle->dbus_connection,
1368                         DBUS_TELEPHONY_SERVICE, handle->path,
1369                         "org.freedesktop.DBus.Properties", "Get",
1370                         g_variant_new("(ss)", dbus_info[0], dbus_info[1]),
1371                         G_VARIANT_TYPE("(v)"), G_DBUS_CALL_FLAGS_NONE,
1372                         TAPI_DEFAULT_TIMEOUT, handle->ca, &error);
1373
1374         if (error) {
1375                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
1376                         warn("Access Denied");
1377                         g_error_free(error);
1378                         return g_strdup("AccessDenied");
1379                 } else {
1380                         warn("dbus error = %d (%s)", error->code, error->message);
1381                         g_error_free(error);
1382                 }
1383         }
1384
1385         if (!value_container)
1386                 return NULL ;
1387
1388         g_variant_get(value_container, "(v)", &value);
1389         g_variant_unref(value_container);
1390
1391         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1392                 data = g_try_malloc0(g_variant_get_size(value));
1393                 if (!data) {
1394                         warn("calloc failed");
1395                         g_variant_unref(value);
1396                         goto OUT;
1397                 }
1398                 memcpy(data, g_variant_get_data(value), g_variant_get_size(value));
1399         } else if (g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
1400                 data = g_strdup_printf("%d", *(guchar *) g_variant_get_data(value));
1401         } else {
1402                 data = g_strdup_printf("%d", *(int *) g_variant_get_data(value));
1403         }
1404         msg("prop:[%s][%s] - [%s]", handle->cp_name, dbus_info[1], data);
1405
1406         g_variant_unref(value);
1407
1408 OUT:
1409         g_strfreev(dbus_info);
1410
1411         return data;
1412 }
1413
1414 EXPORT_API int tel_get_property_int (TapiHandle *handle,
1415         const char *property, int *result)
1416 {
1417         char *data;
1418
1419         TAPI_RET_ERR_NUM_IF_FAIL(handle, TAPI_API_INVALID_INPUT);
1420         TAPI_RET_ERR_NUM_IF_FAIL(property, TAPI_API_INVALID_INPUT);
1421         TAPI_RET_ERR_NUM_IF_FAIL(result, TAPI_API_INVALID_INPUT);
1422
1423         data = get_property(handle, property, G_VARIANT_TYPE_INT32);
1424         if (!data)
1425                 return TAPI_API_OPERATION_FAILED;
1426         else if (!g_strcmp0(data, "AccessDenied"))
1427                 return TAPI_API_ACCESS_DENIED;
1428
1429         *result = atoi(data);
1430
1431         g_free(data);
1432
1433         return TAPI_API_SUCCESS;
1434 }
1435
1436 EXPORT_API int tel_get_property_string(TapiHandle *handle, const char *property, char **result)
1437 {
1438         char *data;
1439
1440         TAPI_RET_ERR_NUM_IF_FAIL(handle, TAPI_API_INVALID_INPUT);
1441         TAPI_RET_ERR_NUM_IF_FAIL(property, TAPI_API_INVALID_INPUT);
1442         TAPI_RET_ERR_NUM_IF_FAIL(result, TAPI_API_INVALID_INPUT);
1443
1444         data = get_property(handle, property, G_VARIANT_TYPE_STRING);
1445         if (!data)
1446                 return TAPI_API_OPERATION_FAILED;
1447         else if (!g_strcmp0(data, "AccessDenied"))
1448                 return TAPI_API_ACCESS_DENIED;
1449
1450         *result = data;
1451
1452         return TAPI_API_SUCCESS;
1453 }
1454
1455 EXPORT_API TapiHandle *tel_init(const char *cp_name)
1456 {
1457         GError *error = NULL;
1458         struct tapi_handle *handle;
1459
1460 #if !GLIB_CHECK_VERSION(2, 35, 0)
1461         g_type_init();
1462 #endif
1463
1464         handle = g_new0(struct tapi_handle, 1);
1465         if (!handle)
1466                 return NULL;
1467
1468         handle->dbus_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1469         if (!handle->dbus_connection) {
1470                 err("Error creating dbus connection: %s\n", error->message);
1471                 g_free(handle);
1472                 g_error_free(error);
1473                 return NULL;
1474         }
1475
1476         msg("tel_init: [%s]:[%s]:[%s]",
1477                 g_dbus_connection_get_unique_name(handle->dbus_connection),
1478                 program_invocation_name, cp_name ? cp_name : "NULL");
1479
1480         handle->ca = g_cancellable_new();
1481
1482         if (cp_name) {
1483                 handle->cp_name = g_strdup(cp_name);
1484         } else {
1485                 char **list = NULL;
1486                 int i = 0;
1487
1488                 list = tel_get_cp_name_list();
1489                 if (!list) {
1490                         g_cancellable_cancel(handle->ca);
1491                         g_object_unref(handle->ca);
1492                         g_object_unref(handle->dbus_connection);
1493                         g_free(handle);
1494                         return NULL;
1495                 }
1496
1497                 if (!list[0]) {
1498                         g_cancellable_cancel(handle->ca);
1499                         g_object_unref(handle->ca);
1500                         g_object_unref(handle->dbus_connection);
1501                         g_free(handle);
1502                         g_free(list);
1503                         return NULL;
1504                 }
1505
1506                 handle->cp_name = g_strdup(list[0]);
1507
1508                 /* Free the list of CP names */
1509                 while (list[i] != NULL)
1510                         g_free(list[i++]);
1511
1512                 g_free(list);
1513         }
1514
1515         handle->evt_list = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
1516         handle->cache_property = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
1517
1518         handle->path = g_strdup_printf("%s/%s",
1519                 DBUS_TELEPHONY_DEFAULT_PATH, handle->cp_name);
1520
1521         return handle;
1522 }
1523
1524 static gboolean _unregister_noti(gpointer key, gpointer value, gpointer user_data)
1525 {
1526         struct tapi_evt_cb *evt_cb_data = value;
1527         TapiHandle *handle = user_data;
1528
1529         g_dbus_connection_signal_unsubscribe(handle->dbus_connection, evt_cb_data->evt_id);
1530
1531         return TRUE;
1532 }
1533
1534 EXPORT_API int tel_deinit(TapiHandle *handle)
1535 {
1536         TAPI_RET_ERR_NUM_IF_FAIL(handle, TAPI_API_INVALID_INPUT);
1537
1538         msg("tel_deinit: [%s]", handle->cp_name);
1539
1540         if (handle->cp_name)
1541                 g_free(handle->cp_name);
1542
1543         if (handle->path)
1544                 g_free(handle->path);
1545
1546         g_dbus_connection_signal_unsubscribe(handle->dbus_connection, handle->prop_callback_evt_id);
1547         g_hash_table_foreach_remove(handle->evt_list, _unregister_noti, handle);
1548         g_hash_table_destroy(handle->evt_list);
1549         g_hash_table_destroy(handle->cache_property);
1550
1551         g_cancellable_cancel(handle->ca);
1552         g_object_unref(handle->ca);
1553
1554         g_object_unref(handle->dbus_connection);
1555
1556         memset(handle, 0, sizeof(struct tapi_handle));
1557         g_free(handle);
1558
1559         msg("tel_deinit done");
1560
1561         return TAPI_API_SUCCESS;
1562 }
1563
1564 EXPORT_API int tel_register_noti_event(TapiHandle *handle, const char *noti_id,
1565         tapi_notification_cb callback, void *user_data)
1566 {
1567         gchar **dbus_str = NULL;
1568         gpointer tmp = NULL;
1569         struct tapi_evt_cb *evt_cb_data = NULL;
1570
1571         TAPI_RET_ERR_NUM_IF_FAIL(handle, TAPI_API_INVALID_INPUT);
1572         TAPI_RET_ERR_NUM_IF_FAIL(handle->dbus_connection, TAPI_API_INVALID_INPUT);
1573         TAPI_RET_ERR_NUM_IF_FAIL(callback, TAPI_API_INVALID_INPUT);
1574         TAPI_RET_ERR_NUM_IF_FAIL(noti_id, TAPI_API_INVALID_INPUT);
1575
1576         tmp = g_hash_table_lookup(handle->evt_list, noti_id);
1577         if (tmp != NULL) {
1578                 dbg("[%s] noti_id(%s) is already registered", handle->cp_name, noti_id);
1579                 return TAPI_API_INVALID_INPUT;
1580         }
1581
1582         dbus_str = g_strsplit(noti_id, ":", 2);
1583         if (!dbus_str) {
1584                 err("[%s] invalid noti_id", handle->cp_name);
1585                 return TAPI_API_INVALID_INPUT;
1586         }
1587
1588         if (!dbus_str[0] || !dbus_str[1]) {
1589                 g_strfreev(dbus_str);
1590                 err("[%s] invalid noti_id", handle->cp_name);
1591                 return TAPI_API_INVALID_INPUT;
1592         }
1593
1594         evt_cb_data = g_new0(struct tapi_evt_cb, 1);
1595         evt_cb_data->cb_fn = callback;
1596         evt_cb_data->user_data = user_data;
1597
1598         dbg("[%s] signal (%s)", handle->cp_name, dbus_str[1]);
1599
1600         if (dbus_str[1][0] >= 'a' && dbus_str[1][0] <= 'z') {
1601                 /* Property change callback - only one time */
1602                 if (handle->prop_callback_evt_id == 0) {
1603                         handle->prop_callback_evt_id = g_dbus_connection_signal_subscribe(handle->dbus_connection,
1604                                 DBUS_TELEPHONY_SERVICE, /* Sender */
1605                                 "org.freedesktop.DBus.Properties", /* Interface */
1606                                 "PropertiesChanged", /* Member */
1607                                 handle->path, /* Object path */
1608                                 NULL, /* arg0 */
1609                                 G_DBUS_SIGNAL_FLAGS_NONE, on_prop_callback, handle, NULL);
1610                 }
1611         } else {
1612                 /* Signal callback */
1613                 evt_cb_data->evt_id = g_dbus_connection_signal_subscribe(handle->dbus_connection,
1614                                 DBUS_TELEPHONY_SERVICE, /* Sender */
1615                                 dbus_str[0], /* Interface */
1616                                 dbus_str[1], /* Member */
1617                                 handle->path, /* Object path */
1618                                 NULL, /* arg0 */
1619                                 G_DBUS_SIGNAL_FLAGS_NONE, on_signal_callback, handle, NULL);
1620
1621         }
1622
1623         g_hash_table_insert(handle->evt_list, g_strdup(noti_id), evt_cb_data);
1624
1625         g_strfreev(dbus_str);
1626
1627         return TAPI_API_SUCCESS;
1628 }
1629
1630 EXPORT_API int tel_deregister_noti_event(TapiHandle *handle,
1631                 const char *noti_id)
1632 {
1633         struct tapi_evt_cb *evt_cb_data = NULL;
1634         gchar **dbus_str = NULL;
1635         gboolean rv = FALSE;
1636
1637         TAPI_RET_ERR_NUM_IF_FAIL(handle, TAPI_API_INVALID_INPUT);
1638         TAPI_RET_ERR_NUM_IF_FAIL(handle->dbus_connection, TAPI_API_INVALID_INPUT);
1639
1640         dbus_str = g_strsplit(noti_id, ":", 2);
1641         if (!dbus_str) {
1642                 err("[%s] invalid noti_id", handle->cp_name);
1643                 return TAPI_API_INVALID_INPUT;
1644         }
1645
1646         if (!dbus_str[0] || !dbus_str[1]) {
1647                 g_strfreev(dbus_str);
1648                 err("[%s] invalid noti_id", handle->cp_name);
1649                 return TAPI_API_INVALID_INPUT;
1650         }
1651
1652         dbg("[%s] signal (%s)", handle->cp_name, dbus_str[1]);
1653         g_strfreev(dbus_str);
1654         dbus_str = NULL;
1655
1656         evt_cb_data = g_hash_table_lookup(handle->evt_list, noti_id);
1657         if (!evt_cb_data) {
1658                 dbg("event does not registered");
1659                 return TAPI_API_INVALID_INPUT;
1660         }
1661
1662         g_dbus_connection_signal_unsubscribe(handle->dbus_connection,
1663                         evt_cb_data->evt_id);
1664
1665         rv = g_hash_table_remove(handle->evt_list, noti_id);
1666         if (!rv) {
1667                 err("[%s] fail to deregister noti event(%s)", handle->cp_name, noti_id);
1668                 return TAPI_API_OPERATION_FAILED;
1669         }
1670
1671         return TAPI_API_SUCCESS;
1672 }
1673
1674 static gpointer _copy_ready_cb_item(gconstpointer src, gpointer data)
1675 {
1676         TelReadyStateCallback_t *orig_data = (TelReadyStateCallback_t *)src;
1677         TelReadyStateCallback_t *cb_data = NULL;
1678
1679         cb_data = g_try_new0(TelReadyStateCallback_t, 1);
1680         if (!cb_data)
1681                 return NULL;
1682
1683         cb_data->callback = orig_data->callback;
1684         cb_data->user_data = orig_data->user_data;
1685
1686         return cb_data;
1687 }
1688
1689 static void on_changed_ready_state(keynode_t *key, void *user_data)
1690 {
1691         int value = 0;
1692         int res = 0;
1693         GSList *list = NULL;
1694         GSList *copied_list_head = NULL;
1695
1696         res = vconf_get_bool(VCONFKEY_TELEPHONY_READY, &value);
1697         if (res == VCONF_ERROR) {
1698                 err("Failed to get vconf state");
1699                 return;
1700         }
1701
1702         /* Copy callback list.
1703          * As user can deregister callback function
1704          * inside of callback function.
1705          * That logic leads process to deadlock. (Recursive locking) */
1706         G_LOCK(state_mutex);
1707         copied_list_head = g_slist_copy_deep(state_callback_list, (GCopyFunc)_copy_ready_cb_item, NULL);
1708         G_UNLOCK(state_mutex);
1709
1710         list = copied_list_head;
1711         while (list) {
1712                 TelReadyStateCallback_t *cb_data = (TelReadyStateCallback_t *)list->data;
1713
1714                 if (cb_data && cb_data->callback)
1715                         cb_data->callback(value, cb_data->user_data);
1716
1717                 list = g_slist_next(list);
1718         }
1719
1720         g_slist_free_full(copied_list_head, g_free);
1721 }
1722
1723 EXPORT_API int tel_register_ready_state_cb(tapi_state_cb callback, void *user_data)
1724 {
1725         gboolean exist = FALSE;
1726         GSList *list = NULL;
1727
1728         TAPI_RET_ERR_NUM_IF_FAIL(callback, TAPI_API_INVALID_INPUT);
1729
1730         G_LOCK(state_mutex);
1731         list = state_callback_list;
1732         while (list) {
1733                 TelReadyStateCallback_t *cb_iter = (TelReadyStateCallback_t *)list->data;
1734                 if (cb_iter && cb_iter->callback == callback) {
1735                         exist = TRUE;
1736                         break;
1737                 }
1738                 list = g_slist_next(list);
1739         }
1740
1741         if (!exist) {
1742                 TelReadyStateCallback_t *cb_data = g_try_new0(TelReadyStateCallback_t, 1);
1743                 if (!cb_data) {
1744                         G_UNLOCK(state_mutex);
1745                         return TAPI_API_OPERATION_FAILED;
1746                 }
1747                 cb_data->callback = callback;
1748                 cb_data->user_data = user_data;
1749
1750                 state_callback_list = g_slist_append(state_callback_list, cb_data);
1751         } else {
1752                 G_UNLOCK(state_mutex);
1753                 return TAPI_API_OPERATION_FAILED;
1754         }
1755         G_UNLOCK(state_mutex);
1756
1757         if (!registered_vconf_cb) {
1758                 vconf_notify_key_changed(VCONFKEY_TELEPHONY_READY, on_changed_ready_state, NULL);
1759                 registered_vconf_cb = TRUE;
1760         }
1761
1762         return TAPI_API_SUCCESS;
1763 }
1764
1765 EXPORT_API int tel_deregister_ready_state_cb(tapi_state_cb callback)
1766 {
1767         GSList *list = NULL;
1768         guint count = 0;
1769
1770         TAPI_RET_ERR_NUM_IF_FAIL(callback, TAPI_API_INVALID_INPUT);
1771
1772         G_LOCK(state_mutex);
1773         list = state_callback_list;
1774
1775         while (list) {
1776                 TelReadyStateCallback_t *cb_data = (TelReadyStateCallback_t *)list->data;
1777
1778                 if (cb_data && cb_data->callback == callback) {
1779                         state_callback_list = g_slist_remove(state_callback_list, cb_data);
1780                         g_free(cb_data);
1781                         break;
1782                 }
1783                 list = g_slist_next(list);
1784         }
1785         count = g_slist_length(state_callback_list);
1786         G_UNLOCK(state_mutex);
1787
1788         if (count == 0) {
1789                 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_READY, on_changed_ready_state);
1790                 registered_vconf_cb = FALSE;
1791         }
1792
1793         return TAPI_API_SUCCESS;
1794 }
1795
1796 EXPORT_API int tel_get_ready_state(int *state)
1797 {
1798         int res = 0;
1799         int value = 0;
1800
1801         TAPI_RET_ERR_NUM_IF_FAIL(state, TAPI_API_INVALID_INPUT);
1802
1803         res = vconf_get_bool(VCONFKEY_TELEPHONY_READY, &value);
1804         if (res == VCONF_ERROR)
1805                 return TAPI_API_OPERATION_FAILED;
1806
1807         *state = (value == 0) ? 0 : 1;
1808
1809         return TAPI_API_SUCCESS;
1810 }
1811 /*      EOF     */