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