2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
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.
17 #include "telephony_common.h"
18 #include "telephony_sim.h"
19 #include "telephony_call.h"
20 #include "telephony_network.h"
21 #include "telephony_private.h"
25 #include <tapi_common.h>
27 #include <TelNetwork.h>
28 #include <TapiUtility.h>
33 #define LOG_TAG "CAPI_TELEPHONY"
35 #define CALLBACK_CALL(data) \
36 if (evt_cb_data->cb) { \
37 evt_cb_data->cb(evt_cb_data->handle, \
38 evt_cb_data->noti_id, data, evt_cb_data->user_data); \
41 #define CHECK_INPUT_PARAMETER(arg) \
43 LOGE("INVALID_PARAMETER"); \
44 return TELEPHONY_ERROR_INVALID_PARAMETER; \
49 telephony_noti_e noti_id;
52 } telephony_evt_cb_data;
54 static const char *voice_call_state_tbl[] = {
55 TAPI_NOTI_VOICE_CALL_STATUS_IDLE,
56 TAPI_NOTI_VOICE_CALL_STATUS_ACTIVE,
57 TAPI_NOTI_VOICE_CALL_STATUS_HELD,
58 TAPI_NOTI_VOICE_CALL_STATUS_DIALING,
59 TAPI_NOTI_VOICE_CALL_STATUS_ALERT,
60 TAPI_NOTI_VOICE_CALL_STATUS_INCOMING
63 static const char *video_call_state_tbl[] = {
64 TAPI_NOTI_VIDEO_CALL_STATUS_IDLE,
65 TAPI_NOTI_VIDEO_CALL_STATUS_ACTIVE,
66 TAPI_NOTI_VIDEO_CALL_STATUS_DIALING,
67 TAPI_NOTI_VIDEO_CALL_STATUS_ALERT,
68 TAPI_NOTI_VIDEO_CALL_STATUS_INCOMING
71 static const char *_mapping_noti_id(telephony_noti_e noti_id)
74 case TELEPHONY_NOTI_SIM_STATUS:
75 return TAPI_NOTI_SIM_STATUS;
76 case TELEPHONY_NOTI_NETWORK_SERVICE_STATE:
77 return TAPI_PROP_NETWORK_SERVICE_TYPE;
78 case TELEPHONY_NOTI_NETWORK_CELLID:
79 return TAPI_PROP_NETWORK_CELLID;
80 case TELEPHONY_NOTI_NETWORK_ROAMING_STATUS:
81 return TAPI_PROP_NETWORK_ROAMING_STATUS;
82 case TELEPHONY_NOTI_NETWORK_SIGNALSTRENGTH_LEVEL:
83 return TAPI_PROP_NETWORK_SIGNALSTRENGTH_LEVEL;
89 static int _mapping_sim_status(TelSimCardStatus_t tapi_sim_status)
93 switch (tapi_sim_status) {
94 case TAPI_SIM_STATUS_CARD_ERROR:
95 case TAPI_SIM_STATUS_CARD_NOT_PRESENT:
96 case TAPI_SIM_STATUS_CARD_BLOCKED:
97 case TAPI_SIM_STATUS_CARD_REMOVED:
98 case TAPI_SIM_STATUS_CARD_CRASHED:
99 sim_status = TELEPHONY_SIM_STATE_UNAVAILABLE;
101 case TAPI_SIM_STATUS_SIM_PIN_REQUIRED:
102 case TAPI_SIM_STATUS_SIM_PUK_REQUIRED:
103 case TAPI_SIM_STATUS_SIM_NCK_REQUIRED:
104 case TAPI_SIM_STATUS_SIM_NSCK_REQUIRED:
105 case TAPI_SIM_STATUS_SIM_SPCK_REQUIRED:
106 case TAPI_SIM_STATUS_SIM_CCK_REQUIRED:
107 case TAPI_SIM_STATUS_SIM_LOCK_REQUIRED:
108 sim_status = TELEPHONY_SIM_STATE_LOCKED;
110 case TAPI_SIM_STATUS_SIM_INIT_COMPLETED:
111 sim_status = TELEPHONY_SIM_STATE_AVAILABLE;
113 case TAPI_SIM_STATUS_UNKNOWN:
114 case TAPI_SIM_STATUS_SIM_INITIALIZING:
116 sim_status = TELEPHONY_SIM_STATE_UNKNOWN;
123 static int _mapping_service_state(int tapi_service_type)
127 switch (tapi_service_type) {
128 case TAPI_NETWORK_SERVICE_TYPE_UNKNOWN:
129 case TAPI_NETWORK_SERVICE_TYPE_NO_SERVICE:
130 case TAPI_NETWORK_SERVICE_TYPE_SEARCH:
131 service_state = TELEPHONY_NETWORK_SERVICE_STATE_OUT_OF_SERVICE;
133 case TAPI_NETWORK_SERVICE_TYPE_EMERGENCY:
134 service_state = TELEPHONY_NETWORK_SERVICE_STATE_EMERGENCY_ONLY;
137 service_state = TELEPHONY_NETWORK_SERVICE_STATE_IN_SERVICE;
141 return service_state;
144 static telephony_error_e __deregister_all_noti(telephony_h handle, telephony_noti_e noti_id)
146 const char *tapi_noti;
150 CHECK_INPUT_PARAMETER(handle);
151 tapi_h = ((telephony_data *)handle)->tapi_h;
153 tapi_noti = _mapping_noti_id(noti_id);
154 if (tapi_noti == NULL && noti_id != TELEPHONY_NOTI_VOICE_CALL_STATE
155 && noti_id != TELEPHONY_NOTI_VIDEO_CALL_STATE) {
156 LOGE("Not supported noti_id");
157 return TELEPHONY_ERROR_INVALID_PARAMETER;
160 /* Deregister all TAPI_NOTI_VOICE/VIDEO_CALL_STATUS_xxx notification */
161 if (noti_id == TELEPHONY_NOTI_VOICE_CALL_STATE) {
162 int count = sizeof(voice_call_state_tbl) / sizeof(char *);
163 for (i = 0; i < count; i++) {
164 ret = tel_deregister_noti_event(tapi_h, voice_call_state_tbl[i]);
165 if (ret != TAPI_API_SUCCESS) {
166 LOGE("Noti [%s] deregistration failed", voice_call_state_tbl[i]);
169 } else if (noti_id == TELEPHONY_NOTI_VIDEO_CALL_STATE) {
170 int count = sizeof(video_call_state_tbl) / sizeof(char *);
171 for (i = 0; i < count; i++) {
172 ret = tel_deregister_noti_event(tapi_h, video_call_state_tbl[i]);
173 if (ret != TAPI_API_SUCCESS) {
174 LOGE("Noti [%s] deregistration failed", video_call_state_tbl[i]);
178 /* Deregister other notifications */
179 ret = tel_deregister_noti_event(tapi_h, tapi_noti);
180 if (ret != TAPI_API_SUCCESS) {
181 LOGE("Noti [%s] deregistration failed", tapi_noti);
185 return TELEPHONY_ERROR_NONE;
188 static void _deregister_noti(gpointer data)
190 telephony_evt_cb_data *evt_cb_data = data;
192 if (evt_cb_data != NULL) {
193 /* Deregister all TAPI_NOTI_VOICE/VIDEO_CALL_STATUS_xxx notification */
194 if (__deregister_all_noti(evt_cb_data->handle, evt_cb_data->noti_id)
195 == TELEPHONY_ERROR_NONE) {
196 LOGI("De-registered noti_id: [%d]", evt_cb_data->noti_id);
199 /* Free evt_cb_data */
204 static void on_signal_callback(TapiHandle *tapi_h, const char *evt_id,
205 void *data, void *user_data)
207 telephony_evt_cb_data *evt_cb_data = user_data;
209 if (evt_cb_data == NULL) {
210 LOGE("evt_cb_data is NULL");
214 if (!g_strcmp0(evt_id, TAPI_NOTI_SIM_STATUS)) {
215 int sim_status = _mapping_sim_status(*(TelSimCardStatus_t *)data);
216 CALLBACK_CALL(&sim_status);
217 } else if (!g_strcmp0(evt_id, TAPI_PROP_NETWORK_SERVICE_TYPE)) {
218 int service_state = _mapping_service_state(*(int *)data);
219 CALLBACK_CALL(&service_state);
220 } else if (!g_strcmp0(evt_id, TAPI_PROP_NETWORK_CELLID)) {
221 int cell_id = *(int *)data;
222 CALLBACK_CALL(&cell_id);
223 } else if (!g_strcmp0(evt_id, TAPI_PROP_NETWORK_ROAMING_STATUS)) {
224 int roaming_status = *(int *)data;
225 CALLBACK_CALL(&roaming_status);
226 } else if (!g_strcmp0(evt_id, TAPI_PROP_NETWORK_SIGNALSTRENGTH_LEVEL)) {
227 int rssi = *(int *)data;
228 CALLBACK_CALL(&rssi);
229 } else if (!g_strcmp0(evt_id, TAPI_NOTI_VOICE_CALL_STATUS_IDLE)
230 || !g_strcmp0(evt_id, TAPI_NOTI_VOICE_CALL_STATUS_ACTIVE)
231 || !g_strcmp0(evt_id, TAPI_NOTI_VOICE_CALL_STATUS_HELD)
232 || !g_strcmp0(evt_id, TAPI_NOTI_VOICE_CALL_STATUS_DIALING)
233 || !g_strcmp0(evt_id, TAPI_NOTI_VOICE_CALL_STATUS_ALERT)
234 || !g_strcmp0(evt_id, TAPI_NOTI_VOICE_CALL_STATUS_INCOMING)) {
235 telephony_call_state_e call_state;
236 telephony_call_get_voice_call_state(evt_cb_data->handle, &call_state);
237 CALLBACK_CALL(&call_state);
238 } else if (!g_strcmp0(evt_id, TAPI_NOTI_VIDEO_CALL_STATUS_IDLE)
239 || !g_strcmp0(evt_id, TAPI_NOTI_VIDEO_CALL_STATUS_ACTIVE)
240 || !g_strcmp0(evt_id, TAPI_NOTI_VIDEO_CALL_STATUS_DIALING)
241 || !g_strcmp0(evt_id, TAPI_NOTI_VIDEO_CALL_STATUS_ALERT)
242 || !g_strcmp0(evt_id, TAPI_NOTI_VIDEO_CALL_STATUS_INCOMING)) {
243 telephony_call_state_e call_state;
244 telephony_call_get_video_call_state(evt_cb_data->handle, &call_state);
245 CALLBACK_CALL(&call_state);
247 LOGE("Unhandled noti: [%s]", evt_id);
251 int telephony_set_noti_cb(telephony_h handle,
252 telephony_noti_e noti_id, telephony_noti_cb cb, void *user_data)
254 telephony_evt_cb_data *evt_cb_data = NULL;
255 const char *tapi_noti;
259 CHECK_TELEPHONY_SUPPORTED(TELEPHONY_FEATURE);
260 CHECK_INPUT_PARAMETER(handle);
263 tapi_h = ((telephony_data *)handle)->tapi_h;
265 /* Mapping TAPI notification */
266 tapi_noti = _mapping_noti_id(noti_id);
267 if (tapi_noti == NULL && noti_id != TELEPHONY_NOTI_VOICE_CALL_STATE
268 && noti_id != TELEPHONY_NOTI_VIDEO_CALL_STATE) {
269 LOGE("Not supported noti_id");
270 return TELEPHONY_ERROR_INVALID_PARAMETER;
273 /* Make evt_cb_data */
274 evt_cb_data = g_new0(telephony_evt_cb_data, 1);
275 evt_cb_data->handle = handle;
276 evt_cb_data->noti_id = noti_id;
277 evt_cb_data->cb = cb;
278 evt_cb_data->user_data = user_data;
281 * In case of register Call State notification,
282 * we should take care of all TAPI_NOTI_VOICE/VIDEO_CALL_STATUS_xxx notification
284 if (noti_id == TELEPHONY_NOTI_VOICE_CALL_STATE) {
285 int count = sizeof(voice_call_state_tbl) / sizeof(char *);
286 for (i = 0; i < count; i++) {
287 ret = tel_register_noti_event(tapi_h, voice_call_state_tbl[i], on_signal_callback, evt_cb_data);
288 if (ret != TAPI_API_SUCCESS) {
289 LOGE("Noti registration failed");
291 return TELEPHONY_ERROR_OPERATION_FAILED;
294 } else if (noti_id == TELEPHONY_NOTI_VIDEO_CALL_STATE) {
295 int count = sizeof(video_call_state_tbl) / sizeof(char *);
296 for (i = 0; i < count; i++) {
297 ret = tel_register_noti_event(tapi_h, video_call_state_tbl[i], on_signal_callback, evt_cb_data);
298 if (ret != TAPI_API_SUCCESS) {
299 LOGE("Noti registration failed");
301 return TELEPHONY_ERROR_OPERATION_FAILED;
304 } else { /* Register other notifications */
305 ret = tel_register_noti_event(tapi_h, tapi_noti, on_signal_callback, evt_cb_data);
306 if (ret != TAPI_API_SUCCESS) {
307 LOGE("Noti registration failed");
309 return TELEPHONY_ERROR_OPERATION_FAILED;
313 /* Append evt_cb_data to free */
314 ((telephony_data *)handle)->evt_list = g_slist_append(((telephony_data *)handle)->evt_list, evt_cb_data);
316 return TELEPHONY_ERROR_NONE;
319 int telephony_unset_noti_cb(telephony_h handle, telephony_noti_e noti_id)
321 telephony_evt_cb_data *evt_cb_data = NULL;
324 CHECK_TELEPHONY_SUPPORTED(TELEPHONY_FEATURE);
325 CHECK_INPUT_PARAMETER(handle);
329 /* Deregister all TAPI_NOTI_VOICE/VIDEO_CALL_STATUS_xxx notification */
330 if (__deregister_all_noti(handle, noti_id) != TELEPHONY_ERROR_NONE) {
331 LOGE("De-registration failed");
332 return TELEPHONY_ERROR_INVALID_PARAMETER;
334 LOGI("De-registered noti_id: [%d]", noti_id);
336 /* Free evt_cb_data */
337 list = g_slist_nth(((telephony_data *)handle)->evt_list, 0);
339 evt_cb_data = list->data;
340 if (evt_cb_data->noti_id == noti_id) {
341 ((telephony_data *)handle)->evt_list = g_slist_remove(((telephony_data *)handle)->evt_list, evt_cb_data);
346 list = g_slist_next(list);
349 return TELEPHONY_ERROR_NONE;
352 int telephony_init(telephony_handle_list_s *list)
358 CHECK_TELEPHONY_SUPPORTED(TELEPHONY_FEATURE);
359 CHECK_INPUT_PARAMETER(list);
361 #if !GLIB_CHECK_VERSION(2,35,0)
362 /* Need g_type_init() to use tel_get_cp_name_list() */
366 cp_list = tel_get_cp_name_list();
367 if (cp_list == NULL) {
368 LOGE("cp_list is NULL");
369 return TELEPHONY_ERROR_OPERATION_FAILED;
372 while (cp_list[cp_count]) {
376 list->count = cp_count;
377 list->handle = g_malloc(cp_count * sizeof(telephony_h));
378 for (i = 0; i < cp_count; i++) {
379 telephony_data *tmp = g_malloc(sizeof(telephony_data));
380 tmp->evt_list = NULL;
381 tmp->tapi_h = tel_init(cp_list[i]);
382 if (tmp->tapi_h == NULL) {
384 LOGE("handle is NULL");
386 /* Need to free already allocated data */
387 if (list->handle[j]) {
388 tel_deinit(((telephony_data *)list->handle[j])->tapi_h);
389 g_free(list->handle[j]);
393 g_free(list->handle);
397 return TELEPHONY_ERROR_OPERATION_FAILED;
399 list->handle[i] = (telephony_h)tmp;
403 return TELEPHONY_ERROR_NONE;
406 int telephony_deinit(telephony_handle_list_s *list)
410 CHECK_TELEPHONY_SUPPORTED(TELEPHONY_FEATURE);
411 CHECK_INPUT_PARAMETER(list);
413 for (i = 0; i < list->count; i++) {
414 telephony_data *tmp = (telephony_data *)list->handle[i];
416 /* De-init all TapiHandle */
417 tel_deinit(tmp->tapi_h);
420 /* De-register all registered events */
421 g_slist_free_full(tmp->evt_list, _deregister_noti);
422 tmp->evt_list = NULL;
425 g_free(list->handle[i]);
427 g_free(list->handle);
431 return TELEPHONY_ERROR_NONE;