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.
19 #define TELEPHONY_NOTI_ID_CNT 8
23 static bool __telephonyInitialized = false;
24 static telephony_noti_e __callNotiIds[] =
26 TELEPHONY_NOTI_VOICE_CALL_STATUS_IDLE,
27 TELEPHONY_NOTI_VOICE_CALL_STATUS_ACTIVE,
28 // TELEPHONY_NOTI_VOICE_CALL_STATUS_HELD,
29 // TELEPHONY_NOTI_VOICE_CALL_STATUS_DIALING,
30 TELEPHONY_NOTI_VOICE_CALL_STATUS_ALERTING,
31 TELEPHONY_NOTI_VOICE_CALL_STATUS_INCOMING,
32 TELEPHONY_NOTI_VIDEO_CALL_STATUS_IDLE,
33 TELEPHONY_NOTI_VIDEO_CALL_STATUS_ACTIVE,
34 // TELEPHONY_NOTI_VIDEO_CALL_STATUS_DIALING,
35 TELEPHONY_NOTI_VIDEO_CALL_STATUS_ALERTING,
36 TELEPHONY_NOTI_VIDEO_CALL_STATUS_INCOMING,
40 SocialStatusCall::SocialStatusCall() :
41 DeviceProviderBase(SOCIAL_ST_SUBJ_CALL)
43 __handleList.count = 0;
44 __handleList.handle = NULL;
47 SocialStatusCall::~SocialStatusCall()
51 bool SocialStatusCall::isSupported()
53 return getSystemInfoBool("tizen.org/feature/network.telephony");
56 void SocialStatusCall::submitTriggerItem()
58 registerTriggerItem(OPS_SUBSCRIBE | OPS_READ,
60 "\"Medium\":{\"type\":\"string\",\"values\":[\"Voice\",\"Video\"]},"
61 "\"State\":{\"type\":\"string\",\"values\":[\"Idle\",\"Connecting\",\"Connected\"]},"
62 "\"Address\":{\"type\":\"string\"}"
65 /* TODO remove Connecting, Connected */
68 void SocialStatusCall::__updateCb(telephony_h handle, telephony_noti_e notiId, void *data, void *userData)
70 SocialStatusCall *instance = static_cast<SocialStatusCall*>(userData);
71 instance->__handleUpdate(handle, notiId, data);
74 void SocialStatusCall::__handleUpdate(telephony_h handle, telephony_noti_e notiId, void* id)
78 telephony_call_h *callList;
82 case TELEPHONY_NOTI_VOICE_CALL_STATUS_IDLE:
83 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_IDLE:
84 data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_IDLE);
86 case TELEPHONY_NOTI_VOICE_CALL_STATUS_ACTIVE:
87 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_ACTIVE:
88 data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_ACTIVE);
90 case TELEPHONY_NOTI_VOICE_CALL_STATUS_ALERTING:
91 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_ALERTING:
92 data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_ALERTING);
94 case TELEPHONY_NOTI_VOICE_CALL_STATUS_INCOMING:
95 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_INCOMING:
96 data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_INCOMING);
98 /* // Ignore below cases
99 case TELEPHONY_NOTI_VOICE_CALL_STATUS_HELD:
100 case TELEPHONY_NOTI_VOICE_CALL_STATUS_DIALING:
101 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_DIALING:*/
103 _E("Unkown noti id: %d", notiId);
109 case TELEPHONY_NOTI_VOICE_CALL_STATUS_IDLE:
110 case TELEPHONY_NOTI_VOICE_CALL_STATUS_ACTIVE:
111 case TELEPHONY_NOTI_VOICE_CALL_STATUS_ALERTING:
112 case TELEPHONY_NOTI_VOICE_CALL_STATUS_INCOMING:
113 data.set(NULL, SOCIAL_ST_TYPE, SOCIAL_ST_VOICE);
115 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_IDLE:
116 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_ACTIVE:
117 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_ALERTING:
118 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_INCOMING:
119 data.set(NULL, SOCIAL_ST_TYPE, SOCIAL_ST_VIDEO);
121 /* // Ignore below cases
122 case TELEPHONY_NOTI_VOICE_CALL_STATUS_HELD:
123 case TELEPHONY_NOTI_VOICE_CALL_STATUS_DIALING:
124 case TELEPHONY_NOTI_VIDEO_CALL_STATUS_DIALING:*/
126 _E("Unkown noti id: %d", notiId);
130 int err = telephony_call_get_call_list(handle, &count, &callList);
131 IF_FAIL_VOID_TAG(err == TELEPHONY_ERROR_NONE, _E, "Getting call list failed");
133 unsigned int callId = *static_cast<unsigned int *>(id);
134 for (unsigned int i = 0; i < count; i++) {
137 if (!__getCallHandleId(callList[i], tempId)) {
141 if (callId != tempId) {
147 if (__getCallAddress(callList[i], address)) {
148 data.set(NULL, SOCIAL_ST_ADDRESS, address);
153 if (__latest != data) {
154 publish(NULL, ERR_NONE, data);
155 __latest = data.str();
157 telephony_call_release_call_list(count, &callList);
160 bool SocialStatusCall::__initTelephony()
162 IF_FAIL_RETURN(!__telephonyInitialized, true);
164 int err = telephony_init(&__handleList);
165 IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, false, _E, "Initialization failed");
167 __telephonyInitialized = true;
171 void SocialStatusCall::__releaseTelephony()
173 IF_FAIL_VOID(__telephonyInitialized);
175 telephony_deinit(&__handleList);
177 __telephonyInitialized = false;
180 bool SocialStatusCall::__setCallback()
182 /* TODO: Consider dual-sim devices */
183 IF_FAIL_RETURN_TAG(__initTelephony(), false, _E, "Initialization failed");
187 for (unsigned int i = 0; i < __handleList.count; i++) {
188 for (unsigned int j = 0; j < TELEPHONY_NOTI_ID_CNT; j++) {
189 err = telephony_set_noti_cb(__handleList.handle[i], __callNotiIds[j], __updateCb, this);
190 IF_FAIL_CATCH(err == TELEPHONY_ERROR_NONE);
197 _E("Initialization failed");
198 __releaseTelephony();
202 void SocialStatusCall::__unsetCallback()
204 for (unsigned int i = 0; i < __handleList.count; i++) {
205 for (unsigned int j = 0; j < TELEPHONY_NOTI_ID_CNT; j++) {
206 telephony_unset_noti_cb(__handleList.handle[i], __callNotiIds[j]);
210 __releaseTelephony();
213 bool SocialStatusCall::__getCallState(telephony_call_h& handle, std::string& state)
217 telephony_call_status_e st;
218 int err = telephony_call_get_status(handle, &st);
219 IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, false, _E, "Getting state failed");
222 case TELEPHONY_CALL_STATUS_ACTIVE:
223 state = SOCIAL_ST_ACTIVE;
225 case TELEPHONY_CALL_STATUS_HELD:
226 state = SOCIAL_ST_HELD;
228 case TELEPHONY_CALL_STATUS_DIALING:
229 state = SOCIAL_ST_DIALING;
231 case TELEPHONY_CALL_STATUS_ALERTING:
232 state = SOCIAL_ST_ALERTING;
234 case TELEPHONY_CALL_STATUS_INCOMING:
235 state = SOCIAL_ST_INCOMING;
238 state = SOCIAL_ST_IDLE;
241 IF_FAIL_RETURN_TAG(!state.empty(), false, _W, "State is empty");
246 bool SocialStatusCall::__getCallType(telephony_call_h& handle, std::string& type)
250 telephony_call_type_e t;
251 int err = telephony_call_get_type(handle, &t);
252 IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, false, _E, "Getting type failed");
255 case TELEPHONY_CALL_TYPE_VOICE:
256 type = SOCIAL_ST_VOICE;
258 case TELEPHONY_CALL_TYPE_VIDEO:
259 type = SOCIAL_ST_VIDEO;
262 _E("Unknown type: %d", t);
266 IF_FAIL_RETURN_TAG(!type.empty(), false, _W, "Type is empty");
271 bool SocialStatusCall::__getCallAddress(telephony_call_h& handle, std::string& address)
276 int err = telephony_call_get_number(handle, &number);
277 IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, false, _E, "Getting address failed");
285 IF_FAIL_RETURN_TAG(!address.empty(), false, _W, "Address is empty");
290 bool SocialStatusCall::__getCallHandleId(telephony_call_h& handle, unsigned int& id)
292 int err = telephony_call_get_handle_id(handle, &id);
293 IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, false, _E, "Getting handle id failed");
298 int SocialStatusCall::subscribe()
300 bool ret = __setCallback();
301 IF_FAIL_RETURN(ret, ERR_OPERATION_FAILED);
305 int SocialStatusCall::unsubscribe()
311 bool SocialStatusCall::__readCurrentStatus(telephony_h& handle, Json* data)
313 unsigned int count = 0;
314 telephony_call_h *callList = NULL;
315 telephony_call_get_call_list(handle, &count, &callList);
318 data->set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_IDLE);
320 // Held & Dialing are ignored
321 for (unsigned int i = 0; i < count; i++) {
324 if (__getCallState(callList[i], state)) {
325 // Skip Held & Dialing
326 if (state.compare(SOCIAL_ST_HELD) == 0 || state.compare(SOCIAL_ST_DIALING) == 0)
329 data->set(NULL, SOCIAL_ST_STATE, state);
334 if (__getCallType(callList[i], type)) {
335 data->set(NULL, SOCIAL_ST_MEDIUM, type);
340 if (__getCallAddress(callList[i], address)) {
341 data->set(NULL, SOCIAL_ST_ADDRESS, address);
344 if (state == SOCIAL_ST_ACTIVE) {
349 telephony_call_release_call_list(count, &callList);
353 int SocialStatusCall::read()
355 bool temporaryHandle = false;
356 if (!__telephonyInitialized) {
357 IF_FAIL_RETURN(__initTelephony(), ERR_OPERATION_FAILED);
358 temporaryHandle = true;
363 data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_IDLE);
365 for (unsigned int i = 0; i < __handleList.count; i++) {
366 telephony_sim_state_e state;
367 int err = telephony_sim_get_state(__handleList.handle[i], &state);
368 IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, ERR_OPERATION_FAILED, _E, "Getting SIM status failed");
370 if (state != TELEPHONY_SIM_STATE_AVAILABLE)
373 ret = __readCurrentStatus(__handleList.handle[i], &data);
378 __releaseTelephony();
381 replyToRead(NULL, ERR_NONE, data);
385 return ERR_OPERATION_FAILED;