2 * Copyright 2012 Samsung Electronics Co., Ltd
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
8 * http://www.tizenopensource.org/license
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.
21 #include <TapiUtility.h>
22 #include <tapi_event.h>
23 #include "cst-tapi-request.h"
24 #include "cst-common.h"
25 #include "cst-common-string.h"
26 #include "cst-tapi-request.h"
28 static void __cst_remove_ss_request(void *data);
29 static void __cst_send_ss_req_to_telephony_server(CallSettingSSReq_t *req);
30 static gboolean __cst_ss_barring_resp_cb(TapiHandle *handle, int result, void *data, void *user_data);
31 static gboolean __cst_ss_forward_resp_cb(TapiHandle *handle, int result, void *data, void *user_data);
32 static gboolean __cst_ss_waiting_resp_cb(TapiHandle *handle, int result, void *data, void *user_data);
33 static int __cst_get_ciss_error_from_tapi_error(TelSsCause_t tapi_err);
35 static gboolean __cst_ss_barring_resp_cb(TapiHandle *handle, int result, void *data, void *user_data)
38 TelSsCause_t ss_result = result;
39 TelSsBarringResp_t *cb_data = NULL;
40 CallSettingSSReq_t *req = NULL;
41 CstUgData_t *ugd = NULL;
43 cb_data = (TelSsBarringResp_t *)data;
44 if (cb_data == NULL) {
45 ERR("data is NULL, returning");
49 req = (CallSettingSSReq_t *)user_data;
51 ERR("User_data is NULL, returning");
55 ugd = (CstUgData_t *)req->ugd;
57 ERR("ugd is NULL, returning");
61 retv_if(req->is_requesting == EINA_FALSE, 0);
62 if (req->is_canceled == EINA_TRUE) {
63 __cst_remove_ss_request(ugd);
67 if (ss_result != TAPI_SS_SUCCESS) {
68 DBG("Event Status is %d", ss_result);
70 error = __cst_get_ciss_error_from_tapi_error(ss_result);
72 req->func(req->call_type, req->flavour, EINA_FALSE, NULL, error, req->action, req->data, req->waiting_time);
74 __cst_remove_ss_request(ugd);
79 Eina_Bool cb_state = EINA_FALSE;
84 for (i = 0; i < cb_data->record_num; ++i) {
86 DBG("TeleCommService=0x%x", cb_data->record[i].Class);
87 DBG("Flavour=0x%x", cb_data->record[i].Flavour);
88 DBG("Status=0x%x", cb_data->record[i].Status);
89 switch (cb_data->record[i].Class) {
90 case TAPI_SS_CLASS_VOICE:
91 call_type = CST_CALLTYPE_VOICE;
93 case TAPI_SS_CLASS_ALL_TELE:
94 case TAPI_SS_CLASS_ALL_TELE_BEARER:
95 call_type = CST_CALLTYPE_ALL;
98 ERR("Invalid call type");
102 if (req->call_type != call_type && call_type != CST_CALLTYPE_ALL)
105 switch (cb_data->record[i].Flavour) {
106 case TAPI_SS_CB_TYPE_BAOC:
107 cb_flavour = CST_SSTYPE_CB_OC;
109 case TAPI_SS_CB_TYPE_BOIC:
110 cb_flavour = CST_SSTYPE_CB_OIC;
112 case TAPI_SS_CB_TYPE_BOIC_NOT_HC:
113 cb_flavour = CST_SSTYPE_CB_OICEH;
115 case TAPI_SS_CB_TYPE_BAIC:
116 cb_flavour = CST_SSTYPE_CB_IC;
118 case TAPI_SS_CB_TYPE_BIC_ROAM:
119 cb_flavour = CST_SSTYPE_CB_ICR;
122 ERR("Invalid CB Flavour");
126 switch (cb_data->record[i].Status) {
127 case TAPI_SS_STATUS_ACTIVE:
128 case TAPI_SS_STATUS_REGISTERED:
129 cb_state = EINA_TRUE;
131 case TAPI_SS_STATUS_NOTHING:
132 case TAPI_SS_STATUS_PROVISIONED:
133 case TAPI_SS_STATUS_QUIESCENT:
134 cb_state = EINA_FALSE;
137 ERR("Invalid CB status");
142 req->func(call_type, cb_flavour, cb_state, NULL, CST_ERROR_NONE, req->action, req->data, req->waiting_time);
143 __cst_remove_ss_request(ugd);
147 static gboolean __cst_ss_forward_resp_cb(TapiHandle *handle, int result, void *data, void *user_data)
149 DBG("Enter __cst_ss_forward_resp_cb");
150 TelSsCause_t ss_result = result;
151 TelSsForwardResp_t *cf_data = NULL;
152 CallSettingSSReq_t *req = NULL;
153 CstUgData_t *ugd = NULL;
155 cf_data = (TelSsForwardResp_t *)data;
156 if (cf_data == NULL) {
157 ERR("data is NULL, returning");
161 req = (CallSettingSSReq_t *)user_data;
163 ERR("User_data is NULL, returning");
167 ugd = (CstUgData_t *)req->ugd;
169 ERR("ugd is NULL, returning");
173 retv_if(req->is_requesting == EINA_FALSE, 0);
174 if (req->is_canceled == EINA_TRUE) {
175 DBG("Req(0x%xp,req_id=%d) was canceled. So It will be removed", req, req->req_id);
176 __cst_remove_ss_request(ugd);
180 if (ss_result != TAPI_SS_SUCCESS) {
181 DBG("Event Status is %d", ss_result);
183 error = __cst_get_ciss_error_from_tapi_error(ss_result);
184 DBG("req=0x%p", req);
186 req->func(req->call_type, req->flavour, EINA_FALSE, NULL, error, req->action, req->data, req->waiting_time);
188 __cst_remove_ss_request(ugd);
192 char number[TAPI_CALL_DIALDIGIT_LEN_MAX];
194 Eina_Bool cf_state = EINA_FALSE;
197 int waiting_time = 30;
200 for (i = 0; i < cf_data->record_num; ++i) {
202 DBG("TeleCommService=%d", cf_data->record[i].Class);
203 DBG("Flavour=%d", cf_data->record[i].ForwardCondition);
204 DBG("Status=%d", cf_data->record[i].Status);
205 switch (cf_data->record[i].Class) {
206 case TAPI_SS_CLASS_VOICE:
207 call_type = CST_CALLTYPE_VOICE;
209 case TAPI_SS_CLASS_ALL_TELE:
210 case TAPI_SS_CLASS_ALL_BEARER:
211 call_type = CST_CALLTYPE_ALL;
214 ERR("Invalid CF call type");
218 DBG("req->call_type == %d call_type=%d", req->call_type, call_type);
219 if (req->call_type != call_type && call_type != CST_CALLTYPE_ALL)
222 switch (cf_data->record[i].ForwardCondition) {
223 case TAPI_SS_CF_WHEN_CFU:
224 cf_flavour = CST_SSTYPE_CF_UNCONDITIONAL;
226 case TAPI_SS_CF_WHEN_CFB:
227 cf_flavour = CST_SSTYPE_CF_BUSY;
229 case TAPI_SS_CF_WHEN_CFNRy:
230 cf_flavour = CST_SSTYPE_CF_NO_REPLY;
231 waiting_time = (int)cf_data->record[i].NoReplyWaitTime;
232 DBG("******** Waiting time =%d **********", waiting_time);
234 case TAPI_SS_CF_WHEN_CFNRc:
235 cf_flavour = CST_SSTYPE_CF_NOT_REACHABLE;
237 case TAPI_SS_CF_WHEN_CF_ALL:
238 cf_flavour = CST_SSTYPE_CF_ALL;
240 case TAPI_SS_CF_WHEN_CFC:
241 cf_flavour = CST_SSTYPE_CF_ALL_CONDITIONAL;
244 ERR("Invalid CF Flavour");
248 switch (cf_data->record[i].Status) {
249 case TAPI_SS_STATUS_ACTIVE:
250 case TAPI_SS_STATUS_REGISTERED:
251 cf_state = EINA_TRUE;
253 case TAPI_SS_STATUS_NOTHING:
254 case TAPI_SS_STATUS_PROVISIONED:
255 case TAPI_SS_STATUS_QUIESCENT:
256 cf_state = EINA_FALSE;
259 ERR("Invalid CF status");
263 if (cf_data->record[i].bCallForwardingNumberPresent == 1) {
264 snprintf(number, TAPI_CALL_DIALDIGIT_LEN_MAX, "%s", cf_data->record[i].szCallForwardingNumber);
267 req->func(call_type, cf_flavour, cf_state, number, CST_ERROR_NONE, req->action, req->data, waiting_time);
270 __cst_remove_ss_request(ugd);
274 static gboolean __cst_ss_waiting_resp_cb(TapiHandle *handle, int result, void *data, void *user_data)
276 DBG("Enter __cst_ss_waiting_resp_cb");
277 TelSsCause_t ss_result = result;
278 TelSsWaitingResp_t *cw_data = NULL;
279 CallSettingSSReq_t *req = NULL;
280 CstUgData_t *ugd = NULL;
282 cw_data = (TelSsWaitingResp_t *)data;
283 if (cw_data == NULL) {
284 ERR("data is NULL, returning");
288 req = (CallSettingSSReq_t *)user_data;
290 ERR("User_data is NULL, returning");
294 ugd = (CstUgData_t *)req->ugd;
296 ERR("ugd is NULL, returning");
300 retv_if(req->is_requesting == EINA_FALSE, 0);
301 if (req->is_canceled == EINA_TRUE) {
302 __cst_remove_ss_request(ugd);
306 if (ss_result != TAPI_SS_SUCCESS) {
307 DBG("Event Status is %d", ss_result);
310 error = __cst_get_ciss_error_from_tapi_error(ss_result);
313 req->func(req->call_type, req->flavour, EINA_TRUE, NULL, error, req->action, req->data, req->waiting_time);
315 __cst_remove_ss_request(ugd);
319 DBG("CW Status = %d", cw_data->record[0].Status);
320 retv_if(NULL == req->func, 0);
321 switch (cw_data->record[0].Status) {
322 case TAPI_SS_STATUS_ACTIVE:
323 case TAPI_SS_STATUS_REGISTERED:
324 req->func(req->call_type, req->flavour, EINA_TRUE, NULL, CST_ERROR_NONE, req->action, req->data, req->waiting_time);
326 case TAPI_SS_STATUS_PROVISIONED:
327 case TAPI_SS_STATUS_QUIESCENT:
328 req->func(req->call_type, req->flavour, EINA_FALSE, NULL, CST_ERROR_NONE, req->action, req->data, req->waiting_time);
331 ERR("Call waiting query error");
335 __cst_remove_ss_request(ugd);
339 static void __cst_print_req_queue(Eina_List *queue)
342 CallSettingSSReq_t *req;
343 EINA_LIST_FOREACH(queue, l, req) {
345 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);
349 void _cst_cancel_all_ss_request(void *data)
351 ENTER(_cst_cancel_all_ss_request);
352 CstUgData_t *ugd = (CstUgData_t *)data;
356 CallSettingSSReq_t *req;
358 EINA_LIST_FOREACH_SAFE(ugd->req_queue, l, l_next, req) {
360 DBG("Cancel req=0x%p", req);
361 if (req->is_requesting == EINA_TRUE) {
362 req->is_canceled = EINA_TRUE;
365 ugd->req_queue = eina_list_remove_list(ugd->req_queue, l);
368 __cst_print_req_queue(ugd->req_queue);
372 void _cst_add_ss_request(Eina_List ** queue, int action_type, int call_type, int flavour, char *number, void *func, void *data, int waiting_time, CstUgData_t *ugd)
374 ENTER(_cst_add_ss_request);
375 ret_if(NULL == data);
376 ret_if(NULL == func);
378 CallSettingSSReq_t *req = (CallSettingSSReq_t *)malloc(sizeof(CallSettingSSReq_t));
380 req->action = action_type;
381 req->original_state = EINA_FALSE;
382 req->call_type = call_type;
383 req->flavour = flavour;
386 req->waiting_time = waiting_time;
388 snprintf(req->number, CST_MAX_PHONE_NUMBER_LEN, "%s", number);
391 DBG("Add req=0x%p", req);
392 req->is_canceled = EINA_FALSE;
393 req->is_requesting = EINA_FALSE;
395 *queue = eina_list_append(*queue, req);
396 cnt = eina_list_count(*queue);
397 DBG("req count=%d", cnt);
399 __cst_send_ss_req_to_telephony_server(req);
404 static void __cst_remove_ss_request(void *data)
406 ENTER(__cst_remove_ss_request);
407 CstUgData_t *ugd = (CstUgData_t *)data;
408 CallSettingSSReq_t *req;
411 ret_if(eina_list_count(ugd->req_queue) == 0);
413 first = eina_list_nth_list(ugd->req_queue, 0);
414 req = (CallSettingSSReq_t *)first->data;
415 DBG("Remove req=0x%p", req);
416 ugd->req_queue = eina_list_remove_list(ugd->req_queue, first);
419 cnt = eina_list_count(ugd->req_queue);
420 DBG("req count=%d", cnt);
423 first = eina_list_nth_list(ugd->req_queue, 0);
424 req = (CallSettingSSReq_t *)first->data;
425 __cst_send_ss_req_to_telephony_server(req);
427 __cst_print_req_queue(ugd->req_queue);
433 static CallSettingSSReq_t *__cst_get_current_request(void *data)
435 ENTER(__cst_get_current_request);
436 CstUgData_t *ugd = (CstUgData_t *)data;
437 CallSettingSSReq_t *req = NULL;
438 retv_if(ugd->req_queue == NULL, NULL);
439 DBG("list length=%d", eina_list_count(ugd->req_queue));
440 if (eina_list_count(ugd->req_queue) > 0) {
441 req = (CallSettingSSReq_t *)ugd->req_queue->data;
442 DBG("current req=0x%p", req);
448 static int __cst_get_ciss_error_from_tapi_error(TelSsCause_t tapi_err)
450 ENTER(__cst_get_ciss_error_from_tapi_error);
454 DBG("Error Code =%d", tapi_err);
457 case TAPI_SS_UNKNOWNSUBSCRIBER:
458 case TAPI_SS_BEARERSERVICENOTPROVISIONED:
459 case TAPI_SS_TELESERVICENOTPROVISIONED:
460 case TAPI_SS_CALLBARRED:
461 case TAPI_SS_ILLEGALSSOPERATION:
462 case TAPI_SS_ERRORSTATUS:
463 case TAPI_SS_FACILITYNOTSUPPORTED:
464 case TAPI_SS_MAXNOMPTYEXCEEDED:
465 case TAPI_SS_RESOURCESNOTAVAILABLE:
466 case TAPI_SS_PWREGISTRATIONFAILURE:
467 case TAPI_SS_SUBSCRIPTIONVIOLATION:
468 case TAPI_SS_NOTAVAILABLE:
469 case TAPI_SS_SYSTEMFAILURE:
470 case TAPI_SS_REJECTEDBYNETWORK:
471 error_code = CST_ERROR_SERVICE_UNAVAILABLE;
473 case TAPI_SS_INCOMPATIBILITY:
474 case TAPI_SS_DATAMISSING:
475 case TAPI_SS_UNEXPECTEDDATAVALUE:
476 error_code = CST_ERROR_INCORRECT_OPERATION;
478 case TAPI_SS_NEGATIVEPWCHECK:
479 error_code = CST_ERROR_INVALID_PASSWORD;
481 case TAPI_SS_NUMBEROFPWATTEMPTSVIOLATION:
482 error_code = CST_ERROR_PASSWORD_BLOCKED;
484 case TAPI_SS_REJECTEDBYUSER:
485 error_code = CST_ERROR_REJECTED_BY_NETWORK;
488 DBG("ciss_get_error_from_tapi_error:undefined =0x%x", tapi_err);
489 error_code = CST_ERROR_UNKNOWN;
496 static int __cst_get_tapi_cf_mode(int ciss_action)
500 switch (ciss_action) {
501 case CST_ACTION_ACTIVATE:
502 mode = TAPI_SS_CF_MODE_REGISTRATION_EV;
504 case CST_ACTION_DEACTIVATE:
505 mode = TAPI_SS_CF_MODE_ERASURE_EV;
509 ERR("Invalid CF mode");
515 static int __cst_get_tapi_cf_flavour(int ciss_cf_flavour)
519 switch (ciss_cf_flavour) {
520 case CST_SSTYPE_CF_UNCONDITIONAL:
521 tel_cf_flavour = TAPI_SS_CF_WHEN_CFU;
523 case CST_SSTYPE_CF_BUSY:
524 tel_cf_flavour = TAPI_SS_CF_WHEN_CFB;
526 case CST_SSTYPE_CF_NO_REPLY:
527 tel_cf_flavour = TAPI_SS_CF_WHEN_CFNRy;
529 case CST_SSTYPE_CF_NOT_REACHABLE:
530 tel_cf_flavour = TAPI_SS_CF_WHEN_CFNRc;
534 ERR("Wrong CF flavour");
536 return tel_cf_flavour;
539 static int __cst_get_tapi_teleservice_type(int ciss_call_type)
543 switch (ciss_call_type) {
544 case CST_CALLTYPE_VOICE:
545 teleservice = TAPI_SS_CLASS_VOICE;
547 case CST_CALLTYPE_ALL:
548 teleservice = TAPI_SS_CLASS_ALL_TELE_BEARER;
552 ERR("Invalid call type");
557 static int __cst_get_tapi_cb_mode(int ciss_action)
561 switch (ciss_action) {
562 case CST_ACTION_ACTIVATE:
563 mode = TAPI_SS_CB_MODE_ACTIVATE;
565 case CST_ACTION_DEACTIVATE:
566 mode = TAPI_SS_CB_MODE_DEACTIVATE;
570 ERR("Invalid CB action");
575 static int __cst_get_tapi_cb_flavour(int ciss_cb_flavour)
579 switch (ciss_cb_flavour) {
580 case CST_SSTYPE_CB_OC:
581 tel_cb_flavour = TAPI_SS_CB_TYPE_BAOC;
583 case CST_SSTYPE_CB_OIC:
584 tel_cb_flavour = TAPI_SS_CB_TYPE_BOIC;
586 case CST_SSTYPE_CB_OICEH:
587 tel_cb_flavour = TAPI_SS_CB_TYPE_BOIC_NOT_HC;
589 case CST_SSTYPE_CB_IC:
590 tel_cb_flavour = TAPI_SS_CB_TYPE_BAIC;
592 case CST_SSTYPE_CB_ICR:
593 tel_cb_flavour = TAPI_SS_CB_TYPE_BIC_ROAM;
597 ERR("Wrong CB flavour");
599 return tel_cb_flavour;
602 static int __cst_get_tapi_cw_mode(int ciss_action)
606 switch (ciss_action) {
607 case CST_ACTION_ACTIVATE:
608 mode = TAPI_SS_CW_MODE_ACTIVATE;
610 case CST_ACTION_DEACTIVATE:
611 mode = TAPI_SS_CW_MODE_DEACTIVATE;
615 ERR("Invalid CW action");
620 static void __cst_send_ss_req_to_telephony_server(CallSettingSSReq_t *req)
622 ENTER(__cst_send_ss_req_to_telephony_server);
623 TelSsForwardInfo_t cf_info;
624 TelSsBarringInfo_t cb_info;
625 TelSsWaitingInfo_t cw_info;
628 CstUgData_t *ugd = req->ugd;
631 DBG("Send req=0x%p action=%d call_type=%d flavour=%d waiting_time=%d", req, req->action, req->call_type, req->flavour, req->waiting_time);
632 req->is_requesting = EINA_TRUE;
634 memset(&cf_info, 0x0, sizeof(TelSsForwardInfo_t));
635 memset(&cb_info, 0x0, sizeof(TelSsBarringInfo_t));
636 memset(&cw_info, 0x0, sizeof(TelSsWaitingInfo_t));
638 switch (req->flavour) {
639 case CST_SSTYPE_CF_UNCONDITIONAL:
640 case CST_SSTYPE_CF_BUSY:
641 case CST_SSTYPE_CF_NO_REPLY:
642 case CST_SSTYPE_CF_NOT_REACHABLE:
643 case CST_SSTYPE_CF_ALL:
644 case CST_SSTYPE_CF_ALL_CONDITIONAL:
645 cf_info.Condition = __cst_get_tapi_cf_flavour(req->flavour);
646 cf_info.Class = TAPI_SS_CLASS_VOICE;
648 if (req->action == CST_ACTION_QUERY) {
649 api_ret = tel_get_ss_forward_status(ugd->tapi_handle, cf_info.Class, cf_info.Condition, __cst_ss_forward_resp_cb, (void *)req);
651 cf_info.Mode = __cst_get_tapi_cf_mode(req->action);
652 if ((req->flavour == CST_SSTYPE_CF_NO_REPLY) && (req->waiting_time > 0)) {
653 cf_info.NoReplyConditionTimer = req->waiting_time;
655 snprintf(cf_info.szPhoneNumber, TAPI_CALL_DIALDIGIT_LEN_MAX, "%s", req->number);
656 api_ret = tel_set_ss_forward(ugd->tapi_handle, &cf_info, __cst_ss_forward_resp_cb, (void *)req);
659 case CST_SSTYPE_CB_OC:
660 case CST_SSTYPE_CB_OIC:
661 case CST_SSTYPE_CB_OICEH:
662 case CST_SSTYPE_CB_IC:
663 case CST_SSTYPE_CB_ICR:
664 cb_info.Type = __cst_get_tapi_cb_flavour(req->flavour);
665 cb_info.Class = __cst_get_tapi_teleservice_type(req->call_type);
667 DBG("%d <= %d <= %d calltype", TAPI_SS_CLASS_VOICE, cb_info.Class, TAPI_SS_CLASS_ALL_TELE);
668 DBG("%d <= %d <= %d type", TAPI_SS_CB_TYPE_AB, cb_info.Type, TAPI_SS_CB_TYPE_BIC_NOT_SIM);
669 if (req->action == CST_ACTION_QUERY) {
670 /*To do - add callback function*/
671 api_ret = tel_get_ss_barring_status(ugd->tapi_handle, cb_info.Class, cb_info.Type, __cst_ss_barring_resp_cb, (void *)req);
673 cb_info.Mode = __cst_get_tapi_cb_mode(req->action);
674 DBG("%d <= %d <= %d mode", TAPI_SS_CB_MODE_ACTIVATE, cb_info.Mode, TAPI_SS_CB_MODE_DEACTIVATE);
675 DBG("%d == %d pwd length", strnlen(cb_info.szPassword, 4), TAPI_SS_GSM_BARR_PW_LEN_MAX);
676 memcpy(cb_info.szPassword, req->number, TAPI_SS_GSM_BARR_PW_LEN_MAX);
677 api_ret = tel_set_ss_barring(ugd->tapi_handle, &cb_info, __cst_ss_barring_resp_cb, (void *)req);
681 cw_info.Class = __cst_get_tapi_teleservice_type(req->call_type);
682 if (req->action == CST_ACTION_QUERY) {
683 api_ret = tel_get_ss_waiting_status(ugd->tapi_handle, cw_info.Class, __cst_ss_waiting_resp_cb, (void *)req);
685 cw_info.Mode = __cst_get_tapi_cw_mode(req->action);
686 api_ret = tel_set_ss_waiting(ugd->tapi_handle, &cw_info, __cst_ss_waiting_resp_cb, (void *)req);
691 if (req->req_id != -1) {
692 req->req_id = req_id;
695 if (api_ret != TAPI_API_SUCCESS) {
696 CstGlItemData_t *item_data;
699 req->func(req->call_type, req->flavour, EINA_FALSE, NULL, CST_ERROR_INCORRECT_OPERATION, req->action, req->data, req->waiting_time);
700 item_data = (CstGlItemData_t *)req->data;
701 ugd = (CstUgData_t *)item_data->ugd;
702 __cst_remove_ss_request(ugd);
704 DBG("api_ret=%d req_id=0x%p", api_ret, req_id);
710 void _cst_ciss_register_tel_event(void *data)
712 ENTER(_cst_ciss_register_tel_event);
713 CstUgData_t *ugd = (CstUgData_t *)data;
716 ERR("ugd = NULL, so returning");
720 ugd->tapi_handle = tel_init(NULL);
721 if (ugd->tapi_handle != NULL)
722 ERR("tel_init() Success, handle created.");
724 ERR("tel_init() failed.");