+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.tizenopensource.org/license
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ITapiSs.h"
+#include "TapiEvent.h"
+#include "cst-tapi-request.h"
+#include "cst-common.h"
+#include "cst-common-string.h"
+#include <Eina.h>
+
+static void __cst_send_ss_req_to_telephony_server(CallSettingReq_t *req);
+
+static void __cst_print_req_queue(Eina_List *queue)
+{
+ Eina_List *l;
+ CallSettingReq_t *req;
+ EINA_LIST_FOREACH(queue, l, req) {
+ ret_if(req == NULL);
+ 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);
+ }
+}
+
+void _cst_cancel_all_ss_request(void *data)
+{
+ ENTER(_cst_cancel_all_ss_request);
+ CstUgData_t *ugd = (CstUgData_t *)data;
+
+ Eina_List *l;
+ Eina_List *l_next;
+ CallSettingReq_t *req;
+
+ EINA_LIST_FOREACH_SAFE(ugd->req_queue, l, l_next, req) {
+ ret_if(req == NULL);
+ DBG("Cancel req=0x%p", req);
+ if (req->is_requesting == EINA_TRUE) {
+ req->is_canceled = EINA_TRUE;
+ } else {
+ free(req);
+ ugd->req_queue = eina_list_remove_list(ugd->req_queue, l);
+ }
+ }
+ __cst_print_req_queue(ugd->req_queue);
+ LEAVE();
+}
+
+void _cst_add_ss_request(Eina_List ** queue, int action_type, int call_type, int flavour, char *number, void *func, void *data)
+{
+ ENTER(_cst_add_ss_request);
+ ret_if(NULL == data);
+ ret_if(NULL == func);
+
+ CallSettingReq_t *req = (CallSettingReq_t *)malloc(sizeof(CallSettingReq_t));
+ ret_if(NULL == req);
+ req->action = action_type;
+ req->original_state = EINA_FALSE;
+ req->call_type = call_type;
+ req->flavour = flavour;
+ req->data = data;
+ req->func = func;
+ snprintf(req->number, CST_MAX_PHONE_NUMBER_LEN, "%s", number);
+ int cnt;
+
+ DBG("Add req=0x%p", req);
+ req->is_canceled = EINA_FALSE;
+ req->is_requesting = EINA_FALSE;
+
+ *queue = eina_list_append(*queue, req);
+ cnt = eina_list_count(*queue);
+ DBG("req count=%d", cnt);
+ if (cnt == 1) {
+ __cst_send_ss_req_to_telephony_server(req);
+ }
+ LEAVE();
+}
+
+static void __cst_remove_ss_request(void *data)
+{
+ ENTER(__cst_remove_ss_request);
+ CstUgData_t *ugd = (CstUgData_t *)data;
+ CallSettingReq_t *req;
+ Eina_List *first;
+ int cnt;
+ ret_if(eina_list_count(ugd->req_queue) == 0);
+
+ first = eina_list_nth_list(ugd->req_queue, 0);
+ req = (CallSettingReq_t *)first->data;
+ DBG("Remove req=0x%p", req);
+ ugd->req_queue = eina_list_remove_list(ugd->req_queue, first);
+ free(req);
+
+ cnt = eina_list_count(ugd->req_queue);
+ DBG("req count=%d", cnt);
+
+ if (cnt > 0) {
+ first = eina_list_nth_list(ugd->req_queue, 0);
+ req = (CallSettingReq_t *)first->data;
+ __cst_send_ss_req_to_telephony_server(req);
+ }
+ __cst_print_req_queue(ugd->req_queue);
+
+ LEAVE();
+
+}
+
+static CallSettingReq_t *__cst_get_current_request(void *data)
+{
+ ENTER(__cst_get_current_request);
+ CstUgData_t *ugd = (CstUgData_t *)data;
+ CallSettingReq_t *req = NULL;
+ retv_if(ugd->req_queue == NULL, NULL);
+ DBG("list length=%d", eina_list_count(ugd->req_queue));
+ if (eina_list_count(ugd->req_queue) > 0) {
+ req = (CallSettingReq_t *)ugd->req_queue->data;
+ DBG("current req=0x%p", req);
+ }
+ LEAVE();
+ return req;
+}
+
+static int __cst_get_ciss_error_from_tapi_error(TelSsCause_t tapi_err)
+{
+ ENTER(__cst_get_ciss_error_from_tapi_error);
+
+ int error_code = -1;
+
+ DBG("Error Code =%d", tapi_err);
+
+ switch (tapi_err) {
+ case TAPI_SS_UNKNOWNSUBSCRIBER:
+ case TAPI_SS_BEARERSERVICENOTPROVISIONED:
+ case TAPI_SS_TELESERVICENOTPROVISIONED:
+ case TAPI_SS_CALLBARRED:
+ case TAPI_SS_ILLEGALSSOPERATION:
+ case TAPI_SS_ERRORSTATUS:
+ case TAPI_SS_FACILITYNOTSUPPORTED:
+ case TAPI_SS_MAXNOMPTYEXCEEDED:
+ case TAPI_SS_RESOURCESNOTAVAILABLE:
+ case TAPI_SS_PWREGISTRATIONFAILURE:
+ case TAPI_SS_SUBSCRIPTIONVIOLATION:
+ case TAPI_SS_NOTAVAILABLE:
+ case TAPI_SS_SYSTEMFAILURE:
+ case TAPI_SS_REJECTEDBYNETWORK:
+ error_code = CST_ERROR_SERVICE_UNAVAILABLE;
+ break;
+ case TAPI_SS_INCOMPATIBILITY:
+ case TAPI_SS_DATAMISSING:
+ case TAPI_SS_UNEXPECTEDDATAVALUE:
+ error_code = CST_ERROR_INCORRECT_OPERATION;
+ break;
+ case TAPI_SS_NEGATIVEPWCHECK:
+ error_code = CST_ERROR_INVALID_PASSWORD;
+ break;
+ /*Show message password error this function has been locked, so please call customer center for Vodafone R11 */
+ case TAPI_SS_NUMBEROFPWATTEMPTSVIOLATION:
+ error_code = CST_ERROR_PASSWORD_BLOCKED;
+ break;
+ case TAPI_SS_REJECTEDBYUSER:
+ error_code = CST_ERROR_REJECTED_BY_NETWORK;
+ break;
+ default:
+ DBG("ciss_get_error_from_tapi_error:undefined =0x%x", tapi_err);
+ error_code = CST_ERROR_UNKNOWN;
+ break;
+ }
+ LEAVE();
+ return error_code;
+}
+
+static int __cst_get_tapi_cf_teleservice_type(int ciss_call_type)
+{
+ int teleservice;
+
+ switch (ciss_call_type) {
+ case CST_CALLTYPE_VOICE:
+ teleservice = TAPI_CS_FORWARD_TYPE_VOICE_EV;
+ break;
+ case CST_CALLTYPE_VIDEO:
+ teleservice = TAPI_CS_FORWARD_TYPE_DATA_EV;
+ break;
+ default:
+ teleservice = 0;
+ ERR("Invalid CF teleservice type");
+ }
+ LEAVE();
+ return teleservice;
+}
+
+static int __cst_get_tapi_cf_mode(int ciss_action)
+{
+ int mode;
+
+ switch (ciss_action) {
+ case CST_ACTION_ACTIVATE:
+ mode = TAPI_CALL_FORWARD_MODE_REGISTRATION_EV;
+ break;
+ case CST_ACTION_DEACTIVATE:
+ mode = TAPI_CALL_FORWARD_MODE_ERASURE_EV;
+ break;
+ default:
+ mode = 0;
+ ERR("Invalid CF mode");
+ }
+
+ return mode;
+}
+
+static int __cst_get_tapi_cf_flavour(int ciss_cf_flavour)
+{
+
+ int tel_cf_flavour;
+ switch (ciss_cf_flavour) {
+ case CST_SSTYPE_CF_UNCONDITIONAL:
+ tel_cf_flavour = TAPI_SS_FORWARD_WHEN_UNCONDITIONAL_EV;
+ break;
+ case CST_SSTYPE_CF_BUSY:
+ tel_cf_flavour = TAPI_SS_FORWARD_WHEN_BUSY_EV;
+ break;
+ case CST_SSTYPE_CF_NO_REPLY:
+ tel_cf_flavour = TAPI_SS_FORWARD_WHEN_NO_ANSWER_EV;
+ break;
+ case CST_SSTYPE_CF_NOT_REACHABLE:
+ tel_cf_flavour = TAPI_SS_FORWARD_WHEN_NOT_REACHABLE_EV;
+ break;
+ default:
+ tel_cf_flavour = -1;
+ ERR("Wrong CF flavour");
+ }
+ return tel_cf_flavour;
+}
+
+static int __cst_get_tapi_teleservice_type(int ciss_call_type)
+{
+ int teleservice;
+
+ switch (ciss_call_type) {
+ case CST_CALLTYPE_VOICE:
+ teleservice = TAPI_CALL_TYPE_VOICE_EV;
+ break;
+ case CST_CALLTYPE_VIDEO:
+ teleservice = TAPI_CALL_TYPE_DATA_CIRCUIT_SYNC_EV;
+ break;
+ case CST_CALLTYPE_ALL:
+ teleservice = TAPI_CALL_TYPE_ALL_TELE_BEARER;
+ break;
+ default:
+ teleservice = 0;
+ ERR("Invalid call type");
+ }
+ return teleservice;
+}
+
+static int __cst_get_tapi_cb_mode(int ciss_action)
+{
+ int mode;
+
+ switch (ciss_action) {
+ case CST_ACTION_ACTIVATE:
+ mode = TAPI_SS_CALL_BAR_ACTIVATE;
+ break;
+ case CST_ACTION_DEACTIVATE:
+ mode = TAPI_SS_CALL_BAR_DEACTIVATE;
+ break;
+ default:
+ mode = 0;
+ ERR("Invalid CB action");
+ }
+ return mode;
+}
+
+static int __cst_get_tapi_cb_flavour(int ciss_cb_flavour)
+{
+
+ int tel_cb_flavour;
+ switch (ciss_cb_flavour) {
+ case CST_SSTYPE_CB_OC:
+ tel_cb_flavour = TAPI_CALL_BARRING_ALL_OUTGOING_CALLS;
+ break;
+ case CST_SSTYPE_CB_OIC:
+ tel_cb_flavour = TAPI_CALL_BARRING_ALL_OUTGOING_INTERN_CALL;
+ break;
+ case CST_SSTYPE_CB_OICEH:
+ tel_cb_flavour = TAPI_CALL_BARRING_ALL_OUTGOING_INTERN_CALL_EXCEPT;
+ break;
+ case CST_SSTYPE_CB_IC:
+ tel_cb_flavour = TAPI_CALL_BARRING_ALL_INCOMING_CALLS;
+ break;
+ case CST_SSTYPE_CB_ICR:
+ tel_cb_flavour = TAPI_CALL_BARRING_ALL_INCOMING_CALLS_ROAMING;
+ break;
+ default:
+ tel_cb_flavour = -1;
+ ERR("Wrong CB flavour");
+ }
+ return tel_cb_flavour;
+}
+
+static int __cst_get_tapi_cw_mode(int ciss_action)
+{
+ int mode;
+
+ switch (ciss_action) {
+ case CST_ACTION_ACTIVATE:
+ mode = TAPI_SS_CW_ACTIVATE;
+ break;
+ case CST_ACTION_DEACTIVATE:
+ mode = TAPI_SS_CW_DEACTIVATE;
+ break;
+ default:
+ mode = 0;
+ ERR("Invalid CW action");
+ }
+ return mode;
+}
+
+void __cst_send_ss_req_to_telephony_server(CallSettingReq_t *req)
+{
+ ENTER(__cst_send_ss_req_to_telephony_server);
+ TelSsForwardInfo_t cf_info;
+ TelSsCallBarringInfo_t cb_info;
+ TelSsWaitingInfo_t cw_info;
+ int api_ret = -1;
+
+ int req_id = -1;
+ ret_if(req == NULL);
+ DBG("Send req=0x%p action=%d call_type=%d flavour=%d", req, req->action, req->call_type, req->flavour);
+ req->is_requesting = EINA_TRUE;
+
+ memset(&cf_info, 0x0, sizeof(TelSsForwardInfo_t));
+ memset(&cb_info, 0x0, sizeof(TelSsCallBarringInfo_t));
+ memset(&cw_info, 0x0, sizeof(TelSsWaitingInfo_t));
+
+ switch (req->flavour) {
+ case CST_SSTYPE_CF_UNCONDITIONAL:
+ case CST_SSTYPE_CF_BUSY:
+ case CST_SSTYPE_CF_NO_REPLY:
+ case CST_SSTYPE_CF_NOT_REACHABLE:
+ case CST_SSTYPE_CF_ALL:
+ case CST_SSTYPE_CF_ALL_CONDITIONAL:
+ cf_info.Condition = __cst_get_tapi_cf_flavour(req->flavour);
+ cf_info.Type = __cst_get_tapi_cf_teleservice_type(req->call_type);
+ if (req->action == CST_ACTION_QUERY) {
+ api_ret = tel_get_ss_forward_status(cf_info.Type, cf_info.Condition, &req_id);
+ } else {
+ cf_info.Mode = __cst_get_tapi_cf_mode(req->action);
+ cf_info.NoReplyConditionTimer = 20;
+ snprintf(cf_info.szPhoneNumber, TAPI_CALL_DIALDIGIT_LEN_MAX, "%s", req->number);
+ api_ret = tel_set_ss_forward(&cf_info, &req_id);
+ }
+ break;
+ case CST_SSTYPE_CB_OC:
+ case CST_SSTYPE_CB_OIC:
+ case CST_SSTYPE_CB_OICEH:
+ case CST_SSTYPE_CB_IC:
+ case CST_SSTYPE_CB_ICR:
+ cb_info.Type = __cst_get_tapi_cb_flavour(req->flavour);
+ cb_info.CallType = __cst_get_tapi_teleservice_type(req->call_type);
+
+ DBG("%d <= %d <= %d calltype", TAPI_CALL_TYPE_VOICE_EV, cb_info.CallType, TAPI_CALL_TYPE_ALL_TELE);
+ DBG("%d <= %d <= %d type", TAPI_CALL_BARRING_ALL, cb_info.Type, TAPI_CALL_BARRING_ALL_INCOMING_CALLS_INSIM);
+ if (req->action == CST_ACTION_QUERY) {
+ api_ret = tel_get_ss_barring_status(cb_info.Type, cb_info.CallType, &req_id);
+ } else {
+ cb_info.Mode = __cst_get_tapi_cb_mode(req->action);
+ DBG("%d <= %d <= %d mode", TAPI_SS_CALL_BAR_ACTIVATE, cb_info.Mode, TAPI_SS_CALL_BAR_DEACTIVATE);
+ DBG("%d == %d pwd length", strnlen(cb_info.szPassword, 4), TAPI_SS_GSM_BARR_PW_LEN_MAX);
+ memcpy(cb_info.szPassword, req->number, TAPI_SS_GSM_BARR_PW_LEN_MAX);
+ api_ret = tel_set_ss_barring(&cb_info, &req_id);
+ }
+ break;
+ case CST_SSTYPE_CW:
+ cw_info.CallType = __cst_get_tapi_teleservice_type(req->call_type);
+ if (req->action == CST_ACTION_QUERY) {
+ api_ret = tel_get_ss_waiting_status(cw_info.CallType, &req_id);
+ } else {
+ cw_info.Mode = __cst_get_tapi_cw_mode(req->action);
+ api_ret = tel_set_ss_waiting(&cw_info, &req_id);
+ }
+ break;
+ }
+
+ if (req->req_id != -1) {
+ req->req_id = req_id;
+ }
+
+ if (api_ret != TAPI_API_SUCCESS) {
+ CstGlItemData_t *item_data;
+ CstUgData_t *ugd;
+
+ req->func(req->call_type, req->flavour, EINA_FALSE, NULL, CST_ERROR_INCORRECT_OPERATION, req->action, req->data);
+ item_data = (CstGlItemData_t *)req->data;
+ ugd = (CstUgData_t *)item_data->ugd;
+ __cst_remove_ss_request(ugd);
+ }
+ DBG("api_ret=%d req_id=0x%p", api_ret, req_id);
+
+ LEAVE();
+ return;
+}
+
+static int __cst_on_tel_event_cf_cnf(const TelTapiEvent_t *event, void *userdata)
+{
+ ENTER(__cst_on_tel_event_cf_cnf);
+
+ CstUgData_t *ugd = (CstUgData_t *)userdata;
+ retv_if(event == NULL, -1);
+ retv_if(ugd == NULL, -1);
+
+ int i;
+
+ DBG("event->type =%d req_id=0x%x status=0x%x dlen=%d", event->EventType, event->RequestId, event->Status, event->pDataLen);
+
+ CallSettingReq_t *req;
+ req = __cst_get_current_request(ugd);
+ retv_if(req == NULL, -1);
+ retv_if(req->req_id != event->RequestId, -1);
+ retv_if(req->is_requesting == EINA_FALSE, -1);
+ if (req->is_canceled == EINA_TRUE) {
+ DBG("Req(0x%xp,req_id=%d) was canceled. So It will be removed", req, req->req_id);
+ __cst_remove_ss_request(ugd);
+ return 0;
+ }
+
+ if (event->EventClass != TAPI_EVENT_CLASS_SS) {
+ DBG("wrong event class");
+ return -1;
+ }
+
+ if (event->EventType != TAPI_EVENT_SS_FORWARD_CNF && event->EventType != TAPI_EVENT_SS_FORWARD_QUERYSTATUS_CNF) {
+ DBG("wrong event type");
+ return -1;
+ }
+
+ if (event->Status != TAPI_SS_SUCCESS) {
+ DBG("Event Status is %d", event->Status);
+ int error;
+ error = __cst_get_ciss_error_from_tapi_error(event->Status);
+ DBG("req=0x%p", req);
+ if (req) {
+ req->func(req->call_type, req->flavour, EINA_FALSE, NULL, error, req->action, req->data);
+ }
+ __cst_remove_ss_request(ugd);
+ return 0;
+ }
+
+ if (event->pData == NULL) {
+ DBG("Event data is NULL");
+ return -1;
+ }
+
+ TelSsInfo_t ss_info;
+ memcpy(&ss_info, event->pData, sizeof(TelSsInfo_t));
+
+ char number[TAPI_CALL_DIALDIGIT_LEN_MAX];
+
+ Eina_Bool cf_state = EINA_FALSE;
+ int cf_flavour;
+ int call_type;
+
+ for (i = 0; i < ss_info.NumberOfRecords; ++i) {
+ number[0] = '\0';
+ DBG("TeleCommService=%d", ss_info.SsRecord.ForwardingRecord.rec_class[i].TeleCommService);
+ DBG("Flavour=%d", ss_info.SsRecord.ForwardingRecord.rec_class[i].ForwardCondition);
+ DBG("Status=%d", ss_info.SsRecord.ForwardingRecord.rec_class[i].Status);
+ switch (ss_info.SsRecord.ForwardingRecord.rec_class[i].TeleCommService) {
+ case TAPI_SS_TS_ALL_SPEECH:
+ call_type = CST_CALLTYPE_VOICE;
+ break;
+ case TAPI_SS_BS_DATA_CIRCUIT_SYNC:
+ call_type = CST_CALLTYPE_VIDEO;
+ break;
+ case TAPI_SS_TS_ALL_TELESERVICES:
+ case TAPI_SS_TS_ALL_TELE_AND_BEARER_SERVICES:
+ call_type = CST_CALLTYPE_ALL;
+ break;
+ default:
+ call_type = -1;
+ break;
+ }
+ //If the call type of the record is not same with request, skip below code
+ DBG("req->call_type == %d call_type=%d", req->call_type, call_type);
+ if (req->call_type != call_type && call_type != CST_CALLTYPE_ALL)
+ continue;
+
+ switch (ss_info.SsRecord.ForwardingRecord.rec_class[i].ForwardCondition) {
+ case TAPI_SS_FORWARD_WHEN_UNCONDITIONAL_EV:
+ cf_flavour = CST_SSTYPE_CF_UNCONDITIONAL;
+ break;
+ case TAPI_SS_FORWARD_WHEN_BUSY_EV:
+ cf_flavour = CST_SSTYPE_CF_BUSY;
+ break;
+ case TAPI_SS_FORWARD_WHEN_NO_ANSWER_EV:
+ cf_flavour = CST_SSTYPE_CF_NO_REPLY;
+ break;
+ case TAPI_SS_FORWARD_WHEN_NOT_REACHABLE_EV:
+ cf_flavour = CST_SSTYPE_CF_NOT_REACHABLE;
+ break;
+ case TAPI_SS_FORWARD_WHEN_ALL_FORWARDING_EV:
+ cf_flavour = CST_SSTYPE_CF_ALL;
+ break;
+ case TAPI_SS_FORWARD_WHEN_ALL_CONDITIONAL_EV:
+ cf_flavour = CST_SSTYPE_CF_ALL_CONDITIONAL;
+ break;
+ default:
+ ERR("Invalid CF Flavour");
+ return -1;
+ }
+
+ switch (ss_info.SsRecord.ForwardingRecord.rec_class[i].Status) {
+ case TAPI_SS_STATUS_ACTIVE:
+ case TAPI_SS_STATUS_REGISTERED:
+ cf_state = EINA_TRUE;
+ break;
+ case TAPI_SS_STATUS_NOTHING:
+ case TAPI_SS_STATUS_PROVISIONED:
+ case TAPI_SS_STATUS_QUIESCENT:
+ cf_state = EINA_FALSE;
+ break;
+ default:
+ ERR("Invalid CF state");
+ return -1;
+ }
+
+ if (ss_info.SsRecord.ForwardingRecord.rec_class[i].bCallForwardingNumberPresent == 1) {
+ snprintf(number, TAPI_CALL_DIALDIGIT_LEN_MAX, "%s", ss_info.SsRecord.ForwardingRecord.rec_class[i].szCallForwardingNumber);
+ }
+
+ req->func(call_type, cf_flavour, cf_state, number, CST_ERROR_NONE, req->action, req->data);
+ }
+
+ __cst_remove_ss_request(ugd);
+
+ LEAVE();
+
+ return 0;
+}
+
+static int __cst_on_tel_event_cb_cnf(const TelTapiEvent_t *event, void *userdata)
+{
+ ENTER(__cst_on_tel_event_cb_cnf);
+
+ CstUgData_t *ugd = (CstUgData_t *)userdata;
+ retv_if(event == NULL, -1);
+ retv_if(ugd == NULL, -1);
+
+ int i;
+
+ DBG("event->type =%d req_id=0x%x status=0x%x dlen=%d", event->EventType, event->RequestId, event->Status, event->pDataLen);
+
+ CallSettingReq_t *req;
+ req = __cst_get_current_request(ugd);
+ retv_if(req == NULL, -1);
+ retv_if(req->req_id != event->RequestId, -1);
+ retv_if(req->is_requesting == EINA_FALSE, -1);
+ if (req->is_canceled == EINA_TRUE) {
+ __cst_remove_ss_request(ugd);
+ return 0;
+ }
+
+ if (event->EventClass != TAPI_EVENT_CLASS_SS) {
+ DBG("wrong event class");
+ return -1;
+ }
+
+ if (event->Status != TAPI_SS_SUCCESS) {
+ DBG("Event Status is %d", event->Status);
+ int error;
+ error = __cst_get_ciss_error_from_tapi_error(event->Status);
+ if (req) {
+ req->func(req->call_type, req->flavour, EINA_FALSE, NULL, error, req->action, req->data);
+ }
+ __cst_remove_ss_request(ugd);
+ return 0;
+ }
+
+ if (event->pData == NULL) {
+ DBG("Event data is NULL");
+ return -1;
+ }
+
+ TelSsInfo_t ss_info;
+ memcpy(&ss_info, event->pData, sizeof(TelSsInfo_t));
+
+ char number[50];
+
+ Eina_Bool cb_state = EINA_FALSE;
+ int cb_flavour = -1;
+ int call_type;
+
+ for (i = 0; i < ss_info.NumberOfRecords; ++i) {
+ number[0] = '\0';
+ DBG("TeleCommService=0x%x", ss_info.SsRecord.BarringRecord.rec_class[i].TeleCommService);
+ DBG("Flavour=0x%x", ss_info.SsRecord.BarringRecord.rec_class[i].Flavour);
+ DBG("Status=0x%x", ss_info.SsRecord.BarringRecord.rec_class[i].Status);
+ switch (ss_info.SsRecord.BarringRecord.rec_class[i].TeleCommService) {
+ case TAPI_SS_TS_ALL_SPEECH:
+ call_type = CST_CALLTYPE_VOICE;
+ break;
+ case TAPI_SS_TS_ALL_DATA_TELESERVICES:
+ call_type = CST_CALLTYPE_VIDEO;
+ break;
+ case TAPI_SS_TS_ALL_TELESERVICES:
+ case TAPI_SS_ALL_TELE_BEARER:
+ call_type = CST_CALLTYPE_ALL;
+ break;
+ default:
+ call_type = -1;
+ break;
+ }
+ //If the call type of the record is not same with request, skip below code
+ if (req->call_type != call_type && call_type != CST_CALLTYPE_ALL)
+ continue;
+
+ switch (ss_info.SsRecord.BarringRecord.rec_class[i].Flavour) {
+ case TAPI_CALL_BARRING_ALL_OUTGOING_CALLS:
+ cb_flavour = CST_SSTYPE_CB_OC;
+ break;
+ case TAPI_CALL_BARRING_ALL_OUTGOING_INTERN_CALL:
+ cb_flavour = CST_SSTYPE_CB_OIC;
+ break;
+ case TAPI_CALL_BARRING_ALL_OUTGOING_INTERN_CALL_EXCEPT:
+ cb_flavour = CST_SSTYPE_CB_OICEH;
+ break;
+ case TAPI_CALL_BARRING_ALL_INCOMING_CALLS:
+ cb_flavour = CST_SSTYPE_CB_IC;
+ break;
+ case TAPI_CALL_BARRING_ALL_INCOMING_CALLS_ROAMING:
+ cb_flavour = CST_SSTYPE_CB_ICR;
+ break;
+ default:
+ ERR("Invalid CB Flavour");
+ return 0;
+ }
+
+ switch (ss_info.SsRecord.BarringRecord.rec_class[i].Status) {
+ case TAPI_SS_STATUS_ACTIVE:
+ case TAPI_SS_STATUS_REGISTERED:
+ cb_state = EINA_TRUE;
+ break;
+ case TAPI_SS_STATUS_NOTHING:
+ case TAPI_SS_STATUS_PROVISIONED:
+ case TAPI_SS_STATUS_QUIESCENT:
+ cb_state = EINA_FALSE;
+ break;
+ default:
+ ERR("Invalid CB state");
+ return 0;
+ }
+
+ }
+
+ req->func(call_type, cb_flavour, cb_state, NULL, CST_ERROR_NONE, req->action, req->data);
+
+ __cst_remove_ss_request(ugd);
+
+ LEAVE();
+
+ return -1;
+}
+
+static int __cst_on_tel_event_cw_cnf(const TelTapiEvent_t *event, void *userdata)
+{
+ ENTER(__cst_on_tel_event_cw_cnf);
+ CstUgData_t *ugd = (CstUgData_t *)userdata;
+ retv_if(event == NULL, -1);
+ retv_if(ugd == NULL, -1);
+
+ CallSettingReq_t *req;
+
+ req = __cst_get_current_request(ugd);
+ retv_if(req == NULL, -1);
+ retv_if(req->req_id != event->RequestId, -1);
+ retv_if(req->is_requesting == EINA_FALSE, -1);
+ retv_if(NULL == req->data, -1);
+ if (req->is_canceled == EINA_TRUE) {
+ __cst_remove_ss_request(ugd);
+ return 0;
+ }
+
+ DBG("event->type =%d req_id=0x%x status=0x%x dlen=%d", event->EventType, event->RequestId, event->Status, event->pDataLen);
+
+ if (event->EventClass != TAPI_EVENT_CLASS_SS) {
+ DBG("wrong event class");
+ return -1;
+ }
+
+ if (event->Status != TAPI_SS_SUCCESS) {
+ DBG("Event Status is %d", event->Status);
+ int error;
+
+ error = __cst_get_ciss_error_from_tapi_error(event->Status);
+
+ if (req) {
+ req->func(req->call_type, req->flavour, EINA_TRUE, NULL, error, req->action, req->data);
+ }
+
+ __cst_remove_ss_request(ugd);
+ return 0;
+ }
+
+ if (event->pData == NULL) {
+ DBG("Event data is NULL");
+ return -1;
+ }
+
+ TelSsInfo_t ss_info;
+ memcpy(&ss_info, event->pData, sizeof(TelSsInfo_t));
+
+ DBG("CW Status = %d", ss_info.SsRecord.WaitingRecord.rec_class[0].Status);
+ retv_if(NULL == req->func, -1);
+ switch (ss_info.SsRecord.WaitingRecord.rec_class[0].Status) {
+ case TAPI_SS_STATUS_ACTIVE:
+ case TAPI_SS_STATUS_REGISTERED:
+ req->func(req->call_type, req->flavour, EINA_TRUE, NULL, CST_ERROR_NONE, req->action, req->data);
+ break;
+ case TAPI_SS_STATUS_PROVISIONED:
+ case TAPI_SS_STATUS_QUIESCENT:
+ req->func(req->call_type, req->flavour, EINA_FALSE, NULL, CST_ERROR_NONE, req->action, req->data);
+ break;
+ default:
+ ERR("Call waiting query error");
+ break;
+ }
+
+ __cst_remove_ss_request(ugd);
+ LEAVE();
+ return 0;
+}
+
+typedef struct _EventHandler {
+ int event_type;
+ TelAppCallback func;
+} EventHandler;
+
+void _cst_ciss_register_tel_event(void *data)
+{
+ ENTER(_cst_ciss_register_tel_event);
+ CstUgData_t *ugd = (CstUgData_t *)data;
+ int i = 0;
+ int len = 0;
+ int sub_id = 0;
+ int api_ret = -1;
+
+ EventHandler event_list[] = {
+ {TAPI_EVENT_SS_FORWARD_QUERYSTATUS_CNF, __cst_on_tel_event_cf_cnf},
+ {TAPI_EVENT_SS_FORWARD_CNF, __cst_on_tel_event_cf_cnf},
+ {TAPI_EVENT_SS_WAITING_QUERYSTATUS_CNF, __cst_on_tel_event_cw_cnf},
+ {TAPI_EVENT_SS_WAITING_CNF, __cst_on_tel_event_cw_cnf},
+ {TAPI_EVENT_SS_BARRING_QUERYSTATUS_CNF, __cst_on_tel_event_cb_cnf},
+ {TAPI_EVENT_SS_BARRING_CNF, __cst_on_tel_event_cb_cnf},
+ };
+
+ len = sizeof(event_list) / sizeof(EventHandler);
+
+ ugd->tel_event_subscription_list = NULL;
+ if (tel_init() == TAPI_API_SUCCESS) {
+ for (i = 0; i < len; i++) {
+ api_ret = tel_register_event(event_list[i].event_type, &sub_id, event_list[i].func, (void *)ugd);
+ if (api_ret != TAPI_API_SUCCESS)
+ DBG("tel_register_event error=%d", api_ret);
+ DBG("tapi callback=0x%p", event_list[i].func);
+ ugd->tel_event_subscription_list = g_slist_append(ugd->tel_event_subscription_list, GINT_TO_POINTER(sub_id));
+ }
+ api_ret = tel_register_app_name("org.tizen.ciss");
+ if (api_ret != TAPI_API_SUCCESS)
+ DBG("tel_register_app_name error=%d", api_ret);
+ } else
+ ERR("TelTapiInit() failed.");
+
+ LEAVE();
+
+ return;
+}
+
+static void __cst_deregister_tel_event(gpointer data, gpointer userdata)
+{
+ int ret;
+ int sub_id = GPOINTER_TO_INT(data);
+ ret = tel_deregister_event(sub_id);
+ DBG("sub_id = %d, ret = %d", sub_id, ret);
+}
+
+void _cst_ciss_deregister_tel_event(void *data)
+{
+ ENTER(_cst_ciss_deregister_tel_event);
+ CstUgData_t *ugd = (CstUgData_t *)data;
+
+ g_slist_foreach(ugd->tel_event_subscription_list, __cst_deregister_tel_event, NULL);
+ g_slist_free(ugd->tel_event_subscription_list);
+ LEAVE();
+}