2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #define TELEPHONY_NOTI_ID_CNT 8
24 static bool __telephonyInitialized = false;
25 static telephony_noti_e __callNotiIds[] =
27 TELEPHONY_NOTI_VOICE_CALL_STATUS_IDLE,
28 TELEPHONY_NOTI_VOICE_CALL_STATUS_ACTIVE,
29 // TELEPHONY_NOTI_VOICE_CALL_STATUS_HELD,
30 // TELEPHONY_NOTI_VOICE_CALL_STATUS_DIALING,
31 TELEPHONY_NOTI_VOICE_CALL_STATUS_ALERTING,
32 TELEPHONY_NOTI_VOICE_CALL_STATUS_INCOMING,
33 TELEPHONY_NOTI_VIDEO_CALL_STATUS_IDLE,
34 TELEPHONY_NOTI_VIDEO_CALL_STATUS_ACTIVE,
35 // TELEPHONY_NOTI_VIDEO_CALL_STATUS_DIALING,
36 TELEPHONY_NOTI_VIDEO_CALL_STATUS_ALERTING,
37 TELEPHONY_NOTI_VIDEO_CALL_STATUS_INCOMING,
41 CallStateProvider::CallStateProvider() :
42 BasicProvider(SUBJ_STATE_CALL)
44 __handleList.count = 0;
45 __handleList.handle = NULL;
48 CallStateProvider::~CallStateProvider()
52 bool CallStateProvider::isSupported()
54 return util::getSystemInfoBool("tizen.org/feature/network.telephony");
57 void CallStateProvider::__updateCb(telephony_h handle, telephony_noti_e notiId, void *data, void *userData)
59 CallStateProvider *instance = static_cast<CallStateProvider*>(userData);
60 instance->__handleUpdate(handle, notiId, data);
63 void CallStateProvider::__handleUpdate(telephony_h handle, telephony_noti_e notiId, void* id)
67 telephony_call_h *callList;
71 case TELEPHONY_NOTI_VOICE_CALL_STATUS_IDLE:
72 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_IDLE:
73 data.set(NULL, KEY_STATE, VAL_IDLE);
75 case TELEPHONY_NOTI_VOICE_CALL_STATUS_ACTIVE:
76 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_ACTIVE:
77 data.set(NULL, KEY_STATE, VAL_ACTIVE);
79 case TELEPHONY_NOTI_VOICE_CALL_STATUS_ALERTING:
80 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_ALERTING:
81 data.set(NULL, KEY_STATE, VAL_ALERTING);
83 case TELEPHONY_NOTI_VOICE_CALL_STATUS_INCOMING:
84 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_INCOMING:
85 data.set(NULL, KEY_STATE, VAL_INCOMING);
87 /* // Ignore below cases
88 case TELEPHONY_NOTI_VOICE_CALL_STATUS_HELD:
89 case TELEPHONY_NOTI_VOICE_CALL_STATUS_DIALING:
90 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_DIALING:*/
92 _E("Unkown noti id: %d", notiId);
98 case TELEPHONY_NOTI_VOICE_CALL_STATUS_IDLE:
99 case TELEPHONY_NOTI_VOICE_CALL_STATUS_ACTIVE:
100 case TELEPHONY_NOTI_VOICE_CALL_STATUS_ALERTING:
101 case TELEPHONY_NOTI_VOICE_CALL_STATUS_INCOMING:
102 data.set(NULL, KEY_TYPE, VAL_VOICE);
104 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_IDLE:
105 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_ACTIVE:
106 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_ALERTING:
107 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_INCOMING:
108 data.set(NULL, KEY_TYPE, VAL_VIDEO);
110 /* // Ignore below cases
111 case TELEPHONY_NOTI_VOICE_CALL_STATUS_HELD:
112 case TELEPHONY_NOTI_VOICE_CALL_STATUS_DIALING:
113 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_DIALING:*/
115 _E("Unkown noti id: %d", notiId);
119 int err = telephony_call_get_call_list(handle, &count, &callList);
120 IF_FAIL_VOID_TAG(err == TELEPHONY_ERROR_NONE, _E, "Getting call list failed");
122 unsigned int callId = *static_cast<unsigned int *>(id);
123 for (unsigned int i = 0; i < count; i++) {
126 if (!__getCallHandleId(callList[i], tempId)) {
130 if (callId != tempId) {
136 if (__getCallAddress(callList[i], address)) {
137 data.set(NULL, KEY_ADDRESS, address);
142 if (__latest != data) {
143 publish(NULL, ERR_NONE, data);
144 __latest = data.str();
146 telephony_call_release_call_list(count, &callList);
149 bool CallStateProvider::__initTelephony()
151 IF_FAIL_RETURN(!__telephonyInitialized, true);
153 int err = telephony_init(&__handleList);
154 IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, false, _E, "Initialization failed");
156 __telephonyInitialized = true;
160 void CallStateProvider::__releaseTelephony()
162 IF_FAIL_VOID(__telephonyInitialized);
164 telephony_deinit(&__handleList);
166 __telephonyInitialized = false;
169 bool CallStateProvider::__setCallback()
171 /* TODO: Consider dual-sim devices */
172 IF_FAIL_RETURN_TAG(__initTelephony(), false, _E, "Initialization failed");
176 for (unsigned int i = 0; i < __handleList.count; i++) {
177 for (unsigned int j = 0; j < TELEPHONY_NOTI_ID_CNT; j++) {
178 err = telephony_set_noti_cb(__handleList.handle[i], __callNotiIds[j], __updateCb, this);
179 IF_FAIL_CATCH(err == TELEPHONY_ERROR_NONE);
186 _E("Initialization failed");
187 __releaseTelephony();
191 void CallStateProvider::__unsetCallback()
193 for (unsigned int i = 0; i < __handleList.count; i++) {
194 for (unsigned int j = 0; j < TELEPHONY_NOTI_ID_CNT; j++) {
195 telephony_unset_noti_cb(__handleList.handle[i], __callNotiIds[j]);
199 __releaseTelephony();
202 bool CallStateProvider::__getCallState(telephony_call_h& handle, std::string& state)
206 telephony_call_status_e st;
207 int err = telephony_call_get_status(handle, &st);
208 IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, false, _E, "Getting state failed");
211 case TELEPHONY_CALL_STATUS_ACTIVE:
214 case TELEPHONY_CALL_STATUS_HELD:
217 case TELEPHONY_CALL_STATUS_DIALING:
220 case TELEPHONY_CALL_STATUS_ALERTING:
221 state = VAL_ALERTING;
223 case TELEPHONY_CALL_STATUS_INCOMING:
224 state = VAL_INCOMING;
230 IF_FAIL_RETURN_TAG(!state.empty(), false, _W, "State is empty");
235 bool CallStateProvider::__getCallType(telephony_call_h& handle, std::string& type)
239 telephony_call_type_e t;
240 int err = telephony_call_get_type(handle, &t);
241 IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, false, _E, "Getting type failed");
244 case TELEPHONY_CALL_TYPE_VOICE:
247 case TELEPHONY_CALL_TYPE_VIDEO:
251 _E("Unknown type: %d", t);
255 IF_FAIL_RETURN_TAG(!type.empty(), false, _W, "Type is empty");
260 bool CallStateProvider::__getCallAddress(telephony_call_h& handle, std::string& address)
265 int err = telephony_call_get_number(handle, &number);
266 IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, false, _E, "Getting address failed");
274 IF_FAIL_RETURN_TAG(!address.empty(), false, _W, "Address is empty");
279 bool CallStateProvider::__getCallHandleId(telephony_call_h& handle, unsigned int& id)
281 int err = telephony_call_get_handle_id(handle, &id);
282 IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, false, _E, "Getting handle id failed");
287 int CallStateProvider::subscribe()
289 bool ret = __setCallback();
290 IF_FAIL_RETURN(ret, ERR_OPERATION_FAILED);
294 int CallStateProvider::unsubscribe()
300 bool CallStateProvider::__readCurrentStatus(telephony_h& handle, Json* data)
302 unsigned int count = 0;
303 telephony_call_h *callList = NULL;
304 telephony_call_get_call_list(handle, &count, &callList);
307 data->set(NULL, KEY_STATE, VAL_IDLE);
309 // Held & Dialing are ignored
310 for (unsigned int i = 0; i < count; i++) {
313 if (__getCallState(callList[i], state)) {
314 // Skip Held & Dialing
315 if (state.compare(VAL_HELD) == 0 || state.compare(VAL_DIALING) == 0)
318 data->set(NULL, KEY_STATE, state);
323 if (__getCallType(callList[i], type)) {
324 data->set(NULL, KEY_MEDIUM, type);
329 if (__getCallAddress(callList[i], address)) {
330 data->set(NULL, KEY_ADDRESS, address);
333 if (state == VAL_ACTIVE) {
338 telephony_call_release_call_list(count, &callList);
342 int CallStateProvider::read()
344 bool temporaryHandle = false;
345 if (!__telephonyInitialized) {
346 IF_FAIL_RETURN(__initTelephony(), ERR_OPERATION_FAILED);
347 temporaryHandle = true;
352 data.set(NULL, KEY_STATE, VAL_IDLE);
354 for (unsigned int i = 0; i < __handleList.count; i++) {
355 telephony_sim_state_e state;
356 int err = telephony_sim_get_state(__handleList.handle[i], &state);
357 IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, ERR_OPERATION_FAILED, _E, "Getting SIM status failed");
359 if (state != TELEPHONY_SIM_STATE_AVAILABLE)
362 ret = __readCurrentStatus(__handleList.handle[i], &data);
367 __releaseTelephony();
370 replyToRead(NULL, ERR_NONE, data);
374 return ERR_OPERATION_FAILED;