apply FSL license
[apps/core/preloaded/call-setting.git] / src / cst-tapi-request.c
1 /*
2   * Copyright 2012  Samsung Electronics Co., Ltd
3   *
4   * Licensed under the Flora License, Version 1.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   * http://www.tizenopensource.org/license
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16
17 #include "ITapiSs.h"
18 #include "TapiEvent.h"
19 #include "cst-tapi-request.h"
20 #include "cst-common.h"
21 #include "cst-common-string.h"
22 #include <Eina.h>
23
24 static void __cst_send_ss_req_to_telephony_server(CallSettingReq_t *req);
25
26 static void __cst_print_req_queue(Eina_List *queue)
27 {
28         Eina_List *l;
29         CallSettingReq_t *req;
30         EINA_LIST_FOREACH(queue, l, req) {
31                 ret_if(req == NULL);
32                 DBG("req=0x%p req_id=0x%x requesting=%d canceled=%d flavour=%d", req, req->req_id, req->is_requesting, req->is_canceled, req->flavour);
33         }
34 }
35
36 void _cst_cancel_all_ss_request(void *data)
37 {
38         ENTER(_cst_cancel_all_ss_request);
39         CstUgData_t *ugd = (CstUgData_t *)data;
40
41         Eina_List *l;
42         Eina_List *l_next;
43         CallSettingReq_t *req;
44
45         EINA_LIST_FOREACH_SAFE(ugd->req_queue, l, l_next, req) {
46                 ret_if(req == NULL);
47                 DBG("Cancel req=0x%p", req);
48                 if (req->is_requesting == EINA_TRUE) {
49                         req->is_canceled = EINA_TRUE;
50                 } else {
51                         free(req);
52                         ugd->req_queue = eina_list_remove_list(ugd->req_queue, l);
53                 }
54         }
55         __cst_print_req_queue(ugd->req_queue);
56         LEAVE();
57 }
58
59 void _cst_add_ss_request(Eina_List ** queue, int action_type, int call_type, int flavour, char *number, void *func, void *data)
60 {
61         ENTER(_cst_add_ss_request);
62         ret_if(NULL == data);
63         ret_if(NULL == func);
64
65         CallSettingReq_t *req = (CallSettingReq_t *)malloc(sizeof(CallSettingReq_t));
66         ret_if(NULL == req);
67         req->action = action_type;
68         req->original_state = EINA_FALSE;
69         req->call_type = call_type;
70         req->flavour = flavour;
71         req->data = data;
72         req->func = func;
73         snprintf(req->number, CST_MAX_PHONE_NUMBER_LEN, "%s", number);
74         int cnt;
75
76         DBG("Add req=0x%p", req);
77         req->is_canceled = EINA_FALSE;
78         req->is_requesting = EINA_FALSE;
79
80         *queue = eina_list_append(*queue, req);
81         cnt = eina_list_count(*queue);
82         DBG("req count=%d", cnt);
83         if (cnt == 1) {
84                 __cst_send_ss_req_to_telephony_server(req);
85         }
86         LEAVE();
87 }
88
89 static void __cst_remove_ss_request(void *data)
90 {
91         ENTER(__cst_remove_ss_request);
92         CstUgData_t *ugd = (CstUgData_t *)data;
93         CallSettingReq_t *req;
94         Eina_List *first;
95         int cnt;
96         ret_if(eina_list_count(ugd->req_queue) == 0);
97
98         first = eina_list_nth_list(ugd->req_queue, 0);
99         req = (CallSettingReq_t *)first->data;
100         DBG("Remove req=0x%p", req);
101         ugd->req_queue = eina_list_remove_list(ugd->req_queue, first);
102         free(req);
103
104         cnt = eina_list_count(ugd->req_queue);
105         DBG("req count=%d", cnt);
106
107         if (cnt > 0) {
108                 first = eina_list_nth_list(ugd->req_queue, 0);
109                 req = (CallSettingReq_t *)first->data;
110                 __cst_send_ss_req_to_telephony_server(req);
111         }
112         __cst_print_req_queue(ugd->req_queue);
113
114         LEAVE();
115
116 }
117
118 static CallSettingReq_t *__cst_get_current_request(void *data)
119 {
120         ENTER(__cst_get_current_request);
121         CstUgData_t *ugd = (CstUgData_t *)data;
122         CallSettingReq_t *req = NULL;
123         retv_if(ugd->req_queue == NULL, NULL);
124         DBG("list length=%d", eina_list_count(ugd->req_queue));
125         if (eina_list_count(ugd->req_queue) > 0) {
126                 req = (CallSettingReq_t *)ugd->req_queue->data;
127                 DBG("current req=0x%p", req);
128         }
129         LEAVE();
130         return req;
131 }
132
133 static int __cst_get_ciss_error_from_tapi_error(TelSsCause_t tapi_err)
134 {
135         ENTER(__cst_get_ciss_error_from_tapi_error);
136
137         int error_code = -1;
138
139         DBG("Error Code =%d", tapi_err);
140
141         switch (tapi_err) {
142         case TAPI_SS_UNKNOWNSUBSCRIBER:
143         case TAPI_SS_BEARERSERVICENOTPROVISIONED:
144         case TAPI_SS_TELESERVICENOTPROVISIONED:
145         case TAPI_SS_CALLBARRED:
146         case TAPI_SS_ILLEGALSSOPERATION:
147         case TAPI_SS_ERRORSTATUS:
148         case TAPI_SS_FACILITYNOTSUPPORTED:
149         case TAPI_SS_MAXNOMPTYEXCEEDED:
150         case TAPI_SS_RESOURCESNOTAVAILABLE:
151         case TAPI_SS_PWREGISTRATIONFAILURE:
152         case TAPI_SS_SUBSCRIPTIONVIOLATION:
153         case TAPI_SS_NOTAVAILABLE:
154         case TAPI_SS_SYSTEMFAILURE:
155         case TAPI_SS_REJECTEDBYNETWORK:
156                 error_code = CST_ERROR_SERVICE_UNAVAILABLE;
157                 break;
158         case TAPI_SS_INCOMPATIBILITY:
159         case TAPI_SS_DATAMISSING:
160         case TAPI_SS_UNEXPECTEDDATAVALUE:
161                 error_code = CST_ERROR_INCORRECT_OPERATION;
162                 break;
163         case TAPI_SS_NEGATIVEPWCHECK:
164                 error_code = CST_ERROR_INVALID_PASSWORD;
165                 break;
166                 /*Show message password error this function has been locked, so please call customer center for Vodafone R11 */
167         case TAPI_SS_NUMBEROFPWATTEMPTSVIOLATION:
168                 error_code = CST_ERROR_PASSWORD_BLOCKED;
169                 break;
170         case TAPI_SS_REJECTEDBYUSER:
171                 error_code = CST_ERROR_REJECTED_BY_NETWORK;
172                 break;
173         default:
174                 DBG("ciss_get_error_from_tapi_error:undefined =0x%x", tapi_err);
175                 error_code = CST_ERROR_UNKNOWN;
176                 break;
177         }
178         LEAVE();
179         return error_code;
180 }
181
182 static int __cst_get_tapi_cf_teleservice_type(int ciss_call_type)
183 {
184         int teleservice;
185
186         switch (ciss_call_type) {
187         case CST_CALLTYPE_VOICE:
188                 teleservice = TAPI_CS_FORWARD_TYPE_VOICE_EV;
189                 break;
190         case CST_CALLTYPE_VIDEO:
191                 teleservice = TAPI_CS_FORWARD_TYPE_DATA_EV;
192                 break;
193         default:
194                 teleservice = 0;
195                 ERR("Invalid CF teleservice type");
196         }
197         LEAVE();
198         return teleservice;
199 }
200
201 static int __cst_get_tapi_cf_mode(int ciss_action)
202 {
203         int mode;
204
205         switch (ciss_action) {
206         case CST_ACTION_ACTIVATE:
207                 mode = TAPI_CALL_FORWARD_MODE_REGISTRATION_EV;
208                 break;
209         case CST_ACTION_DEACTIVATE:
210                 mode = TAPI_CALL_FORWARD_MODE_ERASURE_EV;
211                 break;
212         default:
213                 mode = 0;
214                 ERR("Invalid CF mode");
215         }
216
217         return mode;
218 }
219
220 static int __cst_get_tapi_cf_flavour(int ciss_cf_flavour)
221 {
222
223         int tel_cf_flavour;
224         switch (ciss_cf_flavour) {
225         case CST_SSTYPE_CF_UNCONDITIONAL:
226                 tel_cf_flavour = TAPI_SS_FORWARD_WHEN_UNCONDITIONAL_EV;
227                 break;
228         case CST_SSTYPE_CF_BUSY:
229                 tel_cf_flavour = TAPI_SS_FORWARD_WHEN_BUSY_EV;
230                 break;
231         case CST_SSTYPE_CF_NO_REPLY:
232                 tel_cf_flavour = TAPI_SS_FORWARD_WHEN_NO_ANSWER_EV;
233                 break;
234         case CST_SSTYPE_CF_NOT_REACHABLE:
235                 tel_cf_flavour = TAPI_SS_FORWARD_WHEN_NOT_REACHABLE_EV;
236                 break;
237         default:
238                 tel_cf_flavour = -1;
239                 ERR("Wrong CF flavour");
240         }
241         return tel_cf_flavour;
242 }
243
244 static int __cst_get_tapi_teleservice_type(int ciss_call_type)
245 {
246         int teleservice;
247
248         switch (ciss_call_type) {
249         case CST_CALLTYPE_VOICE:
250                 teleservice = TAPI_CALL_TYPE_VOICE_EV;
251                 break;
252         case CST_CALLTYPE_VIDEO:
253                 teleservice = TAPI_CALL_TYPE_DATA_CIRCUIT_SYNC_EV;
254                 break;
255         case CST_CALLTYPE_ALL:
256                 teleservice = TAPI_CALL_TYPE_ALL_TELE_BEARER;
257                 break;
258         default:
259                 teleservice = 0;
260                 ERR("Invalid call type");
261         }
262         return teleservice;
263 }
264
265 static int __cst_get_tapi_cb_mode(int ciss_action)
266 {
267         int mode;
268
269         switch (ciss_action) {
270         case CST_ACTION_ACTIVATE:
271                 mode = TAPI_SS_CALL_BAR_ACTIVATE;
272                 break;
273         case CST_ACTION_DEACTIVATE:
274                 mode = TAPI_SS_CALL_BAR_DEACTIVATE;
275                 break;
276         default:
277                 mode = 0;
278                 ERR("Invalid CB action");
279         }
280         return mode;
281 }
282
283 static int __cst_get_tapi_cb_flavour(int ciss_cb_flavour)
284 {
285
286         int tel_cb_flavour;
287         switch (ciss_cb_flavour) {
288         case CST_SSTYPE_CB_OC:
289                 tel_cb_flavour = TAPI_CALL_BARRING_ALL_OUTGOING_CALLS;
290                 break;
291         case CST_SSTYPE_CB_OIC:
292                 tel_cb_flavour = TAPI_CALL_BARRING_ALL_OUTGOING_INTERN_CALL;
293                 break;
294         case CST_SSTYPE_CB_OICEH:
295                 tel_cb_flavour = TAPI_CALL_BARRING_ALL_OUTGOING_INTERN_CALL_EXCEPT;
296                 break;
297         case CST_SSTYPE_CB_IC:
298                 tel_cb_flavour = TAPI_CALL_BARRING_ALL_INCOMING_CALLS;
299                 break;
300         case CST_SSTYPE_CB_ICR:
301                 tel_cb_flavour = TAPI_CALL_BARRING_ALL_INCOMING_CALLS_ROAMING;
302                 break;
303         default:
304                 tel_cb_flavour = -1;
305                 ERR("Wrong CB flavour");
306         }
307         return tel_cb_flavour;
308 }
309
310 static int __cst_get_tapi_cw_mode(int ciss_action)
311 {
312         int mode;
313
314         switch (ciss_action) {
315         case CST_ACTION_ACTIVATE:
316                 mode = TAPI_SS_CW_ACTIVATE;
317                 break;
318         case CST_ACTION_DEACTIVATE:
319                 mode = TAPI_SS_CW_DEACTIVATE;
320                 break;
321         default:
322                 mode = 0;
323                 ERR("Invalid CW action");
324         }
325         return mode;
326 }
327
328 void __cst_send_ss_req_to_telephony_server(CallSettingReq_t *req)
329 {
330         ENTER(__cst_send_ss_req_to_telephony_server);
331         TelSsForwardInfo_t cf_info;
332         TelSsCallBarringInfo_t cb_info;
333         TelSsWaitingInfo_t cw_info;
334         int api_ret = -1;
335
336         int req_id = -1;
337         ret_if(req == NULL);
338         DBG("Send req=0x%p action=%d call_type=%d flavour=%d", req, req->action, req->call_type, req->flavour);
339         req->is_requesting = EINA_TRUE;
340
341         memset(&cf_info, 0x0, sizeof(TelSsForwardInfo_t));
342         memset(&cb_info, 0x0, sizeof(TelSsCallBarringInfo_t));
343         memset(&cw_info, 0x0, sizeof(TelSsWaitingInfo_t));
344
345         switch (req->flavour) {
346         case CST_SSTYPE_CF_UNCONDITIONAL:
347         case CST_SSTYPE_CF_BUSY:
348         case CST_SSTYPE_CF_NO_REPLY:
349         case CST_SSTYPE_CF_NOT_REACHABLE:
350         case CST_SSTYPE_CF_ALL:
351         case CST_SSTYPE_CF_ALL_CONDITIONAL:
352                 cf_info.Condition = __cst_get_tapi_cf_flavour(req->flavour);
353                 cf_info.Type = __cst_get_tapi_cf_teleservice_type(req->call_type);
354                 if (req->action == CST_ACTION_QUERY) {
355                         api_ret = tel_get_ss_forward_status(cf_info.Type, cf_info.Condition, &req_id);
356                 } else {
357                         cf_info.Mode = __cst_get_tapi_cf_mode(req->action);
358                         cf_info.NoReplyConditionTimer = 20;
359                         snprintf(cf_info.szPhoneNumber, TAPI_CALL_DIALDIGIT_LEN_MAX, "%s", req->number);
360                         api_ret = tel_set_ss_forward(&cf_info, &req_id);
361                 }
362                 break;
363         case CST_SSTYPE_CB_OC:
364         case CST_SSTYPE_CB_OIC:
365         case CST_SSTYPE_CB_OICEH:
366         case CST_SSTYPE_CB_IC:
367         case CST_SSTYPE_CB_ICR:
368                 cb_info.Type = __cst_get_tapi_cb_flavour(req->flavour);
369                 cb_info.CallType = __cst_get_tapi_teleservice_type(req->call_type);
370
371                 DBG("%d <= %d <= %d calltype", TAPI_CALL_TYPE_VOICE_EV, cb_info.CallType, TAPI_CALL_TYPE_ALL_TELE);
372                 DBG("%d <= %d <= %d type", TAPI_CALL_BARRING_ALL, cb_info.Type, TAPI_CALL_BARRING_ALL_INCOMING_CALLS_INSIM);
373                 if (req->action == CST_ACTION_QUERY) {
374                         api_ret = tel_get_ss_barring_status(cb_info.Type, cb_info.CallType, &req_id);
375                 } else {
376                         cb_info.Mode = __cst_get_tapi_cb_mode(req->action);
377                         DBG("%d <= %d <= %d mode", TAPI_SS_CALL_BAR_ACTIVATE, cb_info.Mode, TAPI_SS_CALL_BAR_DEACTIVATE);
378                         DBG("%d == %d pwd length", strnlen(cb_info.szPassword, 4), TAPI_SS_GSM_BARR_PW_LEN_MAX);
379                         memcpy(cb_info.szPassword, req->number, TAPI_SS_GSM_BARR_PW_LEN_MAX);
380                         api_ret = tel_set_ss_barring(&cb_info, &req_id);
381                 }
382                 break;
383         case CST_SSTYPE_CW:
384                 cw_info.CallType = __cst_get_tapi_teleservice_type(req->call_type);
385                 if (req->action == CST_ACTION_QUERY) {
386                         api_ret = tel_get_ss_waiting_status(cw_info.CallType, &req_id);
387                 } else {
388                         cw_info.Mode = __cst_get_tapi_cw_mode(req->action);
389                         api_ret = tel_set_ss_waiting(&cw_info, &req_id);
390                 }
391                 break;
392         }
393
394         if (req->req_id != -1) {
395                 req->req_id = req_id;
396         }
397
398         if (api_ret != TAPI_API_SUCCESS) {
399                 CstGlItemData_t *item_data;
400                 CstUgData_t *ugd;
401
402                 req->func(req->call_type, req->flavour, EINA_FALSE, NULL, CST_ERROR_INCORRECT_OPERATION, req->action, req->data);
403                 item_data = (CstGlItemData_t *)req->data;
404                 ugd = (CstUgData_t *)item_data->ugd;
405                 __cst_remove_ss_request(ugd);
406         }
407         DBG("api_ret=%d req_id=0x%p", api_ret, req_id);
408
409         LEAVE();
410         return;
411 }
412
413 static int __cst_on_tel_event_cf_cnf(const TelTapiEvent_t *event, void *userdata)
414 {
415         ENTER(__cst_on_tel_event_cf_cnf);
416
417         CstUgData_t *ugd = (CstUgData_t *)userdata;
418         retv_if(event == NULL, -1);
419         retv_if(ugd == NULL, -1);
420
421         int i;
422
423         DBG("event->type =%d req_id=0x%x status=0x%x dlen=%d", event->EventType, event->RequestId, event->Status, event->pDataLen);
424
425         CallSettingReq_t *req;
426         req = __cst_get_current_request(ugd);
427         retv_if(req == NULL, -1);
428         retv_if(req->req_id != event->RequestId, -1);
429         retv_if(req->is_requesting == EINA_FALSE, -1);
430         if (req->is_canceled == EINA_TRUE) {
431                 DBG("Req(0x%xp,req_id=%d) was canceled. So It will be removed", req, req->req_id);
432                 __cst_remove_ss_request(ugd);
433                 return 0;
434         }
435
436         if (event->EventClass != TAPI_EVENT_CLASS_SS) {
437                 DBG("wrong event class");
438                 return -1;
439         }
440
441         if (event->EventType != TAPI_EVENT_SS_FORWARD_CNF && event->EventType != TAPI_EVENT_SS_FORWARD_QUERYSTATUS_CNF) {
442                 DBG("wrong event type");
443                 return -1;
444         }
445
446         if (event->Status != TAPI_SS_SUCCESS) {
447                 DBG("Event Status is %d", event->Status);
448                 int error;
449                 error = __cst_get_ciss_error_from_tapi_error(event->Status);
450                 DBG("req=0x%p", req);
451                 if (req) {
452                         req->func(req->call_type, req->flavour, EINA_FALSE, NULL, error, req->action, req->data);
453                 }
454                 __cst_remove_ss_request(ugd);
455                 return 0;
456         }
457
458         if (event->pData == NULL) {
459                 DBG("Event data is NULL");
460                 return -1;
461         }
462
463         TelSsInfo_t ss_info;
464         memcpy(&ss_info, event->pData, sizeof(TelSsInfo_t));
465
466         char number[TAPI_CALL_DIALDIGIT_LEN_MAX];
467
468         Eina_Bool cf_state = EINA_FALSE;
469         int cf_flavour;
470         int call_type;
471
472         for (i = 0; i < ss_info.NumberOfRecords; ++i) {
473                 number[0] = '\0';
474                 DBG("TeleCommService=%d", ss_info.SsRecord.ForwardingRecord.rec_class[i].TeleCommService);
475                 DBG("Flavour=%d", ss_info.SsRecord.ForwardingRecord.rec_class[i].ForwardCondition);
476                 DBG("Status=%d", ss_info.SsRecord.ForwardingRecord.rec_class[i].Status);
477                 switch (ss_info.SsRecord.ForwardingRecord.rec_class[i].TeleCommService) {
478                 case TAPI_SS_TS_ALL_SPEECH:
479                         call_type = CST_CALLTYPE_VOICE;
480                         break;
481                 case TAPI_SS_BS_DATA_CIRCUIT_SYNC:
482                         call_type = CST_CALLTYPE_VIDEO;
483                         break;
484                 case TAPI_SS_TS_ALL_TELESERVICES:
485                 case TAPI_SS_TS_ALL_TELE_AND_BEARER_SERVICES:
486                         call_type = CST_CALLTYPE_ALL;
487                         break;
488                 default:
489                         call_type = -1;
490                         break;
491                 }
492                 //If the call type of the record is not same with request, skip below code
493                 DBG("req->call_type == %d call_type=%d", req->call_type, call_type);
494                 if (req->call_type != call_type && call_type != CST_CALLTYPE_ALL)
495                         continue;
496
497                 switch (ss_info.SsRecord.ForwardingRecord.rec_class[i].ForwardCondition) {
498                 case TAPI_SS_FORWARD_WHEN_UNCONDITIONAL_EV:
499                         cf_flavour = CST_SSTYPE_CF_UNCONDITIONAL;
500                         break;
501                 case TAPI_SS_FORWARD_WHEN_BUSY_EV:
502                         cf_flavour = CST_SSTYPE_CF_BUSY;
503                         break;
504                 case TAPI_SS_FORWARD_WHEN_NO_ANSWER_EV:
505                         cf_flavour = CST_SSTYPE_CF_NO_REPLY;
506                         break;
507                 case TAPI_SS_FORWARD_WHEN_NOT_REACHABLE_EV:
508                         cf_flavour = CST_SSTYPE_CF_NOT_REACHABLE;
509                         break;
510                 case TAPI_SS_FORWARD_WHEN_ALL_FORWARDING_EV:
511                         cf_flavour = CST_SSTYPE_CF_ALL;
512                         break;
513                 case TAPI_SS_FORWARD_WHEN_ALL_CONDITIONAL_EV:
514                         cf_flavour = CST_SSTYPE_CF_ALL_CONDITIONAL;
515                         break;
516                 default:
517                         ERR("Invalid CF Flavour");
518                         return -1;
519                 }
520
521                 switch (ss_info.SsRecord.ForwardingRecord.rec_class[i].Status) {
522                 case TAPI_SS_STATUS_ACTIVE:
523                 case TAPI_SS_STATUS_REGISTERED:
524                         cf_state = EINA_TRUE;
525                         break;
526                 case TAPI_SS_STATUS_NOTHING:
527                 case TAPI_SS_STATUS_PROVISIONED:
528                 case TAPI_SS_STATUS_QUIESCENT:
529                         cf_state = EINA_FALSE;
530                         break;
531                 default:
532                         ERR("Invalid CF state");
533                         return -1;
534                 }
535
536                 if (ss_info.SsRecord.ForwardingRecord.rec_class[i].bCallForwardingNumberPresent == 1) {
537                         snprintf(number, TAPI_CALL_DIALDIGIT_LEN_MAX, "%s", ss_info.SsRecord.ForwardingRecord.rec_class[i].szCallForwardingNumber);
538                 }
539
540                 req->func(call_type, cf_flavour, cf_state, number, CST_ERROR_NONE, req->action, req->data);
541         }
542
543         __cst_remove_ss_request(ugd);
544
545         LEAVE();
546
547         return 0;
548 }
549
550 static int __cst_on_tel_event_cb_cnf(const TelTapiEvent_t *event, void *userdata)
551 {
552         ENTER(__cst_on_tel_event_cb_cnf);
553
554         CstUgData_t *ugd = (CstUgData_t *)userdata;
555         retv_if(event == NULL, -1);
556         retv_if(ugd == NULL, -1);
557
558         int i;
559
560         DBG("event->type =%d req_id=0x%x status=0x%x dlen=%d", event->EventType, event->RequestId, event->Status, event->pDataLen);
561
562         CallSettingReq_t *req;
563         req = __cst_get_current_request(ugd);
564         retv_if(req == NULL, -1);
565         retv_if(req->req_id != event->RequestId, -1);
566         retv_if(req->is_requesting == EINA_FALSE, -1);
567         if (req->is_canceled == EINA_TRUE) {
568                 __cst_remove_ss_request(ugd);
569                 return 0;
570         }
571
572         if (event->EventClass != TAPI_EVENT_CLASS_SS) {
573                 DBG("wrong event class");
574                 return -1;
575         }
576
577         if (event->Status != TAPI_SS_SUCCESS) {
578                 DBG("Event Status is %d", event->Status);
579                 int error;
580                 error = __cst_get_ciss_error_from_tapi_error(event->Status);
581                 if (req) {
582                         req->func(req->call_type, req->flavour, EINA_FALSE, NULL, error, req->action, req->data);
583                 }
584                 __cst_remove_ss_request(ugd);
585                 return 0;
586         }
587
588         if (event->pData == NULL) {
589                 DBG("Event data is NULL");
590                 return -1;
591         }
592
593         TelSsInfo_t ss_info;
594         memcpy(&ss_info, event->pData, sizeof(TelSsInfo_t));
595
596         char number[50];
597
598         Eina_Bool cb_state = EINA_FALSE;
599         int cb_flavour = -1;
600         int call_type;
601
602         for (i = 0; i < ss_info.NumberOfRecords; ++i) {
603                 number[0] = '\0';
604                 DBG("TeleCommService=0x%x", ss_info.SsRecord.BarringRecord.rec_class[i].TeleCommService);
605                 DBG("Flavour=0x%x", ss_info.SsRecord.BarringRecord.rec_class[i].Flavour);
606                 DBG("Status=0x%x", ss_info.SsRecord.BarringRecord.rec_class[i].Status);
607                 switch (ss_info.SsRecord.BarringRecord.rec_class[i].TeleCommService) {
608                 case TAPI_SS_TS_ALL_SPEECH:
609                         call_type = CST_CALLTYPE_VOICE;
610                         break;
611                 case TAPI_SS_TS_ALL_DATA_TELESERVICES:
612                         call_type = CST_CALLTYPE_VIDEO;
613                         break;
614                 case TAPI_SS_TS_ALL_TELESERVICES:
615                 case TAPI_SS_ALL_TELE_BEARER:
616                         call_type = CST_CALLTYPE_ALL;
617                         break;
618                 default:
619                         call_type = -1;
620                         break;
621                 }
622                 //If the call type of the record is not same with request, skip below code
623                 if (req->call_type != call_type && call_type != CST_CALLTYPE_ALL)
624                         continue;
625
626                 switch (ss_info.SsRecord.BarringRecord.rec_class[i].Flavour) {
627                 case TAPI_CALL_BARRING_ALL_OUTGOING_CALLS:
628                         cb_flavour = CST_SSTYPE_CB_OC;
629                         break;
630                 case TAPI_CALL_BARRING_ALL_OUTGOING_INTERN_CALL:
631                         cb_flavour = CST_SSTYPE_CB_OIC;
632                         break;
633                 case TAPI_CALL_BARRING_ALL_OUTGOING_INTERN_CALL_EXCEPT:
634                         cb_flavour = CST_SSTYPE_CB_OICEH;
635                         break;
636                 case TAPI_CALL_BARRING_ALL_INCOMING_CALLS:
637                         cb_flavour = CST_SSTYPE_CB_IC;
638                         break;
639                 case TAPI_CALL_BARRING_ALL_INCOMING_CALLS_ROAMING:
640                         cb_flavour = CST_SSTYPE_CB_ICR;
641                         break;
642                 default:
643                         ERR("Invalid CB Flavour");
644                         return 0;
645                 }
646
647                 switch (ss_info.SsRecord.BarringRecord.rec_class[i].Status) {
648                 case TAPI_SS_STATUS_ACTIVE:
649                 case TAPI_SS_STATUS_REGISTERED:
650                         cb_state = EINA_TRUE;
651                         break;
652                 case TAPI_SS_STATUS_NOTHING:
653                 case TAPI_SS_STATUS_PROVISIONED:
654                 case TAPI_SS_STATUS_QUIESCENT:
655                         cb_state = EINA_FALSE;
656                         break;
657                 default:
658                         ERR("Invalid CB state");
659                         return 0;
660                 }
661
662         }
663
664         req->func(call_type, cb_flavour, cb_state, NULL, CST_ERROR_NONE, req->action, req->data);
665
666         __cst_remove_ss_request(ugd);
667
668         LEAVE();
669
670         return -1;
671 }
672
673 static int __cst_on_tel_event_cw_cnf(const TelTapiEvent_t *event, void *userdata)
674 {
675         ENTER(__cst_on_tel_event_cw_cnf);
676         CstUgData_t *ugd = (CstUgData_t *)userdata;
677         retv_if(event == NULL, -1);
678         retv_if(ugd == NULL, -1);
679
680         CallSettingReq_t *req;
681
682         req = __cst_get_current_request(ugd);
683         retv_if(req == NULL, -1);
684         retv_if(req->req_id != event->RequestId, -1);
685         retv_if(req->is_requesting == EINA_FALSE, -1);
686         retv_if(NULL == req->data, -1);
687         if (req->is_canceled == EINA_TRUE) {
688                 __cst_remove_ss_request(ugd);
689                 return 0;
690         }
691
692         DBG("event->type =%d req_id=0x%x status=0x%x dlen=%d", event->EventType, event->RequestId, event->Status, event->pDataLen);
693
694         if (event->EventClass != TAPI_EVENT_CLASS_SS) {
695                 DBG("wrong event class");
696                 return -1;
697         }
698
699         if (event->Status != TAPI_SS_SUCCESS) {
700                 DBG("Event Status is %d", event->Status);
701                 int error;
702
703                 error = __cst_get_ciss_error_from_tapi_error(event->Status);
704
705                 if (req) {
706                         req->func(req->call_type, req->flavour, EINA_TRUE, NULL, error, req->action, req->data);
707                 }
708
709                 __cst_remove_ss_request(ugd);
710                 return 0;
711         }
712
713         if (event->pData == NULL) {
714                 DBG("Event data is NULL");
715                 return -1;
716         }
717
718         TelSsInfo_t ss_info;
719         memcpy(&ss_info, event->pData, sizeof(TelSsInfo_t));
720
721         DBG("CW Status = %d", ss_info.SsRecord.WaitingRecord.rec_class[0].Status);
722         retv_if(NULL == req->func, -1);
723         switch (ss_info.SsRecord.WaitingRecord.rec_class[0].Status) {
724         case TAPI_SS_STATUS_ACTIVE:
725         case TAPI_SS_STATUS_REGISTERED:
726                 req->func(req->call_type, req->flavour, EINA_TRUE, NULL, CST_ERROR_NONE, req->action, req->data);
727                 break;
728         case TAPI_SS_STATUS_PROVISIONED:
729         case TAPI_SS_STATUS_QUIESCENT:
730                 req->func(req->call_type, req->flavour, EINA_FALSE, NULL, CST_ERROR_NONE, req->action, req->data);
731                 break;
732         default:
733                 ERR("Call waiting query error");
734                 break;
735         }
736
737         __cst_remove_ss_request(ugd);
738         LEAVE();
739         return 0;
740 }
741
742 typedef struct _EventHandler {
743         int event_type;
744         TelAppCallback func;
745 } EventHandler;
746
747 void _cst_ciss_register_tel_event(void *data)
748 {
749         ENTER(_cst_ciss_register_tel_event);
750         CstUgData_t *ugd = (CstUgData_t *)data;
751         int i = 0;
752         int len = 0;
753         int sub_id = 0;
754         int api_ret = -1;
755
756         EventHandler event_list[] = {
757                 {TAPI_EVENT_SS_FORWARD_QUERYSTATUS_CNF, __cst_on_tel_event_cf_cnf},
758                 {TAPI_EVENT_SS_FORWARD_CNF, __cst_on_tel_event_cf_cnf},
759                 {TAPI_EVENT_SS_WAITING_QUERYSTATUS_CNF, __cst_on_tel_event_cw_cnf},
760                 {TAPI_EVENT_SS_WAITING_CNF, __cst_on_tel_event_cw_cnf},
761                 {TAPI_EVENT_SS_BARRING_QUERYSTATUS_CNF, __cst_on_tel_event_cb_cnf},
762                 {TAPI_EVENT_SS_BARRING_CNF, __cst_on_tel_event_cb_cnf},
763         };
764
765         len = sizeof(event_list) / sizeof(EventHandler);
766
767         ugd->tel_event_subscription_list = NULL;
768         if (tel_init() == TAPI_API_SUCCESS) {
769                 for (i = 0; i < len; i++) {
770                         api_ret = tel_register_event(event_list[i].event_type, &sub_id, event_list[i].func, (void *)ugd);
771                         if (api_ret != TAPI_API_SUCCESS)
772                                 DBG("tel_register_event error=%d", api_ret);
773                         DBG("tapi callback=0x%p", event_list[i].func);
774                         ugd->tel_event_subscription_list = g_slist_append(ugd->tel_event_subscription_list, GINT_TO_POINTER(sub_id));
775                 }
776                 api_ret = tel_register_app_name("org.tizen.ciss");
777                 if (api_ret != TAPI_API_SUCCESS)
778                         DBG("tel_register_app_name error=%d", api_ret);
779         } else
780                 ERR("TelTapiInit() failed.");
781
782         LEAVE();
783
784         return;
785 }
786
787 static void __cst_deregister_tel_event(gpointer data, gpointer userdata)
788 {
789         int ret;
790         int sub_id = GPOINTER_TO_INT(data);
791         ret = tel_deregister_event(sub_id);
792         DBG("sub_id = %d, ret = %d", sub_id, ret);
793 }
794
795 void _cst_ciss_deregister_tel_event(void *data)
796 {
797         ENTER(_cst_ciss_deregister_tel_event);
798         CstUgData_t *ugd = (CstUgData_t *)data;
799
800         g_slist_foreach(ugd->tel_event_subscription_list, __cst_deregister_tel_event, NULL);
801         g_slist_free(ugd->tel_event_subscription_list);
802         LEAVE();
803 }