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