From 31fe66e1a6d3b97acd92a6749b7501894031fea0 Mon Sep 17 00:00:00 2001 From: Dongchul Lim Date: Tue, 17 Mar 2015 13:44:04 +0900 Subject: [PATCH] Code Sync up from tizen_2.4 Change-Id: I97d0feca05ef58a927bfbcf6938c01545c37d50f --- AUTHORS | 10 + CMakeLists.txt | 25 +- include/atmodem_common.h | 52 - include/atmodem_modem.h | 27 - include/atmodem_network.h | 25 - include/{atmodem_ss.h => s_call.h} | 15 +- include/s_common.h | 126 + include/{atmodem_call.h => s_modem.h} | 16 +- include/{atmodem_sim.h => s_network.h} | 14 +- include/{atmodem_ps.h => s_ps.h} | 14 +- include/{atmodem_sms.h => s_sim.h} | 14 +- include/s_sms.h | 27 + include/s_ss.h | 27 + packaging/tel-plugin-atmodem.spec | 57 +- res/convert_to_sql.c | 4 +- src/atmodem_call.c | 1191 ------ src/atmodem_common.c | 55 - src/atmodem_modem.c | 569 --- src/atmodem_network.c | 1287 ------ src/atmodem_ps.c | 639 --- src/atmodem_sim.c | 4284 -------------------- src/atmodem_sms.c | 781 ---- src/atmodem_ss.c | 1570 ------- src/desc_at.c | 135 + src/desc_atmodem.c | 116 - src/s_call.c | 1429 +++++++ src/s_common.c | 285 ++ src/s_modem.c | 538 +++ src/s_network.c | 1149 ++++++ src/s_ps.c | 654 +++ src/s_sim.c | 3172 +++++++++++++++ src/s_sms.c | 1857 +++++++++ src/s_ss.c | 1486 +++++++ ...atmodem.manifest => tel-plugin-atmodem.manifest | 0 34 files changed, 10980 insertions(+), 10670 deletions(-) create mode 100644 AUTHORS mode change 100644 => 100755 CMakeLists.txt delete mode 100755 include/atmodem_common.h delete mode 100644 include/atmodem_modem.h delete mode 100644 include/atmodem_network.h rename include/{atmodem_ss.h => s_call.h} (69%) create mode 100644 include/s_common.h rename include/{atmodem_call.h => s_modem.h} (65%) rename include/{atmodem_sim.h => s_network.h} (68%) rename include/{atmodem_ps.h => s_ps.h} (69%) rename include/{atmodem_sms.h => s_sim.h} (68%) create mode 100644 include/s_sms.h create mode 100644 include/s_ss.h delete mode 100755 src/atmodem_call.c delete mode 100644 src/atmodem_common.c delete mode 100755 src/atmodem_modem.c delete mode 100755 src/atmodem_network.c delete mode 100755 src/atmodem_ps.c delete mode 100755 src/atmodem_sim.c delete mode 100755 src/atmodem_sms.c delete mode 100755 src/atmodem_ss.c create mode 100755 src/desc_at.c delete mode 100644 src/desc_atmodem.c create mode 100755 src/s_call.c create mode 100755 src/s_common.c create mode 100755 src/s_modem.c create mode 100755 src/s_network.c create mode 100644 src/s_ps.c create mode 100755 src/s_sim.c create mode 100755 src/s_sms.c create mode 100755 src/s_ss.c rename packaging/tel-plugin-atmodem.manifest => tel-plugin-atmodem.manifest (100%) diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..19aadbb --- /dev/null +++ b/AUTHORS @@ -0,0 +1,10 @@ +Jongman Park +Ja-young Gu +Kyeongchul Kim +DongHoo Park +Youngman Park +Inho Oh +Hayoon Ko +Junhwan An +Kyoungyoup Park +Jinyup Kim diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100644 new mode 100755 index 710ab8b..0e47a19 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,11 +4,12 @@ PROJECT(atmodem-plugin C) ### Global setting ### SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") SET(INCLUDEDIR "\${prefix}/include") # Set required packages INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED glib-2.0 tcore libtzplatform-config tel-headers vconf) +pkg_check_modules(pkgs REQUIRED glib-2.0 tcore dlog) FOREACH(flag ${pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") @@ -16,7 +17,7 @@ ENDFOREACH(flag) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include/) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wdeclaration-after-statement -Wmissing-declarations -Wredundant-decls -Wcast-align") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -O2 -Werror -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wdeclaration-after-statement -Wmissing-declarations -Wredundant-decls -Wcast-align -Wall -Wno-array-bounds -Wno-empty-body -Wno-ignored-qualifiers -Wshadow -Wwrite-strings -Wswitch-default -Wno-unused-but-set-parameter -Wno-unused-but-set-variable") ADD_DEFINITIONS("-DFEATURE_TLOG_DEBUG") ADD_DEFINITIONS("-DTCORE_LOG_TAG=\"ATMODEM\"") @@ -25,15 +26,15 @@ MESSAGE(${CMAKE_C_FLAGS}) MESSAGE(${CMAKE_EXE_LINKER_FLAGS}) SET(SRCS - src/desc_atmodem.c - src/atmodem_modem.c - src/atmodem_common.c - src/atmodem_network.c - src/atmodem_sim.c - src/atmodem_call.c - src/atmodem_ps.c - src/atmodem_sms.c - src/atmodem_ss.c + src/desc_at.c + src/s_modem.c + src/s_common.c + src/s_network.c + src/s_sim.c + src/s_call.c + src/s_ps.c + src/s_sms.c + src/s_ss.c ) @@ -46,7 +47,7 @@ SET_TARGET_PROPERTIES(atmodem-plugin PROPERTIES PREFIX "" OUTPUT_NAME atmodem-pl # install INSTALL(TARGETS atmodem-plugin - LIBRARY DESTINATION ${LIB_INSTALL_DIR}/telephony/plugins/modems) + LIBRARY DESTINATION lib/telephony/plugins/modems) INSTALL(FILES ${CMAKE_SOURCE_DIR}/res/wiki_mcc_mnc_oper_list.sql DESTINATION /tmp RENAME mcc_mnc_oper_list.sql) INSTALL(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION /usr/share/license RENAME tel-plugin-atmodem) diff --git a/include/atmodem_common.h b/include/atmodem_common.h deleted file mode 100755 index 49050c4..0000000 --- a/include/atmodem_common.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * tel-plugin-atmodem - * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -#ifndef __ATMODEM_COMMON_H__ -#define __ATMODEM_COMMON_H__ - -#define ATMODEM_SWAP_BYTES_16(x) \ -{ \ - unsigned short int data = *(unsigned short int *)&(x); \ - data = ((data & 0xff00) >> 8) | \ - ((data & 0x00ff) << 8); \ - *(unsigned short int *)&(x) = data; \ -} - -typedef struct { - TcoreObjectResponseCallback cb; - void *cb_data; - char data[]; /* Additional data */ -} AtmodemRespCbData; - -#define ATMODEM_GET_DATA_FROM_RESP_CB_DATA(ptr) (gpointer)ptr->data -#define ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, request) \ -do {\ - if (ret != TEL_RETURN_SUCCESS) { \ - err("Failed to process request - [%s]", request); \ - atmodem_destroy_resp_cb_data(resp_cb_data); \ - } \ -} while(0) - -AtmodemRespCbData *atmodem_create_resp_cb_data(TcoreObjectResponseCallback cb, - void *cb_data, void *data, guint data_len); -void atmodem_destroy_resp_cb_data(AtmodemRespCbData *resp_cb_data); - -void on_send_atmodem_request(TcorePending *p, - TelReturn send_status, void *user_data); - -#endif /* __ATMODEM_COMMON_H__ */ diff --git a/include/atmodem_modem.h b/include/atmodem_modem.h deleted file mode 100644 index 2f193ab..0000000 --- a/include/atmodem_modem.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * tel-plugin-atmodem - * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -#ifndef __ATMODEM_MODEM_H__ -#define __ATMODEM_MODEM_H__ - -gboolean atmodem_modem_init(TcorePlugin *p, CoreObject *co); -void atmodem_modem_exit(TcorePlugin *p, CoreObject *co); - -gboolean atmodem_modem_power_on_modem(TcorePlugin *plugin); - -#endif /* __ATMODEM_MODEM_H__ */ diff --git a/include/atmodem_network.h b/include/atmodem_network.h deleted file mode 100644 index c516e68..0000000 --- a/include/atmodem_network.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * tel-plugin-atmodem - * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -#ifndef __ATMODEM_NETWORK_H__ -#define __ATMODEM_NETWORK_H__ - -gboolean atmodem_network_init(TcorePlugin *p, CoreObject *co); -void atmodem_network_exit(TcorePlugin *p, CoreObject *co); - -#endif /* __ATMODEM_NETWORK_H__ */ diff --git a/include/atmodem_ss.h b/include/s_call.h similarity index 69% rename from include/atmodem_ss.h rename to include/s_call.h index 629d6c7..c5135ea 100644 --- a/include/atmodem_ss.h +++ b/include/s_call.h @@ -1,7 +1,9 @@ /* * tel-plugin-atmodem * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hayoon Ko * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +18,11 @@ * limitations under the License. */ -#ifndef __ATMODEM_SS_H__ -#define __ATMODEM_SS_H__ +#ifndef __S_CALL_H__ +#define __S_CALL_H__ + +gboolean s_call_init(TcorePlugin *p, TcoreHal *h); +void s_call_exit(TcorePlugin *p); -gboolean atmodem_ss_init(TcorePlugin *p, CoreObject *co); -void atmodem_ss_exit(TcorePlugin *p, CoreObject *co); +#endif -#endif /* __ATMODEM_SS_H__ */ diff --git a/include/s_common.h b/include/s_common.h new file mode 100644 index 0000000..85835d7 --- /dev/null +++ b/include/s_common.h @@ -0,0 +1,126 @@ +/* + * tel-plugin-atmodem + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hayoon Ko + * + * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef __S_COMMON_H__ +#define __S_COMMON_H__ + +#include +#include +#include + +#define EVENT_SYS_NOTI_MODEM_POWER "system_power" +#define EVENT_MODEM_POWER "modem_power" +#define EVENT_MODEM_PHONE_STATE "modem_phone_state" + +#define EVENT_CALL_STATUS "call_status" +#define EVENT_CALL_INCOMING "call_incoming" +#define EVENT_CALL_WAITING "call_waiting" + +#define EVENT_SS_INFO "ss_info" +#define EVENT_SS_USSD "ss_ussd" + +#define EVENT_PS_CALL_STATUS "ps_call_status" +#define EVENT_PS_DATA_COUNTER "ps_data_counter" +#define EVENT_PS_IPCONFIGURATION "ps_ipconfiguration" +#define EVENT_PS_PIN_CTRL "ps_pin_control" +#define EVENT_PS_HSDPA_STATUS "ps_hsdpa_status" +#define EVENT_PS_ATTACH_DETACH "ps_attach_detach" +#define EVENT_PS_EXTERNAL_CALL "ps_external_call" + +#define EVENT_SAP_STATUS "sap_status" +#define EVENT_SAP_DISCONNECT "sap_disconnect" + +#define EVENT_SIM_PIN_STATUS "sim_pin_status" + +#define EVENT_SAT_ENVELOPE_RESP "sat_envelope_response" +#define EVENT_SAT_REFRESH_STATUS "sat_refresh_status" +#define EVENT_SAT_PROACTIVE_COMMAND "sat_proactive_command" +#define EVENT_SAT_CONTROL_RESULT "sat_control_result" + + +#define EVENT_CALL_STATUS "call_status" +#define EVENT_CALL_INCOMING "call_incoming" + +#define EVENT_NETWORK_REGISTRATION "network_regist" +#define EVENT_NETWORK_ICON_INFO "network_icon_info" +#define EVENT_NETWORK_TIME_INFO "network_time_info" +#define EVENT_NETWORK_IDENTITY "network_identity" + +#define EVENT_SMS_INCOM_MSG "sms_incom_msg" +#define EVENT_SMS_SEND_ACK "sms_send_ack" +#define EVENT_SMS_MEMORY_STATUS "sms_memory_status" +#define EVENT_SMS_CB_INCOM_MSG "sms_cb_incom_msg" +#define EVENT_SMS_DELETE_MSG_CNF "sms_delete_msg_cnf" +#define EVENT_SMS_WRITE_MSG_CNF "sms_write_msg_cnf" +#define EVENT_SMS_DELIVERY_RPT_CNF "sms_deliver_rpt_cnf" +#define EVENT_SMS_DEVICE_READY "sms_device_ready" + +#define EVENT_PHONEBOOK_STATUS "phonebook_status" +#define EVENT_PHONEBOOK_FIRST_INDEX "phonebook_first_index" + +enum direction_e { + RX, + TX +}; + +struct global_data { + unsigned int msg_auto_id_current; + unsigned int msg_auto_id_start; + unsigned int msg_auto_id_end; +}; + +struct work_queue_data { + unsigned int id; + UserRequest *ur; +}; + +#define UTIL_ID(hdr) ((hdr).main_cmd << 8 | (hdr).sub_cmd) +#define UTIL_IDP(hdr) ((hdr)->main_cmd << 8 | (hdr)->sub_cmd) + +/* If condition fails it retuns 'ret_val' without asserting program */ +#define CHECK_AND_RETURN_VALUE(cond, ret_val) \ + do { \ + if(!(cond)) { \ + err("*** Condition (%s) Fails ***", #cond); \ + return ret_val; \ + } \ + } while (0) + +#define CHECK_AND_RETURN(cond) \ + do { \ + if(!(cond)) { \ + err("*** Condition (%s) Fails ***", #cond); \ + return ; \ + } \ + } while (0) + +void hook_hex_dump(enum direction_e d, int size, const void *data); +unsigned int util_assign_message_sequence_id(TcorePlugin *p); +gboolean util_add_waiting_job(GQueue *queue, unsigned int id, UserRequest *ur); +UserRequest* util_pop_waiting_job(GQueue *queue, unsigned int id); +void util_hex_dump(char *pad, int size, const void *data); +unsigned char util_hexCharToInt(char c); +char* util_hexStringToBytes(char * s); +gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes); + +void on_send_at_request(TcorePending *p, + TReturn send_status, void *user_data); + +#endif diff --git a/include/atmodem_call.h b/include/s_modem.h similarity index 65% rename from include/atmodem_call.h rename to include/s_modem.h index 3db004c..f4aa759 100644 --- a/include/atmodem_call.h +++ b/include/s_modem.h @@ -1,7 +1,9 @@ /* * tel-plugin-atmodem * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hayoon Ko * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +18,12 @@ * limitations under the License. */ -#ifndef __ATMODEM_CALL_H__ -#define __ATMODEM_CALL_H__ +#ifndef __S_MODEM_H__ +#define __S_MODEM_H__ + +gboolean s_modem_init(TcorePlugin *p, TcoreHal *h); +void s_modem_exit(TcorePlugin *p); -gboolean atmodem_call_init(TcorePlugin *p, CoreObject *co); -void atmodem_call_exit(TcorePlugin *p, CoreObject *co); +gboolean s_modem_send_poweron(TcorePlugin *p); -#endif /* __ATMODEM_CALL_H__ */ +#endif diff --git a/include/atmodem_sim.h b/include/s_network.h similarity index 68% rename from include/atmodem_sim.h rename to include/s_network.h index 62a7696..a02c75d 100644 --- a/include/atmodem_sim.h +++ b/include/s_network.h @@ -1,7 +1,9 @@ /* * tel-plugin-atmodem * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hayoon Ko * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +18,10 @@ * limitations under the License. */ -#ifndef __ATMODEM_SIM_H__ -#define __ATMODEM_SIM_H__ +#ifndef __S_NETWORK_H__ +#define __S_NETWORK_H__ -gboolean atmodem_sim_init(TcorePlugin *p, CoreObject *co); -void atmodem_sim_exit(TcorePlugin *p, CoreObject *co); +gboolean s_network_init(TcorePlugin *p, TcoreHal *h); +void s_network_exit(TcorePlugin *p); -#endif /* __ATMODEM_SIM_H__ */ +#endif diff --git a/include/atmodem_ps.h b/include/s_ps.h similarity index 69% rename from include/atmodem_ps.h rename to include/s_ps.h index 750cd2d..0707297 100644 --- a/include/atmodem_ps.h +++ b/include/s_ps.h @@ -1,7 +1,9 @@ /* * tel-plugin-atmodem * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hayoon Ko * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +18,10 @@ * limitations under the License. */ -#ifndef __ATMODEM_PS_H__ -#define __ATMODEM_PS_H__ +#ifndef __S_PS_H__ +#define __S_PS_H__ -gboolean atmodem_ps_init(TcorePlugin *p, CoreObject *co); -void atmodem_ps_exit(TcorePlugin *p, CoreObject *co); +gboolean s_ps_init(TcorePlugin *p, TcoreHal *h); +void s_ps_exit(TcorePlugin *p); -#endif /* __ATMODEM_PS_H__ */ +#endif diff --git a/include/atmodem_sms.h b/include/s_sim.h similarity index 68% rename from include/atmodem_sms.h rename to include/s_sim.h index 8effcb3..758d677 100644 --- a/include/atmodem_sms.h +++ b/include/s_sim.h @@ -1,7 +1,9 @@ /* * tel-plugin-atmodem * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hayoon Ko * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +18,10 @@ * limitations under the License. */ -#ifndef __ATMODEM_SMS_H__ -#define __ATMODEM_SMS_H__ +#ifndef __S_SIM_H__ +#define __S_SIM_H__ -gboolean atmodem_sms_init(TcorePlugin *p, CoreObject *co); -void atmodem_sms_exit(TcorePlugin *p, CoreObject *co); +gboolean s_sim_init(TcorePlugin *p, TcoreHal *h); +void s_sim_exit(TcorePlugin *p); -#endif /* __ATMODEM_SMS_H__ */ +#endif diff --git a/include/s_sms.h b/include/s_sms.h new file mode 100644 index 0000000..a477258 --- /dev/null +++ b/include/s_sms.h @@ -0,0 +1,27 @@ +/* + * tel-plugin-atmodem + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hayoon Ko + * + * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef __S_SMS_H__ +#define __S_SMS_H__ + +gboolean s_sms_init(TcorePlugin *p, TcoreHal *h); +void s_sms_exit(TcorePlugin *p); + +#endif diff --git a/include/s_ss.h b/include/s_ss.h new file mode 100644 index 0000000..4467797 --- /dev/null +++ b/include/s_ss.h @@ -0,0 +1,27 @@ +/* + * tel-plugin-atmodem + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hayoon Ko + * + * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef __S_SS_H__ +#define __S_SS_H__ + +gboolean s_ss_init(TcorePlugin *p, TcoreHal *h); +void s_ss_exit(TcorePlugin *p); + +#endif diff --git a/packaging/tel-plugin-atmodem.spec b/packaging/tel-plugin-atmodem.spec index 84abb5e..55a3a02 100644 --- a/packaging/tel-plugin-atmodem.spec +++ b/packaging/tel-plugin-atmodem.spec @@ -1,67 +1,62 @@ -%define major 3 -%define minor 0 -%define patchlevel 1 +%define major 0 +%define minor 1 +%define patchlevel 57 -Name: tel-plugin-atmodem -Summary: Telephony AT Modem library -Version: %{major}.%{minor}.%{patchlevel} -Release: 1 -Group: System/Libraries -License: Apache-2.0 -Source0: tel-plugin-atmodem-%{version}.tar.gz -Source1001: tel-plugin-atmodem.manifest -Requires(post): /sbin/ldconfig -Requires(postun): /sbin/ldconfig -BuildRequires: cmake -BuildRequires: pkgconfig(glib-2.0) -BuildRequires: pkgconfig(tcore) -BuildRequires: pkgconfig(libtzplatform-config) -BuildRequires: pkgconfig(tel-headers) -BuildRequires: pkgconfig(vconf) +Name: tel-plugin-atmodem +Version: %{major}.%{minor}.%{patchlevel} +Release: 1 +License: Apache-2.0 +Summary: Telephony AT Modem library +Group: System/Libraries +Source0: tel-plugin-atmodem-%{version}.tar.gz +BuildRequires: cmake +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(tcore) +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig %description Telephony AT Modem library %prep %setup -q -cp %{SOURCE1001} . %build -%cmake . -make %{?jobs:-j%jobs} +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} +make %{?_smp_mflags} %post /sbin/ldconfig -mkdir -p %{TZ_SYS_DB} +mkdir -p /opt/dbspace -if [ ! -f %{TZ_SYS_DB}/.mcc_mnc_oper_list.db ] +if [ ! -f /opt/dbspace/.mcc_mnc_oper_list.db ] then - sqlite3 %{TZ_SYS_DB}/.mcc_mnc_oper_list.db < /tmp/mcc_mnc_oper_list.sql + sqlite3 /opt/dbspace/.mcc_mnc_oper_list.db < /tmp/mcc_mnc_oper_list.sql fi rm -f /tmp/mcc_mnc_oper_list.sql -if [ -f %{TZ_SYS_DB}/.mcc_mnc_oper_list.db ] +if [ -f /opt/dbspace/.mcc_mnc_oper_list.db ] then -chmod 600 %{TZ_SYS_DB}/.mcc_mnc_oper_list.db +chmod 600 /opt/dbspace/.mcc_mnc_oper_list.db fi -if [ -f %{TZ_SYS_DB}/.mcc_mnc_oper_list.db-journal ] +if [ -f /opt/dbspace/.mcc_mnc_oper_list.db-journal ] then -chmod 644 %{TZ_SYS_DB}/.mcc_mnc_oper_list.db-journal +chmod 644 /opt/dbspace/.mcc_mnc_oper_list.db-journal fi %postun -p /sbin/ldconfig %install -rm -rf %{buildroot} %make_install mkdir -p %{buildroot}/usr/share/license cp LICENSE %{buildroot}/usr/share/license/%{name} %files -%manifest %{name}.manifest +%manifest tel-plugin-atmodem.manifest %defattr(-,root,root,-) #%doc COPYING %{_libdir}/telephony/plugins/modems/atmodem-plugin* diff --git a/res/convert_to_sql.c b/res/convert_to_sql.c index 172a38b..2039c65 100644 --- a/res/convert_to_sql.c +++ b/res/convert_to_sql.c @@ -1,7 +1,9 @@ /* * tel-plugin-atmodem * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Ja-young Gu * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/atmodem_call.c b/src/atmodem_call.c deleted file mode 100755 index 9314a77..0000000 --- a/src/atmodem_call.c +++ /dev/null @@ -1,1191 +0,0 @@ -/* - * tel-plugin-atmodem - * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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 -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "atmodem_call.h" -#include "atmodem_common.h" - -/* Call Status */ -typedef enum { - ATMODEM_CALL_STATUS_ACTIVE, - ATMODEM_CALL_STATUS_HELD, - ATMODEM_CALL_STATUS_DIALING, - ATMODEM_CALL_STATUS_ALERT, - ATMODEM_CALL_STATUS_INCOMING, - ATMODEM_CALL_STATUS_WAITING, - ATMODEM_CALL_STATUS_CONNECTING, - ATMODEM_CALL_STATUS_DISCONNECTED, - ATMODEM_CALL_STATUS_IDLE -} AtmodemCallStatus; - -static void on_response_atmodem_call_default(TcorePending *p, - guint data_len, const void *data, void *user_data); - -static TelReturn __atmodem_call_get_call_list(CoreObject *co, gboolean flag); - -static TelCallType __atmodem_call_type(gint type) -{ - dbg("Entry"); - - switch (type) { - case 0: - return TEL_CALL_TYPE_VOICE; - case 1: - return TEL_CALL_TYPE_VIDEO; - default: - err("invalid call type, returing default call type as voice"); - return TEL_CALL_TYPE_VOICE; - } -} - -static TelCallState __atmodem_call_state(AtmodemCallStatus state) -{ - dbg("Entry"); - - switch (state) { - case ATMODEM_CALL_STATUS_ACTIVE: - return TEL_CALL_STATE_ACTIVE; - - case ATMODEM_CALL_STATUS_HELD: - return TEL_CALL_STATE_HELD; - - case ATMODEM_CALL_STATUS_DIALING: - return TEL_CALL_STATE_DIALING; - - case ATMODEM_CALL_STATUS_ALERT: - return TEL_CALL_STATE_ALERT; - - case ATMODEM_CALL_STATUS_INCOMING: - case ATMODEM_CALL_STATUS_WAITING: - return TEL_CALL_STATE_INCOMING; - - default: - return TEL_CALL_STATE_IDLE; - } -} - -static void __atmodem_call_branch_by_status(CoreObject *co, - CallObject *call_obj, TelCallState call_state) -{ - guint call_id; - TelCallType call_type; - TelCallState state; - TcoreNotification command = TCORE_NOTIFICATION_UNKNOWN; - - if (tcore_call_object_get_state(call_obj, &state) == FALSE) { - err("Unable to get Call status"); - return; - } - - dbg("Call State - Present : [%d] New: [%d]", state, call_state); - if (call_state == state) { - dbg("No change in Call State..."); - return; - } - - if (tcore_call_object_get_call_type(call_obj, &call_type) == FALSE) { - err("Unable to get Call type"); - return; - } - - if (tcore_call_object_get_id(call_obj, &call_id) == FALSE) { - err("Unable to get Call id"); - return; - } - - /* Update Call state */ - tcore_call_object_set_state(call_obj, call_state); - - if (call_type == TEL_CALL_TYPE_VOICE) { /* Voice call notification */ - switch (call_state) { - case TEL_CALL_STATE_ACTIVE: - command = TCORE_NOTIFICATION_CALL_STATUS_ACTIVE; - break; - - case TEL_CALL_STATE_HELD: - command = TCORE_NOTIFICATION_CALL_STATUS_HELD; - break; - - case TEL_CALL_STATE_DIALING: - command = TCORE_NOTIFICATION_CALL_STATUS_DIALING; - break; - - case TEL_CALL_STATE_ALERT: - command = TCORE_NOTIFICATION_CALL_STATUS_ALERT; - break; - - case TEL_CALL_STATE_INCOMING: - case TEL_CALL_STATE_WAITING: - command = TCORE_NOTIFICATION_CALL_STATUS_INCOMING; - break; - - case TEL_CALL_STATE_IDLE: { - TelCallStatusIdleNoti idle; - - idle.call_id = call_id; - /* TODO - get proper call end cause. */ - idle.cause = TEL_CALL_END_CAUSE_NONE; - - /* Send notification */ - tcore_object_send_notification(co, - TCORE_NOTIFICATION_CALL_STATUS_IDLE, - sizeof(TelCallStatusIdleNoti), &idle); - - /* Free Call object */ - tcore_call_object_free(co, call_obj); - - return; - } - } - } else { - err("Unknown Call type: [%d]", call_type); - return; - } - - /* Send notification */ - tcore_object_send_notification(co, - command, sizeof(call_id), &call_id); -} - -static void __atmodem_handle_call_get_call_list(CoreObject *co, - gboolean flag, void *data) -{ - gint call_id; - gint direction; - gint mode; - gint state; - gint mpty; - gint ton; - GSList *tokens = NULL; - gchar *resp = NULL; - gchar *line; - gchar *num = NULL; - gint num_type; - gchar number[TEL_CALL_CALLING_NUMBER_LEN_MAX + 1] = {0, }; - GSList *lines = data; - CallObject *call_obj = NULL; - - while (lines != NULL) { - line = (gchar *)lines->data; - /* point to next node */ - lines = lines->next; - - /* free previous tokens*/ - tcore_at_tok_free(tokens); - - tokens = tcore_at_tok_new(line); - resp = g_slist_nth_data(tokens, 0); - if (NULL == resp) { - err("Invalid call_id"); - continue; - } - - call_id = atoi(resp); - resp = g_slist_nth_data(tokens, 1); - if (NULL == resp) { - err("Invalid direction"); - continue; - } - - direction = (atoi(resp) == 0) ? 1 : 0; - resp = g_slist_nth_data(tokens, 2); - if (NULL == resp) { - err("Invalid state"); - continue; - } - - state = __atmodem_call_state(atoi(resp)); - resp = g_slist_nth_data(tokens, 3); - if (NULL == resp) { - err("Invalid mode"); - continue; - } - mode = __atmodem_call_type(atoi(resp)); - - resp = g_slist_nth_data(tokens, 4); - if (NULL == resp) { - err("Invalid mpty"); - continue; - } - mpty = atoi(resp); - - resp = g_slist_nth_data(tokens, 5); - if (NULL == resp) { - err("Number is NULL"); - } else { - /* Strike off double quotes */ - num = tcore_at_tok_extract(resp); - dbg("Number: [%s]", num); - - resp = g_slist_nth_data(tokens, 6); - if (!resp) { - err("Invalid Number type"); - } else { - num_type = atoi(resp); - - /* Check if number is International or National */ - ton = ((num_type) >> 4) & 0x07; - if (ton == 1 && num[0] != '+') { - /* International number */ - number[0] = '+'; - memcpy(&number[1], num, strlen(num)); - } else { - memcpy(number, num, strlen(num)); - } - } - g_free(num); - } - - dbg("Call ID: [%d] Direction: [%s] Call Type: [%d] " \ - "Multi-party: [%s] Number: [%s] Type-of-Number: [%d] State: [%d]", \ - call_id, (direction ? "Outgoing" : "Incoming"), - mode, (mpty ? "YES" : "NO"), number, ton, state); - - call_obj = tcore_call_object_find_by_id(co, call_id); - if (NULL == call_obj) { - call_obj = tcore_call_object_new(co, call_id); - if (NULL == call_obj) { - err("Unable to create call object"); - continue; - } - } - - /* Set Call parameters */ - tcore_call_object_set_type(call_obj, mode); - tcore_call_object_set_direction(call_obj, direction); - tcore_call_object_set_multiparty_state(call_obj, mpty); - if (number[0] != '\0') - tcore_call_object_set_cli_info(call_obj, - TEL_CALL_CLI_VALIDITY_VALID, number); - else - tcore_call_object_set_cli_info(call_obj, - TEL_CALL_CLI_VALIDITY_NOT_AVAILABLE, number); - tcore_call_object_set_active_line(call_obj, TEL_CALL_ACTIVE_LINE1); - if (flag == TRUE) - __atmodem_call_branch_by_status(co, call_obj, state); - else - tcore_call_object_set_state(call_obj, state); - } -} - -/* Incoming Call notification */ -static void __on_notification_atmodem_call_incoming(CoreObject *co, - guint call_id, const void *data) -{ - GSList *list = NULL; - GSList *tokens = NULL; - gchar *resp = NULL; - gchar *line; - gboolean direction = TRUE; - gint mode; - gpointer state; - gint call_state; - gint mpty; - gint ton; - gchar *num = NULL; - gchar number[TEL_CALL_CALLING_NUMBER_LEN_MAX + 1] = {0, }; - GSList *lines = (GSList *)data; - CallObject *call_obj = NULL; - - dbg("Entry"); - - /* Check call with 'Incoming' status already exist */ - list = tcore_call_object_find_by_status(co, TEL_CALL_STATE_INCOMING); - if (list != NULL) { - err("Incoming Call already exist... Skip!!!"); - return; - } - - call_obj = tcore_call_object_find_by_id(co, call_id); - if (call_obj != NULL) { - err("co with same id already exist. skip"); - return; - } - - /* Create Call object */ - call_obj = tcore_call_object_new(co, (guint)call_id); - if (NULL == call_obj) { - err(" Unable to create call object"); - return; - } - - lines = (GSList *)data; - if (lines == NULL) { - err("Invalid response received"); - return; - } - - line = (gchar *)lines->data; - - /* Tokenize */ - tokens = tcore_at_tok_new(line); - - state = g_slist_nth_data(tokens, 2); - if (NULL == state) { - err("State is missing"); - goto out; - } - call_state = __atmodem_call_state(atoi(state)); - - resp = g_slist_nth_data(tokens, 3); - if (NULL == resp) { - err("Invalid mode"); - goto out; - } - mode = __atmodem_call_type(atoi(resp)); - - resp = g_slist_nth_data(tokens, 4); - if (NULL == resp) { - err("Invalid mpty"); - goto out; - } - mpty = atoi(resp); - - resp = g_slist_nth_data(tokens, 5); - if (NULL == resp) { - err("Number is NULL"); - } else { - /* Strike off double quotes */ - num = tcore_at_tok_extract(resp); - dbg("Number: [%s]", num); - - memcpy(number, num, strlen(num)); - number[strlen(num)] = '\0'; - g_free(num); - } - - dbg("Call ID: [%d] Direction: [%s] Call Type: [%d] " \ - "Multi-party: [%s] Number: [%s] Type-of-Number: [%d] State: [%d]", \ - call_id, (direction ? "Outgoing" : "Incoming"), - mode, (mpty ? "YES" : "NO"), number, ton, call_state); /* Set Call parameters */ - - /* Update Call Object */ - tcore_call_object_set_type(call_obj, mode); - tcore_call_object_set_direction(call_obj, direction); - tcore_call_object_set_multiparty_state(call_obj, mpty); - if (number[0] != '\0') - tcore_call_object_set_cli_info(call_obj, - TEL_CALL_CLI_VALIDITY_VALID, number); - else - tcore_call_object_set_cli_info(call_obj, - TEL_CALL_CLI_VALIDITY_NOT_AVAILABLE, number); - tcore_call_object_set_active_line(call_obj, TEL_CALL_ACTIVE_LINE1); - - /* Send notification */ - __atmodem_call_branch_by_status(co, call_obj, call_state); - -out: - /* Free tokens */ - tcore_at_tok_free(tokens); -} - -static void __on_notification_atmodem_call_status(CoreObject *co, - guint call_id, AtmodemCallStatus call_state) -{ - CallObject *call_obj = NULL; - TelCallState state; - - state = __atmodem_call_state(call_state); - dbg("Call state [%d]", state); - - switch (state) { - case TEL_CALL_STATE_ACTIVE: - case TEL_CALL_STATE_HELD: - case TEL_CALL_STATE_ALERT: - case TEL_CALL_STATE_IDLE: { - call_obj = tcore_call_object_find_by_id(co, call_id); - if (call_obj == NULL) { - err("Unable to find Call Object - Call ID: [%d]", call_id); - return; - } - - /* Send notification to application */ - __atmodem_call_branch_by_status(co, call_obj, state); - } - break; - - case TEL_CALL_STATE_DIALING: { - call_obj = tcore_call_object_find_by_id(co, call_id); - if (!call_obj) { - call_obj = tcore_call_object_new(co, call_id); - if (!call_obj) { - err("Unable to create Call Object"); - return; - } - } - - /* - * Make request to get current Call list. - * Update CallObject with - * and send notification to application - */ - __atmodem_call_get_call_list(co, TRUE); - } - break; - - default: - err("Unhandled Call Status: [%d]", state); - break; - } -} - -/* Internal response operation */ -static void __on_response_atmodem_call_get_call_list(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - GSList *lines = NULL; - TelCallResult result = TEL_CALL_RESULT_FAILURE; //TODO - CME error mapping required - gboolean *flag = ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - gint count; - dbg("Entry"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp && at_resp->success) { - result = TEL_CALL_RESULT_SUCCESS; - if (NULL == at_resp->lines) { - err("invalid response received"); - return; - } - - lines = (GSList *)at_resp->lines; - count = g_slist_length(lines); - dbg("Total records : %d", g_slist_length(lines)); - if (0 == count) { - err("Call count is zero"); - return; - } - - dbg("RESPONSE OK"); - - /* Process +CLCC notification parameter */ - __atmodem_handle_call_get_call_list(co, *flag, lines); - - } else { - err("RESPONSE NOK"); - } - - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -/*internal request operation */ -static TelReturn __atmodem_send_call_request(CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data, - gchar *at_cmd, gchar *func_name) -{ - AtmodemRespCbData *resp_cb_data; - TelReturn ret; - - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, func_name, strlen(func_name) + 1); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - at_cmd, NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - on_response_atmodem_call_default, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, func_name); - - /* Free resources */ - g_free(at_cmd); - return ret; -} - - /* - * Operation - Get current call list. - * - * Request - - * AT-Command: AT+CLCC - * - * Response - - * Success: - *[+CLCC: , , , ,[,,[,[,]]] - *[ +CLCC: ,,,,[,,[,[,]]][…]]] - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn __atmodem_call_get_call_list(CoreObject *co, gboolean flag) -{ - AtmodemRespCbData *resp_cb_data; - TelReturn ret =TEL_RETURN_FAILURE; - dbg("Entry"); - - if (NULL == co) { - err("Core Object is NULL"); - return ret; - } - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(NULL, NULL, &flag, sizeof(gboolean)); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - "AT+CLCC","+CLCC", - TCORE_AT_COMMAND_TYPE_MULTILINE, - NULL, - __on_response_atmodem_call_get_call_list, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get current call list"); - - return ret; -} - -/* Notification */ -/* -* Operation - call status notification from network. -* notification message format: -* %SCLCC: -* where -* -* indicates the call identification. -* -* indicates call direction (MO or MT) -* -* 0 active -* 1 hold -* 2 dialling (MO call) -* 3 alerting (MO call; ringing for the remote party) -* 4 ringing (MT call) -* 5 waiting (MT call) -* 6 connecting (MO call) -* 7 disconneted -* -* call type -* -* multiparty call -* -*/ -static gboolean on_notification_atmodem_call_status(CoreObject *co, - const void *data, void *user_data) -{ - GSList *tokens = NULL; - GSList *lines = NULL; - const gchar *line = NULL; - gchar *state = NULL, *call_handle = NULL; - AtmodemCallStatus status; - guint call_id; - - dbg("Entry"); - - lines = (GSList *)data; - if (lines == NULL) { - err("Invalid response received"); - return TRUE; - } - - line = (gchar *)lines->data; - - /* Tokenize */ - tokens = tcore_at_tok_new(line); - call_handle = g_slist_nth_data(tokens, 0); - if (NULL == call_handle) { - err("call_id missing"); - goto out; - } - call_id = atoi(call_handle); - - state = g_slist_nth_data(tokens, 2); - if (NULL == state) { - err("State is missing"); - goto out; - } - status = atoi(state); - - dbg("Call ID: [%d] Call Status: [%d]", call_id, status); - - switch (status) { - case ATMODEM_CALL_STATUS_INCOMING: - case ATMODEM_CALL_STATUS_WAITING: - dbg("Incoming/Waiting Call..."); - __on_notification_atmodem_call_incoming(co, call_id, data); - break; - - default: - __on_notification_atmodem_call_status(co, call_id, status); - break; - } - -out: - /* Free tokens */ - tcore_at_tok_free(tokens); - return TRUE; -} - -/* - * Operation - SS network initiated notification. - * - * notification message format: - * +CSSU: [ [,,]] - * - * (it is manufacturer specific, which of these codes are supported): - * 0 this is a forwarded call (MT call setup) - * 1 this is a CUG call ( present) (MT call setup) - * 2 call has been put on hold (during a voice call) - * 3 call has been retrieved (during a voice call) - * 4 multiparty call entered (during a voice call) - * 5 Call has been released - not a SS notification (during a voice call) - * 6 forward check SS message received (can be received whenever) - * 7 call is being connected (alerting) with the remote party in alerting state - * in explicit call transfer operation - * (during a voice call) - * 8 call has been connected with the other remote party in explicit call transfer - * operation (during a voice call or MT call setup) - * 9 this is a deflected call (MT call setup) - * 10 additional incoming call forwarded - * - * refer Closed user group +CCUG - * - * string type phone of format specified by - * - * type of address octet in integer format. - */ -static gboolean on_notification_atmodem_call_ss_cssu_info(CoreObject *co, - const void *event_data, void *user_data) -{ - GSList *tokens = NULL; - TcoreNotification command = TCORE_NOTIFICATION_UNKNOWN; - gchar *resp = NULL; - gchar *cmd = 0; - gint index = 0; - gint code2 = -1; - gchar number[TEL_CALL_CALLING_NUMBER_LEN_MAX + 1] = {'\0',}; - - dbg("Entry"); - - if (1 != g_slist_length((GSList *) event_data)) { - err("unsolicited msg but multiple line"); - return TRUE; - } - - cmd = (gchar *) ((GSList *) event_data)->data; - dbg("ss notification message[%s]", cmd); - - tokens = tcore_at_tok_new(cmd); - - /* parse */ - resp = g_slist_nth_data(tokens, 0); - if (NULL == resp) { - err("Code2 is missing from %CSSU indiaction"); - tcore_at_tok_free(tokens); - return TRUE; - } - code2 = atoi(resp); - - /* parse [ , ] */ - if ((resp = g_slist_nth_data(tokens, 1))) - index = atoi(resp); - - if ((resp = g_slist_nth_data(tokens, 2))) { - resp = tcore_at_tok_extract((const gchar *)resp); - memcpy(number, resp, strlen(resp)); - number[strlen(resp)] = '\0';; - g_free(resp); - } - dbg("+CSSU: : %d : %d : %s ", code2, index, number); - - /* - other values will be ignored */ - switch (code2) { - case 0: - command = TCORE_NOTIFICATION_CALL_INFO_MT_FORWARDED; - break; - - case 2: - command = TCORE_NOTIFICATION_CALL_INFO_HELD; - break; - - case 3: - command = TCORE_NOTIFICATION_CALL_INFO_ACTIVE; - break; - - case 4: - command = TCORE_NOTIFICATION_CALL_INFO_JOINED; - break; - - case 7: - case 8: - command = TCORE_NOTIFICATION_CALL_INFO_TRANSFERED; - break; - - case 9: - command = TCORE_NOTIFICATION_CALL_INFO_MT_DEFLECTED; - break; - - default: - dbg("Unsupported +CSSU notification: [%d]", code2); - break; - } - - if (command != TCORE_NOTIFICATION_UNKNOWN) - tcore_object_send_notification(co, command, 0, NULL); - - tcore_at_tok_free(tokens); - return TRUE; -} - -/* Response */ -static void on_response_atmodem_call_default(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - - TelCallResult result; - dbg("Entry"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp && at_resp->success) { - result = TEL_CALL_RESULT_SUCCESS; - } else { - err("ERROR: [%s]", at_resp->final_response); - result = TEL_CALL_RESULT_FAILURE; - /* - * TODO - - * need to map CME error and final response - * error to TelCallResult - */ - } - dbg("%s: [%s]", ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data), - (result == TEL_CALL_RESULT_SUCCESS ? "SUCCESS" : "FAIL")); - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data); - - /* Free callback data */ - atmodem_destroy_resp_cb_data(resp_cb_data); -} - - /* Request */ - /* - * Operation - dial - * - * Request - - * AT-Command: ATD [I] [G] [;] - * - dialed number - * [I][i] - CLI presentation(supression or invocation) - * [G] - control the CUG supplementary service information for this call. - * - * Response - - * Success: - * OK or CONNECT - * Failure: - * "ERROR" - * "NO ANSWER" - * "NO CARRIER" - * "BUSY" - * "NO DIALTONE" - * +CME ERROR: - */ -static TelReturn atmodem_call_dial(CoreObject *co, const TelCallDial *dial_info, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd; - const gchar *clir; - gchar *num; - dbg("Entry"); - - if (dial_info->call_type == TEL_CALL_TYPE_VIDEO) { - err("Video call is not supported in atmodem"); - return TEL_RETURN_OPERATION_NOT_SUPPORTED; - } - - if (!strncmp(dial_info->number, "*31#", 4)) { - dbg("clir suppression"); - clir = "i"; - num = (gchar *)&(dial_info->number[4]); - } else if (!strncmp(dial_info->number, "#31#", 4)) { - dbg("clir invocation"); - clir = "I"; - num = (gchar *)&(dial_info->number[4]); - } else { - dbg("set clir state to default"); - clir = ""; - num = (gchar *)dial_info->number; - } - - /* AT-Command */ - at_cmd = g_strdup_printf("ATD%s%s;", num, clir); - dbg(" at command : %s", at_cmd); - - return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_answer"); -} - -/* - * Operation - Answer/Reject/Replace/hold(current call) & accept incoming call. - * - * Request - - * - * 1. AT-Command: ATA - * Response - - * Success: - * OK - * Failure: - * +CME ERROR: - * - * 2. AT-Command: AT+CHLD=[] - * - * 0 - (deafult)release all held calls or set User Determined User Busy for a waiting/incoming - * call; if both exists then only the waiting call will be rejected. - * 1 - release all active calls and accepts the other (held or waiting) - * Note: In the scenario: An active call, a waiting call and held call, when the active call is - * terminated, we will make the Waiting call as active. - * 2 - place all active calls (if exist) on hold and accepts the other call (held or waiting/in-coming). - * If only one call exists which is active, place it on hold and if only held call exists make it active call. - * Response - - * Success: - * OK - * Failure: - * +CME ERROR: - * For more informatiion refer 3GPP TS 27.007. - */ -static TelReturn atmodem_call_answer(CoreObject *co, TelCallAnswerType ans_type, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd; - dbg("Entry"); - - if (ans_type == TEL_CALL_ANSWER_ACCEPT) { - /* AT-Command */ - at_cmd = g_strdup_printf("%s", "ATA"); - }else if (ans_type == TEL_CALL_ANSWER_REJECT) { - /* AT-Command */ - at_cmd = g_strdup_printf("%s", "AT+CHLD=0"); - } else if (ans_type == TEL_CALL_ANSWER_REPLACE) { - /* AT-Command */ - at_cmd = g_strdup_printf("%s", "AT+CHLD=1"); - } else if (ans_type == TEL_CALL_ANSWER_HOLD_AND_ACCEPT) { - /* AT-Command */ - at_cmd = g_strdup_printf("%s", "AT+CHLD=2"); - }else { - err("Unsupported call answer type"); - return TEL_RETURN_FAILURE; - } - - dbg("at command : %s", at_cmd); - - return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_answer"); -} - -/* - * Operation - release all calls/release specific call/release all active call/release all held calls. - * - * Request - - * 1. AT-Command: AT+CHLD=[] - * - * 0 - (defualt)release all held calls or set User Determined User Busy for a waiting/incoming. - * call; if both exists then only the waiting call will be rejected. - * 1 - release all active calls and accepts the other (held or waiting). - * 1x - release a specific call (x specific call number as indicated by call id). - * 8 - release all calls. - * Response - - * Success: - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_call_end(CoreObject *co, const TelCallEnd *end_info, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd; - dbg("Entry"); - - if (end_info->end_type == TEL_CALL_END_ALL) { - /* AT-Command */ - at_cmd = g_strdup_printf("%s", "AT+CHLD=8"); - }else if (end_info->end_type == TEL_CALL_END) { - /* AT-Command */ - at_cmd = g_strdup_printf("%s%d", "AT+CHLD=1",end_info->call_id); - } else if (end_info->end_type == TEL_CALL_END_ACTIVE_ALL) { - /* AT-Command */ - at_cmd = g_strdup_printf("%s", "AT+CHLD=1"); - } else if (end_info->end_type == TEL_CALL_END_HOLD_ALL) { - /* AT-Command */ - at_cmd = g_strdup_printf("%s", "AT+CHLD=0"); - }else { - err("Unsupported call end type"); - return TEL_RETURN_FAILURE; - } - - dbg("at command : %s", at_cmd); - - return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_end"); -} - -/* - * Operation - call hold. - * - * Request - - * 1. AT-Command: AT+CHLD=[] - * Where - * - * 2 - place all active calls (if exist) on hold and accepts the other call (held or waiting/incoming). - * If only one call exists which is active, place it on hold and if only held call exists - * make it active call - * Response - - * Success: - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_call_hold(CoreObject *co, TcoreObjectResponseCallback cb, - void *cb_data) - -{ - gchar *at_cmd; - dbg("Entry"); - - at_cmd = g_strdup_printf("%s", "AT+CHLD=2"); - dbg("at command : %s", at_cmd); - - return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_hold"); -} - -/* - * Operation - call active. - * - * Request - - * 1. AT-Command: AT+CHLD=[] - * Where - * - * 2 - place all active calls (if exist) on hold and accepts the other call (held or waiting/incoming). - * If only one call exists which is active, place it on hold and if only held call exists - * make it active call - * Response - - * Success: - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_call_active(CoreObject *co, TcoreObjectResponseCallback cb, - void *cb_data) -{ - gchar *at_cmd; - dbg("Entry"); - - at_cmd = g_strdup_printf("%s", "AT+CHLD=2"); - dbg("at command : %s", at_cmd); - - return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_active"); -} - -/* - * Operation - call swap. - * - * Request - - * 1. AT-Command: AT+CHLD=[] - * Where - * - * 2 - place all active calls (if exist) on hold and accepts the other call (held or waiting/incoming). - * If only one call exists which is active, place it on hold and if only held call exists - * make it active call - * Response - - * Success: - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_call_swap(CoreObject *co, TcoreObjectResponseCallback cb, - void *cb_data) -{ - gchar *at_cmd; - dbg("Entry"); - - at_cmd = g_strdup_printf("%s", "AT+CHLD=2"); - dbg("at command : %s", at_cmd); - - return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_swap"); -} - -/* - * Operation - call join. - * - * Request - - * 1. AT-Command: AT+CHLD=[] - * Where - * - * 3 - adds a held call to the conversation - * Response - - * Success: - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_call_join(CoreObject *co, TcoreObjectResponseCallback cb, - void *cb_data) -{ - gchar *at_cmd; - dbg("Entry"); - - at_cmd = g_strdup_printf("%s", "AT+CHLD=3"); - dbg("at command : %s", at_cmd); - - return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_join"); -} - -/* - * Operation - call split. - * - * Request - - * 1. AT-Command: AT+CHLD=[] - * Where - * - * 2x - place all active calls on hold except call x with which communication is supported - * Response - - * Success: - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_call_split(CoreObject *co, guint call_id, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd; - dbg("Entry"); - - at_cmd = g_strdup_printf("%s%d", "AT+CHLD=2", call_id); - dbg("at command : %s", at_cmd); - - return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_split"); -} - -/* - * Operation - call transfer. - * - * Request - - * 1. AT-Command: AT+CHLD=[] - * Where - * - * 4 connects the two calls and disconnects the subscriber from both calls (Explicit Call Transfer) - * Response - - * Success: - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_call_transfer(CoreObject *co, TcoreObjectResponseCallback cb, - void *cb_data) -{ - gchar *at_cmd; - dbg("Entry"); - - at_cmd = g_strdup_printf("%s", "AT+CHLD=4"); - dbg("at command : %s", at_cmd); - - return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_transfer"); -} - -/* - * Operation - call transfer. - * - * Request - - * 1. AT-Command: AT+CTFR= [,] - * Where - * number> - * string type phone number - * - * type of address octet in integer format. It is optional parameter. - * - * Response - - * Success: - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_call_deflect(CoreObject *co, const gchar *deflect_to, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd; - dbg("Entry"); - - at_cmd = g_strdup_printf("AT+CTFR=%s", deflect_to); - dbg("at command : %s", at_cmd); - - return __atmodem_send_call_request(co, cb, cb_data, at_cmd, "atmodem_call_deflect"); -} - -/* Call Operations */ -static TcoreCallOps atmodem_call_ops = { - .dial = atmodem_call_dial, - .answer = atmodem_call_answer, - .end = atmodem_call_end, - .send_dtmf = NULL, - .hold = atmodem_call_hold, - .active = atmodem_call_active, - .swap = atmodem_call_swap, - .join = atmodem_call_join, - .split = atmodem_call_split, - .transfer = atmodem_call_transfer, - .deflect = atmodem_call_deflect, - .set_active_line = NULL, - .get_active_line = NULL, - .set_volume_info = NULL, - .get_volume_info = NULL, - .set_sound_path = NULL, - .set_mute = NULL, - .get_mute_status = NULL, - .set_sound_recording = NULL, - .set_sound_equalization = NULL, -}; - -gboolean atmodem_call_init(TcorePlugin *p, CoreObject *co) -{ - dbg("Entry"); - - /* Set operations */ - tcore_call_set_ops(co, &atmodem_call_ops); - - /* Add Callbacks */ - tcore_object_add_callback(co, - "%SCLCC:", - on_notification_atmodem_call_status, NULL); - tcore_object_add_callback(co, - "+CSSU:", - on_notification_atmodem_call_ss_cssu_info, NULL); - - return TRUE; -} - -void atmodem_call_exit(TcorePlugin *p, CoreObject *co) -{ - dbg("Exit"); -} diff --git a/src/atmodem_common.c b/src/atmodem_common.c deleted file mode 100644 index 1788a5a..0000000 --- a/src/atmodem_common.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * tel-plugin-atmodem - * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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 -#include -#include - -#include - -#include -#include - -#include "atmodem_common.h" - -void on_send_atmodem_request(TcorePending *p, - TelReturn send_status, void *user_data) -{ - dbg("Send - [%s]", - (send_status == TEL_RETURN_SUCCESS ? "OK" : "NOK")); -} - -AtmodemRespCbData *atmodem_create_resp_cb_data(TcoreObjectResponseCallback cb, - void *cb_data, void *data, guint data_len) -{ - AtmodemRespCbData *resp_cb_data; - - resp_cb_data = tcore_malloc0(sizeof(AtmodemRespCbData) + data_len); - resp_cb_data->cb = cb; - resp_cb_data->cb_data = cb_data; - if ((data != NULL) && (data_len > 0)) - memcpy(resp_cb_data->data, data, data_len); - - return resp_cb_data; -} - -void atmodem_destroy_resp_cb_data(AtmodemRespCbData *resp_cb_data) -{ - if (resp_cb_data) - tcore_free(resp_cb_data); -} diff --git a/src/atmodem_modem.c b/src/atmodem_modem.c deleted file mode 100755 index 91b769b..0000000 --- a/src/atmodem_modem.c +++ /dev/null @@ -1,569 +0,0 @@ -/* - * tel-plugin-atmodem - * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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 -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "atmodem_modem.h" -#include "atmodem_common.h" - -typedef enum { - ATMODEM_CP_STATE_OFFLINE, - ATMODEM_CP_STATE_CRASH_RESET, - ATMODEM_CP_STATE_CRASH_EXIT, - ATMODEM_CP_STATE_BOOTING, - ATMODEM_CP_STATE_ONLINE, - ATMODEM_CP_STATE_NV_REBUILDING, - ATMODEM_CP_STATE_LOADER_DONE, -} AtmodemCpState; - -/* Notifications */ -#if 0 /* To be supported later */ -static gboolean on_event_atmodem_cp_power(CoreObject *co, const void *event_info, void *user_data) -{ - GSList *lines = (GSList *)event_info; - const gchar *line; - - dbg("Modem Power notification - SIM status: [\%SCSIM]"); - - if (g_slist_length(lines) != 1) { - err("\%SCSIM unsolicited message expected to be " - "Single line but received multiple lines"); - return TRUE; - } - - line = (const gchar *)lines->data; - if (line != NULL) { - GSList *tokens; - AtmodemCpState cp_state; - TelModemPowerStatus power_status; - - tokens = tcore_at_tok_new(line); - - /* */ - cp_state = atoi(g_slist_nth_data(tokens, 0)); - dbg("CP state: [0x%x]", cp_state); - switch (cp_state) { - case ATMODEM_CP_STATE_OFFLINE: - power_status = TEL_MODEM_POWER_OFF; - break; - - case ATMODEM_CP_STATE_CRASH_RESET: - power_status = TEL_MODEM_POWER_ERROR; - break; - - default: - dbg("Unhandled State : [0x%x]", cp_state); - goto out; - } - - /* Set Power */ - tcore_modem_set_powered(co, FALSE); - - /* Send notification */ - tcore_object_send_notification(co, - TCORE_NOTIFICATION_MODEM_POWER, - sizeof(TelModemPowerStatus), &power_status); - -out: - tcore_at_tok_free(tokens); - } - - return TRUE; -} -#endif /* To be supported later */ - -static gboolean on_event_atmodem_phone_state(CoreObject *co, const void *event_info, void *user_data) -{ - GSList *lines = (GSList *)event_info; - const gchar *line; - - dbg("Modem Power notification - SIM status: [\%SCFUN]"); - - if (g_slist_length(lines) != 1) { - err("\%SCFUN unsolicited message expected to be " - "Single line but received multiple lines"); - return TRUE; - } - - line = (const gchar *)lines->data; - if (line != NULL) { - GSList *tokens; - guint state; - - tokens = tcore_at_tok_new(line); - - /* */ - state = atoi(g_slist_nth_data(tokens, 0)); - dbg("Flight mdoe State: [%s]", (state ? "OFF" : "ON")); - - /* Set Flight mode */ - tcore_modem_set_flight_mode_state(co, !state); - - tcore_at_tok_free(tokens); - - /* - * TODO: - * Handle Notification as response to Request - */ - } - - return TRUE; -} - -/* System function responses */ -static void on_response_modem_set_flight_mode_internal(TcorePlugin *plugin, - gint result, const void *response, void *user_data) -{ - CoreObject *co; - gboolean flight_mode; - dbg("Enter"); - - co = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_MODEM); - tcore_check_return_assert(co != NULL); - - tcore_check_return(result == TEL_MODEM_RESULT_SUCCESS); - - /* Get Flight mode state */ - (void)tcore_modem_get_flight_mode_state(co, &flight_mode); - - dbg("Setting Modem Fiight mode (internal) - [%s] - [SUCCESS]", - (flight_mode ? "ON": "OFF")); - - /* - * Send notification - * - * This is an internal request to set Flight mode, which is sent during - * boot-up based on AP-side configuration (VCONF). - * - * Need to notify TAPI through Notiifcation - - * TCORE_NOTIFICATION_MODEM_FLIGHT_MODE - */ - (void)tcore_object_send_notification(co, - TCORE_NOTIFICATION_MODEM_FLIGHT_MODE, - sizeof(gboolean), &flight_mode); -} - -/* System functions */ -gboolean atmodem_modem_power_on_modem(TcorePlugin *plugin) -{ - CoreObject *co; - TcoreStorage *strg; - gboolean flight_mode; - TelModemPowerStatus power_status; - - co = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_MODEM); - tcore_check_return_value_assert(co != NULL, FALSE); - - /* Set Modem Power State to 'ON' */ - tcore_modem_set_powered(co, TRUE); - - /* - * Set Flight mode (as per AP settings -VCONF) - */ - /* Get Flight mode from VCONFKEY */ - strg = tcore_server_find_storage(tcore_plugin_ref_server(plugin), "vconf"); - tcore_check_return_value_assert(strg != NULL, FALSE); - - flight_mode = tcore_storage_get_bool(strg, STORAGE_KEY_FLIGHT_MODE); - - /* - * Set Flight mode request is dispatched to Core Object (Modem) - * to ensure that 'Request Hooks' get executed. - */ - (void)tcore_object_dispatch_request(co, TRUE, - TCORE_COMMAND_MODEM_SET_FLIGHTMODE, - &flight_mode, sizeof(gboolean), - on_response_modem_set_flight_mode_internal, NULL); - - /* - * Send notification - * - * Need to notify Modem is Powered UP through Notiifcation - - * TCORE_NOTIFICATION_MODEM_POWER - */ - power_status = TEL_MODEM_POWER_ON; - (void)tcore_object_send_notification(co, - TCORE_NOTIFICATION_MODEM_POWER, - sizeof(TelModemPowerStatus), &power_status); - dbg("Modem Powered ON"); - - return FALSE; -} - -/* Modem Responses */ -static void on_response_atmodem_modem_set_flight_mode(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - gboolean *enable; - - TelModemResult result = TEL_MODEM_RESULT_FAILURE; - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp && at_resp->success) - result = TEL_MODEM_RESULT_SUCCESS; - - enable = (gboolean *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - dbg("Setting Modem Flight mode - [%s] - [%s]", - (*enable ? "ON": "OFF"), - (result == TEL_MODEM_RESULT_SUCCESS ? "SUCCESS" : "FAIL")); - - /* Update Core Object */ - (void)tcore_modem_set_flight_mode_state(co, *enable); - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data); - - /* Free callback data */ - atmodem_destroy_resp_cb_data(resp_cb_data); - - /* - * In case Flight mode is set to OFF, we need to trigger - * Network Registration. - * - * This is taken care by Network module which hooks on - * Set Flight mode Request of Modem module. - */ -} - -static void on_response_atmodem_modem_get_version(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - TelModemVersion version = {{0}, {0}, {0}, {0}}; - - TelModemResult result = TEL_MODEM_RESULT_FAILURE; - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp) { - if (at_resp->lines) { - const gchar *line; - GSList *tokens = NULL; - - line = (const gchar *)at_resp->lines->data; - tokens = tcore_at_tok_new(line); - if (g_slist_length(tokens) > 0) { - if (at_resp->success) { - gchar *sw_ver = NULL, *hw_ver = NULL; - gchar *calib_date = NULL, *p_code = NULL; - - sw_ver = g_slist_nth_data(tokens, 0); - hw_ver = g_slist_nth_data(tokens, 1); - calib_date = g_slist_nth_data(tokens, 2); - p_code = g_slist_nth_data(tokens, 3); - - g_strlcpy(version.software_version, - sw_ver, - TEL_MODEM_VERSION_LENGTH_MAX + 1); - g_strlcpy(version.hardware_version, - hw_ver, - TEL_MODEM_VERSION_LENGTH_MAX + 1); - g_strlcpy(version.calibration_date, - calib_date, - TEL_MODEM_VERSION_LENGTH_MAX + 1); - g_strlcpy(version.product_code, - p_code, - TEL_MODEM_VERSION_LENGTH_MAX + 1); - - dbg("Version - Software: [%s] Hardware: [%s] " - "Calibration date: [%s] Product " - "Code: [%s]", sw_ver, hw_ver, - calib_date, p_code); - - result = TEL_MODEM_RESULT_SUCCESS; - } else { - err("RESPONSE - [NOK]"); - err("[%s]", g_slist_nth_data(tokens, 0)); - } - } else { - err("Invalid response message"); - result = TEL_MODEM_RESULT_UNKNOWN_FAILURE; - } - tcore_at_tok_free(tokens); - } - } - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, &version, resp_cb_data->cb_data); - - /* Free callback data */ - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -static void on_response_atmodem_modem_get_imei(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - gchar imei[TEL_MODEM_IMEI_LENGTH_MAX +1] = {0}; - - TelModemResult result = TEL_MODEM_RESULT_FAILURE; - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp) { - if (at_resp->lines) { - const gchar *line; - GSList *tokens = NULL; - - line = (const gchar *)at_resp->lines->data; - tokens = tcore_at_tok_new(line); - if (g_slist_length(tokens) == 1) { - if (at_resp->success) { - dbg("RESPONSE - [OK]"); - g_strlcpy(imei, - (const gchar *)g_slist_nth_data(tokens, 0), - TEL_MODEM_IMEI_LENGTH_MAX+1); - dbg("IMEI: [%s]", imei); - - result = TEL_MODEM_RESULT_SUCCESS; - } else { - err("RESPONSE - [NOK]"); - err("[%s]", g_slist_nth_data(tokens, 0)); - } - } else { - err("Invalid response message"); - result = TEL_MODEM_RESULT_UNKNOWN_FAILURE; - } - tcore_at_tok_free(tokens); - } - } - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, imei, resp_cb_data->cb_data); - - /* Free callback data */ - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -/* Modem Operations */ -/* - * Operation - set_flight_mode - * - * Request - - * AT-Command: AT+CFUN= - * where, - * - * 0 ENABLE Flight Mode - * 1 DISABLE Flight Mode - * Response - - * Success: (No Result) - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_modem_set_flight_mode(CoreObject *co, gboolean enable, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd; - guint power_mode; - - AtmodemRespCbData *resp_cb_data; - TelReturn ret; - - if (enable) { - dbg("Flight mode - [ON]"); - power_mode = 0; - } else { - dbg("Flight mode - [OFF]"); - power_mode = 1; - } - - /* AT-Command */ - at_cmd = g_strdup_printf("AT+CFUN=%d", power_mode); - - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - &enable, sizeof(gboolean)); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - at_cmd, NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - on_response_atmodem_modem_set_flight_mode, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Flight mode"); - - /* Free resources */ - g_free(at_cmd); - - return ret; -} - -/* - * Operation - get_flight_mode - * - * Request - - * AT-Command: None - * Fetch information from Core Object - * - * Response - flight_mode (gboolean) - */ -static TelReturn atmodem_modem_get_flight_mode(CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gboolean flight_mode; - - /* Fetch Flight mode from Core Object */ - (void)tcore_modem_get_flight_mode_state(co, &flight_mode); - dbg("Modem Flight mode - [%s]", (flight_mode ? "ON": "OFF")); - - /* Invoke response callback */ - if (cb) - cb(co, (gint)TEL_MODEM_RESULT_SUCCESS, &flight_mode, cb_data); - - return TEL_RETURN_SUCCESS; -} - -/* - * Operation - get_version - * - * Request - - * AT-Command: AT+CGMR - * - * Response - version (TelModemVersion) - * Success: (Single line) - - * , , , - * OK - * Note: - * Success Response is different from standard 3GPP AT-Command (+CGMR) - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_modem_get_version(CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - AtmodemRespCbData *resp_cb_data; - TelReturn ret; - - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - NULL, 0); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - "AT+CGMR", NULL, - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - on_response_atmodem_modem_get_version, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Version"); - - return ret; -} - -/* - * Operation - get_imei - * - * Request - - * AT-Command: AT+CGSN - * - * Response - imei (gchar array of length 20+'\0' bytes) - * Success: (Single line) - * - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_modem_get_imei(CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - AtmodemRespCbData *resp_cb_data; - TelReturn ret; - - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - NULL, 0); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - "AT+CGSN", NULL, - TCORE_AT_COMMAND_TYPE_NUMERIC, - NULL, - on_response_atmodem_modem_get_imei, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get IMEI"); - - return ret; -} - -/* Modem Operations */ -static TcoreModemOps atmodem_modem_ops = { - .set_power_status = NULL, - .set_flight_mode = atmodem_modem_set_flight_mode, - .get_flight_mode = atmodem_modem_get_flight_mode, - .get_version = atmodem_modem_get_version, - .get_imei = atmodem_modem_get_imei -}; - -gboolean atmodem_modem_init(TcorePlugin *p, CoreObject *co) -{ - dbg("Enter"); - - /* Set operations */ - tcore_modem_set_ops(co, &atmodem_modem_ops); - - /* Add Callbacks */ -#if 0 /* To be supported later */ - tcore_object_add_callback(co, "\%SCSIM:", - on_event_atmodem_cp_power, NULL); -#endif /* To be supported later */ - tcore_object_add_callback(co, "\%SCFUN:", - on_event_atmodem_phone_state, NULL); - - dbg("Exit"); - return TRUE; -} - -void atmodem_modem_exit(TcorePlugin *p, CoreObject *co) -{ - dbg("Exit"); -} diff --git a/src/atmodem_network.c b/src/atmodem_network.c deleted file mode 100755 index 38f96c5..0000000 --- a/src/atmodem_network.c +++ /dev/null @@ -1,1287 +0,0 @@ -/* - * tel-plugin-atmodem - * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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 -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "atmodem_network.h" -#include "atmodem_common.h" - -#define ATMODEM_NETWORK_BASE_16 16 - -typedef enum { - ATMDOEM_NETWORK_ACT_GSM, /* GSM */ - ATMDOEM_NETWORK_ACT_GSM_COMPACT, /* GSM Compact */ - ATMDOEM_NETWORK_ACT_UTRAN, /* UTRAN */ - ATMDOEM_NETWORK_ACT_GSM_EGPRS, /* GSM w/EGPRS */ - ATMDOEM_NETWORK_ACT_UTRAN_HSDPA, /* UTRAN w/HSDPA */ - ATMDOEM_NETWORK_ACT_UTRAN_HSUPA, /* UTRAN w/HSUPA */ - ATMDOEM_NETWORK_ACT_UTRAN_HSDPA_HSUPA, /* UTRAN w/HSDPA and HSUPA */ - ATMDOEM_NETWORK_ACT_E_UTRAN, /* E-UTRAN */ -} AtmodemNetworkAct; - -static TelNetworkAct __atmodem_network_map_act(AtmodemNetworkAct act) -{ - /* - * - * 0 GSM - * 1 GSM Compact - * 2 UTRAN - * 3 GSM w/EGPRS - * 4 UTRAN w/HSDPA - * 5 UTRAN w/HSUPA - * 6 UTRAN w/HSDPA and HSUPA - HSPA - */ - switch (act) { - case ATMDOEM_NETWORK_ACT_GSM: - case ATMDOEM_NETWORK_ACT_GSM_COMPACT: - return TEL_NETWORK_ACT_GSM; - - case ATMDOEM_NETWORK_ACT_UTRAN: - return TEL_NETWORK_ACT_UMTS; - - case ATMDOEM_NETWORK_ACT_GSM_EGPRS: - return TEL_NETWORK_ACT_EGPRS; - - case ATMDOEM_NETWORK_ACT_UTRAN_HSDPA: - return TEL_NETWORK_ACT_HSDPA; - - case ATMDOEM_NETWORK_ACT_UTRAN_HSUPA: - return TEL_NETWORK_ACT_HSUPA; - - case ATMDOEM_NETWORK_ACT_UTRAN_HSDPA_HSUPA: - return TEL_NETWORK_ACT_HSPA; - - default: - return TEL_NETWORK_ACT_UNKNOWN; - } -} - -static TelNetworkRegStatus __atmodem_network_map_stat(guint stat) -{ - /* - * - * 0 Not registered, ME is not currently searching a - * new operator to register to - * 1 Registered, home network - * 2 Not registered, but ME is currently searching a - * new operator to register - * 3 Registration denied - * 4 Unknown - * 5 Registered, in roaming - */ - switch (stat) { - case 0: - return TEL_NETWORK_REG_STATUS_UNREGISTERED; - - case 1: - return TEL_NETWORK_REG_STATUS_REGISTERED; - - case 2: - return TEL_NETWORK_REG_STATUS_SEARCHING; - - case 3: - return TEL_NETWORK_REG_STATUS_DENIED; - - case 4: - return TEL_NETWORK_REG_STATUS_UNKNOWN; - - case 5: - return TEL_NETWORK_REG_STATUS_ROAMING; - - default: - return TEL_NETWORK_REG_STATUS_UNKNOWN; - } -} - -static void __on_response_atmodem_network_registration(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - dbg("Entry"); - - if (at_resp && at_resp->success) { - dbg("Network Registration - [OK]"); - } else { - err("Network Registration - [NOK]"); - } -} - -static void __atmodem_network_register_to_network(CoreObject *co) -{ - TelReturn ret; - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - "AT+COPS=0", NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - __on_response_atmodem_network_registration, NULL, - on_send_atmodem_request, NULL); - dbg("Sending Network Registration request: [%s]", - (ret == TEL_RETURN_SUCCESS ? "SUCCESS" : "FAIL")); -} - -static void __on_response_atmodem_network_fetch_nw_name_internal(CoreObject *co, - gint result, const void *response, void *user_data) -{ - TelNetworkIdentityInfo *identity = (TelNetworkIdentityInfo *)response; - - /* Send notification if result is SUCCESS */ - if (result == TEL_NETWORK_RESULT_SUCCESS) - tcore_plugin_send_notification(tcore_object_ref_plugin(co), - TCORE_NOTIFICATION_NETWORK_IDENTITY, - sizeof(TelNetworkIdentityInfo), &identity); -} - -static TcoreHookReturn __on_response_atmodem_hook_set_flight_mode(CoreObject *co, - gint result, TcoreCommand command, const void *response, const void *user_data) -{ - - tcore_check_return_value(result == TEL_MODEM_RESULT_SUCCESS, - TCORE_HOOK_RETURN_CONTINUE); - - dbg("Flight mode 'disabled', register to Network"); - - /* - * TODO - Check for selection_mode - * Need to check if it is Manual or Automatic and based on - * that need to initiate Network Registratin accordingly. - */ - __atmodem_network_register_to_network(co); - - return TCORE_HOOK_RETURN_CONTINUE; -} - -static void __on_response_atmodem_network_fetch_nw_name(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - TelNetworkIdentityInfo identity = {0, }; - - TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE; - - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp && at_resp->success) { - if (at_resp->lines) { - const gchar *line; - GSList *tokens = NULL; - gchar *token_str; - guint i, nol; - - /* Validate that only 3 lines of response is received */ - nol = g_slist_length(at_resp->lines); - if (nol > 3) { - err("Invalid response message"); - return; - } - - /* Process the Multi-line response */ - for (i = 0; i < nol; i++) { - line = g_slist_nth_data(at_resp->lines, i); - - /* - * Tokenize - * - * +COPS: [,,[,< AcT>]] - */ - tokens = tcore_at_tok_new(line); - - if ((token_str = tcore_at_tok_nth(tokens, 0))) { - guint mode = atoi(token_str); - dbg(" : [%d]", mode); - } - - if ((token_str = tcore_at_tok_nth(tokens, 0))) { - guint format = atoi(token_str); - dbg(" : [%d]", format); - - switch (format) { - case 0: /* Long Network Name */ - if ((token_str = tcore_at_tok_nth(tokens, 1))) { - if (strlen(token_str) > 0) { - identity.long_name = tcore_at_tok_extract((const char *)token_str); - - /* Update Long name */ - tcore_network_set_long_name(co, identity.long_name); - } - } - break; - - case 1: /* Short Network Name */ - if ((token_str = tcore_at_tok_nth(tokens, 1))) { - if (strlen(token_str) > 0) { - identity.short_name = tcore_at_tok_extract((const char *)token_str); - - /* Update Short name */ - tcore_network_set_short_name(co, identity.short_name); - } - } - break; - - case 2: /* PLMN (mcc, mnc) */ - if ((token_str = tcore_at_tok_nth(tokens, 1))) { - if (strlen(token_str) > 0) { - identity.plmn = tcore_at_tok_extract((const char *)token_str); - - /* Update PLMN */ - tcore_network_set_plmn( co, identity.plmn); - } - } - break; - - default: - break; - } - } - - /* Free resource */ - tcore_at_tok_free(tokens); - } - - /* Send Notification - Network identity */ - dbg("Network name - Long name: [%s] Short name: [%s] " - "PLMN: [%s]", identity.long_name, - identity.short_name, identity.plmn); - - result = TEL_NETWORK_RESULT_SUCCESS; - } - } - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, &identity, resp_cb_data->cb_data); - - /* Free resource */ - tcore_free(identity.long_name); - tcore_free(identity.short_name); - tcore_free(identity.plmn); - - /* Free callback data */ - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -/* - * Operation - fetch_nw_name - * - * Request - - * AT-Command: AT+COPS=[[,[,[,< AcT>]]]] - * - * may be - * 1 Manual. Other parameters like format and operator need to be passed - * 2 Deregister from network - * 3 It sets value. In this case becomes a mandatory input - * 4 Manual / Automatic. In this case if manual selection fails then automatic mode - * is entered - * - * may be - * 0 format presentations are set to long alphanumeric. If Network name not - * available it displays combination of Mcc and MNC in string format. - * 1 format presentation is set to short alphanumeric. - * 2 format presentations set to numeric. - * - * may be - * string type given in format - * - * Response - Network name - * Success: (Multiple Single line) - * +COPS: [,,[,< AcT>]] - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn __atmodem_network_fetch_nw_name(CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - AtmodemRespCbData *resp_cb_data = NULL; - TelReturn ret; - - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - "AT+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,0+COPS?;", "+COPS", - TCORE_AT_COMMAND_TYPE_MULTILINE, - NULL, - __on_response_atmodem_network_fetch_nw_name, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Fetch Network name"); - - return ret; -} - -/* Hook functions */ -static TcoreHookReturn on_hook_atmodem_set_flight_mode(CoreObject *co, - TcoreCommand command, const void *request, const void *user_data, - TcoreObjectResponseCallback cb, const void *cb_data) -{ - gboolean *flight_mode = (gboolean *)request; - - /* - * Hook Set Flight mode request. - * - * Disable Flight mode - Hook response (if success Register to Network) - * Enable Flight mode - return - */ - if(*flight_mode != TRUE) { - /* Add response hook */ - tcore_object_add_response_hook(co, command, request, - __on_response_atmodem_hook_set_flight_mode, NULL); - - return TCORE_HOOK_RETURN_CONTINUE; - } - - dbg("Flight mode - [Enabled]"); - return TCORE_HOOK_RETURN_CONTINUE; -} - -static TcoreHookReturn on_hook_atmodem_sim_status(TcorePlugin *plugin, - TcoreNotification command, guint data_len, void *data, void *user_data) -{ - const TelSimCardStatus *sim_status = (TelSimCardStatus *)data; - - tcore_check_return_value(sim_status != NULL, - TCORE_HOOK_RETURN_CONTINUE); - - /* - * Hook SIM initialization Notification - * - * SIM INIT complete - Attach to network (Register to network) - * SIM INIT not complete - return - */ - if (*sim_status == TEL_SIM_STATUS_SIM_INIT_COMPLETED) { - CoreObject *co = (CoreObject *)user_data; - dbg("SIM Initialized!!! Attach to Network"); - - tcore_check_return_value_assert(co != NULL, - TCORE_HOOK_RETURN_CONTINUE); - - /* - * TODO - Check for selection_mode - * Need to check if it is Manual or Automatic and based on - * that need to initiate Network Registratin accordingly. - */ - __atmodem_network_register_to_network(co); - - return TCORE_HOOK_RETURN_CONTINUE; - } - - dbg("SIM not yet initialized - SIM Status: [%d]", *sim_status); - return TCORE_HOOK_RETURN_CONTINUE; -} - -/* Notification callbacks */ -/* - * Notification: +CREG: [,,[,]] - * - * Possible values of can be - * 0 Not registered, ME is not currently searching - * a new operator to register to - * 1 Registered, home network - * 2 Not registered, but ME is currently searching - * a new operator to register - * 3 Registration denied - * 4 Unknown - * 5 Registered, in roaming - * - * - * string type; two byte location area code in - * hexadecimal format (e.g. 00C3) - * - * - * string type; four byte cell ID in hexadecimal - * format (e.g. 0000A13F) - * - * - * 0 GSM - * 2 UTRAN - * 3 GSM w/EGPRS - * 4 UTRAN w/HSDPA - * 5 UTRAN w/HSUPA - * 6 UTRAN w/HSDPA and HSUPA - */ -static gboolean on_notification_atmodem_cs_network_info(CoreObject *co, - const void *event_info, void *user_data) -{ - GSList *lines = NULL; - gchar *line = NULL; - - dbg("Network notification - CS network info: [+CREG]"); - - lines = (GSList *)event_info; - if (g_slist_length(lines) != 1) { - err("+CREG unsolicited message expected to be Single line " - "but received multiple lines"); - return TRUE; - } - - line = (gchar *) (lines->data); - if (line != NULL) { - TelNetworkRegStatusInfo registration_status = {0, }; - TelNetworkCellInfo cell_info = {0, }; - GSList *tokens = NULL; - gchar *token_str; - guint stat = 0, act = 0, lac = 0, ci = 0; - gboolean roam_state = FALSE; - - /* - * Tokenize - * - * +CREG: [,,[,]] - */ - tokens = tcore_at_tok_new(line); - if (g_slist_length(tokens) < 1) { - err("Invalid notification message"); - goto out; - } - - /* */ - if ((token_str = g_slist_nth_data(tokens, 0)) == NULL) { - err("No in +CREG"); - goto out; - } - stat = __atmodem_network_map_stat(atoi(token_str)); - (void)tcore_network_set_cs_reg_status(co, stat); - - /* */ - if ((token_str = g_slist_nth_data(tokens, 1))) { - token_str = tcore_at_tok_extract((const gchar *)token_str); - - lac = (guint)strtol(token_str, NULL, ATMODEM_NETWORK_BASE_16); - - /* Update Location Area Code (lac) information */ - (void)tcore_network_set_lac(co, lac); - - tcore_free(token_str); - } else { - dbg("No in +CREG"); - (void)tcore_network_get_lac(co, &lac); - } - - /* */ - if ((token_str = g_slist_nth_data(tokens, 2))) { - token_str = tcore_at_tok_extract((const gchar *)token_str); - - ci = (guint)strtol(token_str, NULL, ATMODEM_NETWORK_BASE_16); - - /* Update Cell ID (ci) information */ - (void)tcore_network_set_cell_id(co, ci); - - tcore_free(token_str); - } else { - dbg("No in +CREG"); - (void)tcore_network_get_cell_id(co, &ci); - } - - /* */ - if ((token_str = g_slist_nth_data(tokens, 3))) { - act = __atmodem_network_map_act(atoi(token_str)); - (void)tcore_network_set_access_technology(co, act); - } else { - dbg("No in +CREG"); - (void)tcore_network_get_access_technology(co, &act); - } - dbg(": %d : 0x%x : 0x%x : %d", stat, lac, ci, act); - - /* Send Notification - Network (CS) Registration status */ - registration_status.cs_status = stat; - registration_status.act = act; - (void)tcore_network_get_ps_reg_status(co, ®istration_status.ps_status); - - tcore_object_send_notification(co, - TCORE_NOTIFICATION_NETWORK_REGISTRATION_STATUS, - sizeof(TelNetworkRegStatusInfo), ®istration_status); - - switch (stat) { - case TEL_NETWORK_REG_STATUS_ROAMING: - roam_state = TRUE; // no break - case TEL_NETWORK_REG_STATUS_REGISTERED: - /* Fetch Network name - Internal request */ - (void)__atmodem_network_fetch_nw_name(co, - __on_response_atmodem_network_fetch_nw_name_internal, NULL); - break; - default: - break; - } - - /* Set Roaming state */ - tcore_network_set_roam_state(co, roam_state); - - /* Send Notification - Cell info */ - cell_info.lac = (gint)lac; - cell_info.cell_id = (gint)ci; - (void)tcore_network_get_rac(co, &cell_info.rac); - - tcore_plugin_send_notification(tcore_object_ref_plugin(co), - TCORE_NOTIFICATION_NETWORK_LOCATION_CELLINFO, - sizeof(TelNetworkCellInfo), &cell_info); - -out: - /* Free resource */ - tcore_at_tok_free(tokens); - } - - return TRUE; -} - -/* - * Notification: +CGREG: [,,[,,]] - * - * Possible values of can be - * 0 Not registered, ME is not currently searching a - * new operator to register to - * 1 Registered, home network - * 2 Not registered, but ME is currently searching a - * new operator to register - * 3 Registration denied - * 4 Unknown - * 5 Registered, in roaming - * - * - * string type; two byte location area code in - * hexadecimal format (e.g. 00C3) - * - * - * string type; four byte cell ID in hexadecimal - * format (e.g. 0000A13F) - * - * - * 0 GSM - * 2 UTRAN - * 3 GSM w/EGPRS - * 4 UTRAN w/HSDPA - * 5 UTRAN w/HSUPA - * 6 UTRAN w/HSDPA and HSUPA - * - * : - * string type; one byte routing area code in hexadecimal format - */ -static gboolean on_notification_atmodem_ps_network_info(CoreObject *co, - const void *event_info, void *user_data) -{ - GSList *lines = NULL; - gchar *line = NULL; - - dbg("Network notification - PS network info: [+CGREG]"); - - lines = (GSList *)event_info; - if (g_slist_length(lines) != 1) { - err("+CGREG unsolicited message expected to be Single line " - "but received multiple lines"); - return TRUE; - } - - line = (gchar *) (lines->data); - if (line != NULL) { - TelNetworkRegStatusInfo registration_status = {0, }; - TelNetworkCellInfo cell_info = {0, }; - GSList *tokens = NULL; - gchar *token_str; - guint stat = 0, act = 0, lac = 0, ci = 0, rac = 0; - gboolean roam_state = FALSE; - - /* - * Tokenize - * - * +CGREG: [,,[,,]] - */ - tokens = tcore_at_tok_new(line); - if (g_slist_length(tokens) < 1) { - err("Invalid notification message"); - goto out; - } - - /* */ - if ((token_str = g_slist_nth_data(tokens, 0)) == NULL) { - err("No in +CGREG"); - goto out; - } - stat = __atmodem_network_map_stat(atoi(token_str)); - (void)tcore_network_set_ps_reg_status(co, stat); - - /* */ - if ((token_str = g_slist_nth_data(tokens, 1))) { - token_str = tcore_at_tok_extract((const gchar *)token_str); - - lac = (guint)strtol(token_str, NULL, ATMODEM_NETWORK_BASE_16); - - /* Update Location Area Code (lac) information */ - (void)tcore_network_set_lac(co, lac); - - tcore_free(token_str); - } else { - dbg("No in +CGREG"); - (void)tcore_network_get_lac(co, &lac); - } - - /* */ - if ((token_str = g_slist_nth_data(tokens, 2))) { - token_str = tcore_at_tok_extract((const gchar *)token_str); - - ci = (guint)strtol(token_str, NULL, ATMODEM_NETWORK_BASE_16); - - /* Update Cell ID (ci) information */ - (void)tcore_network_set_cell_id(co, ci); - - tcore_free(token_str); - } else { - dbg("No in +CGREG"); - (void)tcore_network_get_cell_id(co, &ci); - } - - /* */ - if ((token_str = g_slist_nth_data(tokens, 3))) { - act = __atmodem_network_map_act(atoi(token_str)); - (void)tcore_network_set_access_technology(co, act); - } else { - dbg("No in +CGREG"); - (void)tcore_network_get_access_technology(co, &act); - } - - /* */ - if ((token_str = g_slist_nth_data(tokens, 4))) { - token_str = tcore_at_tok_extract((const gchar *)token_str); - - rac = (guint)strtol(token_str, NULL, ATMODEM_NETWORK_BASE_16); - - /* Update Routing Area Code (rac) information */ - (void)tcore_network_set_rac(co, rac); - - tcore_free(token_str); - } else { - err("No in +CGREG"); - (void)tcore_network_get_rac(co, &rac); - } - dbg(": %d : 0x%x : 0x%x : %d : 0x%x", stat, lac, ci, act, rac); - - /* Send Notification - Network (PS) Registration status */ - registration_status.ps_status = stat; - registration_status.act = act; - (void)tcore_network_get_cs_reg_status(co, ®istration_status.cs_status); - - tcore_object_send_notification(co, - TCORE_NOTIFICATION_NETWORK_REGISTRATION_STATUS, - sizeof(TelNetworkRegStatusInfo), ®istration_status); - - - /* Set Roaming state */ - if (registration_status.ps_status == TEL_NETWORK_REG_STATUS_ROAMING) - roam_state = TRUE; - - tcore_network_set_roam_state(co, roam_state); - - /* Send Notification - Cell info */ - cell_info.lac = lac; - cell_info.cell_id = ci; - cell_info.rac = rac; - tcore_plugin_send_notification(tcore_object_ref_plugin(co), - TCORE_NOTIFICATION_NETWORK_LOCATION_CELLINFO, - sizeof(TelNetworkCellInfo), &cell_info); - -out: - /* Free resource */ - tcore_at_tok_free(tokens); - } - - return TRUE; -} - -static gboolean on_notification_atmodem_network_rssi(CoreObject *co, - const void *event_info, void *user_data) -{ - GSList *lines; - const gchar *line = NULL; - - dbg("Network notification - Icon (rssi) info: [+CIEV]"); - - lines = (GSList *)event_info; - if (g_slist_length(lines) != 1) { - err("+CIEV unsolicited message expected to be " - "Single line but received multiple lines"); - return TRUE; - } - - line = (const gchar *)lines->data; - if (line != NULL) { - GSList *tokens; - guint descriptor; - guint value; - - tokens = tcore_at_tok_new(line); - - /* */ - descriptor = atoi(g_slist_nth_data(tokens, 0)); - dbg("Descriptor: [%s]", (descriptor == 10 ? "RSSI" - : (descriptor == 15 ? "Battery" : "Unknown"))); - - /* */ - value = atoi(g_slist_nth_data(tokens, 1)); - - switch (descriptor) { - case 10: - dbg("RSSI Level: [%d]", value); - - /* Send Notification - Network Rssi */ - tcore_object_send_notification(co, - TCORE_NOTIFICATION_NETWORK_RSSI, - sizeof(guint), &value); - break; - case 15: - dbg("Battery Level: [%d]", value); - break; - default: - warn("Unknown descriptor: [%d]", descriptor); - break; - } - - /* Free resource */ - tcore_at_tok_free(tokens); - } - - return TRUE; -} - -/* Network Responses */ -static void on_response_atmodem_network_search(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE; //TODO - CME Error mapping required. - TelNetworkPlmnList plmn_list = {0,}; - guint num_network_avail; - guint count; - GSList *tokens = NULL; - - dbg("Enter"); - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp && at_resp->success) { - const gchar *line; - GSList *net_token = NULL; - gchar *resp; - gint act; - - if (!at_resp->lines) { - err("invalid response received"); - goto END; - } - - line = (char *) at_resp->lines->data; - tokens = tcore_at_tok_new(line); - num_network_avail = g_slist_length(tokens); - if (num_network_avail < 1) { - err("invalid message"); - goto END; - } - - plmn_list.network_list = tcore_malloc0(sizeof(TelNetworkInfo) * num_network_avail); - dbg("RESPONSE OK"); - plmn_list.count = 0; - for (count = 0; count < num_network_avail; count++) { - - net_token = tcore_at_tok_new(g_slist_nth_data(tokens, count)); - if (NULL == net_token) - continue; - - resp = tcore_at_tok_nth(net_token, 0); - if (resp != NULL) { - plmn_list.network_list[count].plmn_status = atoi(resp); - dbg("status[%d]", plmn_list.network_list[count].plmn_status); - } - - if ((resp = tcore_at_tok_nth(net_token, 1))) { - /* Long Alpha name */ - dbg("long alpha name[%s]", resp); - plmn_list.network_list[count].network_identity.long_name = - tcore_at_tok_extract(resp); - } - - if ((resp = tcore_at_tok_nth(net_token, 2))) { - /* Short Alpha name */ - dbg("Short Alpha name[%s]", resp); - plmn_list.network_list[count].network_identity.short_name = - tcore_at_tok_extract(resp); - } - - /* PLMN ID */ - if ((resp = tcore_at_tok_nth(net_token, 3))) { - dbg("PLMN ID[%s]", resp); - plmn_list.network_list[count].network_identity.plmn = - tcore_at_tok_extract(resp); - } - - /* Parse Access Technology */ - if ((resp = tcore_at_tok_nth(tokens, 4))) { - act = atoi(resp); - if (0 == act) - plmn_list.network_list[count].act = TEL_NETWORK_ACT_GSM; - else if (2 == act) - plmn_list.network_list[count].act = TEL_NETWORK_ACT_UMTS; - } - - dbg("Operator [%d] :: status = %d, long_name = %s, short_name = %s plmn = %s, AcT=%d", - plmn_list.network_list[count].plmn_status, - plmn_list.network_list[count].network_identity.long_name, - plmn_list.network_list[count].network_identity.short_name, - plmn_list.network_list[count].network_identity.plmn, - plmn_list.network_list[count].act); - - plmn_list.count ++; - tcore_at_tok_free(net_token); - } - result = TEL_NETWORK_RESULT_SUCCESS; - } else { - err("RESPONSE NOK"); - if (at_resp->lines) - err("CME Error[%s]",(char *)at_resp->lines->data); - } - -END: - dbg("Network search : [%s]", - (result == TEL_NETWORK_RESULT_SUCCESS ? "SUCCESS" : "FAIL")); - - /* Invoke callback */ - if(resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, &plmn_list, resp_cb_data->cb_data); - - atmodem_destroy_resp_cb_data(resp_cb_data); - /* Free resources*/ - for (count = 0; count < num_network_avail; count++) { - g_free(plmn_list.network_list[count].network_identity.long_name); - g_free(plmn_list.network_list[count].network_identity.short_name); - g_free(plmn_list.network_list[count].network_identity.plmn); - } - - tcore_free(plmn_list.network_list); - tcore_at_tok_free(tokens); -} - -static void on_response_atmodem_network_get_selection_mode(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - TelNetworkSelectionMode selection_mode = -1; - GSList *tokens = NULL; - - TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE; //TODO - CME Error mapping required. - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp && at_resp->success) { - const gchar *line; - gint mode; - - if (!at_resp->lines) { - err("invalid response received"); - goto END; - } - - line = (char *) at_resp->lines->data; - tokens = tcore_at_tok_new(line); - if (g_slist_length(tokens) < 1) { - msg("invalid message"); - goto END; - } - dbg("RESPONSE OK"); - - mode = atoi(tcore_at_tok_nth(tokens, 0)); - if(mode == 0) - selection_mode = TEL_NETWORK_SELECTION_MODE_AUTOMATIC; - else if (mode == 1) - selection_mode = TEL_NETWORK_SELECTION_MODE_MANUAL; - - dbg("selection mode[%d]", selection_mode); - result = TEL_NETWORK_RESULT_SUCCESS; - - } else { - err("RESPONSE NOK"); - } - -END: - dbg("Get selection mode : [%s]", - (result == TEL_NETWORK_RESULT_SUCCESS ? "SUCCESS" : "FAIL")); - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, &selection_mode, resp_cb_data->cb_data); - - /* Free callback data */ - atmodem_destroy_resp_cb_data(resp_cb_data); - - /* Free resource*/ - tcore_at_tok_free(tokens); -} - -static void on_response_atmodem_network_default(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - TelNetworkResult result = TEL_NETWORK_RESULT_FAILURE; //TODO - CME Error mapping required. - - dbg("Enter"); - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp && at_resp->success) { - dbg("RESPONSE OK"); - result = TEL_NETWORK_RESULT_SUCCESS; - } else { - err("RESPONSE NOK"); - if (at_resp->lines) - err("CME Error[%s]",(char *)at_resp->lines->data); - } - - /* Invoke callback */ - if(resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data); - - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -/* Network Operations */ -/* - * Operation - fetch_nw_name - * - * Request - - * AT-Command: AT+COPS=[[,[,[,< AcT>]]]] - * - * may be - * 1 Manual. Other parameters like format and operator need to be passed - * 2 Deregister from network - * 3 It sets value. In this case becomes a mandatory input - * 4 Manual / Automatic. In this case if manual selection fails then automatic mode - * is entered - * - * may be - * 0 format presentations are set to long alphanumeric. If Network name not - * available it displays combination of Mcc and MNC in string format. - * 1 format presentation is set to short alphanumeric. - * 2 format presentations set to numeric. - * - * may be - * string type given in format - * - * Response - Network name - * Success: (Multiple Single line) - * +COPS: [,,[,< AcT>]] - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_network_get_identity_info(CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - return __atmodem_network_fetch_nw_name(co, cb, cb_data); -} - -/* - * Operation - network search - * Request - - * AT-Command: AT+COPS=? - * - * Response - - * Success: (Single line) - * +COPS: [list of supported (,long alphanumeric - * ,short alphanumeric ,numeric [,< AcT>] - * [,,(list of supported s),(list of supported s)] - - * - * describes the format in which operator name is to be displayed. Different values of can be: - * 0 format presentations are set to long alphanumeric. If Network name not available it displays - * combination of Mcc and MNC in string format. - * 1 format presentation is set to short alphanumeric. - * 2 format presentations set to numeric. - * : - * string type given in format ; this field may be up to 16 character long for long alphanumeric format, up - * to 8 characters for short alphanumeric format and 5 Characters long for numeric format (MCC/MNC codes) - * : - * describes the status of the network. It is one of the response parameter for test command. - * 0 Unknown Networks - * 1 Network Available - * 2 Current - * 3 Forbidden Network - * - * indicates the radio access technology and values can be: - * 0 GSM - * 2 UMTS - * OK - * Failure: - * +CME ERROR: - */ - -static TelReturn atmodem_network_search(CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - AtmodemRespCbData *resp_cb_data; - TelReturn ret = TEL_RETURN_INVALID_PARAMETER; - - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - "AT+COPS=?", "+COPS", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - on_response_atmodem_network_search, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Network Search"); - - return ret; -} - -/* - * Operation - automatic network selection - * Request - - * AT-Command: AT+COPS= [ [, [, > [, ]]]] - * where - * - * is used to select, whether the selection is done automatically by the ME or is forced by this command to - * operator given in the format . - * The values of can be: - * 0 Automatic, in this case other fields are ignored and registration is done automatically by ME - * 1 Manual. Other parameters like format and operator need to be passed - * 2 Deregister from network - * 3 It sets value. In this case becomes a mandatory input - * 4 Manual / Automatic. In this case if manual selection fails then automatic mode is entered - * - * Response - - * Success:(No result) - * OK or - * +CME ERROR: - */ -static TelReturn atmodem_network_select_automatic(CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - AtmodemRespCbData *resp_cb_data; - TelReturn ret = TEL_RETURN_INVALID_PARAMETER; - dbg("entry"); - - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - "AT+COPS=0", NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - on_response_atmodem_network_default, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Automatic network selection"); - - return ret; -} - -/* - * Operation - manual network selection - * Request - - * AT-Command: AT+COPS= [ [, [, > [, ]]]] - * where - * - * is used to select, whether the selection is done automatically by the ME or is forced by this command to - * operator given in the format . - * The values of can be: - * 0 Automatic, in this case other fields are ignored and registration is done automatically by ME - * 1 Manual. Other parameters like format and operator need to be passed - * 2 Deregister from network - * 3 It sets value. In this case becomes a mandatory input - * 4 Manual / Automatic. In this case if manual selection fails then automatic mode is entered. - * - * string type given in format ; this field may be up to 16 character long for long alphanumeric format, up - * to 8 characters for short alphanumeric format and 5 Characters long for numeric format (MCC/MNC codes) - * - * indicates the radio access technology and values can be: - * 0 GSM - * 2 UMTS - * - * Response - - * Success:(No result) - * OK or - * +CME ERROR: - */ -static TelReturn atmodem_network_select_manual(CoreObject *co, - const TelNetworkSelectManualInfo *sel_manual, - TcoreObjectResponseCallback cb, void *cb_data) -{ - AtmodemRespCbData *resp_cb_data; - TelReturn ret = TEL_RETURN_INVALID_PARAMETER; - gchar *at_cmd; - gint act; - dbg("entry"); - - switch(sel_manual->act) { - case TEL_NETWORK_ACT_GSM: - case TEL_NETWORK_ACT_GPRS: - case TEL_NETWORK_ACT_EGPRS: - act = 0; - break; - case TEL_NETWORK_ACT_UMTS: - case TEL_NETWORK_ACT_GSM_AND_UMTS: - case TEL_NETWORK_ACT_HSDPA: - case TEL_NETWORK_ACT_HSPA: - act = 2; - break; - default: - err("unsupported AcT"); - return ret; - } - - /* AT-Command */ - at_cmd = g_strdup_printf("AT+COPS=1,2,\"%s\",%d", sel_manual->plmn, act); - - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - at_cmd, NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - on_response_atmodem_network_default, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Manual network selection"); - - /* Free resources*/ - g_free(at_cmd); - return ret; -} - -/* - * Operation - get network selection mode - * Request - - * AT-Command: AT+COPS? - * - * Response - - * Success: (Single line) - * +COPS: [,,[,< AcT>]] - * - * is used to select, whether the selection is done automatically by the ME or is forced by this command to - * operator given in the format . - * The values of can be: - * 0 Automatic, in this case other fields are ignored and registration is done automatically by ME - * 1 Manual. Other parameters like format and operator need to be passed - * 2 Deregister from network - * 3 It sets value. In this case becomes a mandatory input - * 4 Manual / Automatic. In this case if manual selection fails then automatic mode is entered - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_network_get_selection_mode(CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - AtmodemRespCbData *resp_cb_data; - TelReturn ret = TEL_RETURN_INVALID_PARAMETER; - - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - "AT+COPS?", "+COPS", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - on_response_atmodem_network_get_selection_mode, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get selection mode"); - - return ret; -} - -/* Network Operations */ -static TcoreNetworkOps atmodem_network_ops = { - .get_identity_info = atmodem_network_get_identity_info, - .search = atmodem_network_search, - .cancel_search = NULL, - .select_automatic = atmodem_network_select_automatic, - .select_manual = atmodem_network_select_manual, - .get_selection_mode = atmodem_network_get_selection_mode, - .set_preferred_plmn = NULL, - .get_preferred_plmn = NULL, - .set_mode = NULL, - .get_mode = NULL, - .get_neighboring_cell_info = NULL -}; - -gboolean atmodem_network_init(TcorePlugin *p, CoreObject *co) -{ - dbg("Enter"); - - /* Set operations */ - tcore_network_set_ops(co, &atmodem_network_ops); - - /* Add Callbacks */ - tcore_object_add_callback(co, - "+CREG:", - on_notification_atmodem_cs_network_info, NULL); - tcore_object_add_callback(co, - "+CGREG:", - on_notification_atmodem_ps_network_info, NULL); - tcore_object_add_callback(co, - "+CIEV:", - on_notification_atmodem_network_rssi, NULL); - - /* - * Add Hooks - Request and Notification - */ - tcore_plugin_add_request_hook(p, - TCORE_COMMAND_MODEM_SET_FLIGHTMODE, - on_hook_atmodem_set_flight_mode, NULL); - tcore_plugin_add_notification_hook(p, - TCORE_NOTIFICATION_SIM_STATUS, - on_hook_atmodem_sim_status, co); - - //_insert_mcc_mnc_oper_list(cp, co_network); - - dbg("Exit"); - return TRUE; -} - -void atmodem_network_exit(TcorePlugin *p, CoreObject *co) -{ - dbg("Exit"); -} diff --git a/src/atmodem_ps.c b/src/atmodem_ps.c deleted file mode 100755 index ec2e0db..0000000 --- a/src/atmodem_ps.c +++ /dev/null @@ -1,639 +0,0 @@ -/* - * tel-plugin-atmodem - * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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 -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "atmodem_ps.h" -#include "atmodem_common.h" - -typedef struct { - TcorePsCallState ps_call_status; -} PrivateInfo; - -static void __notify_context_status_changed(CoreObject *co_ps, guint context_id, - TcorePsCallState status) -{ - PrivateInfo *private_info = tcore_object_ref_user_data(co_ps); - TcorePsCallStatusInfo data_resp = {0,}; - tcore_check_return_assert(private_info != NULL); - - dbg("Entry"); - - private_info->ps_call_status = status; - data_resp.context_id = context_id; - data_resp.state = status; - dbg("Sending PS Call Status Notification - Context ID: [%d] Context State: [%d]", - data_resp.context_id, data_resp.state); - - /* Send PS CALL Status Notification */ - (void)tcore_object_send_notification(co_ps, - TCORE_NOTIFICATION_PS_CALL_STATUS, - sizeof(TcorePsCallStatusInfo), - &data_resp); - - dbg("Exit"); -} - -static void __atmodem_ps_setup_pdp(CoreObject *co_ps, gint result, const gchar *netif_name, - void *user_data) -{ - CoreObject *ps_context = user_data; - guint context_id; - - tcore_check_return_assert(ps_context != NULL); - - dbg("Enter"); - - if (result < 0) { - /* Deactivate PDP context */ - (void)tcore_object_dispatch_request(co_ps, TRUE, - TCORE_COMMAND_PS_DEACTIVATE_CONTEXT, - NULL, 0, - NULL, NULL); - - return; - } - - dbg("devname = [%s]", netif_name); - - tcore_context_set_ipv4_devname(ps_context, netif_name); - - (void)tcore_context_get_id(ps_context, &context_id); - dbg("Context ID : %d", context_id); - - __notify_context_status_changed(co_ps, context_id, TCORE_PS_CALL_STATE_CONNECTED); - - dbg("Exit"); -} - -static void __on_response_atmodem_get_ipconfiguration(TcorePending *p, guint data_len, const void *data, void *user_data) -{ - CoreObject *co_ps = tcore_pending_ref_core_object(p); - CoreObject *ps_context = user_data; - const TcoreAtResponse *at_resp = data; - TcoreHal *hal = tcore_object_get_hal(co_ps); - PrivateInfo *private_info = tcore_object_ref_user_data(co_ps); - guint context_id; - TcorePsCallState curr_call_status; - GSList *p_cur = NULL; - - (void)tcore_context_get_id(ps_context, &context_id); - - if (at_resp && at_resp->success) { - for (p_cur = at_resp->lines; p_cur != NULL; p_cur = p_cur->next) { - const gchar *line; - GSList *tokens = NULL; - - line = (const char *) p_cur->data; - tokens = tcore_at_tok_new(line); - - if (g_slist_length(tokens) >= 2) { - gchar *pdp_type = NULL, *apn = NULL; - gchar *ip = NULL, *pdp_address = NULL, *p_cid = NULL; - - p_cid = g_slist_nth_data(tokens, 0); - dbg("cid: %d", p_cid); - - /* Send IP Configuration noti only on the requested CID. */ - if (atoi(p_cid) && (context_id == (unsigned int)atoi(p_cid))) { - pdp_type = g_slist_nth_data(tokens, 1); - dbg("PDP type: %s", pdp_type); - - if (pdp_type != NULL) { - apn = g_slist_nth_data(tokens, 2); - dbg("APN: %s", apn); - } - if (apn != NULL) { - ip = g_slist_nth_data(tokens, 3); - pdp_address = tcore_at_tok_extract(ip); - dbg("IP address: %s", ip); - } - - (void)tcore_context_set_ipv4_addr(ps_context, (const char*)pdp_address); - tcore_free(pdp_address); - - dbg("Adding default DNS pri: 8.8.8.8 sec: 8.8.4.4"); - - tcore_context_set_ipv4_dns(ps_context, "8.8.8.8", "8.8.4.4"); - - /* Mount network interface */ - if (tcore_hal_setup_netif(hal, co_ps, __atmodem_ps_setup_pdp, ps_context, context_id, TRUE) - != TEL_RETURN_SUCCESS) { - err("Setup network interface failed"); - return; - } - } else { - err("No matched response with CID: %d", atoi(p_cid)); - } - } - } - }else { - err("Response NOK"); - - (void)tcore_context_get_id(ps_context, &context_id); - - curr_call_status = private_info->ps_call_status; - - __notify_context_status_changed(co_ps, context_id, curr_call_status); - } -} - -static void __atmodem_get_ipconfiguration(CoreObject *co_ps, CoreObject *ps_context) -{ - TelReturn ret; - - dbg("Enter"); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co_ps, - "AT+CGDCONT?", NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - __on_response_atmodem_get_ipconfiguration, - ps_context, - on_send_atmodem_request, NULL); - if (ret != TEL_RETURN_SUCCESS){ - err("Failed to prepare and send AT request"); - /* Deactivate PDP context */ - (void)tcore_object_dispatch_request(co_ps, TRUE, - TCORE_COMMAND_PS_DEACTIVATE_CONTEXT, - NULL, 0, - NULL, NULL); - } - - dbg("Exit"); -} - -static void __on_response_atmodem_attach_ps(TcorePending *p, guint data_len, - const void *data, void *user_data) -{ - CoreObject *co_ps = tcore_pending_ref_core_object(p); - CoreObject *ps_context = user_data; - const TcoreAtResponse *at_resp = data; - PrivateInfo *private_info = tcore_object_ref_user_data(co_ps); - guint context_id; - TcorePsCallState curr_call_status; - - tcore_check_return_assert(at_resp != NULL); - tcore_check_return_assert(ps_context != NULL); - - if (at_resp && at_resp->success) { - __atmodem_get_ipconfiguration(co_ps, ps_context); - return; - } - - err("Response NOK"); - - (void)tcore_context_get_id(ps_context, &context_id); - - curr_call_status = private_info->ps_call_status; - - __notify_context_status_changed(co_ps, context_id, curr_call_status); - - dbg("Exit"); -} - -static void __atmodem_attach_ps(CoreObject *co_ps, CoreObject *ps_context) -{ - TelReturn ret; - - dbg("Enter"); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co_ps, - "ATD*99***1#", NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - __on_response_atmodem_attach_ps, - ps_context, - on_send_atmodem_request, NULL); - if (ret != TEL_RETURN_SUCCESS){ - err("Failed to prepare and send AT request"); - /* Deactivate PDP context */ - (void)tcore_object_dispatch_request(co_ps, TRUE, - TCORE_COMMAND_PS_DEACTIVATE_CONTEXT, - NULL, 0, - NULL, NULL); - } - - dbg("Exit"); -} - -static void on_response_atmodem_ps_activate_context(TcorePending *p, guint data_len, - const void *data, - void *user_data) -{ - CoreObject *co_ps = tcore_pending_ref_core_object(p); - const TcoreAtResponse *at_resp = data; - CoreObject *ps_context = user_data; - PrivateInfo *private_info = tcore_object_ref_user_data(co_ps); - tcore_check_return_assert(private_info != NULL); - - dbg("Enter"); - - tcore_check_return_assert(at_resp != NULL); - tcore_check_return_assert(ps_context != NULL); - - if (at_resp && at_resp->success) { - dbg("Response OK"); - __atmodem_attach_ps(co_ps, ps_context); - } else { - guint context_id; - TcorePsCallState curr_call_status; - - (void)tcore_context_get_id(ps_context, &context_id); - - err("Response NOK"); - curr_call_status = private_info->ps_call_status; - __notify_context_status_changed(co_ps, context_id, curr_call_status); - } - - dbg("Exit"); -} - -static void on_response_atmodem_ps_deactivate_context(TcorePending *p, guint data_len, - const void *data, - void *user_data) -{ - CoreObject *co_ps = tcore_pending_ref_core_object(p); - TcoreHal *hal = tcore_object_get_hal(co_ps); - const TcoreAtResponse *at_resp = data; - CoreObject *ps_context = user_data; - guint context_id; - - dbg("Enter"); - - tcore_check_return_assert(at_resp != NULL); - tcore_check_return_assert(ps_context != NULL); - - (void)tcore_context_get_id(ps_context, &context_id); - dbg("Context ID : %d", context_id); - - /* - * AT+CGACT = 0 is returning NO CARRIER or an error. Just test if the - * response contains NO CARRIER else decode CME error. - */ - if (at_resp && at_resp->success) { - const gchar *line; - - line = (const gchar *)at_resp->lines->data; - if (g_strcmp0(line, "NO CARRIER") != 0) { - err("%s", line); - err("Context %d has not been deactivated", context_id); - - goto out; - } - } - - __notify_context_status_changed(co_ps, context_id, TCORE_PS_CALL_STATE_NOT_CONNECTED); - - if (tcore_hal_setup_netif(hal, co_ps, NULL, NULL, context_id, FALSE) != TEL_RETURN_SUCCESS) - err("Failed to disable network interface"); - -out: - dbg("Exit"); -} - -static void on_response_atmodem_ps_define_context(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *ps_context = (CoreObject *) user_data; - CoreObject *co_ps = tcore_pending_ref_core_object(p); - PrivateInfo *private_info = tcore_object_ref_user_data(co_ps); - guint context_id; - TcorePsCallState curr_call_status; - - dbg("entry"); - - tcore_check_return_assert(at_resp != NULL); - tcore_check_return_assert(ps_context != NULL); - tcore_check_return_assert(private_info != NULL); - - if (at_resp && at_resp->success) { - dbg("Response OK"); - curr_call_status = TCORE_PS_CALL_STATE_CTX_DEFINED; - tcore_context_set_state(co_ps, curr_call_status); - }else { - err("ERROR[%s]",at_resp->final_response); - curr_call_status =private_info->ps_call_status; - } - (void)tcore_context_get_id(ps_context, &context_id); - __notify_context_status_changed(co_ps, context_id, curr_call_status); -} - -/* - * Operation - PDP Context Activate - * - * Request - - * AT-Command: AT+CGACT= [ [, [, [,...]]]] - * - * where, - * - * indicates the state of PDP context activation - * - * 1 activated - * - * - * It is a numeric parameter which specifies a particular PDP context definition - * - * Response - - * Success: (No Result) - * OK - * Failure: - * +CME ERROR: - */ - -static TelReturn atmodem_ps_activate_context(CoreObject *co_ps, CoreObject *ps_context, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd = NULL; - TelReturn ret; - guint context_id; - PrivateInfo *private_info = tcore_object_ref_user_data(co_ps); - tcore_check_return_value_assert(private_info != NULL, TEL_RETURN_INVALID_PARAMETER); - - dbg("Entry"); - - (void)tcore_context_get_id(ps_context, &context_id); - dbg("Context ID : %d", context_id); - - at_cmd = g_strdup_printf("AT+CGACT=1,%d", context_id); - dbg(" at command : %s", at_cmd); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co_ps, - at_cmd, NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - on_response_atmodem_ps_activate_context, - ps_context, - on_send_atmodem_request, NULL); - if (ret != TEL_RETURN_SUCCESS){ - TcorePsCallState curr_call_status; - - curr_call_status = private_info->ps_call_status; - err("AT request failed. Send notification for call status [%d]", curr_call_status); - __notify_context_status_changed(co_ps, context_id, curr_call_status); - } - tcore_free(at_cmd); - dbg("Exit"); - - return ret; -} - -/* - * Operation - PDP Context Deactivate - * - * Request - - * AT-Command: AT+CGACT= [ [, [, [,...]]]] - * - * where, - * - * indicates the state of PDP context activation - * - * 0 deactivated - * - * - * It is a numeric parameter which specifies a particular PDP context definition - * - * Response - - * Success: (No Result) - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_ps_deactivate_context(CoreObject *co_ps, CoreObject *ps_context, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd = NULL; - TelReturn ret; - guint context_id; - PrivateInfo *private_info = tcore_object_ref_user_data(co_ps); - tcore_check_return_value_assert(private_info != NULL, TEL_RETURN_INVALID_PARAMETER); - - dbg("Entry"); - - (void)tcore_context_get_id(ps_context, &context_id); - dbg("Context ID : %d", context_id); - - at_cmd = g_strdup_printf("AT+CGACT=0,%d", context_id); - dbg(" at command : %s", at_cmd); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co_ps, - at_cmd, NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - on_response_atmodem_ps_deactivate_context, - ps_context, - on_send_atmodem_request, NULL); - if (ret != TEL_RETURN_SUCCESS){ - TcorePsCallState curr_call_status; - - curr_call_status = private_info->ps_call_status; - err("AT request failed. Send notification for call status [%d]", curr_call_status); - __notify_context_status_changed(co_ps, context_id, curr_call_status); - } - tcore_free(at_cmd); - dbg("Exit"); - - return ret; -} - -/* - * Operation - Define PDP Context - * - * Request - - * AT-Command: AT+CGDCONT= [ [, [, [, [, - * [, [, [... [, pdN]]]]]]]]] - * where, - * - * It is a numeric parameter, which specifies a particular PDP context definition - * - * - * "IP" Internet Protocol (IETF STD 5) - * "IPV6" Internet Protocol, version 6 (IETF RFC 2460) - * "IPV4V6" Virtual introduced to handle dual IP stack UE capability (see 3GPP - * TS 24.301[83]) - * - * - * Access Point Name - * - * - * It is the string parameter that identifies the MT in the address space applicable to the PDP - * The allocated address may be read using the command +CGPADDR command - * - * - * A numeric parameter that controls PDP data compression - * 0 off - * 1 on - * 2 V.42 bis - * - * - * A numeric parameter that controls PDP header compression - * 0 off - * 1 on - * 2 RFC1144 - * 3 RFC2507 - * 4 RFC3095 - * - * ... - * zero to N string parameters whose meanings are specific to the - * - * Response - - * Success: (No Result) - * OK - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_ps_define_context(CoreObject *co_ps, CoreObject *ps_context, - TcoreObjectResponseCallback cb, void *cb_data) -{ - guint context_id = 0; - gchar *at_cmd = NULL; - gchar *apn = NULL; - gchar *pdp_type_str = NULL; - TcoreContextType pdp_type; - TcoreContextDComp d_comp; - TcoreContextHComp h_comp; - TelReturn ret = TEL_RETURN_FAILURE; - TcorePsCallState curr_call_status; - PrivateInfo *private_info = tcore_object_ref_user_data(co_ps); - tcore_check_return_value_assert(private_info != NULL, TEL_RETURN_INVALID_PARAMETER); - - dbg("Entry"); - - (void)tcore_context_get_id(ps_context, &context_id); - (void)tcore_context_get_type(ps_context, &pdp_type); - - switch (pdp_type) { - case TCORE_CONTEXT_TYPE_X25: - dbg("CONTEXT_TYPE_X25"); - pdp_type_str = g_strdup("X.25"); - break; - - case TCORE_CONTEXT_TYPE_IP: - dbg("CONTEXT_TYPE_IP"); - pdp_type_str = g_strdup("IP"); - break; - - case TCORE_CONTEXT_TYPE_PPP: - dbg("CONTEXT_TYPE_PPP"); - pdp_type_str = g_strdup("PPP"); - break; - - case TCORE_CONTEXT_TYPE_IPV6: - dbg("CONTEXT_TYPE_IPV6"); - pdp_type_str = g_strdup("IPV6"); - break; - - default: - /*PDP Type not supported*/ - dbg("Unsupported PDP type: %d", pdp_type); - goto error; - } - - (void)tcore_context_get_data_compression(ps_context, &d_comp); - (void)tcore_context_get_header_compression(ps_context, &h_comp); - (void) tcore_context_get_apn(ps_context, &apn); - - dbg("Define context for CID: %d", context_id); - /* AT-Command */ - at_cmd = g_strdup_printf("AT+CGDCONT=%d,\"%s\",\"%s\",,%d,%d", context_id, pdp_type_str, apn, d_comp, h_comp); - dbg(" at command : %s", at_cmd); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co_ps, - at_cmd, NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - on_response_atmodem_ps_define_context, - ps_context, - on_send_atmodem_request, NULL); - - tcore_free(pdp_type_str); - tcore_free(at_cmd); - tcore_free(apn); - - if (ret == TEL_RETURN_SUCCESS) - goto out; - -error: - err("Failed to prepare and send AT request"); - - curr_call_status = private_info->ps_call_status; - __notify_context_status_changed(co_ps, context_id, curr_call_status); - -out: - dbg("Exit"); - return ret; -} - -/* PS Operations */ -static TcorePsOps atmodem_ps_ops = { - .define_context = atmodem_ps_define_context, - .activate_context = atmodem_ps_activate_context, - .deactivate_context = atmodem_ps_deactivate_context -}; - - -gboolean atmodem_ps_init(TcorePlugin *p, CoreObject *co) -{ - PrivateInfo *private_info; - - dbg("Entry"); - - /* Set PrivateInfo */ - private_info = tcore_malloc0(sizeof(PrivateInfo)); - tcore_object_link_user_data(co, private_info); - - /* Set operations */ - tcore_ps_set_ops(co, &atmodem_ps_ops); - - dbg("Exit"); - return TRUE; -} - -void atmodem_ps_exit(TcorePlugin *p, CoreObject *co) -{ - PrivateInfo *private_info; - - private_info = tcore_object_ref_user_data(co); - tcore_check_return_assert(private_info != NULL); - - tcore_free(private_info); - - dbg("Exit"); -} diff --git a/src/atmodem_sim.c b/src/atmodem_sim.c deleted file mode 100755 index f8db93a..0000000 --- a/src/atmodem_sim.c +++ /dev/null @@ -1,4284 +0,0 @@ -/* - * tel-plugin-atmodem - * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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 -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "atmodem_sim.h" -#include "atmodem_common.h" - -#define ENABLE_FLAG 1 -#define DISABLE_FLAG 2 - -#define ATMODEM_SIM_ACCESS_READ_BINARY 176 -#define ATMODEM_SIM_ACCESS_READ_RECORD 178 -#define ATMODEM_SIM_ACCESS_GET_RESPONSE 192 -#define ATMODEM_SIM_ACCESS_UPDATE_BINARY 214 -#define ATMODEM_SIM_ACCESS_UPDATE_RECORD 220 - -typedef enum { - ATMODEM_SIM_FILE_TYPE_DEDICATED = 0x00, /**< Dedicated */ - ATMODEM_SIM_FILE_TYPE_TRANSPARENT = 0x01, /**< Transparent -binary type*/ - ATMODEM_SIM_FILE_TYPE_LINEAR_FIXED = 0x02, /**< Linear fixed - record type*/ - ATMODEM_SIM_FILE_TYPE_CYCLIC = 0x04, /**< Cyclic - record type*/ - ATMODEM_SIM_FILE_TYPE_INVALID_TYPE = 0xFF /**< Invalid type */ -} AtmodemSimFileType; - -typedef enum { - ATMODEM_SIM_CURR_SEC_OP_PIN1_VERIFY, - ATMODEM_SIM_CURR_SEC_OP_PIN2_VERIFY, - ATMODEM_SIM_CURR_SEC_OP_PUK1_VERIFY, - ATMODEM_SIM_CURR_SEC_OP_PUK2_VERIFY, - ATMODEM_SIM_CURR_SEC_OP_SIM_VERIFY, - ATMODEM_SIM_CURR_SEC_OP_ADM_VERIFY, - ATMODEM_SIM_CURR_SEC_OP_PIN1_CHANGE, - ATMODEM_SIM_CURR_SEC_OP_PIN2_CHANGE, - ATMODEM_SIM_CURR_SEC_OP_PIN1_ENABLE, - ATMODEM_SIM_CURR_SEC_OP_PIN1_DISABLE, - ATMODEM_SIM_CURR_SEC_OP_PIN2_ENABLE, - ATMODEM_SIM_CURR_SEC_OP_PIN2_DISABLE, // 10 - ATMODEM_SIM_CURR_SEC_OP_SIM_ENABLE, - ATMODEM_SIM_CURR_SEC_OP_SIM_DISABLE, - ATMODEM_SIM_CURR_SEC_OP_NET_ENABLE, - ATMODEM_SIM_CURR_SEC_OP_NET_DISABLE, - ATMODEM_SIM_CURR_SEC_OP_NS_ENABLE, - ATMODEM_SIM_CURR_SEC_OP_NS_DISABLE, - ATMODEM_SIM_CURR_SEC_OP_SP_ENABLE, - ATMODEM_SIM_CURR_SEC_OP_SP_DISABLE, - ATMODEM_SIM_CURR_SEC_OP_CP_ENABLE, - ATMODEM_SIM_CURR_SEC_OP_CP_DISABLE, // 20 - ATMODEM_SIM_CURR_SEC_OP_FDN_ENABLE, - ATMODEM_SIM_CURR_SEC_OP_FDN_DISABLE, - ATMODEM_SIM_CURR_SEC_OP_PIN1_STATUS, - ATMODEM_SIM_CURR_SEC_OP_PIN2_STATUS, - ATMODEM_SIM_CURR_SEC_OP_FDN_STATUS, - ATMODEM_SIM_CURR_SEC_OP_NET_STATUS, - ATMODEM_SIM_CURR_SEC_OP_NS_STATUS, - ATMODEM_SIM_CURR_SEC_OP_SP_STATUS, - ATMODEM_SIM_CURR_SEC_OP_CP_STATUS, - ATMODEM_SIM_CURR_SEC_OP_SIM_STATUS, - ATMODEM_SIM_CURR_SEC_OP_SIM_UNKNOWN = 0xff -} AtmodemSimCurrSecOp; - -typedef enum { - SEC_LOCK_TYPE_NONE =0, - SEC_LOCK_TYPE_READY, /* ME is not locked */ - SEC_LOCK_TYPE_PS, /* PH-SIM, Lock Phone to SIM/UICC card(MT asks password when other than current SIM/UICC card inserted; MT may remember certain amount of - previously used cards thus not requiring password when they are inserted ) */ - SEC_LOCK_TYPE_PF, /* PH-FSIM, Lock Phone to the very First inserted SIM/UICC card ( MT asks password when other than the first SIM/UICC card is inserted ) */ - SEC_LOCK_TYPE_SC, /*Lock SIM/UICC card ( SIM asks password in ME power-up and when this command is issued ) */ - SEC_LOCK_TYPE_FD, /* SIM card or active application in the UICC(GSM or USIM) fixed dialing memory feature */ - SEC_LOCK_TYPE_PN, /* Network Personalization */ - SEC_LOCK_TYPE_PU, /* Network subset Personalization */ - SEC_LOCK_TYPE_PP, /* Service Provider Personalization */ - SEC_LOCK_TYPE_PC, /* Corporate Personalization */ - SEC_LOCK_TYPE_SC2, /* Lock PIN2 ( ... ) */ - SEC_LOCK_TYPE_PUK2, /* Lock PUK2 (... ) */ - SEC_LOCK_TYPE_ACL, /* ACL */ - - SEC_LOCK_TYPE_NO_SIM, /* SIM is not inserted */ - SEC_LOCK_TYPE_UNAVAIL, /* SIM is inserted but can not communicate with SIM ( SIM interface error ) */ - SEC_SIM_INIT_COMPLETED, /* SIM Initialize Completed */ - SEC_PB_INIT_COMPLETED, /* Phonebook Initialize Completed*/ - SEC_SIM_INIT_CRASH, /* SIM Crash request from SMC lab*/ - - SEC_LOCK_TYPE_MAX -} AtmodemSimSecLockType; - -typedef enum { - SEC_LOCK_KEY_NONE, - SEC_LOCK_KEY_UNLOCKED, /* Not necessary */ - SEC_LOCK_KEY_PIN, /* PIN required as a password */ - SEC_LOCK_KEY_PUK, /* 0PUK required as a password */ - SEC_LOCK_KEY_PIN2, /* PIN2 required as a password */ - SEC_LOCK_KEY_PUK2, /* PUK2 required as a password */ - SEC_LOCK_KEY_PERM_BLOCKED, /* PIN Permanent Blocked */ - SEC_LOCK_KEY_PIN2_DISABLE, /* PIN2 Lock Disabled*/ - SEC_LOCK_KEY_MAX -} AtmodemSimSecLockKey; - -typedef struct { - guint smsp_count; /**< SMSP record count */ - guint smsp_rec_len; /**< SMSP record length */ -} AtmodemSimPrivateInfo; - -typedef struct { - gboolean b_valid; /**< Valid or not */ - guint rec_length; /**< Length of one record in file */ - guint rec_count; /**< Number of records in file */ - guint data_size; /**< File size */ - guint current_index; /**< Current index to read */ - AtmodemSimFileType file_type; /**< File type and structure */ - AtmodemSimCurrSecOp sec_op; /**< Current index to read */ - TelSimMailboxList mbi_list; /**< Mailbox List */ - TelSimMailBoxNumber mb_list[TEL_SIM_MSP_CNT_MAX*5]; /**< Mailbox number */ - TelSimFileId file_id; /**< Current file id */ - TelSimResult file_result; /**< File access result */ - TelSimFileResult files; /**< File read data */ - TcoreCommand req_command; /**< Request command Id */ - TelSimImsiInfo imsi; /**< Stored locally as of now, - Need to store in secure storage*/ -} AtmodemSimMetaInfo; - -/* Request Function Declaration */ -static TelReturn atmodem_sim_get_imsi (CoreObject *co_sim, TcoreObjectResponseCallback cb, void *cb_data); -static TelReturn atmodem_sim_get_ecc (CoreObject *co_sim, TcoreObjectResponseCallback cb, void *cb_data); -static TelReturn atmodem_sim_get_spdi (CoreObject *co_sim, TcoreObjectResponseCallback cb, void *cb_data); -static TelReturn atmodem_sim_get_spn (CoreObject *co_sim, TcoreObjectResponseCallback cb, void *cb_data); -static TelReturn atmodem_sim_get_language (CoreObject *co_sim, TcoreObjectResponseCallback cb, void *cb_data); -static TelReturn atmodem_sim_get_cfis (CoreObject *co_sim, TcoreObjectResponseCallback cb, void *cb_data); -static TelReturn atmodem_sim_verify_pins(CoreObject *co, const TelSimSecPinPw *request, - TcoreObjectResponseCallback cb, void *cb_data); -static TelReturn atmodem_sim_verify_puks(CoreObject *co, const TelSimSecPukPw *request, - TcoreObjectResponseCallback cb, void *cb_data); -static TelReturn atmodem_sim_change_pins(CoreObject *co, const TelSimSecChangePinPw *request, - TcoreObjectResponseCallback cb, void *cb_data); -static TelReturn atmodem_sim_disable_facility(CoreObject *co, const TelSimFacilityPw *request, - TcoreObjectResponseCallback cb, void *cb_data); -static TelReturn atmodem_sim_enable_facility(CoreObject *co, const TelSimFacilityPw *request, - TcoreObjectResponseCallback cb, void *cb_data); -static TelReturn atmodem_sim_get_facility(CoreObject *co, TelSimLockType lock_type, - TcoreObjectResponseCallback cb, void *cb_data); - -/* Utility Function Declaration */ -static TelSimResult __atmodem_sim_decode_status_word(unsigned short status_word1, unsigned short status_word2); -static void __atmodem_sim_update_sim_status(CoreObject *co, TelSimCardStatus sim_status); -static void __atmodem_sim_get_sim_type(CoreObject *co, TcoreObjectResponseCallback cb, void *cb_data); -static void __atmodem_sim_next_from_get_file_data(CoreObject *co, - AtmodemRespCbData *resp_cb_data, TelSimResult sim_result, gboolean decode_ret); -static void __atmodem_sim_next_from_get_file_info(CoreObject *co, - AtmodemRespCbData *resp_cb_data, TelSimResult sim_result); -static void __atmodem_sim_get_file_record(CoreObject *co, - AtmodemRespCbData *resp_cb_data); -static void __atmodem_sim_get_file_data(CoreObject *co, - AtmodemRespCbData *resp_cb_data); -static TelReturn __atmodem_sim_get_file_info(CoreObject *co, - AtmodemRespCbData *resp_cb_data); -static char *__atmodem_sim_get_fac_from_lock_type(TelSimLockType lock_type, - AtmodemSimCurrSecOp *sec_op, int flag); -static int __atmodem_sim_get_lock_type(AtmodemSimCurrSecOp sec_op); -static gboolean __atmodem_convert_scpin_str_to_enum(char* line, - AtmodemSimSecLockType* lock_type, AtmodemSimSecLockKey* lock_key); - -/* Internal Response Functions*/ -static void __atmodem_sim_next_from_read_binary(CoreObject *co, - AtmodemRespCbData *resp_cb_data, - TelSimResult sim_result, gboolean decode_ret); -static void __atmodem_sim_next_from_get_response(CoreObject *co, - AtmodemRespCbData *resp_cb_data, TelSimResult sim_result); - -#if 0 //blocking for the moment -static TelReturn __atmodem_sim_update_file(CoreObject *co, - AtmodemRespCbData *resp_cb_data, - int cmd, TelSimFileId ef, - int p1, int p2, int p3, char *encoded_data); -#endif -static void __atmodem_sim_read_record(CoreObject *co, AtmodemRespCbData *resp_cb_data); -static void __atmodem_sim_read_binary(CoreObject *co, AtmodemRespCbData *resp_cb_data); -static TelReturn __atmodem_sim_get_response (CoreObject *co, AtmodemRespCbData *resp_cb_data); -static void __on_response_atmodem_sim_get_sim_type_internal(CoreObject *co, - gint result, const void *response, void *user_data); -static void __on_response_atmodem_sim_get_sim_type(TcorePending *p, - guint data_len, const void *data, void *user_data); -static void __on_response_atmodem_sim_get_file_data(TcorePending *p, - guint data_len, const void *data, void *user_data); -static void __on_response_atmodem_sim_get_file_info(TcorePending *p, - guint data_len, const void *data, void *user_data); - -#define ATMODEM_SIM_READ_FILE(co, cb, cb_data, fileId, ret) \ -{ \ - AtmodemSimMetaInfo file_meta = {0, }; \ - AtmodemRespCbData *resp_cb_data = NULL; \ - \ - file_meta.file_id = fileId; \ - file_meta.file_result = TEL_SIM_RESULT_FAILURE; \ - \ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(AtmodemSimMetaInfo)); \ - \ - ret = __atmodem_sim_get_response(co, resp_cb_data); \ -} - -static void __atmodem_sim_set_identity(CoreObject *co, TelSimImsiInfo *imsi) -{ - gchar new_imsi[15 + 1] = {0, }; - gchar *old_imsi; - - memcpy(&new_imsi, imsi->mcc, strlen(imsi->mcc)); - memcpy(&new_imsi[strlen(imsi->mcc)], imsi->mnc, strlen(imsi->mnc)); - memcpy(&new_imsi[strlen(imsi->mcc) + strlen(imsi->mnc)], imsi->msin, strlen(imsi->msin)); - - /* TODO: This is temporary code, we should use secure storage instead of vconf */ - old_imsi = vconf_get_str("db/telephony/imsi"); - if (old_imsi) { - if (g_strcmp0(old_imsi, new_imsi) != 0) { - dbg("New SIM"); - vconf_set_str("db/telephony/imsi", new_imsi); - tcore_sim_set_identification(co, TRUE); - } else { - dbg("Same SIM"); - tcore_sim_set_identification(co, FALSE); - } - } else { - dbg("Old IMSI value is NULL, set IMSI"); - vconf_set_str("db/telephony/imsi", new_imsi); - tcore_sim_set_identification(co, TRUE); - } -} - -/* Utility Functions */ -static TelSimResult __atmodem_sim_decode_status_word(unsigned short status_word1, - unsigned short status_word2) -{ - TelSimResult rst = TEL_SIM_RESULT_FAILURE; - - if (status_word1 == 0x93 && status_word2 == 0x00) { - /*Failed SIM request command*/ - dbg("error - SIM application toolkit busy [%x][%x]", - status_word1, status_word2); - } else if (status_word1 == 0x94 && status_word2 == 0x00) { - /*Failed SIM request command*/ - dbg("error - No EF Selected [%x][%x]", status_word1, status_word2); - } else if (status_word1 == 0x94 && status_word2 == 0x02) { - /*Failed SIM request command*/ - dbg("error - Out of Range - Invalid address or record number[%x][%x]", - status_word1, status_word2); - } else if (status_word1 == 0x94 && status_word2 == 0x04) { - /*Failed SIM request command*/ - dbg("error - File ID not found [%x][%x]", - status_word1, status_word2); - } else if (status_word1 == 0x94 && status_word2 == 0x08) { - /*Failed SIM request command*/ - dbg("error - File is inconsistent with command - "\ - "Modem not support or USE IPC [%x][%x]", - status_word1, status_word2); - } else if (status_word1 == 0x98 && status_word2 == 0x02) { - /*Failed SIM request command*/ - dbg("error - CHV not initialized [%x][%x]", - status_word1, status_word2); - } else if (status_word1 == 0x98 && status_word2 == 0x04) { - /*Failed SIM request command*/ - dbg("error - Access condition not fullfilled [%x][%x]", - status_word1, status_word2); - dbg("error -Unsuccessful CHV verification - "\ - "at least one attempt left [%x][%x]", - status_word1, status_word2); - dbg("error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]", - status_word1, status_word2); - dbg("error - Authentication failure [%x][%x]", - status_word1, status_word2); - } else if (status_word1 == 0x98 && status_word2 == 0x08) { - /*Failed SIM request command*/ - dbg("error - Contradiction with CHV status [%x][%x]", - status_word1, status_word2); - } else if (status_word1 == 0x98 && status_word2 == 0x10) { - /*Failed SIM request command*/ - dbg("error - Contradiction with invalidation status [%x][%x]", - status_word1, status_word2); - } else if (status_word1 == 0x98 && status_word2 == 0x40) { - /*Failed SIM request command*/ - dbg("error -Unsuccessful CHV verification - no attempt left [%x][%x]", - status_word1, status_word2); - dbg("error - Unsuccessful Unblock CHV - no attempt left [%x][%x]", - status_word1, status_word2); - dbg("error - CHV blocked [%x][%x]", status_word1, status_word2); - } else if (status_word1 == 0x67 && status_word2 == 0x00) { - dbg("error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2); - } else if (status_word1 == 0x6B && status_word2 == 0x00) { - dbg("error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2); - } else if (status_word1 == 0x6D && status_word2 == 0x00) { - dbg("error -Unknown instruction given as command [%x][%x]", - status_word1, status_word2); - } else if (status_word1 == 0x6E && status_word2 == 0x00) { - dbg("error -Unknown instruction given as command [%x][%x]", - status_word1, status_word2); - } else if (status_word1 == 0x69 && status_word2 == 0x82) { - dbg("error -Access denied [%x][%x]", status_word1, status_word2); - } else if (status_word1 == 0x6A && status_word2 == 0x87) { - dbg("error -Incorrect parameters [%x][%x]", status_word1, status_word2); - } else if (status_word1 == 0x6A && status_word2 == 0x82) { - dbg("error -File Not found [%x][%x]", status_word1, status_word2); - } else if (status_word1 == 0x6A && status_word2 == 0x83) { - dbg("error -Record Not found [%x][%x]", status_word1, status_word2); - } else { - rst = TEL_SIM_RESULT_CARD_ERROR; - dbg("error -Unknown state [%x][%x]", status_word1, status_word2); - } - return rst; -} - -static void __atmodem_sim_update_sim_status(CoreObject *co_sim, - TelSimCardStatus sim_status) -{ - TelSimCardStatus curr_sim_status; - - /* - * Send SIM Init status, if not sent already - */ - (void)tcore_sim_get_status(co_sim, &curr_sim_status); - if (sim_status != curr_sim_status) { - TelSimCardStatusInfo sim_status_noti = {0, }; - - dbg("Change in SIM State - Old State: [0x%02x] --> New State: [0x%02x]", - curr_sim_status, sim_status); - - /* Update SIM Status */ - tcore_sim_set_status(co_sim, sim_status); - sim_status_noti.status = sim_status; - sim_status_noti.change_status = TEL_SIM_CHANGE_STATUS_SAME; /* TODO: checkout */ - - /* Send notification: SIM Status */ - tcore_object_send_notification(co_sim, - TCORE_NOTIFICATION_SIM_STATUS, - sizeof(sim_status_noti), &sim_status_noti); - } -} - -static gboolean __atmodem_convert_scpin_str_to_enum(char* line, - AtmodemSimSecLockType *lock_type, AtmodemSimSecLockKey *lock_key) -{ - char *type =NULL, *key = NULL; - GSList *tokens = NULL; - - if(line == NULL) - return FALSE; - - tokens = tcore_at_tok_new(line); - - type = g_slist_nth_data(tokens, 0); - if (!type) { - err("Type is missing"); - tcore_at_tok_free(tokens); - return FALSE; - } - - if (g_strcmp0(type, "NO_LOCK") == 0) { - key = g_slist_nth_data(tokens, 1); - if (!key) { - err("Key is missing"); - tcore_at_tok_free(tokens); - return FALSE; - } - - dbg("type: [%s], key: [%s]", type, key); - } - - if(g_str_has_prefix (type, "NO_SIM")) - *lock_type = SEC_LOCK_TYPE_NO_SIM; - else if(g_str_has_prefix (type, "UNAVAIL")) - *lock_type = SEC_LOCK_TYPE_UNAVAIL; - else if(g_str_has_prefix (type, "NO_LOCK")) - *lock_type = SEC_LOCK_TYPE_READY; - else if(g_str_has_prefix (type, "LOCK_PS")) - *lock_type = SEC_LOCK_TYPE_PS; - else if(g_str_has_prefix (type, "LOCK_PF")) - *lock_type = SEC_LOCK_TYPE_PF ; - else if(g_str_has_prefix (type, "LOCK_SC")) - *lock_type = SEC_LOCK_TYPE_SC; - else if(g_str_has_prefix (type, "LOCK_FD")) - *lock_type = SEC_LOCK_TYPE_FD; - else if(g_str_has_prefix (type, "LOCK_PN")) - *lock_type = SEC_LOCK_TYPE_PN ; - else if(g_str_has_prefix (type, "LOCK_PU")) - *lock_type = SEC_LOCK_TYPE_PU ; - else if(g_str_has_prefix (type, "LOCK_PP")) - *lock_type = SEC_LOCK_TYPE_PP; - else if(g_str_has_prefix (type, "LOCK_PC")) - *lock_type = SEC_LOCK_TYPE_PC; - else if(g_str_has_prefix (type, "LOCK_SC2")) - *lock_type = SEC_LOCK_TYPE_SC2 ; - else if(g_str_has_prefix (type, "LOCK_ACL")) - *lock_type = SEC_LOCK_TYPE_ACL; - else if(g_str_has_prefix (type, "LOCK_PUK2")) - *lock_type = SEC_LOCK_TYPE_PUK2; - else if(g_str_has_prefix (type, "INIT_COMP")) - *lock_type = SEC_SIM_INIT_COMPLETED; - else if(g_str_has_prefix (type, "INIT_ERROR")) - *lock_type = SEC_SIM_INIT_CRASH; - else - *lock_type = SEC_LOCK_TYPE_NONE; - - if(g_str_has_prefix (key, "PIN")) - *lock_key = SEC_LOCK_KEY_PIN; - else if(g_str_has_prefix (key, "PUK")) - *lock_key = SEC_LOCK_KEY_PUK; - else if(g_str_has_prefix (key, "PIN2")) - *lock_key = SEC_LOCK_KEY_PIN2; - else if(g_str_has_prefix (key, "PUK2")) - *lock_key = SEC_LOCK_KEY_PUK2; - else if(g_str_has_prefix (key, "BLOCKED")) - *lock_key = SEC_LOCK_KEY_PERM_BLOCKED ; - else if(g_str_has_prefix (key, "UNLOCKED")) - *lock_key = SEC_LOCK_KEY_UNLOCKED ; - else if(g_str_has_prefix (key, "PIN2_DISABLE")) - *lock_key = SEC_LOCK_KEY_PIN2_DISABLE; - else - *lock_key = SEC_LOCK_KEY_NONE; - - if(*lock_type == SEC_LOCK_TYPE_READY) - *lock_key = SEC_LOCK_KEY_UNLOCKED; - - if((*lock_type == SEC_LOCK_TYPE_NO_SIM)||(*lock_type == SEC_LOCK_TYPE_UNAVAIL)|| - (*lock_type == SEC_SIM_INIT_COMPLETED)||(*lock_type == SEC_SIM_INIT_CRASH)) - *lock_key = SEC_LOCK_KEY_NONE; - - dbg("type: [%d], key: [%d]", *lock_type, *lock_key); - - tcore_at_tok_free(tokens); - - return TRUE; -} - -static void __on_response_atmodem_sim_get_sim_type_internal(CoreObject *co_sim, - gint result, const void *response, void *user_data) -{ - dbg("SIM Response - SIM Type (internal): [\%SCCT]"); - - /* Get SIM type if SIM is initialized */ - if (result == TEL_SIM_RESULT_SUCCESS) { - TelSimCardType *sim_type = (TelSimCardType *)response; - - /* Update SIM type */ - tcore_sim_set_type(co_sim, *sim_type); - if (*sim_type != TEL_SIM_CARD_TYPE_UNKNOWN) { - /* Send SIM Type notification */ - tcore_object_send_notification(co_sim, - TCORE_NOTIFICATION_SIM_TYPE, - sizeof(TelSimCardType), sim_type); - } - } -} - -static void __on_response_atmodem_sim_get_sim_type(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co_sim = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - TelSimCardType sim_type = TEL_SIM_CARD_TYPE_UNKNOWN; - - TelSimResult result = TEL_SIM_RESULT_FAILURE; - - dbg("SIM Response - SIM Type: [\%SCCT]"); - - tcore_check_return_assert(co_sim != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp && at_resp->success) { - if (at_resp->lines) { - const gchar *line; - GSList *tokens; - - line = (const gchar *)at_resp->lines->data; - - /* - * Tokenize - * - * %SCCT: - */ - tokens = tcore_at_tok_new(line); - - /* */ - if (g_slist_length(tokens) == 1) { - sim_type = atoi(g_slist_nth_data(tokens, 0)); - dbg("SIM Type: [%d]", sim_type); - - result = TEL_SIM_RESULT_SUCCESS; - } - else { - err("Invalid message"); - } - - tcore_at_tok_free(tokens); - } - } - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)result, &sim_type, resp_cb_data->cb_data); - - /* Free callback data */ - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -/* - * Operation - get_sim_type - * - * Request - - * AT-Command: AT%SCCT? - * - * Response - sim_type (TelSimCardType) - * Success: (Single line) - - * +SCCT: - * OK - * Failure: - * +CME ERROR: - */ -static void __atmodem_sim_get_sim_type(CoreObject *co_sim, - TcoreObjectResponseCallback cb, void *cb_data) -{ - AtmodemRespCbData *resp_cb_data; - TelReturn ret; - - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - NULL, 0); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co_sim, - "AT\%SCCT?", "\%SCCT:", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - __on_response_atmodem_sim_get_sim_type, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SIM Type"); - - dbg("ret: [%d]", ret); -} - -static void __atmodem_sim_process_sim_status(CoreObject *co, - TelSimCardStatus sim_card_status) -{ - switch (sim_card_status) { - case TEL_SIM_STATUS_SIM_INIT_COMPLETED: { - TelReturn ret; - - dbg("SIM INIT COMPLETED"); - - ATMODEM_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_IMSI, ret); - ATMODEM_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_SPDI, ret); - dbg("ret: [%d]", ret); - - return; - } - - case TEL_SIM_STATUS_SIM_INITIALIZING: { - TelSimCardType sim_type; - - dbg("SIM INITIALIZING"); - - (void)tcore_sim_get_type(co, &sim_type); - if (sim_type == TEL_SIM_CARD_TYPE_UNKNOWN) { - /* - * SIM is initialized for first time, need to - * fetch SIM type - */ - __atmodem_sim_get_sim_type(co, - __on_response_atmodem_sim_get_sim_type_internal, NULL); - - return; - } - } - break; - - case TEL_SIM_STATUS_CARD_REMOVED: - dbg("SIM CARD REMOVED"); - tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN); - break; - - case TEL_SIM_STATUS_CARD_NOT_PRESENT: - dbg("SIM CARD NOT PRESENT"); - tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN); - break; - - case TEL_SIM_STATUS_CARD_ERROR: - dbg("SIM CARD ERROR"); - tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN); - break; - - default: - err("SIM Status: [0x%02x]", sim_card_status); - break; - } - - /* Update SIM Status */ - return __atmodem_sim_update_sim_status(co, sim_card_status); -} - -static void __atmodem_sim_next_from_get_file_data(CoreObject *co_sim, - AtmodemRespCbData *resp_cb_data, - TelSimResult sim_result, gboolean decode_ret) -{ - AtmodemSimMetaInfo *file_meta = - (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN; - - dbg("Entry"); - - dbg("[SIM]EF[0x%x] read sim_result[%d] Decode rt[%d]", - file_meta->file_id, sim_result, decode_ret); - switch (file_meta->file_id) { - case TEL_SIM_EF_ELP: - case TEL_SIM_EF_USIM_PL: - case TEL_SIM_EF_LP: - case TEL_SIM_EF_USIM_LI: - if (decode_ret == TRUE) { - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - tcore_sim_get_type(co_sim, &card_type); - /* 2G */ - /* - * The ME requests the Extended Language Preference. - * The ME only requests the Language Preference (EFLP) if at - * least one of the following conditions holds: - * - EFELP is not available; - * - EFELP does not contain an entry corresponding to a - * language specified in ISO 639[30]; - * - the ME does not support any of the languages in EFELP. - */ - /* 3G */ - /* - * The ME only requests the Language Preference (EFPL) - * if at least one of the following conditions holds: - * - if the EFLI has the value 'FFFF' in its highest - * priority position - * - if the ME does not support any of the language codes - * indicated in EFLI , or if EFLI is not present - */ - if (TEL_SIM_CARD_TYPE_GSM == card_type) { - if (file_meta->file_id == TEL_SIM_EF_LP) { - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - file_meta->file_id = TEL_SIM_EF_LP; - __atmodem_sim_get_file_info(co_sim, resp_cb_data); - } - } else if (TEL_SIM_CARD_TYPE_USIM) { - if (file_meta->file_id == TEL_SIM_EF_LP - || file_meta->file_id == TEL_SIM_EF_USIM_LI) { - file_meta->file_id = TEL_SIM_EF_ELP; - __atmodem_sim_get_file_info(co_sim, resp_cb_data); - } else { - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } - } - } - break; - - case TEL_SIM_EF_ECC: - tcore_sim_get_type(co_sim, &card_type); - if (TEL_SIM_CARD_TYPE_USIM == card_type) { - if (file_meta->current_index == file_meta->rec_count) { - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - file_meta->current_index++; - __atmodem_sim_get_file_record(co_sim, resp_cb_data); - } - } else if (TEL_SIM_CARD_TYPE_GSM == card_type) { - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - dbg("[SIM DATA] Invalid CardType: [%d]. Unable to handle", card_type); - } - break; - - case TEL_SIM_EF_IMSI: - if (resp_cb_data->cb) { - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->imsi, resp_cb_data->cb_data); - } else { - /* Update Status */ - __atmodem_sim_update_sim_status(co_sim, TEL_SIM_STATUS_SIM_INIT_COMPLETED); - } - break; - - case TEL_SIM_EF_MSISDN: - if (file_meta->current_index == file_meta->rec_count) { - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - file_meta->current_index++; - __atmodem_sim_get_file_record(co_sim, resp_cb_data); - } - break; - - case TEL_SIM_EF_OPL: - if (file_meta->current_index == file_meta->rec_count) { - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - file_meta->current_index++; - __atmodem_sim_get_file_record(co_sim, resp_cb_data); - } - break; - - case TEL_SIM_EF_PNN: - if (file_meta->current_index == file_meta->rec_count) { - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - file_meta->current_index++; - __atmodem_sim_get_file_record(co_sim, resp_cb_data); - } - break; - - case TEL_SIM_EF_USIM_CFIS: - case TEL_SIM_EF_USIM_MWIS: - case TEL_SIM_EF_USIM_MBI: - case TEL_SIM_EF_MBDN: - case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS: - case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS: - if (file_meta->current_index == file_meta->rec_count) { - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - file_meta->current_index++; - __atmodem_sim_get_file_record(co_sim, resp_cb_data); - } - break; - - case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING: - { - file_meta->files.result = sim_result; - if (decode_ret == TRUE && sim_result == TEL_SIM_RESULT_SUCCESS) { - memcpy(file_meta->files.data.cphs_net.full_name, file_meta->files.data.cphs_net.full_name, strlen((char *)file_meta->files.data.cphs_net.full_name)); - } - - file_meta->file_id = TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING; - file_meta->file_result = TEL_SIM_RESULT_FAILURE; - file_meta->req_command = TCORE_COMMAND_SIM_GET_CPHS_NET_NAME; - - __atmodem_sim_get_file_info(co_sim, resp_cb_data); - } - break; - - case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING: - if (file_meta->files.result == TEL_SIM_RESULT_SUCCESS) - file_meta->files.result = TEL_SIM_RESULT_SUCCESS; - - if (strlen((char *)file_meta->files.data.cphs_net.full_name)) - memcpy(&file_meta->files.data.cphs_net.full_name, - &file_meta->files.data.cphs_net.full_name, - strlen((char *)file_meta->files.data.cphs_net.full_name)); - - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - break; - - case TEL_SIM_EF_ICCID: - case TEL_SIM_EF_SST: - case TEL_SIM_EF_SPN: - case TEL_SIM_EF_SPDI: - case TEL_SIM_EF_OPLMN_ACT: - case TEL_SIM_EF_CPHS_CPHS_INFO: - case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS: - case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING: - case TEL_SIM_EF_CPHS_DYNAMICFLAGS: - case TEL_SIM_EF_CPHS_DYNAMIC2FLAG: - case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE: - case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2: - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - break; - - default: - err("File id not handled [0x%x]", file_meta->file_id); - break; - } -} - -static void __atmodem_sim_next_from_get_file_info(CoreObject *co_sim, - AtmodemRespCbData *resp_cb_data, TelSimResult sim_result) -{ - AtmodemSimMetaInfo *file_meta = - (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN; - - dbg("EF[0x%x] access Result[%d]", file_meta->file_id, sim_result); - - file_meta->files.result = sim_result; - memset(&file_meta->files.data, 0x00, sizeof(file_meta->files.data)); - - if ((file_meta->file_id != TEL_SIM_EF_ELP - && file_meta->file_id != TEL_SIM_EF_LP - && file_meta->file_id != TEL_SIM_EF_USIM_PL - && file_meta->file_id != TEL_SIM_EF_CPHS_CPHS_INFO) - && (sim_result != TEL_SIM_RESULT_SUCCESS)) { - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - - return; - } - - switch (file_meta->file_id) { - case TEL_SIM_EF_ELP: - if (sim_result == TEL_SIM_RESULT_SUCCESS) { - dbg("[SIM DATA] exist EFELP/PL(0x2F05)"); - __atmodem_sim_get_file_data(co_sim, resp_cb_data); - } else { - tcore_sim_get_type(co_sim, &card_type); - if (TEL_SIM_CARD_TYPE_GSM == card_type) { - AtmodemSimMetaInfo file_meta_new = {0,}; - - dbg("[SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info"); - /* The ME requests the Language Preference (EFLP) if EFELP is not available */ - file_meta_new.file_id = TEL_SIM_EF_LP; - file_meta_new.file_result = TEL_SIM_RESULT_FAILURE; - file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE; - - memcpy(resp_cb_data->data, &file_meta_new, sizeof(AtmodemSimMetaInfo)); - - __atmodem_sim_get_file_info(co_sim, resp_cb_data); - } else if (TEL_SIM_CARD_TYPE_USIM == card_type) { - dbg(" [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05))"); - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - - return; - } - } - break; - - case TEL_SIM_EF_LP: - if (sim_result == TEL_SIM_RESULT_SUCCESS) { - dbg("[SIM DATA] exist EFLP/LI(0x6F05)"); - __atmodem_sim_get_file_data(co_sim, resp_cb_data); - } else { - tcore_sim_get_type(co_sim, &card_type); - dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]", card_type); - if (TEL_SIM_CARD_TYPE_GSM == card_type) { - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - return; - } - - /* - * If EFLI is not present, then the language selection - * shall be as defined in EFPL at the MF level - */ - else if (TEL_SIM_CARD_TYPE_USIM == card_type) { - AtmodemSimMetaInfo file_meta_new = {0,}; - - dbg("[SIM DATA] try USIM EFPL(0x2F05)"); - file_meta_new.file_id = TEL_SIM_EF_ELP; - file_meta_new.file_result = TEL_SIM_RESULT_FAILURE; - file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE; - - memcpy(resp_cb_data->data, &file_meta_new, sizeof(AtmodemSimMetaInfo)); - - __atmodem_sim_get_file_info(co_sim, resp_cb_data); - } - } - break; - - case TEL_SIM_EF_USIM_PL: - if (sim_result == TEL_SIM_RESULT_SUCCESS) { - dbg("[SIM DATA] exist EFELP/PL(0x2F05)"); - __atmodem_sim_get_file_data(co_sim, resp_cb_data); - } else { - /* - * EFELIand EFPL not present, so set language - * count as zero and select ECC - */ - dbg("[SIM DATA] SIM_EF_USIM_PL(2A05) access fail. "\ - "Request SIM_EF_ECC(0x6FB7) info"); - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - - return; - } - break; - - case TEL_SIM_EF_ECC: - tcore_sim_get_type(co_sim, &card_type); - if (TEL_SIM_CARD_TYPE_GSM == card_type) { - __atmodem_sim_get_file_data(co_sim, resp_cb_data); - } else if (TEL_SIM_CARD_TYPE_USIM == card_type) { - if (file_meta->rec_count > TEL_SIM_ECC_LIST_MAX) - file_meta->rec_count = TEL_SIM_ECC_LIST_MAX; - - file_meta->current_index++; - __atmodem_sim_get_file_record(co_sim, resp_cb_data); - } - break; - - case TEL_SIM_EF_ICCID: - case TEL_SIM_EF_IMSI: - case TEL_SIM_EF_SST: - case TEL_SIM_EF_SPN: - case TEL_SIM_EF_SPDI: - case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS: - case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING: - case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING: - case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING: - case TEL_SIM_EF_CPHS_DYNAMICFLAGS: - case TEL_SIM_EF_CPHS_DYNAMIC2FLAG: - case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE: - case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2: - __atmodem_sim_get_file_data(co_sim, resp_cb_data); - break; - - case TEL_SIM_EF_CPHS_CPHS_INFO: - if (sim_result == TEL_SIM_RESULT_SUCCESS) { - tcore_sim_set_cphs_status(co_sim, TRUE); - __atmodem_sim_update_sim_status(co_sim, TEL_SIM_STATUS_SIM_INIT_COMPLETED); - - __atmodem_sim_get_file_data(co_sim, resp_cb_data); - } else { - tcore_sim_set_cphs_status(co_sim, FALSE); - __atmodem_sim_update_sim_status(co_sim, TEL_SIM_STATUS_SIM_INIT_COMPLETED); - - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } - break; - - - case TEL_SIM_EF_USIM_CFIS: - if (file_meta->rec_count > TEL_SIM_CALL_FORWARDING_TYPE_MAX) - file_meta->rec_count = TEL_SIM_CALL_FORWARDING_TYPE_MAX; - - file_meta->current_index++; - - __atmodem_sim_get_file_record(co_sim, resp_cb_data); - break; - - case TEL_SIM_EF_OPL: - case TEL_SIM_EF_PNN: - case TEL_SIM_EF_USIM_MWIS: - case TEL_SIM_EF_USIM_MBI: - case TEL_SIM_EF_MBDN: - case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS: - case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS: - case TEL_SIM_EF_MSISDN: - file_meta->current_index++; - - __atmodem_sim_get_file_record(co_sim, resp_cb_data); - break; - - default: - err("Unknown File ID for get File info: [0x%x]", file_meta->file_id); - break; - } -} - -static void __on_response_atmodem_sim_get_file_data(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *resp = data; - CoreObject *co_sim = NULL; - GSList *tokens = NULL; - TelSimResult sim_result; - gboolean dr = FALSE; - const char *line = NULL; - char *res = NULL; - char *tmp = NULL; - int res_len; - int sw1 = 0; - int sw2 = 0; - TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN; - AtmodemRespCbData *resp_cb_data = (AtmodemRespCbData *) user_data; - AtmodemSimMetaInfo *file_meta = - (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - dbg("Entry"); - - co_sim = tcore_pending_ref_core_object(p); - - if (resp->success > 0) { - dbg("RESPONSE OK"); - if (resp->lines) { - line = (const char *)resp->lines->data; - tokens = tcore_at_tok_new(line); - if (g_slist_length(tokens) < 2) { - msg("Invalid message"); - tcore_at_tok_free(tokens); - return; - } - } - sw1 = atoi(g_slist_nth_data(tokens, 0)); - sw2 = atoi(g_slist_nth_data(tokens, 1)); - res = g_slist_nth_data(tokens, 2); - - tmp = tcore_at_tok_extract(res); - tcore_util_hexstring_to_bytes(tmp, &res, (guint *)&res_len); - - dbg("Response: [%s] Response length: [%d]", res, res_len); - - if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) { - sim_result = TEL_SIM_RESULT_SUCCESS; - file_meta->files.result = sim_result; - - dbg("File ID: [0x%x]", file_meta->file_id); - switch (file_meta->file_id) { - case TEL_SIM_EF_IMSI: { - dbg("Data: [%s]", res); - dr = tcore_sim_decode_imsi((unsigned char *)res, res_len, &file_meta->imsi); - if (dr == FALSE) { - err("IMSI decoding failed"); - } else { - /* Update IMSI */ - tcore_sim_set_imsi(co_sim, &file_meta->imsi); - } - } - break; - - case TEL_SIM_EF_ICCID: - dr = tcore_sim_decode_iccid((unsigned char *)res, res_len, - file_meta->files.data.iccid); - break; - - case TEL_SIM_EF_ELP: /* 2G EF - 2 bytes decoding */ - case TEL_SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding */ - case TEL_SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding */ - case TEL_SIM_EF_LP: /* 1 byte encoding */ - { - tcore_sim_get_type(co_sim, &card_type); - if ((TEL_SIM_CARD_TYPE_GSM == card_type) - && (file_meta->file_id == TEL_SIM_EF_LP)) { - /* - * 2G LP(0x6F05) has 1 byte for each language - */ - dr = tcore_sim_decode_lp((unsigned char *)res, res_len, - &file_meta->files.data.language); - } else { - /* - * 3G LI(0x6F05)/PL(0x2F05), - * 2G ELP(0x2F05) has 2 bytes for each language - */ - dr = tcore_sim_decode_li((unsigned char *)res, res_len, - file_meta->file_id, &file_meta->files.data.language); - } - } - break; - - case TEL_SIM_EF_SPN: - dr = tcore_sim_decode_spn((unsigned char *)res, res_len, - &file_meta->files.data.spn); - break; - - case TEL_SIM_EF_SPDI: - dr = tcore_sim_decode_spdi((unsigned char *)res, res_len, - &file_meta->files.data.spdi); - break; - - case TEL_SIM_EF_SST: { - TelSimServiceTable *svct = NULL; - - svct = g_try_new0(TelSimServiceTable, 1); - tcore_sim_get_type(co_sim, &card_type); - svct->sim_type = card_type; - if (TEL_SIM_CARD_TYPE_GSM == card_type) { - dr = tcore_sim_decode_sst((unsigned char *)res, res_len, - svct->table.sst_service); - } else if (TEL_SIM_CARD_TYPE_USIM == card_type) { - dr = tcore_sim_decode_ust((unsigned char *)res, res_len, - svct->table.ust_service); - } else { - err("Not handled card_type[%d]", card_type); - } - - if (dr == FALSE) { - err("SST/UST decoding failed"); - } else { - tcore_sim_set_service_table(co_sim, svct); - } - - /* Free memory */ - g_free(svct); - } - break; - - case TEL_SIM_EF_ECC: { - tcore_sim_get_type(co_sim, &card_type); - if (TEL_SIM_CARD_TYPE_GSM == card_type) { - dr = tcore_sim_decode_ecc((unsigned char *)res, res_len, - &file_meta->files.data.ecc); - } else if (TEL_SIM_CARD_TYPE_USIM == card_type) { - TelSimEcc *ecc = NULL; - - ecc = g_try_new0(TelSimEcc, 1); - dbg("Index [%d]", file_meta->current_index); - - dr = tcore_sim_decode_uecc((unsigned char *)res, res_len, ecc); - if (dr == TRUE) { - memcpy(&file_meta->files.data.ecc.list[file_meta->files.data.ecc.count], - ecc, sizeof(TelSimEcc)); - file_meta->files.data.ecc.count++; - } - - /* Free memory */ - g_free(ecc); - } else { - dbg("Unknown/Unsupported SIM card Type: [%d]", card_type); - } - } - break; - - case TEL_SIM_EF_MSISDN: { - TelSimSubscriberInfo *msisdn = NULL; - - dbg("Index [%d]", file_meta->current_index); - msisdn = g_try_new0(TelSimSubscriberInfo, 1); - dr = tcore_sim_decode_msisdn((unsigned char *)res, res_len, msisdn); - if (dr == TRUE) { - memcpy(&file_meta->files.data.msisdn_list.list[file_meta->files.data.msisdn_list.count], - msisdn, sizeof(TelSimSubscriberInfo)); - - file_meta->files.data.msisdn_list.count++; - } - - /* Free memory */ - g_free(msisdn); - } - break; - - case TEL_SIM_EF_OPL: { - TelSimOpl *opl = NULL; - - dbg("decode w/ index [%d]", file_meta->current_index); - opl = g_try_new0(TelSimOpl, 1); - - dr = tcore_sim_decode_opl((unsigned char *)res, res_len, opl); - if (dr == TRUE) { - memcpy(&file_meta->files.data.opl.list[file_meta->files.data.opl.opl_count], - opl, sizeof(TelSimOpl)); - - file_meta->files.data.opl.opl_count++; - } - - /* Free memory */ - g_free(opl); - } - break; - - case TEL_SIM_EF_PNN: { - TelSimPnn *pnn = NULL; - - dbg("decode w/ index [%d]", file_meta->current_index); - pnn = g_try_new0(TelSimPnn, 1); - - dr = tcore_sim_decode_pnn((unsigned char *)res, res_len, pnn); - if (dr == TRUE) { - memcpy(&file_meta->files.data.pnn.list[file_meta->files.data.pnn.pnn_count], - pnn, sizeof(TelSimPnn)); - - file_meta->files.data.pnn.pnn_count++; - } - - /* Free memory */ - g_free(pnn); - } - break; - - case TEL_SIM_EF_OPLMN_ACT: - /*dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa, - (unsigned char *)res, res_len);*/ - break; - - case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE: - /*dr = tcore_sim_decode_csp(&po->p_cphs->csp, - p_data->response, p_data->response_len);*/ - break; - - case TEL_SIM_EF_USIM_MBI: { /* linear type */ - TelSimMbi *mbi = NULL; - - mbi = g_try_new0(TelSimMbi, 1); - dr = tcore_sim_decode_mbi((unsigned char *)res, res_len, mbi); - if (dr == TRUE) { - memcpy(&file_meta->mbi_list.list[file_meta->mbi_list.count], - mbi, sizeof(TelSimMbi)); - file_meta->mbi_list.count++; - - dbg("mbi count[%d]", file_meta->mbi_list.count); - } - - /* Free memory */ - g_free(mbi); - } - break; - - case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS: /* linear type */ - case TEL_SIM_EF_MBDN: /* linear type */ -#if 0 /* Temporarily blocked, MBDN is NOT suported in Emulator */ - dr = tcore_sim_decode_xdn((unsigned char *)res, res_len, - file_meta->mb_list[file_meta->current_index-1].alpha_id, - file_meta->mb_list[file_meta->current_index-1].number); - - file_meta->mb_list[file_meta->current_index-1].alpha_id_len = - strlen(file_meta->mb_list[file_meta->current_index-1].alpha_id); - - file_meta->mb_list[file_meta->current_index-1].profile_id = - file_meta->current_index; -#endif /* Temporarily blocked, MBDN is NOT suported in Emulator */ - break; - - case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING: /* transparent type */ - dr = tcore_sim_decode_vmwf((unsigned char *)res, res_len, - file_meta->files.data.mw.mw); - break; - - case TEL_SIM_EF_USIM_MWIS: { /* linear type */ - TelSimMwis *mw = NULL; - - mw = g_try_new0(TelSimMwis, 1); - - dr = tcore_sim_decode_mwis((unsigned char *)res, res_len, mw); - if (dr == TRUE) { - memcpy(&file_meta->files.data.mw.mw[file_meta->files.data.mw.profile_count], - mw, sizeof(TelSimMwis)); - - file_meta->files.data.mw.profile_count++; - } - - /* Free memory */ - g_free(mw); - } - break; - - case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS: /* transparent type */ - dr = tcore_sim_decode_cff((unsigned char *)res, res_len, - file_meta->files.data.mw.mw); - break; - - case TEL_SIM_EF_USIM_CFIS: /* linear type */ - { - TelSimCfis *cf = NULL; - - cf = g_try_new0(TelSimCfis, 1); - dr = tcore_sim_decode_cfis((unsigned char *)res, res_len, cf); - if (dr == TRUE) { - memcpy(&file_meta->files.data.cf.cf[file_meta->files.data.cf.profile_count], - cf, sizeof(TelSimCfis)); - - file_meta->files.data.cf.profile_count++; - } - - /* Free memory */ - g_free(cf); - } - break; - - case TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE: - dbg("not handled - TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE "); - break; - - case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING: - dr = tcore_sim_decode_ons((unsigned char *)res, res_len, - (unsigned char*)&file_meta->files.data.cphs_net.full_name); - dbg("file_meta->files.result: [%d] " \ - "file_meta->files.data.cphs_net.full_name[%s]", - file_meta->files.result, - file_meta->files.data.cphs_net.full_name); - break; - - case TEL_SIM_EF_CPHS_DYNAMICFLAGS: - /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo, - p_data->response, p_data->response_len);*/ - break; - - case TEL_SIM_EF_CPHS_DYNAMIC2FLAG: - /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, - p_data->response, p_data->response_len);*/ - break; - - case TEL_SIM_EF_CPHS_CPHS_INFO: - /*dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs, - (unsigned char *)res, res_len);*/ - break; - - case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING: - dr = tcore_sim_decode_short_ons((unsigned char *)res, res_len, - (unsigned char*)&file_meta->files.data.cphs_net.short_name); - - dbg("file_meta->files.result[%d] "\ - "file_meta->files.data.cphs_net.short_name[%s]", - file_meta->files.result, - file_meta->files.data.cphs_net.short_name); - break; - - case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS: - /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn, - p_data->response, p_data->response_len);*/ - break; - - default: - dbg("File Decoding Failed - not handled File[0x%x]", - file_meta->file_id); - dr = 0; - break; - } - } else { - sim_result = __atmodem_sim_decode_status_word(sw1, sw2); - file_meta->files.result = sim_result; - } - - /* Free memory */ - g_free(tmp); - g_free(res); - - /* Free tokens */ - tcore_at_tok_free(tokens); - } else { - dbg("RESPONSE NOK"); - dbg("Error - File ID: [0x%x]", file_meta->file_id); - sim_result = TEL_SIM_RESULT_FAILURE; - } - - /* Get File data */ - __atmodem_sim_next_from_get_file_data(tcore_pending_ref_core_object(p), - resp_cb_data, sim_result, dr); - - dbg("Exit"); -} - -static void __on_response_atmodem_sim_get_file_info(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *resp = data; - CoreObject *co_sim = NULL; - TelSimResult sim_result; - GSList *tokens = NULL; - const char *line = NULL; - int sw1 = 0; - int sw2 = 0; - AtmodemRespCbData *resp_cb_data = (AtmodemRespCbData *)user_data; - AtmodemSimMetaInfo *file_meta = - (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - dbg("SIM Response - SIM File info: [+CRSM]"); - - co_sim = tcore_pending_ref_core_object(p); - - if (resp->success > 0) { - dbg("RESPONSE OK"); - if (resp->lines) { - line = (const char *)resp->lines->data; - tokens = tcore_at_tok_new(line); - if (g_slist_length(tokens) < 2) { - err("Invalid message"); - tcore_at_tok_free(tokens); - return; - } - } - sw1 = atoi(g_slist_nth_data(tokens, 0)); - sw2 = atoi(g_slist_nth_data(tokens, 1)); - - /*1. SIM access success case*/ - if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) { - unsigned char tag_len = 0; - unsigned short record_len = 0; - char num_of_records = 0; - unsigned char file_id_len = 0; - unsigned short file_id = 0; - unsigned short file_size = 0; - unsigned short file_type = 0; - unsigned short arr_file_id = 0; - int arr_file_id_rec_num = 0; - guint buf_len = 0; - TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN; - - /* handling only last 3 bits */ - unsigned char file_type_tag = 0x07; - unsigned char *ptr_data; - - char *hexData; - char *tmp; - char *record_data = NULL; - hexData = g_slist_nth_data(tokens, 2); - dbg("hexData: %s", hexData); - dbg("hexData: %s", hexData + 1); - - tmp = tcore_at_tok_extract(hexData); - tcore_util_hexstring_to_bytes(tmp, &record_data, &buf_len); /*TODO : Check*/ - tcore_util_hex_dump(" ", buf_len, record_data); - g_free(tmp); - - ptr_data = (unsigned char *)record_data; - tcore_sim_get_type(co_sim, &card_type); - if (TEL_SIM_CARD_TYPE_USIM == card_type) { - /* - ETSI TS 102 221 v7.9.0 - - Response Data - '62' FCP template tag - - Response for an EF - '82' M File Descriptor - '83' M File Identifier - 'A5' O Proprietary information - '8A' M Life Cycle Status Integer - '8B', '8C' or 'AB' C1 Security attributes - '80' M File size - '81' O Total file size - '88' O Short File Identifier (SFI) - */ - - /* rsim.res_len has complete data length received */ - - /* FCP template tag - File Control Parameters tag*/ - if (*ptr_data == 0x62) { - /* parse complete FCP tag*/ - /* increment to next byte */ - ptr_data++; - tag_len = *ptr_data++; - dbg("tag_len: %02x", tag_len); - /* FCP file descriptor - file type, accessibility, DF, ADF etc*/ - if (*ptr_data == 0x82) { - /* increment to next byte */ - ptr_data++; - /* 2 or 5 value*/ - ptr_data++; - /* consider only last 3 bits*/ - dbg("file_type_tag: %02x", file_type_tag); - file_type_tag = file_type_tag & (*ptr_data); - dbg("file_type_tag: %02x", file_type_tag); - - switch (file_type_tag) { - /* increment to next byte */ - // ptr_data++; - case 0x1: - dbg("Getting FileType: [Transparent file type]"); - file_type = ATMODEM_SIM_FILE_TYPE_TRANSPARENT; - - /* increment to next byte */ - ptr_data++; - /* increment to next byte */ - ptr_data++; - break; - - case 0x2: - dbg("Getting FileType: [Linear fixed file type]"); - /* increment to next byte */ - ptr_data++; - /* data coding byte - value 21 */ - ptr_data++; - /* 2bytes */ - memcpy(&record_len, ptr_data, 2); - /* swap bytes */ - ATMODEM_SWAP_BYTES_16(record_len); - ptr_data = ptr_data + 2; - num_of_records = *ptr_data++; - /* Data lossy conversation from enum (int) to unsigned char */ - file_type = ATMODEM_SIM_FILE_TYPE_LINEAR_FIXED; - break; - - case 0x6: - dbg("Cyclic fixed file type"); - /* increment to next byte */ - ptr_data++; - /* data coding byte - value 21 */ - ptr_data++; - /* 2bytes */ - memcpy(&record_len, ptr_data, 2); - /* swap bytes */ - ATMODEM_SWAP_BYTES_16(record_len); - ptr_data = ptr_data + 2; - num_of_records = *ptr_data++; - file_type = ATMODEM_SIM_FILE_TYPE_CYCLIC; - break; - - default: - dbg("not handled file type [0x%x]", *ptr_data); - break; - } - } else { - dbg("INVALID FCP received - DEbug!"); - tcore_at_tok_free(tokens); - g_free(record_data); - return; - } - - /*File identifier - 0x84,0x85,0x86 etc are currently ignored and not handled */ - if (*ptr_data == 0x83) { - /* increment to next byte */ - ptr_data++; - file_id_len = *ptr_data++; - dbg("file_id_len: %02x", file_id_len); - - memcpy(&file_id, ptr_data, file_id_len); - dbg("file_id: %x", file_id); - - /* swap bytes */ - ATMODEM_SWAP_BYTES_16(file_id); - dbg("file_id: %x", file_id); - - ptr_data = ptr_data + 2; - dbg("Getting FileID=[0x%x]", file_id); - } else { - dbg("INVALID FCP received - DEbug!"); - tcore_at_tok_free(tokens); - g_free(record_data); - return; - } - - /* proprietary information */ - if (*ptr_data == 0xA5) { - unsigned short prop_len; - /* increment to next byte */ - ptr_data++; - - /* length */ - prop_len = *ptr_data; - dbg("prop_len: %02x", prop_len); - - /* skip data */ - ptr_data = ptr_data + prop_len + 1; - } else { - dbg("INVALID FCP received - DEbug!"); - } - - /* life cycle status integer [8A][length:0x01][status]*/ - /* - status info b8~b1 - 00000000 : No information given - 00000001 : creation state - 00000011 : initialization state - 000001-1 : operation state -activated - 000001-0 : operation state -deactivated - 000011-- : Termination state - b8~b5 !=0, b4~b1=X : Proprietary - Any other value : RFU - */ - if (*ptr_data == 0x8A) { - /* increment to next byte */ - ptr_data++; - /* length - value 1 */ - ptr_data++; - - switch (*ptr_data) { - case 0x04: - case 0x06: - dbg(" operation state -deactivated"); - ptr_data++; - break; - - case 0x05: - case 0x07: - dbg(" operation state -activated"); - ptr_data++; - break; - - default: - dbg(" DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data); - ptr_data++; - break; - } - } - - /* related to security attributes : currently not handled*/ - if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) { - /* increment to next byte */ - ptr_data++; - /* if tag length is 3 */ - if (*ptr_data == 0x03) { - /* increment to next byte */ - ptr_data++; - /* EFARR file id */ - memcpy(&arr_file_id, ptr_data, 2); - /* swap byes */ - ATMODEM_SWAP_BYTES_16(arr_file_id); - ptr_data = ptr_data + 2; - arr_file_id_rec_num = *ptr_data++; - dbg("arr_file_id_rec_num:[%d]", arr_file_id_rec_num); - } else { - /* if tag length is not 3 */ - /* ignoring bytes */ - // ptr_data = ptr_data + 4; - dbg("Useless security attributes, so jump to next tag"); - ptr_data = ptr_data + (*ptr_data + 1); - } - } else { - dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data); - tcore_at_tok_free(tokens); - g_free(record_data); - return; - } - - dbg("Current ptr_data value is [%x]", *ptr_data); - - /* file size excluding structural info*/ - if (*ptr_data == 0x80) { - /* for EF file size is body of file and for Linear or cyclic it is - * number of recXsizeof(one record) - */ - /* increment to next byte */ - ptr_data++; - /* length is 1 byte - value is 2 bytes or more */ - ptr_data++; - memcpy(&file_size, ptr_data, 2); - /* swap bytes */ - ATMODEM_SWAP_BYTES_16(file_size); - ptr_data = ptr_data + 2; - } else { - dbg("INVALID FCP received - DEbug!"); - tcore_at_tok_free(tokens); - g_free(record_data); - return; - } - - /* total file size including structural info*/ - if (*ptr_data == 0x81) { - int len; - /* increment to next byte */ - ptr_data++; - /* length */ - len = *ptr_data; - dbg("len:[%d]", len); - /* ignored bytes */ - ptr_data = ptr_data + 3; - } else { - dbg("INVALID FCP received - DEbug!"); - /* 0x81 is optional tag?? check out! so do not return -1 from here! */ - } - /*short file identifier ignored*/ - if (*ptr_data == 0x88) { - dbg("0x88: Do Nothing"); - /*DO NOTHING*/ - } - } else { - dbg("INVALID FCP received - DEbug!"); - tcore_at_tok_free(tokens); - g_free(record_data); - return; - } - } else if (TEL_SIM_CARD_TYPE_GSM == card_type) { - unsigned char gsm_specific_file_data_len = 0; - /* ignore RFU byte1 and byte2 */ - ptr_data++; - ptr_data++; - /* file size */ - // file_size = p_info->response_len; - memcpy(&file_size, ptr_data, 2); - /* swap bytes */ - ATMODEM_SWAP_BYTES_16(file_size); - /* parsed file size */ - ptr_data = ptr_data + 2; - /* file id */ - memcpy(&file_id, ptr_data, 2); - ATMODEM_SWAP_BYTES_16(file_id); - dbg("FILE id --> [%x]", file_id); - ptr_data = ptr_data + 2; - /* save file type - transparent, linear fixed or cyclic */ - file_type_tag = (*(ptr_data + 7)); - - switch (*ptr_data) { - case 0x0: - /* RFU file type */ - dbg("RFU file type- not handled - Debug!"); - break; - - case 0x1: - /* MF file type */ - dbg("MF file type - not handled - Debug!"); - break; - - case 0x2: - /* DF file type */ - dbg("DF file type - not handled - Debug!"); - break; - - case 0x4: - /* EF file type */ - dbg("EF file type [%d] ", file_type_tag); - /* increment to next byte */ - ptr_data++; - - if (file_type_tag == 0x00 || file_type_tag == 0x01) { - /* increament to next byte as this byte is RFU */ - ptr_data++; - file_type = - (file_type_tag == 0x00) ? ATMODEM_SIM_FILE_TYPE_TRANSPARENT : ATMODEM_SIM_FILE_TYPE_LINEAR_FIXED; - } else { - /* increment to next byte */ - ptr_data++; - /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */ - /* the INCREASE command is allowed on the selected cyclic file. */ - file_type = ATMODEM_SIM_FILE_TYPE_CYCLIC; - } - /* bytes 9 to 11 give SIM file access conditions */ - ptr_data++; - /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */ - ptr_data++; - /* byte 11 is invalidate and rehabilate nibbles */ - ptr_data++; - /* byte 12 - file status */ - ptr_data++; - /* byte 13 - GSM specific data */ - gsm_specific_file_data_len = *ptr_data; - dbg("gsm_specific_file_data_len:[%d]", gsm_specific_file_data_len); - ptr_data++; - /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */ - ptr_data++; - /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */ - record_len = *ptr_data; - dbg("record length[%d], file size[%d]", record_len, file_size); - if (record_len != 0) - num_of_records = (file_size / record_len); - - dbg("Number of records [%d]", num_of_records); - break; - - default: - dbg("not handled file type"); - break; - } - } else { - err("Unknown Card Type - [%d]", card_type); - } - - dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]", - file_meta->file_id, file_id, file_size, file_type, num_of_records, record_len); - - file_meta->file_type = file_type; - file_meta->data_size = file_size; - file_meta->rec_length = record_len; - file_meta->rec_count = num_of_records; - file_meta->current_index = 0; /* reset for new record type EF */ - sim_result = TEL_SIM_RESULT_SUCCESS; - g_free(record_data); - } else { - /*2. SIM access fail case*/ - err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id); - sim_result = __atmodem_sim_decode_status_word(sw1, sw2); - } - - tcore_at_tok_free(tokens); - } else { - err("RESPONSE NOK"); - err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id); - sim_result = TEL_SIM_RESULT_FAILURE; - } - dbg("Calling __atmodem_sim_next_from_get_file_info"); - __atmodem_sim_next_from_get_file_info(co_sim, resp_cb_data, sim_result); - dbg("Exit"); -} - -static void __atmodem_sim_get_file_record(CoreObject *co_sim, AtmodemRespCbData *resp_cb_data) -{ - gchar *at_cmd = NULL; - int p1 = 0; - int p2 = 0; - int p3 = 0; - AtmodemSimMetaInfo *file_meta = - (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - TelReturn ret = TEL_RETURN_FAILURE; - - dbg("Entry File-id:[0x%02x]", file_meta->file_id); - - /* According to TS 102 221, values of p1, p2, p3 can be as below: - * 11.1.5 READ RECORD - * P1: Record number - * P2: Mode, see table 11.11 - * Lc: Not present - * Data: Not present - * Le: Number of bytes to be read (P3) - */ - - p1 = (unsigned char) file_meta->current_index; - p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */ - p3 = (unsigned char) file_meta->rec_length; - - at_cmd = g_strdup_printf("AT+CRSM=%d, %d", - ATMODEM_SIM_ACCESS_READ_RECORD, file_meta->file_id); - - ret = tcore_at_prepare_and_send_request(co_sim, - at_cmd, "+CRSM:", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - __on_response_atmodem_sim_get_file_data, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Record"); - - dbg("ret:[%d]", ret); - g_free(at_cmd); - - dbg("Exit"); -} - -static void __atmodem_sim_get_file_data(CoreObject *co_sim, - AtmodemRespCbData *resp_cb_data) -{ - gchar *at_cmd = NULL; - int p1 = 0; - int p2 = 0; - int p3 = 0; - int offset = 0; - AtmodemSimMetaInfo *file_meta = - (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - TelReturn ret = TEL_RETURN_FAILURE; - - dbg("Entry File-id:[0x%02x]", file_meta->file_id); - - /* - * According to TS 102 221, values of P1, P2, P3 can be as below: - * 11.1.3 READ BINARY - * P1: See table 11.10 - * P2: Offset low - * Lc: Not present - * Data: Not present - * Le: Number of bytes to be read (P3) - */ - - p1 = (unsigned char) (offset & 0xFF00) >> 8; - p2 = (unsigned char) offset & 0x00FF; /* offset low */ - p3 = (unsigned char) file_meta->data_size; - - if (file_meta->file_id == TEL_SIM_EF_IMSI - || file_meta->file_id == TEL_SIM_EF_SPN - || file_meta->file_id == TEL_SIM_EF_LP) - at_cmd = g_strdup_printf("AT+CRSM=%d, %d ", - ATMODEM_SIM_ACCESS_READ_BINARY, file_meta->file_id); - else - at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d", - ATMODEM_SIM_ACCESS_READ_BINARY, file_meta->file_id, p1, p2, p3); - - ret = tcore_at_prepare_and_send_request(co_sim, - at_cmd, "+CRSM:", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - __on_response_atmodem_sim_get_file_data, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Data"); - - dbg("ret:[%d]", ret); - g_free(at_cmd); - - dbg("Exit"); -} - -static TelReturn __atmodem_sim_get_file_info(CoreObject *co_sim, - AtmodemRespCbData *resp_cb_data) -{ - gchar *at_cmd = NULL; - AtmodemSimMetaInfo *file_meta = - (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - TelReturn ret = TEL_RETURN_FAILURE; - - dbg("Entry File-id:[0x%02x]", file_meta->file_id); - - at_cmd = g_strdup_printf("AT+CRSM=%d, %d", - ATMODEM_SIM_ACCESS_GET_RESPONSE, file_meta->file_id); - - ret = tcore_at_prepare_and_send_request(co_sim, - at_cmd, "+CRSM:", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - __on_response_atmodem_sim_get_file_info, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Info"); - - g_free(at_cmd); - dbg("Exit"); - return ret; -} - -static char *__atmodem_sim_get_fac_from_lock_type(TelSimLockType lock_type, - AtmodemSimCurrSecOp *sec_op, int flag) -{ - char *fac = NULL; - switch(lock_type) { - case TEL_SIM_LOCK_PS: - fac = "PS"; - if (flag == ENABLE_FLAG) - *sec_op = ATMODEM_SIM_CURR_SEC_OP_SIM_ENABLE; - else if (flag == DISABLE_FLAG) - *sec_op = ATMODEM_SIM_CURR_SEC_OP_SIM_DISABLE; - else - *sec_op = ATMODEM_SIM_CURR_SEC_OP_SIM_STATUS; - break; - - case TEL_SIM_LOCK_SC: - fac = "SC"; - if (flag == ENABLE_FLAG) - *sec_op = ATMODEM_SIM_CURR_SEC_OP_PIN1_ENABLE; - else if (flag == DISABLE_FLAG) - *sec_op = ATMODEM_SIM_CURR_SEC_OP_PIN1_DISABLE; - else - *sec_op = ATMODEM_SIM_CURR_SEC_OP_PIN1_STATUS; - break; - - case TEL_SIM_LOCK_FD: - fac = "FD"; - if (flag == ENABLE_FLAG) - *sec_op = ATMODEM_SIM_CURR_SEC_OP_FDN_ENABLE; - else if (flag == DISABLE_FLAG) - *sec_op = ATMODEM_SIM_CURR_SEC_OP_FDN_DISABLE; - else - *sec_op = ATMODEM_SIM_CURR_SEC_OP_FDN_STATUS; - break; - - case TEL_SIM_LOCK_PN: - fac = "PN"; - if (flag == ENABLE_FLAG) - *sec_op = ATMODEM_SIM_CURR_SEC_OP_NET_ENABLE; - else if (flag == DISABLE_FLAG) - *sec_op = ATMODEM_SIM_CURR_SEC_OP_NET_DISABLE; - else - *sec_op = ATMODEM_SIM_CURR_SEC_OP_NET_STATUS; - break; - - case TEL_SIM_LOCK_PU: - fac = "PU"; - if (flag == ENABLE_FLAG) - *sec_op = ATMODEM_SIM_CURR_SEC_OP_NS_ENABLE; - else if (flag == DISABLE_FLAG) - *sec_op = ATMODEM_SIM_CURR_SEC_OP_NS_DISABLE; - else - *sec_op = ATMODEM_SIM_CURR_SEC_OP_NS_STATUS; - break; - - case TEL_SIM_LOCK_PP: - fac = "PP"; - if (flag == ENABLE_FLAG) - *sec_op = ATMODEM_SIM_CURR_SEC_OP_SP_ENABLE; - else if (flag == DISABLE_FLAG) - *sec_op = ATMODEM_SIM_CURR_SEC_OP_SP_DISABLE; - else - *sec_op = ATMODEM_SIM_CURR_SEC_OP_SP_STATUS; - break; - - case TEL_SIM_LOCK_PC: - fac = "PC"; - if (flag == ENABLE_FLAG) - *sec_op = ATMODEM_SIM_CURR_SEC_OP_CP_ENABLE; - else if (flag == DISABLE_FLAG) - *sec_op = ATMODEM_SIM_CURR_SEC_OP_CP_DISABLE; - else - *sec_op = ATMODEM_SIM_CURR_SEC_OP_CP_STATUS; - break; - - default: - err("Unhandled sim lock type [%d]", lock_type); - } - - return fac; -} - -static void __atmodem_sim_next_from_read_binary(CoreObject *co, - AtmodemRespCbData *resp_cb_data, TelSimResult sim_result, gboolean decode_ret) -{ - AtmodemSimMetaInfo *file_meta = - (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN; - - dbg("Entry"); - - dbg("[SIM]EF[0x%x] read sim_result[%d] Decode rt[%d]", - file_meta->file_id, sim_result, decode_ret); - switch (file_meta->file_id) { - case TEL_SIM_EF_ELP: - case TEL_SIM_EF_USIM_PL: - case TEL_SIM_EF_LP: - case TEL_SIM_EF_USIM_LI: - if (decode_ret == TRUE) { - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - tcore_sim_get_type(co, &card_type); - /* 2G */ - /* The ME requests the Extended Language Preference. - * The ME only requests the Language Preference (EFLP) - * if at least one of the following conditions holds: - * - EFELP is not available; - * - EFELP does not contain an entry corresponding to - * a language specified in ISO 639[30]; - * - the ME does not support any of the languages in EFELP. - */ - /* 3G */ - /* - * The ME only requests the Language Preference (EFPL) - * if at least one of the following conditions holds: - * - if the EFLI has the value 'FFFF' in its highest - * priority position - * - if the ME does not support any of the language - * codes indicated in EFLI , or if EFLI is not present - */ - if (TEL_SIM_CARD_TYPE_GSM == card_type) { - if (file_meta->file_id == TEL_SIM_EF_LP) { - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - file_meta->file_id = TEL_SIM_EF_LP; - __atmodem_sim_get_response(co, resp_cb_data); - } - } else if (TEL_SIM_CARD_TYPE_USIM) { - if (file_meta->file_id == TEL_SIM_EF_LP - || file_meta->file_id == TEL_SIM_EF_USIM_LI) { - file_meta->file_id = TEL_SIM_EF_ELP; - __atmodem_sim_get_response(co, resp_cb_data); - } else { - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } - } - } - break; - - case TEL_SIM_EF_ECC: - tcore_sim_get_type(co, &card_type); - if (TEL_SIM_CARD_TYPE_USIM == card_type) { - if (file_meta->current_index == file_meta->rec_count) { - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - file_meta->current_index++; - __atmodem_sim_read_record(co, resp_cb_data); - } - } else if (TEL_SIM_CARD_TYPE_GSM == card_type) { - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", card_type); - } - break; - - case TEL_SIM_EF_IMSI: - __atmodem_sim_update_sim_status(co, TEL_SIM_STATUS_SIM_INIT_COMPLETED); - break; - - case TEL_SIM_EF_MSISDN: - if (file_meta->current_index == file_meta->rec_count) { - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - file_meta->current_index++; - __atmodem_sim_read_record(co, resp_cb_data); - } - break; - - case TEL_SIM_EF_OPL: - if (file_meta->current_index == file_meta->rec_count) { - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - file_meta->current_index++; - __atmodem_sim_read_record(co, resp_cb_data); - } - break; - - case TEL_SIM_EF_PNN: - if (file_meta->current_index == file_meta->rec_count) { - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - file_meta->current_index++; - __atmodem_sim_read_record(co, resp_cb_data); - } - break; - - case TEL_SIM_EF_USIM_CFIS: - case TEL_SIM_EF_USIM_MWIS: - case TEL_SIM_EF_USIM_MBI: - case TEL_SIM_EF_MBDN: - case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS: - case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS: - if (file_meta->current_index == file_meta->rec_count) { - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } else { - file_meta->current_index++; - __atmodem_sim_read_record(co, resp_cb_data); - } - break; - - case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING: - { - file_meta->files.result = sim_result; - if (decode_ret == TRUE && sim_result == TEL_SIM_RESULT_SUCCESS) { - memcpy(file_meta->files.data.cphs_net.full_name, - file_meta->files.data.cphs_net.full_name, - strlen((char *)file_meta->files.data.cphs_net.full_name)); - } - - file_meta->file_id = TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING; - file_meta->file_result = TEL_SIM_RESULT_FAILURE; - __atmodem_sim_get_response(co, resp_cb_data); - } - break; - - case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING: - if (file_meta->files.result == TEL_SIM_RESULT_SUCCESS) { - file_meta->files.result = TEL_SIM_RESULT_SUCCESS; - } - if (strlen((char *)file_meta->files.data.cphs_net.full_name)) { - memcpy(&file_meta->files.data.cphs_net.full_name, - &file_meta->files.data.cphs_net.full_name, - strlen((char *)file_meta->files.data.cphs_net.full_name)); - } - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - break; - - case TEL_SIM_EF_ICCID: - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data.iccid, resp_cb_data->cb_data); - break; - - case TEL_SIM_EF_SST: - case TEL_SIM_EF_SPN: - case TEL_SIM_EF_SPDI: - case TEL_SIM_EF_OPLMN_ACT: - case TEL_SIM_EF_CPHS_CPHS_INFO: - case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS: - case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING: - case TEL_SIM_EF_CPHS_DYNAMICFLAGS: - case TEL_SIM_EF_CPHS_DYNAMIC2FLAG: - case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE: - case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2: - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - break; - - default: - err("File id not handled [0x%x]", file_meta->file_id); - break; - } -} - -static void __atmodem_sim_next_from_get_response(CoreObject *co, - AtmodemRespCbData *resp_cb_data, TelSimResult sim_result) -{ - AtmodemSimMetaInfo *file_meta = - (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN; - - dbg("EF[0x%x] access Result[%d]", file_meta->file_id, sim_result); - - file_meta->files.result = sim_result; - memset(&file_meta->files.data, 0x00, sizeof(file_meta->files.data)); - - if ((file_meta->file_id != TEL_SIM_EF_ELP - && file_meta->file_id != TEL_SIM_EF_LP - && file_meta->file_id != TEL_SIM_EF_USIM_PL - && file_meta->file_id != TEL_SIM_EF_CPHS_CPHS_INFO) - && (sim_result != TEL_SIM_RESULT_SUCCESS)) { - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - - return; - } - - switch (file_meta->file_id) { - case TEL_SIM_EF_ELP: { - if (sim_result == TEL_SIM_RESULT_SUCCESS) { - dbg("[SIM DATA] exist EFELP/PL(0x2F05)"); - __atmodem_sim_read_binary(co, resp_cb_data); - } else { - tcore_sim_get_type(co, &card_type); - if (TEL_SIM_CARD_TYPE_GSM == card_type) { - AtmodemSimMetaInfo file_meta_new = {0,}; - - dbg("[SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info"); - /* The ME requests the Language Preference (EFLP) if EFELP is not available */ - file_meta_new.file_id = TEL_SIM_EF_LP; - file_meta_new.file_result = TEL_SIM_RESULT_FAILURE; - file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE; - - memcpy(resp_cb_data->data, &file_meta_new, sizeof(AtmodemSimMetaInfo)); - - __atmodem_sim_get_response(co, resp_cb_data); - } else if (TEL_SIM_CARD_TYPE_USIM == card_type) { - dbg(" [SIM DATA]fail to get Language information "\ - "in USIM(EF-LI(6F05),EF-PL(2F05))"); - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - return; - } - } - } - break; - - case TEL_SIM_EF_LP: { - if (sim_result == TEL_SIM_RESULT_SUCCESS) { - dbg("[SIM DATA] exist EFLP/LI(0x6F05)"); - __atmodem_sim_read_binary(co, resp_cb_data); - } else { - tcore_sim_get_type(co, &card_type); - dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]", card_type); - if (TEL_SIM_CARD_TYPE_GSM == card_type) { - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - return; - } - /* - * If EFLI is not present, then the language selection - * shall be as defined in EFPL at the MF level - */ - else if (TEL_SIM_CARD_TYPE_USIM == card_type) { - AtmodemSimMetaInfo file_meta_new = {0,}; - - dbg("[SIM DATA] try USIM EFPL(0x2F05)"); - file_meta_new.file_id = TEL_SIM_EF_ELP; - file_meta_new.file_result = TEL_SIM_RESULT_FAILURE; - file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE; - - memcpy(resp_cb_data->data, &file_meta_new, sizeof(AtmodemSimMetaInfo)); - - __atmodem_sim_get_response(co, resp_cb_data); - } - } - } - break; - - case TEL_SIM_EF_USIM_PL: { - if (sim_result == TEL_SIM_RESULT_SUCCESS) { - dbg("[SIM DATA] exist EFELP/PL(0x2F05)"); - __atmodem_sim_read_binary(co, resp_cb_data); - } else { - /* - * EFELIand EFPL not present, so set language count - * as zero and select ECC - */ - dbg("[SIM DATA]SIM_EF_USIM_PL(2A05) access fail. "\ - "Request SIM_EF_ECC(0x6FB7) info"); - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - - return; - } - } - break; - - case TEL_SIM_EF_ECC: { - tcore_sim_get_type(co, &card_type); - if (TEL_SIM_CARD_TYPE_GSM == card_type) { - __atmodem_sim_read_binary(co, resp_cb_data); - } else if (TEL_SIM_CARD_TYPE_USIM == card_type) { - if (file_meta->rec_count > TEL_SIM_ECC_LIST_MAX) - file_meta->rec_count = TEL_SIM_ECC_LIST_MAX; - - file_meta->current_index++; - __atmodem_sim_read_record(co, resp_cb_data); - } - } - break; - - case TEL_SIM_EF_ICCID: - case TEL_SIM_EF_IMSI: - case TEL_SIM_EF_SST: - case TEL_SIM_EF_SPN: - case TEL_SIM_EF_SPDI: - case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS: - case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING: - case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING: - case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING: - case TEL_SIM_EF_CPHS_DYNAMICFLAGS: - case TEL_SIM_EF_CPHS_DYNAMIC2FLAG: - case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE: - case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2: - __atmodem_sim_read_binary(co, resp_cb_data); - break; - - case TEL_SIM_EF_CPHS_CPHS_INFO: { - if (sim_result == TEL_SIM_RESULT_SUCCESS) { - tcore_sim_set_cphs_status(co, TRUE); - __atmodem_sim_update_sim_status(co, TEL_SIM_STATUS_SIM_INIT_COMPLETED); - - __atmodem_sim_read_binary(co, resp_cb_data); - } else { - tcore_sim_set_cphs_status(co, FALSE); - __atmodem_sim_update_sim_status(co, TEL_SIM_STATUS_SIM_INIT_COMPLETED); - - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)sim_result, - &file_meta->files.data, resp_cb_data->cb_data); - } - } - break; - - - case TEL_SIM_EF_USIM_CFIS: { - if (file_meta->rec_count > TEL_SIM_CALL_FORWARDING_TYPE_MAX) - file_meta->rec_count = TEL_SIM_CALL_FORWARDING_TYPE_MAX; - - file_meta->current_index++; - __atmodem_sim_read_record(co, resp_cb_data); - } - break; - - case TEL_SIM_EF_OPL: - case TEL_SIM_EF_PNN: - case TEL_SIM_EF_USIM_MWIS: - case TEL_SIM_EF_USIM_MBI: - case TEL_SIM_EF_MBDN: - case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS: - case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS: - case TEL_SIM_EF_MSISDN: - file_meta->current_index++; - __atmodem_sim_read_record(co, resp_cb_data); - break; - - case TEL_SIM_EF_SMSP: { - AtmodemSimPrivateInfo *priv_info = NULL; - - priv_info = tcore_sim_ref_userdata(co); - - dbg("SMSP info set to tcore : count:[%d], rec_len:[%d]", - file_meta->rec_count, file_meta->rec_length); - priv_info->smsp_count = file_meta->rec_count; - priv_info->smsp_rec_len = file_meta->rec_length; - } - break; - - default: - dbg("error - File id for get file info [0x%x]", file_meta->file_id); - break; - } - return; -} - -#if 0 //blocking for the moment -static void __on_response_atmodem_sim_update_file(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *resp = data; - CoreObject *co_sim = NULL; - GSList *tokens = NULL; - TelSimResult sim_result = TEL_SIM_RESULT_CARD_ERROR; - const char *line; - AtmodemRespCbData *resp_cb_data = (AtmodemRespCbData *)user_data; - AtmodemSimMetaInfo *file_meta = - (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - dbg("Entry"); - - co_sim = tcore_pending_ref_core_object(p); - - dbg("file_id:[0x%x]", file_meta->file_id); - - if (resp->success > 0) { - int sw1 = 0; - int sw2 = 0; - dbg("RESPONSE OK"); - if (resp->lines) { - line = (const char *)resp->lines->data; - tokens = tcore_at_tok_new(line); - if (g_slist_length(tokens) != 2) { - err("Invalid message"); - goto out; - } - sw1 = atoi(g_slist_nth_data(tokens, 0)); - sw2 = atoi(g_slist_nth_data(tokens, 1)); - } - - if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) { - sim_result = TEL_SIM_RESULT_SUCCESS; - } else { - sim_result = __atmodem_sim_decode_status_word(sw1, sw2); - } - } else { - err("RESPONSE NOK"); - sim_result = TEL_SIM_RESULT_FAILURE; - } -out: - /* Send Response */ - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)sim_result, - NULL, resp_cb_data->cb_data); - - tcore_at_tok_free(tokens); - dbg("Exit"); -} -#endif - -static void __on_response_atmodem_sim_read_data(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *resp = data; - CoreObject *co = NULL; - GSList *tokens = NULL; - TelSimResult sim_result; - gboolean dr = FALSE; - const char *line = NULL; - char *res = NULL; - char *tmp = NULL; - guint res_len; - int sw1 = 0; - int sw2 = 0; - TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN; - AtmodemRespCbData *resp_cb_data = (AtmodemRespCbData *) user_data; - AtmodemSimMetaInfo *file_meta = - (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - dbg("Entry"); - - co = tcore_pending_ref_core_object(p); - - if (resp->success > 0) { - dbg("RESPONSE OK"); - if (resp->lines) { - line = (const char *)resp->lines->data; - tokens = tcore_at_tok_new(line); - if (g_slist_length(tokens) < 2) { - err("Invalid message"); - tcore_at_tok_free(tokens); - return; - } - } - sw1 = atoi(g_slist_nth_data(tokens, 0)); - sw2 = atoi(g_slist_nth_data(tokens, 1)); - res = g_slist_nth_data(tokens, 2); - - tmp = tcore_at_tok_extract(res); - tcore_util_hexstring_to_bytes(tmp, &res, &res_len); - dbg("Response: [%s] Response length: [%d]", res, res_len); - - if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) { - sim_result = TEL_SIM_RESULT_SUCCESS; - file_meta->files.result = sim_result; - - dbg("File ID: [0x%x]", file_meta->file_id); - switch (file_meta->file_id) { - case TEL_SIM_EF_IMSI: { - dbg("Data: [%s]", res); - dr = tcore_sim_decode_imsi((unsigned char *)res, - res_len, &file_meta->imsi); - if (dr == FALSE) { - err("IMSI decoding failed"); - } else { - __atmodem_sim_set_identity(co, &file_meta->imsi); - - /* Update IMSI */ - tcore_sim_set_imsi(co, &file_meta->imsi); - } - } - break; - - case TEL_SIM_EF_ICCID: { - dr = tcore_sim_decode_iccid((unsigned char *)res, res_len, - file_meta->files.data.iccid); - } - break; - - case TEL_SIM_EF_ELP: /* 2G EF - 2 bytes decoding */ - case TEL_SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding */ - case TEL_SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding */ - case TEL_SIM_EF_LP: /* 1 byte encoding */ - { - tcore_sim_get_type(co, &card_type); - if ((TEL_SIM_CARD_TYPE_GSM == card_type) - && (file_meta->file_id == TEL_SIM_EF_LP)) { - /* - * 2G LP(0x6F05) has 1 byte for each language - */ - dr = tcore_sim_decode_lp((unsigned char *)res, - res_len, &file_meta->files.data.language); - } else { - /* - * 3G LI(0x6F05)/PL(0x2F05), - * 2G ELP(0x2F05) has 2 bytes for each language - */ - dr = tcore_sim_decode_li((unsigned char *)res, res_len, - file_meta->file_id, &file_meta->files.data.language); - } - } - break; - - case TEL_SIM_EF_SPN: - dr = tcore_sim_decode_spn((unsigned char *)res, - res_len, &file_meta->files.data.spn); - break; - - case TEL_SIM_EF_SPDI: - dr = tcore_sim_decode_spdi((unsigned char *)res, - res_len, &file_meta->files.data.spdi); - break; - - case TEL_SIM_EF_SST: { - TelSimServiceTable *svct = NULL; - - svct = g_try_new0(TelSimServiceTable, 1); - tcore_sim_get_type(co, &card_type); - svct->sim_type = card_type; - if (TEL_SIM_CARD_TYPE_GSM == card_type) { - dr = tcore_sim_decode_sst((unsigned char *)res, - res_len, svct->table.sst_service); - } else if (TEL_SIM_CARD_TYPE_USIM == card_type) { - dr = tcore_sim_decode_ust((unsigned char *)res, - res_len, svct->table.ust_service); - } else { - err("Not handled card_type[%d]", card_type); - } - - if (dr == FALSE) { - err("SST/UST decoding failed"); - } else { - tcore_sim_set_service_table(co, svct); - } - - /* Free memory */ - g_free(svct); - } - break; - - case TEL_SIM_EF_ECC: { - tcore_sim_get_type(co, &card_type); - if (TEL_SIM_CARD_TYPE_GSM == card_type) { - dr = tcore_sim_decode_ecc((unsigned char *)res, - res_len, &file_meta->files.data.ecc); - } else if (TEL_SIM_CARD_TYPE_USIM == card_type) { - TelSimEcc *ecc = NULL; - - ecc = g_try_new0(TelSimEcc, 1); - dbg("Index [%d]", file_meta->current_index); - - dr = tcore_sim_decode_uecc((unsigned char *)res, res_len, ecc); - if (dr == TRUE) { - memcpy(&file_meta->files.data.ecc.list[file_meta->files.data.ecc.count], - ecc, sizeof(TelSimEcc)); - file_meta->files.data.ecc.count++; - } - - /* Free memory */ - g_free(ecc); - } else { - dbg("Unknown/Unsupported SIM card Type: [%d]", card_type); - } - } - break; - - case TEL_SIM_EF_MSISDN: { - TelSimSubscriberInfo *msisdn = NULL; - - dbg("Index [%d]", file_meta->current_index); - msisdn = g_try_new0(TelSimSubscriberInfo, 1); - dr = tcore_sim_decode_msisdn((unsigned char *)res, res_len, msisdn); - if (dr == TRUE) { - memcpy(&file_meta->files.data.msisdn_list.list[file_meta->files.data.msisdn_list.count], - msisdn, sizeof(TelSimSubscriberInfo)); - - file_meta->files.data.msisdn_list.count++; - } - - /* Free memory */ - g_free(msisdn); - } - break; - - case TEL_SIM_EF_OPL: { - TelSimOpl *opl = NULL; - - dbg("decode w/ index [%d]", file_meta->current_index); - opl = g_try_new0(TelSimOpl, 1); - - dr = tcore_sim_decode_opl((unsigned char *)res, res_len, opl); - if (dr == TRUE) { - memcpy(&file_meta->files.data.opl.list[file_meta->files.data.opl.opl_count], - opl, sizeof(TelSimOpl)); - - file_meta->files.data.opl.opl_count++; - } - - /* Free memory */ - g_free(opl); - } - break; - - case TEL_SIM_EF_PNN: { - TelSimPnn *pnn = NULL; - - dbg("decode w/ index [%d]", file_meta->current_index); - pnn = g_try_new0(TelSimPnn, 1); - - dr = tcore_sim_decode_pnn((unsigned char *)res, res_len, pnn); - if (dr == TRUE) { - memcpy(&file_meta->files.data.pnn.list[file_meta->files.data.pnn.pnn_count], - pnn, sizeof(TelSimPnn)); - - file_meta->files.data.pnn.pnn_count++; - } - - /* Free memory */ - g_free(pnn); - } - break; - - case TEL_SIM_EF_OPLMN_ACT: - /*dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa, - (unsigned char *)res, res_len);*/ - break; - - case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE: - /*dr = tcore_sim_decode_csp(&po->p_cphs->csp, - p_data->response, p_data->response_len);*/ - break; - - case TEL_SIM_EF_USIM_MBI: { /* linear type */ - TelSimMbi *mbi = NULL; - - mbi = g_try_new0(TelSimMbi, 1); - dr = tcore_sim_decode_mbi((unsigned char *)res, res_len, mbi); - if (dr == TRUE) { - memcpy(&file_meta->mbi_list.list[file_meta->mbi_list.count], - mbi, sizeof(TelSimMbi)); - file_meta->mbi_list.count++; - - dbg("mbi count[%d]", file_meta->mbi_list.count); - } - - /* Free memory */ - g_free(mbi); - } - break; - - case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS: /* linear type */ - case TEL_SIM_EF_MBDN: /* linear type */ -#if 0 /* Temporarily blocked, MBDN is NOT suported in Emulator */ - dr = tcore_sim_decode_xdn((unsigned char *)res, res_len, - file_meta->mb_list[file_meta->current_index-1].alpha_id, - file_meta->mb_list[file_meta->current_index-1].number); - file_meta->mb_list[file_meta->current_index-1].alpha_id_len = - strlen(file_meta->mb_list[file_meta->current_index-1].alpha_id); - file_meta->mb_list[file_meta->current_index-1].profile_id = - file_meta->current_index; -#endif /* Temporarily blocked, MBDN is NOT suported in Emulator */ - break; - - case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING: /* transparent type */ - dr = tcore_sim_decode_vmwf((unsigned char *)res, - res_len, file_meta->files.data.mw.mw); - break; - - case TEL_SIM_EF_USIM_MWIS: { /* linear type */ - TelSimMwis *mw = NULL; - - mw = g_try_new0(TelSimMwis, 1); - - dr = tcore_sim_decode_mwis((unsigned char *)res, res_len, mw); - if (dr == TRUE) { - memcpy(&file_meta->files.data.mw.mw[file_meta->files.data.mw.profile_count], - mw, sizeof(TelSimMwis)); - file_meta->files.data.mw.profile_count++; - } - - /* Free memory */ - g_free(mw); - } - break; - - case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS: /* transparent type */ - dr = tcore_sim_decode_cff((unsigned char *)res, - res_len, file_meta->files.data.mw.mw); - break; - - case TEL_SIM_EF_USIM_CFIS: { /* linear type */ - TelSimCfis *cf = NULL; - - cf = g_try_new0(TelSimCfis, 1); - dr = tcore_sim_decode_cfis((unsigned char *)res, res_len, cf); - if (dr == TRUE) { - memcpy(&file_meta->files.data.cf.cf[file_meta->files.data.cf.profile_count], - cf, sizeof(TelSimCfis)); - file_meta->files.data.cf.profile_count++; - } - - /* Free memory */ - g_free(cf); - } - break; - - case TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE: - dbg("not handled - TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE "); - break; - - case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING: - dr = tcore_sim_decode_ons((unsigned char *)res, - res_len, - (unsigned char*)&file_meta->files.data.cphs_net.full_name); - dbg("file_meta->files.result[%d],file_meta->files.data.cphs_net.full_name[%s]", - file_meta->files.result, file_meta->files.data.cphs_net.full_name); - break; - - case TEL_SIM_EF_CPHS_DYNAMICFLAGS: - /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo, - p_data->response, p_data->response_len);*/ - break; - - case TEL_SIM_EF_CPHS_DYNAMIC2FLAG: - /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response, - p_data->response_len);*/ - break; - - case TEL_SIM_EF_CPHS_CPHS_INFO: - /*dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs, - (unsigned char *)res, res_len);*/ - break; - - case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING: - dr = tcore_sim_decode_short_ons((unsigned char *)res, res_len, - (unsigned char*)&file_meta->files.data.cphs_net.short_name); - dbg("file_meta->files.result[%d],file_meta->files.data.cphs_net.short_name[%s]", - file_meta->files.result, file_meta->files.data.cphs_net.short_name); - break; - - case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS: - /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn, - p_data->response, p_data->response_len);*/ - break; - - default: - dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id); - dr = 0; - break; - } - } else { - sim_result = __atmodem_sim_decode_status_word(sw1, sw2); - file_meta->files.result = sim_result; - } - - /* Free memory */ - g_free(tmp); - g_free(res); - - /* Free tokens */ - tcore_at_tok_free(tokens); - } else { - err("RESPONSE NOK"); - dbg("Error - File ID: [0x%x]", file_meta->file_id); - sim_result = TEL_SIM_RESULT_FAILURE; - } - - /* Get File data */ - __atmodem_sim_next_from_read_binary(tcore_pending_ref_core_object(p), - resp_cb_data, sim_result, dr); - - dbg("Exit"); -} - -static void __on_response_atmodem_sim_get_response(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *resp = data; - CoreObject *co = NULL; - TelSimResult sim_result; - GSList *tokens = NULL; - const char *line = NULL; - int sw1 = 0; - int sw2 = 0; - AtmodemRespCbData *resp_cb_data = (AtmodemRespCbData *)user_data; - AtmodemSimMetaInfo *file_meta = - (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - dbg("SIM Response - SIM File info: [+CRSM]"); - - co = tcore_pending_ref_core_object(p); - - if (resp->success > 0) { - dbg("RESPONSE OK"); - if (resp->lines) { - line = (const char *)resp->lines->data; - tokens = tcore_at_tok_new(line); - if (g_slist_length(tokens) < 2) { - err("Invalid message"); - tcore_at_tok_free(tokens); - return; - } - } - sw1 = atoi(g_slist_nth_data(tokens, 0)); - sw2 = atoi(g_slist_nth_data(tokens, 1)); - - /*1. SIM access success case*/ - if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) { - unsigned char tag_len = 0; - unsigned short record_len = 0; - char num_of_records = 0; - unsigned char file_id_len = 0; - unsigned short file_id = 0; - unsigned short file_size = 0; - unsigned short file_type = 0; - unsigned short arr_file_id = 0; - int arr_file_id_rec_num = 0; - TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN; - - /* handling only last 3 bits */ - unsigned char file_type_tag = 0x07; - unsigned char *ptr_data; - - char *hexData; - char *tmp; - char *record_data = NULL; - guint record_data_len; - hexData = g_slist_nth_data(tokens, 2); - dbg("hexData: %s", hexData); - dbg("hexData: %s", hexData + 1); - - tmp = tcore_at_tok_extract(hexData); - tcore_util_hexstring_to_bytes(tmp, &record_data, &record_data_len); - tcore_util_hex_dump(" ", record_data_len, record_data); - g_free(tmp); - - ptr_data = (unsigned char *)record_data; - tcore_sim_get_type(co, &card_type); - if (TEL_SIM_CARD_TYPE_USIM == card_type) { - /* - * ETSI TS 102 221 v7.9.0 - * - Response Data - * '62' FCP template tag - * - * - Response for an EF - * '82' M File Descriptor - * '83' M File Identifier - * 'A5' O Proprietary information - * '8A' M Life Cycle Status Integer - * '8B', '8C' or 'AB' C1 Security attributes - * '80' M File size - * '81' O Total file size - * '88' O Short File Identifier (SFI) - */ - - /* rsim.res_len has complete data length received */ - - /* FCP template tag - File Control Parameters tag*/ - if (*ptr_data == 0x62) { - /* parse complete FCP tag*/ - /* increment to next byte */ - ptr_data++; - tag_len = *ptr_data++; - dbg("tag_len: %02x", tag_len); - /* FCP file descriptor - file type, accessibility, DF, ADF etc*/ - if (*ptr_data == 0x82) { - /* increment to next byte */ - ptr_data++; - /* 2 or 5 value*/ - ptr_data++; - /* consider only last 3 bits*/ - dbg("file_type_tag: %02x", file_type_tag); - file_type_tag = file_type_tag & (*ptr_data); - dbg("file_type_tag: %02x", file_type_tag); - - switch (file_type_tag) { - /* increment to next byte */ - // ptr_data++; - case 0x1: - dbg("Getting FileType: [Transparent file type]"); - file_type = ATMODEM_SIM_FILE_TYPE_TRANSPARENT; - - /* increment to next byte */ - ptr_data++; - /* increment to next byte */ - ptr_data++; - break; - - case 0x2: - dbg("Getting FileType: [Linear fixed file type]"); - /* increment to next byte */ - ptr_data++; - /* data coding byte - value 21 */ - ptr_data++; - /* 2bytes */ - memcpy(&record_len, ptr_data, 2); - /* swap bytes */ - ATMODEM_SWAP_BYTES_16(record_len); - ptr_data = ptr_data + 2; - num_of_records = *ptr_data++; - /* Data lossy conversation from enum (int) to unsigned char */ - file_type = ATMODEM_SIM_FILE_TYPE_LINEAR_FIXED; - break; - - case 0x6: - dbg("Cyclic fixed file type"); - /* increment to next byte */ - ptr_data++; - /* data coding byte - value 21 */ - ptr_data++; - /* 2bytes */ - memcpy(&record_len, ptr_data, 2); - /* swap bytes */ - ATMODEM_SWAP_BYTES_16(record_len); - ptr_data = ptr_data + 2; - num_of_records = *ptr_data++; - file_type = ATMODEM_SIM_FILE_TYPE_CYCLIC; - break; - - default: - dbg("not handled file type [0x%x]", *ptr_data); - break; - } - } else { - dbg("INVALID FCP received - DEbug!"); - tcore_at_tok_free(tokens); - g_free(record_data); - return; - } - - /*File identifier - 0x84,0x85,0x86 etc are currently ignored and not handled */ - if (*ptr_data == 0x83) { - /* increment to next byte */ - ptr_data++; - file_id_len = *ptr_data++; - dbg("file_id_len: %02x", file_id_len); - - memcpy(&file_id, ptr_data, file_id_len); - dbg("file_id: %x", file_id); - - /* swap bytes */ - ATMODEM_SWAP_BYTES_16(file_id); - dbg("file_id: %x", file_id); - - ptr_data = ptr_data + 2; - dbg("Getting FileID=[0x%x]", file_id); - } else { - dbg("INVALID FCP received - DEbug!"); - tcore_at_tok_free(tokens); - g_free(record_data); - return; - } - - /* proprietary information */ - if (*ptr_data == 0xA5) { - unsigned short prop_len; - /* increment to next byte */ - ptr_data++; - - /* length */ - prop_len = *ptr_data; - dbg("prop_len: %02x", prop_len); - - /* skip data */ - ptr_data = ptr_data + prop_len + 1; - } else { - dbg("INVALID FCP received - DEbug!"); - } - - /* life cycle status integer [8A][length:0x01][status]*/ - /* - status info b8~b1 - 00000000 : No information given - 00000001 : creation state - 00000011 : initialization state - 000001-1 : operation state -activated - 000001-0 : operation state -deactivated - 000011-- : Termination state - b8~b5 !=0, b4~b1=X : Proprietary - Any other value : RFU - */ - if (*ptr_data == 0x8A) { - /* increment to next byte */ - ptr_data++; - /* length - value 1 */ - ptr_data++; - - switch (*ptr_data) { - case 0x04: - case 0x06: - dbg(" operation state -deactivated"); - ptr_data++; - break; - - case 0x05: - case 0x07: - dbg(" operation state -activated"); - ptr_data++; - break; - - default: - dbg(" DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data); - ptr_data++; - break; - } - } - - /* related to security attributes : currently not handled*/ - if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) { - /* increment to next byte */ - ptr_data++; - /* if tag length is 3 */ - if (*ptr_data == 0x03) { - /* increment to next byte */ - ptr_data++; - /* EFARR file id */ - memcpy(&arr_file_id, ptr_data, 2); - /* swap byes */ - ATMODEM_SWAP_BYTES_16(arr_file_id); - ptr_data = ptr_data + 2; - arr_file_id_rec_num = *ptr_data++; - dbg("arr_file_id_rec_num:[%d]", arr_file_id_rec_num); - } else { - /* if tag length is not 3 */ - /* ignoring bytes */ - // ptr_data = ptr_data + 4; - dbg("Useless security attributes, so jump to next tag"); - ptr_data = ptr_data + (*ptr_data + 1); - } - } else { - dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data); - tcore_at_tok_free(tokens); - g_free(record_data); - return; - } - - dbg("Current ptr_data value is [%x]", *ptr_data); - - /* file size excluding structural info*/ - if (*ptr_data == 0x80) { - /* for EF file size is body of file and for Linear or cyclic it is - * number of recXsizeof(one record) - */ - /* increment to next byte */ - ptr_data++; - /* length is 1 byte - value is 2 bytes or more */ - ptr_data++; - memcpy(&file_size, ptr_data, 2); - /* swap bytes */ - ATMODEM_SWAP_BYTES_16(file_size); - ptr_data = ptr_data + 2; - } else { - dbg("INVALID FCP received - DEbug!"); - tcore_at_tok_free(tokens); - g_free(record_data); - return; - } - - /* total file size including structural info*/ - if (*ptr_data == 0x81) { - int len; - /* increment to next byte */ - ptr_data++; - /* length */ - len = *ptr_data; - dbg("len:[%d]", len); - /* ignored bytes */ - ptr_data = ptr_data + 3; - } else { - dbg("INVALID FCP received - DEbug!"); - /* 0x81 is optional tag?? check out! so do not return -1 from here! */ - } - /*short file identifier ignored*/ - if (*ptr_data == 0x88) { - dbg("0x88: Do Nothing"); - /*DO NOTHING*/ - } - } else { - dbg("INVALID FCP received - DEbug!"); - tcore_at_tok_free(tokens); - g_free(record_data); - return; - } - } else if (TEL_SIM_CARD_TYPE_GSM == card_type) { - unsigned char gsm_specific_file_data_len = 0; - /* ignore RFU byte1 and byte2 */ - ptr_data++; - ptr_data++; - /* file size */ - // file_size = p_info->response_len; - memcpy(&file_size, ptr_data, 2); - /* swap bytes */ - ATMODEM_SWAP_BYTES_16(file_size); - /* parsed file size */ - ptr_data = ptr_data + 2; - /* file id */ - memcpy(&file_id, ptr_data, 2); - ATMODEM_SWAP_BYTES_16(file_id); - dbg("FILE id --> [%x]", file_id); - ptr_data = ptr_data + 2; - /* save file type - transparent, linear fixed or cyclic */ - file_type_tag = (*(ptr_data + 7)); - - switch (*ptr_data) { - case 0x0: - /* RFU file type */ - dbg("RFU file type- not handled - Debug!"); - break; - - case 0x1: - /* MF file type */ - dbg("MF file type - not handled - Debug!"); - break; - - case 0x2: - /* DF file type */ - dbg("DF file type - not handled - Debug!"); - break; - - case 0x4: - /* EF file type */ - dbg("EF file type [%d] ", file_type_tag); - /* increment to next byte */ - ptr_data++; - - if (file_type_tag == 0x00 || file_type_tag == 0x01) { - /* increament to next byte as this byte is RFU */ - ptr_data++; - file_type = - (file_type_tag == 0x00) ? ATMODEM_SIM_FILE_TYPE_TRANSPARENT : ATMODEM_SIM_FILE_TYPE_LINEAR_FIXED; - } else { - /* increment to next byte */ - ptr_data++; - /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */ - /* the INCREASE command is allowed on the selected cyclic file. */ - file_type = ATMODEM_SIM_FILE_TYPE_CYCLIC; - } - /* bytes 9 to 11 give SIM file access conditions */ - ptr_data++; - /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */ - ptr_data++; - /* byte 11 is invalidate and rehabilate nibbles */ - ptr_data++; - /* byte 12 - file status */ - ptr_data++; - /* byte 13 - GSM specific data */ - gsm_specific_file_data_len = *ptr_data; - dbg("gsm_specific_file_data_len:[%d]", gsm_specific_file_data_len); - ptr_data++; - /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */ - ptr_data++; - /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */ - record_len = *ptr_data; - dbg("record length[%d], file size[%d]", record_len, file_size); - if (record_len != 0) - num_of_records = (file_size / record_len); - - dbg("Number of records [%d]", num_of_records); - break; - - default: - dbg("not handled file type"); - break; - } - } else { - err("Unknown Card Type - [%d]", card_type); - } - - dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] "\ - "NumOfRecords[%ld] RecordLen[%ld]", - file_meta->file_id, file_id, file_size, - file_type, num_of_records, record_len); - - file_meta->file_type = file_type; - file_meta->data_size = file_size; - file_meta->rec_length = record_len; - file_meta->rec_count = num_of_records; - file_meta->current_index = 0; /* reset for new record type EF */ - sim_result = TEL_SIM_RESULT_SUCCESS; - g_free(record_data); - } else { - /*2. SIM access fail case*/ - err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id); - sim_result = __atmodem_sim_decode_status_word(sw1, sw2); - } - - tcore_at_tok_free(tokens); - } else { - err("RESPONSE NOK"); - err("Failed to get ef[0x%x] (file_meta->file_id)", - file_meta->file_id); - sim_result = TEL_SIM_RESULT_FAILURE; - } - - dbg("Calling __atmodem_sim_next_from_get_response"); - __atmodem_sim_next_from_get_response(co, resp_cb_data, sim_result); - dbg("Exit"); -} - -#if 0 //blocking for the moment -static TelReturn __atmodem_sim_update_file(CoreObject *co, - AtmodemRespCbData *resp_cb_data, - int cmd, TelSimFileId ef, - int p1, int p2, int p3, char *encoded_data) -{ - char *cmd_str = NULL; - TelReturn ret = TEL_RETURN_FAILURE; - AtmodemSimMetaInfo *file_meta = - (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - dbg("Entry File-id:[0x%02x]", file_meta->file_id); - - cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"", - cmd, ef, p1, p2, p3, encoded_data); - - ret = tcore_at_prepare_and_send_request(co, - cmd_str, "+CRSM:", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - __on_response_atmodem_sim_update_file, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Update SIM File"); - - tcore_free(encoded_data); - g_free(cmd_str); - - dbg("Exit"); - return ret; -} -#endif - -static void __atmodem_sim_read_record(CoreObject *co, - AtmodemRespCbData *resp_cb_data) -{ - gchar *at_cmd = NULL; - int p1 = 0; - int p2 = 0; - int p3 = 0; - AtmodemSimMetaInfo *file_meta = (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - TelReturn ret = TEL_RETURN_FAILURE; - - dbg("Entry File-id:[0x%02x]", file_meta->file_id); - - /* According to TS 102 221, values of p1, p2, p3 can be as below: - * 11.1.5 READ RECORD - * P1: Record number - * P2: Mode, see table 11.11 - * Lc: Not present - * Data: Not present - * Le: Number of bytes to be read (P3) - */ - p1 = (unsigned char) file_meta->current_index; - p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */ - p3 = (unsigned char) file_meta->rec_length; - - at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d", - ATMODEM_SIM_ACCESS_READ_RECORD, file_meta->file_id, p1, p2, p3); - - ret = tcore_at_prepare_and_send_request(co, - at_cmd, "+CRSM:", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - __on_response_atmodem_sim_read_data, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Record"); - - dbg("ret:[%d]", ret); - g_free(at_cmd); - - dbg("Exit"); -} - -static void __atmodem_sim_read_binary(CoreObject *co, AtmodemRespCbData *resp_cb_data) -{ - gchar *at_cmd = NULL; - int p1 = 0; - int p2 = 0; - int p3 = 0; - int offset = 0; - AtmodemSimMetaInfo *file_meta = (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - TelReturn ret = TEL_RETURN_FAILURE; - - dbg("Entry File-id:[0x%02x]", file_meta->file_id); - - /* - * According to TS 102 221, values of P1, P2, P3 can be as below: - * 11.1.3 READ BINARY - * P1: See table 11.10 - * P2: Offset low - * Lc: Not present - * Data: Not present - * Le: Number of bytes to be read (P3) - */ - p1 = (unsigned char) (offset & 0xFF00) >> 8; - p2 = (unsigned char) offset & 0x00FF; /* offset low */ - p3 = (unsigned char) file_meta->data_size; - - if (file_meta->file_id == TEL_SIM_EF_SPDI) - at_cmd = g_strdup_printf("AT+CRSM=%d, %d", - ATMODEM_SIM_ACCESS_READ_BINARY, file_meta->file_id); - else - at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d", - ATMODEM_SIM_ACCESS_READ_BINARY, file_meta->file_id, p1, p2, p3); - - ret = tcore_at_prepare_and_send_request(co, at_cmd, "+CRSM:", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - __on_response_atmodem_sim_read_data, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Data"); - - dbg("ret:[%d]", ret); - g_free(at_cmd); - - dbg("Exit"); -} - -static TelReturn __atmodem_sim_get_response(CoreObject *co, AtmodemRespCbData *resp_cb_data) -{ - gchar *at_cmd = NULL; - AtmodemSimMetaInfo *file_meta = - (AtmodemSimMetaInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - TelReturn ret = TEL_RETURN_FAILURE; - - dbg("Entry File-id:[0x%02x]", file_meta->file_id); - - at_cmd = g_strdup_printf("AT+CRSM=%d, %d", - ATMODEM_SIM_ACCESS_GET_RESPONSE, file_meta->file_id); - - ret = tcore_at_prepare_and_send_request(co, - at_cmd, "+CRSM:", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - __on_response_atmodem_sim_get_response, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Info"); - - g_free(at_cmd); - dbg("Exit"); - return ret; -} - -static int __atmodem_sim_get_lock_type(AtmodemSimCurrSecOp sec_op) -{ - switch(sec_op) { - case ATMODEM_SIM_CURR_SEC_OP_SIM_DISABLE : - case ATMODEM_SIM_CURR_SEC_OP_SIM_ENABLE : - case ATMODEM_SIM_CURR_SEC_OP_SIM_STATUS : - return TEL_SIM_LOCK_PS; - case ATMODEM_SIM_CURR_SEC_OP_PIN1_DISABLE : - case ATMODEM_SIM_CURR_SEC_OP_PIN1_ENABLE : - case ATMODEM_SIM_CURR_SEC_OP_PIN1_STATUS : - return TEL_SIM_LOCK_SC; - case ATMODEM_SIM_CURR_SEC_OP_FDN_DISABLE : - case ATMODEM_SIM_CURR_SEC_OP_FDN_ENABLE : - case ATMODEM_SIM_CURR_SEC_OP_FDN_STATUS : - return TEL_SIM_LOCK_FD; - case ATMODEM_SIM_CURR_SEC_OP_NET_DISABLE : - case ATMODEM_SIM_CURR_SEC_OP_NET_ENABLE : - case ATMODEM_SIM_CURR_SEC_OP_NET_STATUS : - return TEL_SIM_LOCK_PN; - case ATMODEM_SIM_CURR_SEC_OP_NS_DISABLE : - case ATMODEM_SIM_CURR_SEC_OP_NS_ENABLE : - case ATMODEM_SIM_CURR_SEC_OP_NS_STATUS : - return TEL_SIM_LOCK_PU; - case ATMODEM_SIM_CURR_SEC_OP_SP_DISABLE : - case ATMODEM_SIM_CURR_SEC_OP_SP_ENABLE : - case ATMODEM_SIM_CURR_SEC_OP_SP_STATUS : - return TEL_SIM_LOCK_PP; - case ATMODEM_SIM_CURR_SEC_OP_CP_DISABLE : - case ATMODEM_SIM_CURR_SEC_OP_CP_ENABLE : - case ATMODEM_SIM_CURR_SEC_OP_CP_STATUS : - return TEL_SIM_LOCK_PC ; - default : - err("Invalid sec op [%d]", sec_op); - return -1; - } -} - -/* Notifications */ -/* - * Notification: +SCSIM: - * - * Possible values of can be - * 0 SIM not present - * 1 PIN verification needed - * 2 PIN verification not needed - Ready - * 3 PIN verified - Ready - * 4 PUK verification needed - * 5 SIM permanently blocked - * 6 SIM Error - * 7 ready for attach (+COPS) - * 8 SIM Technical Problem - * 9 SIM Removed - * 10 SIM Reactivating - * 11 SIM Reactivated - * 12 SIM SMS Caching Completed. (Sent only when SMS caching enabled) - * 99 SIM State Unknown - */ -static gboolean on_notification_atmodem_sim_status(CoreObject *co, - const void *event_info, void *user_data) -{ - GSList *lines = (GSList *)event_info; - const gchar *line = (const gchar *)lines->data; - TelSimCardStatus sim_status = TEL_SIM_STATUS_SIM_INITIALIZING; - AtmodemSimSecLockType locktype = SEC_LOCK_TYPE_NONE; - AtmodemSimSecLockKey lockkey = SEC_LOCK_KEY_NONE; - - if (__atmodem_convert_scpin_str_to_enum((char *)line, &locktype, &lockkey) == FALSE) - return TRUE; - - switch (locktype) { - case SEC_LOCK_TYPE_READY: - if (lockkey == SEC_LOCK_KEY_UNLOCKED) - sim_status = TEL_SIM_STATUS_SIM_INITIALIZING; - else - sim_status = TEL_SIM_STATUS_UNKNOWN; - break; - - case SEC_LOCK_TYPE_PS: - sim_status = TEL_SIM_STATUS_SIM_LOCK_REQUIRED; - break; - - case SEC_LOCK_TYPE_PF: - sim_status = TEL_SIM_STATUS_CARD_ERROR; - break; - - case SEC_LOCK_TYPE_SC: - switch (lockkey) { - case SEC_LOCK_KEY_UNLOCKED: - break; - - case SEC_LOCK_KEY_PIN: - sim_status = TEL_SIM_STATUS_SIM_PIN_REQUIRED; - break; - - case SEC_LOCK_KEY_PUK: - sim_status = TEL_SIM_STATUS_SIM_PUK_REQUIRED; - break; - - case SEC_LOCK_KEY_PERM_BLOCKED: - sim_status = TEL_SIM_STATUS_CARD_BLOCKED; - break; - - default: - err("Not handled SEC Lock key: [%d]", lockkey); - sim_status = TEL_SIM_STATUS_UNKNOWN; - break; - } - break; - - case SEC_LOCK_TYPE_FD: - break; - - case SEC_LOCK_TYPE_PN: - if (SEC_LOCK_KEY_PIN) - sim_status = TEL_SIM_STATUS_SIM_NCK_REQUIRED; - else - sim_status = TEL_SIM_STATUS_UNKNOWN; - break; - - case SEC_LOCK_TYPE_PU: - if (SEC_LOCK_KEY_PIN) - sim_status = TEL_SIM_STATUS_SIM_NSCK_REQUIRED; - else - sim_status = TEL_SIM_STATUS_UNKNOWN; - break; - - case SEC_LOCK_TYPE_PP: - if (SEC_LOCK_KEY_PIN) - sim_status = TEL_SIM_STATUS_SIM_SPCK_REQUIRED; - else - sim_status = TEL_SIM_STATUS_UNKNOWN; - break; - - case SEC_LOCK_TYPE_PC: - if (SEC_LOCK_KEY_PIN) - sim_status = TEL_SIM_STATUS_SIM_CCK_REQUIRED; - else - sim_status = TEL_SIM_STATUS_UNKNOWN; - break; - - case SEC_LOCK_TYPE_SC2: - case SEC_LOCK_TYPE_PUK2: - break; - - case SEC_LOCK_TYPE_NO_SIM: - sim_status = TEL_SIM_STATUS_CARD_NOT_PRESENT; - break; - - case SEC_LOCK_TYPE_UNAVAIL: - case SEC_SIM_INIT_CRASH: - sim_status = TEL_SIM_STATUS_CARD_ERROR; - break; - - case SEC_SIM_INIT_COMPLETED: - sim_status = TEL_SIM_STATUS_SIM_INIT_COMPLETED; - break; - - case SEC_PB_INIT_COMPLETED: - break; - - default: - err("Not handled SEC lock type: [%d]", locktype); - sim_status = TEL_SIM_STATUS_UNKNOWN; - break; - } - - __atmodem_sim_process_sim_status(co, sim_status); - - return TRUE; -} - -/* Response Functions */ -static void on_response_atmodem_sim_verify_pins(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - AtmodemRespCbData *resp_cb_data = user_data; - CoreObject *co_sim = tcore_pending_ref_core_object(p); - TelSimResult result = TEL_SIM_RESULT_FAILURE; - AtmodemSimCurrSecOp *sec_op = NULL; - TelSimSecPinResult verify_pin_resp = {0, }; - - dbg("Entry"); - - tcore_check_return_assert(co_sim != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - sec_op = (AtmodemSimCurrSecOp *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - if (*sec_op == ATMODEM_SIM_CURR_SEC_OP_PIN1_VERIFY) { - TelSimCardStatus status; - - verify_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1; - - tcore_sim_get_status(co_sim, &status); - if (status != TEL_SIM_STATUS_SIM_INIT_COMPLETED) { - /*Update sim status*/ - __atmodem_sim_update_sim_status(co_sim, - TEL_SIM_STATUS_SIM_INITIALIZING); - } - } else if (*sec_op == ATMODEM_SIM_CURR_SEC_OP_PIN2_VERIFY) { - verify_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN2; - } - - if (at_resp && at_resp->success) { - dbg("SIM Verify Pin Response- [OK]"); - result = TEL_SIM_RESULT_SUCCESS; - - } else { - err("SIM Verify Pin Response- [NOK]"); - - /* Update retry count */ - verify_pin_resp.retry_count = 3; - } - - /*Invoke callback*/ - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)result, - &verify_pin_resp, resp_cb_data->cb_data); - - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -static void on_response_atmodem_sim_verify_puks(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - AtmodemRespCbData *resp_cb_data = user_data; - CoreObject *co_sim = tcore_pending_ref_core_object(p); - TelSimResult result = TEL_SIM_RESULT_FAILURE; - AtmodemSimCurrSecOp *sec_op = NULL; - TelSimSecPukResult verify_puk_resp = {0, }; - - dbg("Entry"); - - tcore_check_return_assert(co_sim != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - sec_op = (AtmodemSimCurrSecOp *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - if (*sec_op == ATMODEM_SIM_CURR_SEC_OP_PUK1_VERIFY) { - verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK1; - } else if (*sec_op == ATMODEM_SIM_CURR_SEC_OP_PUK2_VERIFY) { - verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK2; - } - if (at_resp && at_resp->success) { - dbg("SIM Verify Puk Response- [OK]"); - result = TEL_SIM_RESULT_SUCCESS; - } else { - err("SIM Verify Puk Response- [NOK]"); - - /* Update retry count */ - verify_puk_resp.retry_count = 3; - } - - /*Invoke callback*/ - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)result, - &verify_puk_resp, - resp_cb_data->cb_data); - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -static void on_response_atmodem_sim_change_pins(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - AtmodemRespCbData *resp_cb_data = user_data; - CoreObject *co_sim = tcore_pending_ref_core_object(p); - TelSimResult result = TEL_SIM_RESULT_FAILURE; - AtmodemSimCurrSecOp *sec_op = NULL; - TelSimSecPinResult change_pin_resp = {0, }; - - dbg("Entry"); - - tcore_check_return_assert(co_sim != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - sec_op = (AtmodemSimCurrSecOp *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - if (at_resp && at_resp->success) { - dbg("SIM Change Pin Response- [OK]"); - - result = TEL_SIM_RESULT_SUCCESS; - - if (*sec_op == ATMODEM_SIM_CURR_SEC_OP_PIN1_CHANGE) { - change_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1; - } else if (*sec_op == ATMODEM_SIM_CURR_SEC_OP_PIN2_CHANGE) { - change_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN2; - } - - /*Invoke callback*/ - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)result, - &change_pin_resp, resp_cb_data->cb_data); - } - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -static void on_response_atmodem_sim_disable_facility(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - AtmodemRespCbData *resp_cb_data = user_data; - CoreObject *co_sim = tcore_pending_ref_core_object(p); - TelSimResult result = TEL_SIM_RESULT_FAILURE; - AtmodemSimCurrSecOp *sec_op = NULL; - TelSimFacilityResult disable_facility_resp = {0, }; - - dbg("Entry"); - - tcore_check_return_assert(co_sim != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - sec_op = (AtmodemSimCurrSecOp *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - if (at_resp && at_resp->success) { - int lock_type; - dbg("SIM Disable Facility Response- [OK]"); - - lock_type = __atmodem_sim_get_lock_type(*sec_op); - if (lock_type == -1) { - result = TEL_SIM_RESULT_INVALID_PARAMETER; - - /*Invoke callback*/ - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)result, - NULL, resp_cb_data->cb_data); - atmodem_destroy_resp_cb_data(resp_cb_data); - return; - } - - disable_facility_resp.type = lock_type; - result = TEL_SIM_RESULT_SUCCESS; - - /*Invoke callback*/ - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)result, - &disable_facility_resp, resp_cb_data->cb_data); - } - - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -static void on_response_atmodem_sim_enable_facility(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - AtmodemRespCbData *resp_cb_data = user_data; - CoreObject *co_sim = tcore_pending_ref_core_object(p); - TelSimResult result = TEL_SIM_RESULT_FAILURE; - AtmodemSimCurrSecOp *sec_op = NULL; - TelSimFacilityResult enable_facility_resp = {0, }; - - dbg("Entry"); - - tcore_check_return_assert(co_sim != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - sec_op = (AtmodemSimCurrSecOp *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - if (at_resp && at_resp->success) { - int lock_type; - dbg("SIM Enable Facility Response- [OK]"); - - lock_type = __atmodem_sim_get_lock_type(*sec_op); - if (lock_type == -1) { - result = TEL_SIM_RESULT_INVALID_PARAMETER; - - /*Invoke callback*/ - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)result, - NULL, resp_cb_data->cb_data); - atmodem_destroy_resp_cb_data(resp_cb_data); - return; - } - - enable_facility_resp.type = lock_type; - result = TEL_SIM_RESULT_SUCCESS; - - /*Invoke callback*/ - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)result, - &enable_facility_resp, - resp_cb_data->cb_data); - } - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -static void on_response_atmodem_sim_get_facility(TcorePending *p, guint data_len, - const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - AtmodemRespCbData *resp_cb_data = user_data; - CoreObject *co_sim = tcore_pending_ref_core_object(p); - TelSimResult result = TEL_SIM_RESULT_FAILURE; - AtmodemSimCurrSecOp *sec_op = NULL; - TelSimFacilityInfo get_facility_resp = {0, }; - - dbg("Entry"); - - tcore_check_return_assert(co_sim != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - sec_op = (AtmodemSimCurrSecOp *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - if (at_resp && at_resp->success) { - GSList *tokens = NULL; - const char *line; - int lock_type; - - dbg("SIM Get Facility Response- [OK]"); - - lock_type = __atmodem_sim_get_lock_type(*sec_op); - if (lock_type == -1) { - result = TEL_SIM_RESULT_INVALID_PARAMETER; - goto out; - } - if (at_resp->lines) { - line = (const char *)at_resp->lines->data; - tokens = tcore_at_tok_new(line); - if (g_slist_length(tokens) != 1) { - err("Invalid message"); - tcore_at_tok_free(tokens); - goto out; - } - get_facility_resp.f_status = atoi(g_slist_nth_data(tokens, 0)); - get_facility_resp.type = lock_type; - result = TEL_SIM_RESULT_SUCCESS; - } - - tcore_at_tok_free(tokens); - } else { - err("SIM Get Facility Response- [NOK]"); - } -out: - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co_sim, (gint)result, &get_facility_resp, resp_cb_data->cb_data); - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -/* SIM Operations */ -/* - * Operation - get_imsi - * - * Request - - * AT-Command: AT+CRSM= [,[,,,[,[,]]]] - * where, - * - * 176 READ BINARY - * 178 READ RECORD - * 192 GET RESPONSE - * 214 UPDATE BINARY - * 220 UPDATE RECORD - * 242 STATUS - * - * - * 28423 meaning IMSI file (6F07) - * 28473 meaning ACM file (6F39) - * 28481 meaning PUKT file (6F41) - * 28482 meaning SMS file (6F42) - * - * , , - * Integer type defining the request. - * These parameters are mandatory for every command, except GET RESPONSE and STATUS. - * - * - * Information which shall be written to the SIM - * - * - * String type, contains the path of an elementary file on the SIM/USIM in hexadecimal format - * - * - * 0 not active - * 1 active - * - * Success: - * OK - * +CRSM: ,[,] - * - * , - * Integer type containing the SIM information - * - * - * Response of successful completion of the command previously issued - * - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_sim_get_imsi (CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - AtmodemSimMetaInfo file_meta = {0, }; - AtmodemRespCbData *resp_cb_data = NULL; - - dbg("Entry"); - - file_meta.file_id = TEL_SIM_EF_IMSI; - file_meta.file_result = TEL_SIM_RESULT_FAILURE; - file_meta.req_command = TCORE_COMMAND_SIM_GET_IMSI; - - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - &file_meta, sizeof(AtmodemSimMetaInfo)); - - return __atmodem_sim_get_file_info(co, resp_cb_data); -} - -static TelReturn atmodem_sim_get_ecc (CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - AtmodemSimMetaInfo file_meta = {0, }; - AtmodemRespCbData *resp_cb_data = NULL; - - dbg("Entry"); - - file_meta.file_id = TEL_SIM_EF_ECC; - file_meta.file_result = TEL_SIM_RESULT_FAILURE; - file_meta.req_command = TCORE_COMMAND_SIM_GET_ECC; - - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - &file_meta, sizeof(AtmodemSimMetaInfo)); - - return __atmodem_sim_get_file_info(co, resp_cb_data); -} - -static TelReturn atmodem_sim_get_spdi (CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - AtmodemSimMetaInfo file_meta = {0, }; - AtmodemRespCbData *resp_cb_data = NULL; - - dbg("Entry"); - - file_meta.file_id = TEL_SIM_EF_SPDI; - file_meta.file_result = TEL_SIM_RESULT_FAILURE; - file_meta.req_command = TCORE_COMMAND_SIM_GET_SP_DISPLAY_INFO; - - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - &file_meta, sizeof(AtmodemSimMetaInfo)); - - return __atmodem_sim_get_file_info(co, resp_cb_data); -} - -static TelReturn atmodem_sim_get_cfis (CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - AtmodemSimMetaInfo file_meta = {0, }; - AtmodemRespCbData *resp_cb_data = NULL; - - dbg("Entry"); - - file_meta.file_id = TEL_SIM_EF_USIM_CFIS; - file_meta.file_result = TEL_SIM_RESULT_FAILURE; - file_meta.req_command = TCORE_COMMAND_SIM_GET_CALL_FORWARDING_INFO; - - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - &file_meta, sizeof(AtmodemSimMetaInfo)); - - return __atmodem_sim_get_file_info(co, resp_cb_data); -} - -static TelReturn atmodem_sim_get_spn (CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - AtmodemSimMetaInfo file_meta = {0, }; - AtmodemRespCbData *resp_cb_data = NULL; - - dbg("Entry"); - - file_meta.file_id = TEL_SIM_EF_SPN; - file_meta.file_result = TEL_SIM_RESULT_FAILURE; - file_meta.req_command = TCORE_COMMAND_SIM_GET_SPN; - - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - &file_meta, sizeof(AtmodemSimMetaInfo)); - - return __atmodem_sim_get_file_info(co, resp_cb_data); -} - -static TelReturn atmodem_sim_get_language (CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - AtmodemSimMetaInfo file_meta = {0, }; - AtmodemRespCbData *resp_cb_data = NULL; - - dbg("Entry"); - - file_meta.file_id = TEL_SIM_EF_LP; - file_meta.file_result = TEL_SIM_RESULT_FAILURE; - file_meta.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE; - - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - &file_meta, sizeof(AtmodemSimMetaInfo)); - - return __atmodem_sim_get_file_info(co, resp_cb_data); -} - -/* - * Operation - verify_pins/verify_puks/change_pins - * - * Request - - * For SIM PIN - * AT-Command: AT+CPIN= [, ] - * where, - * , - * String type values - * - * For SIM PIN2 - * AT-Command: AT+CPIN2= [, ]andAT+CPIN2= - * where, - * , - * String type values - * - * Success: - * OK - * - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_sim_verify_pins(CoreObject *co, - const TelSimSecPinPw *request, - TcoreObjectResponseCallback cb, void *cb_data) -{ - TelReturn ret = TEL_RETURN_FAILURE; - AtmodemRespCbData *resp_cb_data = NULL; - AtmodemSimCurrSecOp sec_op; - gchar *cmd_str = NULL; - - dbg("Entry"); - - if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) { - sec_op = ATMODEM_SIM_CURR_SEC_OP_PIN1_VERIFY; - } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) { - sec_op = ATMODEM_SIM_CURR_SEC_OP_PIN2_VERIFY; - } else { - err("Invalid pin type [%d]", request->pin_type); - return TEL_RETURN_INVALID_PARAMETER; - } - - cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", request->pw); - - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - &sec_op, sizeof(sec_op)); - - ret = tcore_at_prepare_and_send_request(co, - cmd_str, NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - on_response_atmodem_sim_verify_pins, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "SIM Verify PIN"); - - g_free(cmd_str); - return ret; -} - -static TelReturn atmodem_sim_verify_puks(CoreObject *co, - const TelSimSecPukPw *request, - TcoreObjectResponseCallback cb, void *cb_data) -{ - TelReturn ret = TEL_RETURN_FAILURE; - AtmodemRespCbData *resp_cb_data = NULL; - AtmodemSimCurrSecOp sec_op; - gchar *cmd_str = NULL; - - dbg("Entry"); - - if (request->puk_type == TEL_SIM_PUK_TYPE_PUK1) { - sec_op = ATMODEM_SIM_CURR_SEC_OP_PUK1_VERIFY; - } else if (request->puk_type == TEL_SIM_PUK_TYPE_PUK2) { - sec_op = ATMODEM_SIM_CURR_SEC_OP_PUK2_VERIFY; - } else { - err("Invalid puk type [%d]", request->puk_type); - return TEL_RETURN_INVALID_PARAMETER; - } - - cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", - request->puk_pw, request->new_pin_pw); - - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - &sec_op, sizeof(sec_op)); - - ret = tcore_at_prepare_and_send_request(co, - cmd_str, NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - on_response_atmodem_sim_verify_puks, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "SIM Verify PUK"); - - g_free(cmd_str); - return ret; -} - -static TelReturn atmodem_sim_change_pins(CoreObject *co, - const TelSimSecChangePinPw *request, - TcoreObjectResponseCallback cb, void *cb_data) -{ - TelReturn ret = TEL_RETURN_FAILURE; - AtmodemRespCbData *resp_cb_data = NULL; - AtmodemSimCurrSecOp sec_op; - gchar *cmd_str = NULL; - - dbg("Entry"); - - if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) { - sec_op = ATMODEM_SIM_CURR_SEC_OP_PIN1_CHANGE; - } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) { - sec_op = ATMODEM_SIM_CURR_SEC_OP_PIN2_CHANGE; - } else { - err("Invalid pin type [%d]", request->pin_type); - return TEL_RETURN_INVALID_PARAMETER; - } - - cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", request->old_pw, request->new_pw); - - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - &sec_op, sizeof(sec_op)); - - ret = tcore_at_prepare_and_send_request(co, - cmd_str, NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - on_response_atmodem_sim_change_pins, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "SIM Change PIN"); - - g_free(cmd_str); - return ret; -} - -/* - * Operation - disable_facility/enable_facility/get_facility - * - * Request - - * AT-Command: AT+CLCK = , [, [, ]] - * where, - * - * SIM facility - * - * - * 0 unlock - * 1 lock - * 2 query status - * - * - * Password string - * - * - * 0 not active - * 1 active - * - * Success: when =2: - * OK - * +CLCK: [, [ - * +CLCK: , [...]] - * - * Failure: - */ -static TelReturn atmodem_sim_disable_facility(CoreObject *co, - const TelSimFacilityPw *request, - TcoreObjectResponseCallback cb, void *cb_data) -{ - TelReturn ret = TEL_RETURN_FAILURE; - AtmodemRespCbData *resp_cb_data = NULL; - AtmodemSimCurrSecOp sec_op; - gchar *cmd_str = NULL; - char *fac = "SC"; - int mode = 0; /*mode = 0 for disable lock*/ - - dbg("Entry"); - - fac = __atmodem_sim_get_fac_from_lock_type(request->lock_type, - &sec_op, DISABLE_FLAG); - if (!fac) - return TEL_RETURN_INVALID_PARAMETER; - - cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", - fac, mode, request->pw); - - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - &sec_op, sizeof(sec_op)); - - ret = tcore_at_prepare_and_send_request(co, - cmd_str, "+CLCK:", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - on_response_atmodem_sim_disable_facility, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "SIM Disable Facility"); - - g_free(cmd_str); - return ret; -} - -static TelReturn atmodem_sim_enable_facility(CoreObject *co, - const TelSimFacilityPw *request, - TcoreObjectResponseCallback cb, void *cb_data) -{ - TelReturn ret = TEL_RETURN_FAILURE; - AtmodemRespCbData *resp_cb_data = NULL; - AtmodemSimCurrSecOp sec_op; - gchar *cmd_str = NULL; - char *fac = "SC"; - int mode = 1; /*mode = 1 for enable lock*/ - - dbg("Entry"); - - fac = __atmodem_sim_get_fac_from_lock_type(request->lock_type, - &sec_op, ENABLE_FLAG); - if (!fac) - return TEL_RETURN_INVALID_PARAMETER; - - cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", - fac, mode, request->pw); - - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - &sec_op, sizeof(sec_op)); - - ret = tcore_at_prepare_and_send_request(co, - cmd_str, "+CLCK:", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - on_response_atmodem_sim_enable_facility, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "SIM Disable Facility"); - - g_free(cmd_str); - return ret; -} - -static TelReturn atmodem_sim_get_facility(CoreObject *co, - TelSimLockType lock_type, - TcoreObjectResponseCallback cb, void *cb_data) -{ - TelReturn ret = TEL_RETURN_FAILURE; - AtmodemRespCbData *resp_cb_data = NULL; - AtmodemSimCurrSecOp sec_op; - gchar *cmd_str = NULL; - char *fac = "SC"; - int mode = 2; /*mode = 2 for Get Facility*/ - - dbg("Entry"); - - fac = __atmodem_sim_get_fac_from_lock_type(lock_type, - &sec_op, 0); - if (!fac) - return TEL_RETURN_INVALID_PARAMETER; - - cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode); - - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - &sec_op, sizeof(sec_op)); - - ret = tcore_at_prepare_and_send_request(co, - cmd_str, "+CLCK:", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - on_response_atmodem_sim_get_facility, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "SIM Get Facility"); - - g_free(cmd_str); - return ret; -} - -/* SIM Operations */ -static TcoreSimOps atmodem_sim_ops = { - .get_imsi = atmodem_sim_get_imsi, - .get_ecc = atmodem_sim_get_ecc, - .get_iccid = NULL, - .get_language = atmodem_sim_get_language, - .set_language = NULL, - .get_callforwarding_info = atmodem_sim_get_cfis, - .get_messagewaiting_info = NULL, - .set_messagewaiting_info = NULL, - .get_mailbox_info = NULL, - .set_mailbox_info = NULL, - .get_msisdn = NULL, - .get_spn = atmodem_sim_get_spn, - .get_cphs_netname = NULL, - .get_sp_display_info = atmodem_sim_get_spdi, - .req_authentication = NULL, - .verify_pins = atmodem_sim_verify_pins, - .verify_puks = atmodem_sim_verify_puks, - .change_pins = atmodem_sim_change_pins, - .disable_facility = atmodem_sim_disable_facility, - .enable_facility = atmodem_sim_enable_facility, - .get_facility = atmodem_sim_get_facility, - .get_lock_info = NULL, - .req_apdu = NULL, - .req_atr = NULL -}; - -gboolean atmodem_sim_init(TcorePlugin *p, CoreObject *co_sim) -{ - dbg("Entry"); - - /* Set operations */ - tcore_sim_set_ops(co_sim, &atmodem_sim_ops); - - /* Add Callbacks */ - tcore_object_add_callback(co_sim, "\%SCSIM:", - on_notification_atmodem_sim_status, NULL); - - dbg("Exit"); - return TRUE; -} - -void atmodem_sim_exit(TcorePlugin *plugin, CoreObject *co_sim) -{ - dbg("Entry"); -} diff --git a/src/atmodem_sms.c b/src/atmodem_sms.c deleted file mode 100755 index 3908554..0000000 --- a/src/atmodem_sms.c +++ /dev/null @@ -1,781 +0,0 @@ -/* - * tel-plugin-atmodem - * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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 -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "atmodem_sms.h" -#include "atmodem_common.h" - -#define CR '\r' -#define CTRL_Z '\x1A' - -#define AT_MT_UNREAD 0 /* Received and Unread */ -#define AT_MT_READ 1 /* Received and Read */ -#define AT_MO_UNSENT 2 /* Unsent */ -#define AT_MO_SENT 3 /* Sent */ -#define AT_ALL 4 /* Unknown */ - -#define ATMODEM_NUM_PLAN_ID(sca) (gchar)(sca & 0x0F) -#define ATMODEM_TYPE_OF_NUM(sca) (gchar)((sca & 0x70) >> 4) - -/* SCA 12 bytes long and TDPU is 164 bytes long */ -#define PDU_LEN_MAX 176 -#define HEX_PDU_LEN_MAX ((PDU_LEN_MAX * 2) + 1) - -#define ATMODEM_SIM_TON_INTERNATIONAL 1 -#define ATMODEM_SIM_TON_NATIONAL 2 - -/* - * Notification - SMS-DELIVER - * +CMT = [], (PDU mode enabled) - * - * where, - * alpha_id - * length of the PDU - * Incomming SMS PDU - * - * Notification - SMS-STATUS-REPORT - * +CDS: (PDU mode enabled) - * - * where, - * length of the PDU - * Incomming SMS PDU - * - */ -static gboolean on_notification_atmodem_sms_incoming_msg(CoreObject *co, - const void *event_info, void *user_data) -{ - GSList *tokens = NULL; - GSList *lines = NULL; - char *line = NULL; - int pdu_len = 0, no_of_tokens = 0; - gchar *byte_pdu = NULL; - guint buf_len = 0; - - TelSmsDatapackageInfo incoming_msg = {{0}, }; - int sca_length = 0; - dbg("Enter"); - - lines = (GSList *)event_info; - if (2 != g_slist_length(lines)) { - err("Invalid number of lines for +CMT. Must be 2"); - return TRUE; - } - line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */ - if (!line) { - err("Line 1 is invalid"); - return TRUE; - } - dbg("Line 1: [%s]", line); - tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */ - no_of_tokens = g_slist_length(tokens); - - /* - * Incoming SMS: +CMT - * Number of tokens: 2 - * - * Incoming SMS-STATUS-REPORT: +CDS - * Number of tokens: 1 - */ - if (2 == no_of_tokens) { - /* Token 0: Alpha ID */ - dbg("Alpha ID: [0x%x]", g_slist_nth_data(tokens, 0)); - - /* Token 1: PDU Length */ - pdu_len = atoi((char *)g_slist_nth_data(tokens, 1)); - dbg("pdu_len: [%d]", pdu_len); - } else if (1 == no_of_tokens) { - /* 0: PDU Length */ - pdu_len = atoi((char *)g_slist_nth_data(tokens, 0)); - dbg("pdu_len: [%d]", pdu_len); - } - - /* Fetch Line 2 */ - line = (char *)g_slist_nth_data(lines, 1); - if (!line) { - err("Line 2 is invalid"); - tcore_at_tok_free(tokens); - return TRUE; - } - dbg("Line 2: [%s]", line); - - /* Convert to Bytes */ - tcore_util_hexstring_to_bytes(line, &byte_pdu, &buf_len); - - sca_length = byte_pdu[0]; - dbg("SCA length = %d", sca_length); - - if (sca_length) { - gchar *decoded_sca; - guint encoded_sca_len; - /* - * byte_pdu[1] - sca_address_type - * Excluding sca_address_type and copy SCA - */ - encoded_sca_len = sca_length - 1; - decoded_sca = - tcore_util_convert_bcd_to_ascii(&byte_pdu[2], encoded_sca_len, encoded_sca_len*2); - dbg("Decoded SCA: [%s]", decoded_sca); - g_strlcpy(incoming_msg.sca.number, decoded_sca, strlen(decoded_sca)+1); - tcore_free(decoded_sca); - - /*SCA Conversion for Address type*/ - incoming_msg.sca.ton = ATMODEM_TYPE_OF_NUM(byte_pdu[1]); - incoming_msg.sca.npi = ATMODEM_NUM_PLAN_ID(byte_pdu[1]); - dbg("TON: [%d] NPI: [%d] SCA: [%s]", - incoming_msg.sca.ton, incoming_msg.sca.npi, - incoming_msg.sca.number); - } - else { - dbg("NO SCA Present"); - } - - - /* TPDU */ - incoming_msg.tpdu_length = pdu_len; - memcpy(incoming_msg.tpdu, - &byte_pdu[sca_length+1], incoming_msg.tpdu_length); - - /* Send notification */ - tcore_object_send_notification(co, - TCORE_NOTIFICATION_SMS_INCOM_MSG, - sizeof(TelSmsDatapackageInfo), &incoming_msg); - - tcore_at_tok_free(tokens); - g_free(byte_pdu); - - return TRUE; -} - -static gboolean on_notification_atmodem_sms_device_ready(CoreObject *co, - const void *event_info, void *user_data) -{ - gboolean sms_status = TRUE; - - dbg("SMS notification - [Device Ready]"); - - /* Set Device Ready */ - tcore_sms_set_ready_status(co, sms_status); - - /* Send notification: SMS Device ready */ - tcore_object_send_notification(co, - TCORE_NOTIFICATION_SMS_DEVICE_READY, - sizeof(sms_status), &sms_status); - - return TRUE; -} - -static void on_response_atmodem_sms_send_more_msg(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - - dbg("Enter"); - - if (at_resp && at_resp->success) - dbg("Response OK for AT+CMMS: More msgs to send!!"); - else - err("Response NOK for AT+CMMS: More msgs to send"); - - /* Need not send any response */ -} - -static void on_response_atmodem_sms_send_sms(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - - TelSmsResult result = TEL_SMS_RESULT_FAILURE;/*TODO: CMS error mapping required */ - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp && at_resp->success) { - dbg("Response OK"); - if (at_resp->lines) { - const gchar *line; - gchar* line_token; - GSList *tokens = NULL; - gint msg_ref = 0; - - line = (const gchar *)at_resp->lines->data; - tokens = tcore_at_tok_new(line); - line_token = g_slist_nth_data(tokens, 0); - if (line_token != NULL) { - /*Response from MODEM for send SMS: +CMGS: [,]*/ - /*Message Reference is not used by MSG_SERVER and application.So Filling only result*/ - msg_ref = atoi(line_token); - - dbg("Message Reference: [%d]", msg_ref); - - result = TEL_SMS_RESULT_SUCCESS; - } else { - dbg("No Message Reference received"); - } - tcore_at_tok_free(tokens); - } - } else { - err("Response NOK"); - } - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data); - - /* Free callback data */ - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -static void on_response_atmodem_sms_get_count(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - TelSmsStoredMsgCountInfo count_info = {0, }; - - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - - GSList *tokens = NULL; - TelSmsResult result = TEL_SMS_RESULT_FAILURE; - - dbg("Enter"); - - if (at_resp && at_resp->success) { - dbg("RESPONSE OK"); - if (at_resp->lines) { - char *line = NULL, *line_token = NULL; - - line = (char *)at_resp->lines->data; - dbg("line: [%s]",line); - - /* - * Tokenize - * - * +CPMS: , , , , , - */ - tokens = tcore_at_tok_new(line); - - /* */ - line_token = g_slist_nth_data(tokens, 0); - if (line_token == NULL) { - err("Line Token for used count is NULL"); - goto ERROR; - } - count_info.used_count = atoi(line_token); - - /* */ - line_token = g_slist_nth_data(tokens, 1); - if (line_token == NULL) { - err("Line Token for Total count is NULL"); - goto ERROR; - } - count_info.total_count = atoi(line_token); - - dbg("Count - used: [%d] total: [%d]", - count_info.used_count, count_info.total_count); - result = TEL_SMS_RESULT_SUCCESS; - } - else { - err("Invalid Response Received: NO Lines Present"); - } - } - else { - err("RESPONSE NOK"); - } - -ERROR: - /* Invoke callback in case of error*/ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, &count_info, resp_cb_data->cb_data); - - /* Free callback data */ - atmodem_destroy_resp_cb_data(resp_cb_data); - - tcore_at_tok_free(tokens); -} - -static void on_response_atmodem_sms_send_deliver_report(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - - TelSmsResult result = TEL_SMS_RESULT_FAILURE; // TODO: CMEE error mapping is required - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp && at_resp->success) - result = TEL_SMS_RESULT_SUCCESS; - - dbg("Send Deliver Report: [%s]", - (result == TEL_SMS_RESULT_SUCCESS ? "SUCCESS" : "FAIL")); - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data); - - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -static void on_response_atmodem_sms_set_sca(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - - TelSmsResult result = TEL_SMS_RESULT_FAILURE; - dbg("Enter"); - - if (at_resp && at_resp->success) { - dbg("Response OK"); - result = TEL_SMS_RESULT_SUCCESS; - } else { - err("Response NOK"); - } - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data); - - /* Free callback data */ - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -static void on_response_atmodem_sms_get_sca(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - - TelSmsSca sca_resp = { 0, }; - TelSmsResult result = TEL_SMS_RESULT_FAILURE; - dbg("Enter"); - - if (at_resp && at_resp->success) { - dbg("Response OK"); - if (at_resp->lines) { - GSList *tokens = NULL; - const char *sca_tok_addr; - gchar *line = NULL, *sca_addr = NULL, *sca_toa = NULL; - - line = (char *)at_resp->lines->data; - tokens = tcore_at_tok_new(line); - sca_tok_addr = g_slist_nth_data(tokens, 0); - sca_toa = g_slist_nth_data(tokens, 1); - - sca_addr = tcore_at_tok_extract(sca_tok_addr); - dbg("SCA: [%s] SCA-TOA: [%s]", sca_addr, sca_toa); - if ((NULL != sca_addr) && (NULL != sca_toa)) { - gchar *sca; - guint sca_len = 0; - tcore_util_hexstring_to_bytes(sca_addr, &sca, &sca_len); /*TODO : Check*/ - memcpy(sca_resp.number, sca, sca_len); - g_free(sca); - - /* Type-of-Address */ - if (145 == atoi(sca_toa)) { - sca_resp.ton = ATMODEM_SIM_TON_INTERNATIONAL; - } else { - sca_resp.ton = ATMODEM_SIM_TON_NATIONAL; - } - sca_resp.npi = 0;/* TODO */ - result = TEL_SMS_RESULT_SUCCESS; - } else { - err("SCA is NULL"); - } - tcore_at_tok_free(tokens); - g_free(sca_addr); - } else { - err("Invalid Response.No Lines Received"); - } - } else { - err("Response NOK"); - } - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, &sca_resp, resp_cb_data->cb_data); - - /* Free callback data */ - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -/* SMS Operations */ -/* - * Operation - send_sms - * - * Request - - * AT-Command: AT+CMGS - * For PDU mode (+CMGF=0): - * +CMGS= - * PDU is given - * where, - * Length of the pdu. - * PDU to send. - * - * Response - - *+CMGS: [,] - * OK - * Failure: - * +CMS ERROR: - */ -static TelReturn atmodem_sms_send_sms(CoreObject *co, - const TelSmsSendInfo *send_info, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd; - TcorePending *pending; - TcoreAtRequest *at_req; - TcoreHal *hal; - TcoreAT *at; - TcoreQueue *queue; - TelReturn ret = TEL_RETURN_FAILURE; - AtmodemRespCbData *resp_cb_data; - - const unsigned char *tpdu_byte_data; - gint tpdu_byte_len, pdu_byte_len; - char buf[HEX_PDU_LEN_MAX]; - char pdu[PDU_LEN_MAX]; - - dbg("Enter"); - - /*get HAL*/ - hal = tcore_object_get_hal(co); - if (hal == NULL) { - err("HAL is NULL"); - return ret; - } - - tpdu_byte_data = send_info->send_data.tpdu; - - /* TPDU length is in byte */ - tpdu_byte_len = send_info->send_data.tpdu_length; - - /* Prepare PDU for hex encoding */ - pdu_byte_len = tcore_util_encode_pdu(&(send_info->send_data.sca), - tpdu_byte_data, tpdu_byte_len, pdu); - - tcore_util_encode_hex((unsigned char *) pdu, pdu_byte_len, buf); - - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0); - - /* - * More messages - * Use same Radio Resource Channel :More Messages to send - */ - if (send_info->more_msgs > 0) { - /* AT Command: More Msgs to Send */ - ret = tcore_at_prepare_and_send_request(co, - "AT+CMMS=1", "+CMMS:", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - on_response_atmodem_sms_send_more_msg, NULL, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, NULL, "More Msgs to Send"); - } - /* AT-Command : Send SMS */ - at_cmd = g_strdup_printf("AT+CMGS=%d\r%s%x", tpdu_byte_len, buf, 0x1A); - - /* Create AT-Command Request */ - at_req = tcore_at_request_new(at_cmd, "+CMGS:", TCORE_AT_COMMAND_TYPE_SINGLELINE); - if (at_req == NULL) { - err("Request is NULL"); - atmodem_destroy_resp_cb_data(resp_cb_data); - g_free(at_cmd); - return TEL_RETURN_FAILURE; - } - - /* Create Pending Request */ - pending = tcore_pending_new(co, 0); - if (pending == NULL) { - err("Pending is NULL"); - atmodem_destroy_resp_cb_data(resp_cb_data); - g_free(at_cmd); - return TEL_RETURN_FAILURE; - } - - tcore_pending_set_request_data(pending, 0, at_req); - tcore_pending_link_request(pending, NULL); - tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT); - tcore_pending_set_response_callback(pending, on_response_atmodem_sms_send_sms, resp_cb_data); - tcore_pending_set_send_callback(pending, on_send_atmodem_request, NULL); - tcore_pending_set_timeout_callback(pending, NULL, NULL); - - at = tcore_hal_get_at(hal); - tcore_at_set_request(at, at_req); - - queue = tcore_hal_ref_queue(hal); - tcore_queue_push(queue, pending); - - ret = tcore_hal_send_data(hal, strlen(at_cmd), at_cmd); - dbg("ret: [0x%x]", ret); - - /* Free resources */ - g_free(at_cmd); - - return ret; -} - -/* - * Operation - get_sms_count_in_sim - * - * Request - - * AT-Command: AT+CPMS - * +CPMS=[, [,]] - * where - * memory storage to read. - * - * Response - - * Success: (Single-line output) - * +CPMS: ,,,,,, - * ,, - * OK - * - * Failure: - * +CMS ERROR: - */ -static TelReturn atmodem_sms_get_count(CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd; - - AtmodemRespCbData *resp_cb_data; - TelReturn ret; - dbg("Enter"); - - /*AT Command*/ - at_cmd = g_strdup_printf("AT+CPMS=\"SM\""); - - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - at_cmd, "+CPMS", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - on_response_atmodem_sms_get_count, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SMS Count"); - - /* Free resources */ - g_free(at_cmd); - - return ret; -} - -/* - * Operation - send_deliver_report - * - * Request - - * Modem Takes care of sending the ACK to the network - * - * Response - - * Success: Default response always SUCCESS posted - * - */ -static TelReturn atmodem_sms_send_deliver_report(CoreObject *co, - const TelSmsDeliverReportInfo *dr_info, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd; - AtmodemRespCbData *resp_cb_data; - TelReturn ret; - dbg("Enter"); - - /*AT Command*/ - if(dr_info->report== TEL_SMS_DELIVERY_REPORT_SUCCESS) - at_cmd = g_strdup_printf("AT+CNMA=0%s", "\r"); - else - at_cmd = g_strdup_printf("AT+CNMA=2,3%s%x%s", "/n", 0x00ff00, ""); - - - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - at_cmd, NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - on_response_atmodem_sms_send_deliver_report, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Send deliver Report"); - - /* Free resources */ - g_free(at_cmd); - return ret; -} - -/* - * Operation - set SCA - * - * Request - - * AT-Command: AT+CSCA - * AT+CSCA=[,] - * where - * Service center number - * address type of SCA - * - * Response - - * Success: No result - * OK - * - * Failure: - * +CMS ERROR: - */ - static TelReturn atmodem_sms_set_sca(CoreObject *co, - const TelSmsSca *sca, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd; - - AtmodemRespCbData *resp_cb_data; - TelReturn ret; - gint address_type; - - address_type = ((sca->ton << 4) | sca->npi ) | 0x80; - - /* AT Command */ - at_cmd = g_strdup_printf("AT+CSCA=\"%s\",%d", sca->number, address_type); - - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - at_cmd, NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - on_response_atmodem_sms_set_sca, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Set SCA"); - - /* Free resources */ - g_free(at_cmd); - - return ret; -} - -/* - * Operation - get SCA - * - * Request - - * AT-Command: AT+CSCA? - * - * Response - - * Success: Single-Line - * +CSCA: , - * OK - * where - * Service center number - * address type of SCA - * - */ - static TelReturn atmodem_sms_get_sca(CoreObject *co, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd; - - AtmodemRespCbData *resp_cb_data; - TelReturn ret; - dbg("Enter"); - - /* AT Command */ - at_cmd = g_strdup_printf("AT+CSCA?"); - - /* Response callback data */ - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - at_cmd, "+CSCA", - TCORE_AT_COMMAND_TYPE_SINGLELINE, - NULL, - on_response_atmodem_sms_get_sca, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SCA"); - - /* Free resources */ - g_free(at_cmd); - - return ret; -} - -/* SMS Operations */ -static TcoreSmsOps atmodem_sms_ops = { - .send_sms = atmodem_sms_send_sms, - .read_in_sim = NULL, - .write_in_sim = NULL, - .delete_in_sim = NULL, - .get_count = atmodem_sms_get_count, - .set_cb_config = NULL, - .get_cb_config = NULL, - .get_parameters = NULL, /* TODO - After implemented in imc code */ - .set_parameters = NULL, /* TODO - After implemented in imc code */ - .send_deliver_report = atmodem_sms_send_deliver_report, - .set_sca = atmodem_sms_set_sca, - .get_sca = atmodem_sms_get_sca, - .set_memory_status = NULL, - .set_message_status = NULL -}; - -gboolean atmodem_sms_init(TcorePlugin *p, CoreObject *co) -{ - dbg("Entry"); - - /* Set operations */ - tcore_sms_set_ops(co, &atmodem_sms_ops); - - /* Add Callbacks */ - tcore_object_add_callback(co, - "\e+CMT:", - on_notification_atmodem_sms_incoming_msg, NULL); - tcore_object_add_callback(co, - "\%SCDEV", - on_notification_atmodem_sms_device_ready, NULL); - - dbg("Exit"); - return TRUE; -} - -void atmodem_sms_exit(TcorePlugin *p, CoreObject *co) -{ - dbg("Exit"); -} diff --git a/src/atmodem_ss.c b/src/atmodem_ss.c deleted file mode 100755 index b11aeb6..0000000 --- a/src/atmodem_ss.c +++ /dev/null @@ -1,1570 +0,0 @@ -/* - * tel-plugin-atmodem - * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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 -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "atmodem_ss.h" -#include "atmodem_common.h" - -/* AT+CUSD = [ [, [, ]]] - * where, - * - * 0 Disable - * 1 Enable - * 2 Cancel the session - * - * - * Ussd string - * - * - * Decoding format - */ -static gboolean on_notification_atmodem_ss_ussd(CoreObject *co, - const void *event_data, void *user_data) -{ - gchar *cmd; - gchar *resp_str = NULL; - guchar *dcs_str = NULL; - TelUtilAlphabetFormat dcs = TEL_UTIL_ALPHABET_FORMAT_SMS_DEFAULT; - gushort len; - GSList *tokens = NULL; - GSList *lines = NULL; - gint ussd_status = 0; - TelSsUssdNoti ussd_noti = {0,}; - - lines = (GSList *) event_data; - if (g_slist_length(lines) != 1) { - dbg("Unsolicited message but multiple lines"); - return TRUE; - } - - cmd = (gchar *)lines->data; - tokens = tcore_at_tok_new(cmd); - - /* Parse USSD status */ - resp_str = g_slist_nth_data(tokens, 0); - if (NULL == resp_str) { - err("Status is missing from +CUSD Notification"); - goto out; - } else { - ussd_status = atoi(resp_str); - dbg("USSD status[%d]", ussd_status); - - if (ussd_status < TEL_SS_USSD_STATUS_NO_ACTION_REQUIRED || - ussd_status > TEL_SS_USSD_STATUS_TIME_OUT) { - err("Invalid USSD status"); - goto out; - } - - /* - * When network terminated the USSD session, - * no need to send notification to application - */ - if (ussd_status == TEL_SS_USSD_STATUS_TERMINATED_BY_NETWORK) { - /* Destroy USSD session, if any exists */ - UssdSession *ussd_session = tcore_ss_ussd_get_session(co); - if (ussd_session) - tcore_ss_ussd_destroy_session(ussd_session); - - goto out; - } - - /* Parse USSD string */ - resp_str = g_slist_nth_data(tokens, 1); - - resp_str = tcore_at_tok_extract(resp_str); - if (resp_str) { - len = strlen((gchar *)resp_str); - dbg("USSD String: [%s] Length: [%d]", resp_str, len); - } else { - dbg("USSD strings is missing from +CUSD Notification"); - goto out; - } - - dcs_str = g_slist_nth_data(tokens, 2); - } - - if (dcs_str) { - dcs = tcore_util_get_cbs_coding_scheme(atoi((gchar *)dcs_str)); - } else { - warn("No DCS string! Using default DCS value"); - } - - ussd_noti.str = tcore_malloc0(len+1); - tcore_util_convert_str_to_utf8(ussd_noti.str, - &len, dcs, (const guchar *)resp_str, len+1); - ussd_noti.status = ussd_status; - - /* Send notification */ - tcore_object_send_notification(co, - TCORE_NOTIFICATION_SS_USSD, - sizeof(TelSsUssdNoti), (void *)&ussd_noti); - - tcore_free(resp_str); - tcore_free(ussd_noti.str); - -out: - tcore_at_tok_free(tokens); - return TRUE; -} - -static gboolean __atmodem_ss_convert_modem_class_to_class(gint classx, - TelSsClass *class) -{ - switch (classx) { - case 7: - *class = TEL_SS_CLASS_ALL_TELE; - break; - - case 1: - *class = TEL_SS_CLASS_VOICE; - break; - - case 2: - *class = TEL_SS_CLASS_ALL_DATA_TELE; - break; - - case 4: - *class = TEL_SS_CLASS_FAX; - break; - - case 8: - *class = TEL_SS_CLASS_SMS; - break; - - case 16: - *class = TEL_SS_CLASS_ALL_CS_SYNC; - break; - - case 32: - *class = TEL_SS_CLASS_ALL_CS_ASYNC; - break; - - case 64: - *class = TEL_SS_CLASS_ALL_DEDI_PS; - break; - - case 128: - *class = TEL_SS_CLASS_ALL_DEDI_PAD; - break; - - default: - err("Invalid modem class: [%d]", classx); - return FALSE; - } - - return TRUE; -} - -static guint __atmodem_ss_convert_class_to_atmodem_class(TelSsClass class) -{ - switch (class) { - case TEL_SS_CLASS_ALL_TELE: - return 7; - - case TEL_SS_CLASS_VOICE: - return 1; - - case TEL_SS_CLASS_ALL_DATA_TELE: - return 2; - - case TEL_SS_CLASS_FAX: - return 4; - - case TEL_SS_CLASS_SMS: - return 8; - - case TEL_SS_CLASS_ALL_CS_SYNC: - return 16; - - case TEL_SS_CLASS_ALL_CS_ASYNC: - return 32; - - case TEL_SS_CLASS_ALL_DEDI_PS: - return 64; - - case TEL_SS_CLASS_ALL_DEDI_PAD: - return 128; - - default: - dbg("Unsupported class: [%d], returning default value 7", class); - return 7; - } -} - -static gboolean __atmodem_ss_convert_barring_type_to_facility(TelSsBarringType type, - gchar **facility) -{ - switch (type) { - case TEL_SS_CB_TYPE_BAOC: - *facility = "AO"; - break; - - case TEL_SS_CB_TYPE_BOIC: - *facility = "OI"; - break; - - case TEL_SS_CB_TYPE_BOIC_NOT_HC: - *facility = "OX"; - break; - - case TEL_SS_CB_TYPE_BAIC: - *facility = "AI"; - break; - - case TEL_SS_CB_TYPE_BIC_ROAM: - *facility = "IR"; - break; - - case TEL_SS_CB_TYPE_AB: - *facility = "AB"; - break; - - case TEL_SS_CB_TYPE_AOB: - *facility = "AG"; - break; - - case TEL_SS_CB_TYPE_AIB: - *facility = "AC"; - break; - - case TEL_SS_CB_TYPE_NS: - *facility = "NS"; - break; - - default: - err("Unspported type: [%d]", type); - return FALSE; - } - return TRUE; -} - -static gboolean __atmodem_ss_convert_forwarding_mode_to_modem_mode(TelSsForwardMode mode, - guint *modex) -{ - switch (mode) { - case TEL_SS_CF_MODE_DISABLE: - *modex = 0; - break; - - case TEL_SS_CF_MODE_ENABLE: - *modex = 1; - break; - - case TEL_SS_CF_MODE_REGISTER: - *modex = 3; - break; - - case TEL_SS_CF_MODE_DEREGISTER: - *modex = 4; - break; - - default: - err("Unspported mode: [%d]", mode); - return FALSE; - } - - return TRUE; -} - -static gboolean __atmodem_ss_convert_forwarding_condition_to_modem_reason(TelSsForwardCondition condition, - guint *reason) -{ - switch (condition) { - case TEL_SS_CF_COND_CFU: - *reason = 0; - break; - - case TEL_SS_CF_COND_CFB: - *reason = 1; - break; - - case TEL_SS_CF_COND_CFNRY: - *reason = 2; - break; - - case TEL_SS_CF_COND_CFNRC: - *reason = 3; - break; - - case TEL_SS_CF_COND_ALL: - *reason = 4; - break; - - case TEL_SS_CF_COND_ALL_CFC: - *reason = 5; - break; - - default: - dbg("Unsupported condition: [%d]", condition); - return FALSE; - } - return TRUE; -} - -static gboolean __atmodem_ss_convert_modem_cli_dev_status_cli_status(TelSsCliType cli_type, - gint dev_status, gint *status) -{ - if (cli_type == TEL_SS_CLI_CLIR) { - switch (dev_status) { - case 0: - *status = TEL_CLIR_STATUS_DEFAULT; - break; - - case 1: - *status = TEL_CLIR_STATUS_INVOCATION; - break; - - case 2: - *status = TEL_CLIR_STATUS_SUPPRESSION; - break; - default: - err("Invalid dev status: [%d]", dev_status); - return FALSE; - } - } else { //CLIP, COLP,COLR,CNAP. - switch (dev_status) { - case 0: - *status = TEL_SS_CLI_DISABLE; - break; - - case 1: - *status = TEL_SS_CLI_ENABLE; - break; - - default: - err("Invalid dev status: [%d]", dev_status); - return FALSE; - } - } - - return TRUE; -} - -static gboolean __atmodem_ss_convert_modem_cli_net_status_cli_status(TelSsCliType cli_type, gint net_status, - gint *status) -{ - if (cli_type == TEL_SS_CLI_CLIR) { - switch (net_status) { - case 0: - *status = TEL_CLIR_STATUS_NOT_PROVISIONED; - break; - case 1: - *status = TEL_CLIR_STATUS_PROVISIONED; - break; - case 2: - *status = TEL_CLIR_STATUS_UNKNOWN; - break; - case 3: - *status = TEL_CLIR_STATUS_TEMP_RESTRICTED; - break; - case 4: - *status = TEL_CLIR_STATUS_TEMP_ALLOWED; - break; - default: - err("Invalid clir net status: [%d]", net_status); - return FALSE; - } - } else { //CLIP, COLP,COLR,CNAP. - switch (net_status) { - case 0: - *status = TEL_SS_CLI_NOT_PROVISIONED; - break; - case 1: - *status = TEL_SS_CLI_PROVISIONED; - break; - case 2: - *status = TEL_SS_CLI_UNKNOWN; - break; - default: - err("Invalid status: [%d]", net_status); - return FALSE; - } - } - return TRUE; -} - - -/* SS Responses */ -static void on_response_atmodem_ss_set_barring(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - - TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp && at_resp->success) - result = TEL_SS_RESULT_SUCCESS; - - dbg("Setting Barring status: [%s]", - (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL")); - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data); - - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -static void on_response_atmodem_ss_get_barring_status(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - TelSsBarringResp barring_resp = {0,}; - TelSsBarringGetInfo *req_info; - gint valid_records = 0; - GSList *resp_data = NULL; - - TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - req_info = (TelSsBarringGetInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - if (at_resp) { - if (at_resp->lines && at_resp->success) { - resp_data = (GSList *) at_resp->lines; - barring_resp.record_num= g_slist_length(resp_data); - dbg("Total records: [%d]", barring_resp.record_num); - } - else { - err("RESPONSE - [NOK]"); - } - } else { - err("No response data"); - } - - if (barring_resp.record_num > 0) { - barring_resp.records = tcore_malloc0( - (barring_resp.record_num) * sizeof(TelSsBarringInfoRecord)); - for (valid_records = 0; resp_data != NULL; resp_data = resp_data->next) { - const gchar *line; - GSList *tokens = NULL; - - line = (const gchar *) resp_data->data; - tokens = tcore_at_tok_new(line); - if (g_slist_length(tokens) > 0) { - gchar *classx_str; - gchar *status = NULL; - - status = g_slist_nth_data(tokens, 0); - if (!status) { - dbg("Status is missing"); - tcore_at_tok_free(tokens); - continue; - } - - if (atoi(status) == 1) { - barring_resp.records[valid_records].enable = TRUE; - } else { - barring_resp.records[valid_records].enable = FALSE; - } - - classx_str = g_slist_nth_data(tokens, 1); - if (!classx_str) { - dbg("Class error. Setting to the requested class: [%d]", req_info->class); - barring_resp.records[valid_records].class = req_info->class; - } else { - if (__atmodem_ss_convert_modem_class_to_class(atoi(classx_str), - &(barring_resp.records[valid_records].class)) == FALSE) { - tcore_at_tok_free(tokens); - continue; - } - } - - barring_resp.records[valid_records].type= req_info->type; - result = TEL_SS_RESULT_SUCCESS; - valid_records++; - } else { - err("Invalid response message"); - } - tcore_at_tok_free(tokens); - } - } - - dbg("Getting Barring status: [%s]", - (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL")); - barring_resp.record_num = valid_records; - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, &barring_resp, resp_cb_data->cb_data); - - atmodem_destroy_resp_cb_data(resp_cb_data); - - if (barring_resp.records) { - tcore_free(barring_resp.records); - } -} - -static void on_response_atmodem_ss_change_barring_password(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - - TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp && at_resp->success) - result = TEL_SS_RESULT_SUCCESS; - - dbg("Change Barring Password: [%s]", - (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL")); - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data); - - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -static void on_response_atmodem_ss_set_forwarding(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - - TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp && at_resp->success) - result = TEL_SS_RESULT_SUCCESS; - - dbg("Set Forwarding Status: [%s]", - (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL")); - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data); - - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -static void on_response_atmodem_ss_get_forwarding_status(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - TelSsForwardingResp forwarding_resp = {0,}; - TelSsForwardGetInfo *req_info; - gint valid_records = 0; - GSList *resp_data = NULL; - - TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - req_info = (TelSsForwardGetInfo *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - if (at_resp) { - if (at_resp->lines && at_resp->success) { - resp_data = (GSList *) at_resp->lines; - forwarding_resp.record_num= g_slist_length(resp_data); - dbg("Total records: [%d]", forwarding_resp.record_num); - } - else { - err("RESPONSE - [NOK]"); - } - } else { - err("No response data"); - } - - if (forwarding_resp.record_num > 0) { - forwarding_resp.records = tcore_malloc0( - (forwarding_resp.record_num) * sizeof(TelSsForwardingInfoRecord)); - for (valid_records = 0; resp_data != NULL; resp_data = resp_data->next) { - const gchar *line; - GSList *tokens = NULL; - - line = (const gchar *) resp_data->data; - tokens = tcore_at_tok_new(line); - if (g_slist_length(tokens) > 0) { - gchar *classx_str; - gchar *status = NULL; - gchar *number = NULL; - gchar *time_str = NULL; - - status = g_slist_nth_data(tokens, 0); - if (!status) { - dbg("Status is missing"); - tcore_at_tok_free(tokens); - continue; - } - - if (atoi(status) == 1) { - forwarding_resp.records[valid_records].enable = TRUE; - } else { - forwarding_resp.records[valid_records].enable = FALSE; - } - - classx_str = g_slist_nth_data(tokens, 1); - if (!classx_str) { - dbg("Class error. Setting to the requested class: [%d]", req_info->class); - forwarding_resp.records[valid_records].class = req_info->class; - } else { - if (__atmodem_ss_convert_modem_class_to_class(atoi(classx_str), - &(forwarding_resp.records[valid_records].class)) == FALSE) { - tcore_at_tok_free(tokens); - continue; - } - } - - number = g_slist_nth_data(tokens, 2); - if (number) - memcpy((forwarding_resp.records[valid_records].number), - number, strlen(number)); - - time_str = g_slist_nth_data(tokens, 6); - if (time_str) - forwarding_resp.records[valid_records].wait_time = atoi(time_str); - - forwarding_resp.records[valid_records].condition = req_info->condition; - - result = TEL_SS_RESULT_SUCCESS; - valid_records++; - } else { - err("Invalid response message"); - } - tcore_at_tok_free(tokens); - } - } - - dbg("Getting Forwarding Status: [%s]", - (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL")); - forwarding_resp.record_num = valid_records; - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, &forwarding_resp, resp_cb_data->cb_data); - - atmodem_destroy_resp_cb_data(resp_cb_data); - - if (forwarding_resp.records) { - tcore_free(forwarding_resp.records); - } -} - -static void on_response_atmodem_ss_set_waiting(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - - TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - if (at_resp && at_resp->success) - result = TEL_SS_RESULT_SUCCESS; - - dbg("Set Waiting Status: [%s]", - (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL")); - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data); - - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -static void on_response_atmodem_ss_get_waiting_status(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - TelSsWaitingResp waiting_resp = {0,}; - TelSsClass *class; - gint valid_records = 0; - GSList *resp_data = NULL; - - TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - class = (TelSsClass *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - if (at_resp) { - if (at_resp->lines && at_resp->success) { - resp_data = (GSList *) at_resp->lines; - waiting_resp.record_num= g_slist_length(resp_data); - dbg("Total records: [%d]", waiting_resp.record_num); - } - else { - err("RESPONSE - [NOK]"); - } - } else { - err("No response data"); - } - - if (waiting_resp.record_num > 0) { - waiting_resp.records = tcore_malloc0( - (waiting_resp.record_num) * sizeof(TelSsWaitingInfo)); - for (valid_records = 0; resp_data != NULL; resp_data = resp_data->next) { - const gchar *line; - GSList *tokens = NULL; - - line = (const gchar *) resp_data->data; - tokens = tcore_at_tok_new(line); - if (g_slist_length(tokens) > 0) { - gchar *classx_str; - gchar *status = NULL; - - status = g_slist_nth_data(tokens, 0); - if (!status) { - dbg("Status is missing"); - tcore_at_tok_free(tokens); - continue; - } - - if (atoi(status) == 1) { - waiting_resp.records[valid_records].enable= TRUE; - } else { - waiting_resp.records[valid_records].enable = FALSE; - } - - classx_str = g_slist_nth_data(tokens, 1); - if (!classx_str) { - dbg("Class error. Setting to the requested class: [%d]", *class); - waiting_resp.records[valid_records].class = *class; - } else { - if (__atmodem_ss_convert_modem_class_to_class(atoi(classx_str), - &(waiting_resp.records[valid_records].class)) == FALSE) { - tcore_at_tok_free(tokens); - continue; - } - } - - result = TEL_SS_RESULT_SUCCESS; - valid_records++; - } else { - err("Invalid response message"); - } - tcore_at_tok_free(tokens); - } - } - - dbg("Getting Waiting Status: [%s]", - (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL")); - waiting_resp.record_num = valid_records; - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, - &waiting_resp, resp_cb_data->cb_data); - - atmodem_destroy_resp_cb_data(resp_cb_data); - - if (waiting_resp.records) - tcore_free(waiting_resp.records); -} - -static void on_response_atmodem_ss_get_cli_status(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - TelSsCliResp cli_resp = {0,}; - TelSsCliType *cli_type; - GSList *tokens = NULL; - - TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - cli_type = (TelSsCliType *)ATMODEM_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data); - - if (*cli_type == TEL_SS_CLI_CDIP) { - err("Unsupported CLI type: [%d]", *cli_type); - result = TEL_SS_RESULT_INVALID_PARAMETER; - goto out; - } - - if (at_resp && at_resp->success) { - const gchar *line; - gchar *status = NULL; - gint net_status; - gint dev_status; - - if (!at_resp->lines) { - err("Invalid response message"); - goto out; - } - line = (const gchar *)at_resp->lines->data; - tokens = tcore_at_tok_new(line); - if (g_slist_length(tokens) < 1) { - err("Invalid response message"); - goto out; - } - - dbg("RESPONSE OK"); - status = g_slist_nth_data(tokens, 0); - if (!status) { - err("dev_status is missing"); - goto out; - } - if (!__atmodem_ss_convert_modem_cli_dev_status_cli_status(*cli_type, - atoi(status), &dev_status)) - goto out; - - status = g_slist_nth_data(tokens, 1); - if (!status) { - err("net_status is missing"); - goto out; - } - if (!__atmodem_ss_convert_modem_cli_net_status_cli_status(*cli_type, - atoi(status), &net_status)) - goto out; - - switch (*cli_type){ - case TEL_SS_CLI_CLIR: - cli_resp.status.clir.net_status = net_status; - cli_resp.status.clir.dev_status = dev_status; - break; - - case TEL_SS_CLI_CLIP: - cli_resp.status.clip.net_status = net_status; - cli_resp.status.clip.dev_status = dev_status; - break; - - case TEL_SS_CLI_COLP: - cli_resp.status.colp.net_status = net_status; - cli_resp.status.colp.dev_status = dev_status; - break; - - case TEL_SS_CLI_COLR: - cli_resp.status.colr.net_status = net_status; - cli_resp.status.colr.dev_status = dev_status; - break; - - case TEL_SS_CLI_CNAP: - cli_resp.status.cnap.net_status = net_status; - cli_resp.status.cnap.dev_status = dev_status; - break; - - default: - err("Unsupported CLI type: [%d]", *cli_type); - result = TEL_SS_RESULT_INVALID_PARAMETER; - goto out; - } - - cli_resp.type = *cli_type; - } else { - err("RESPONSE NOK"); - } - -out: - tcore_at_tok_free(tokens); - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, - &cli_resp, resp_cb_data->cb_data); - - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -static void on_response_atmodem_ss_send_ussd_request(TcorePending *p, - guint data_len, const void *data, void *user_data) -{ - const TcoreAtResponse *at_resp = data; - CoreObject *co = tcore_pending_ref_core_object(p); - AtmodemRespCbData *resp_cb_data = user_data; - TelSsUssdResp ussd_resp = {0,}; - UssdSession *ussd_s = NULL; - - - TelSsResult result = TEL_SS_RESULT_FAILURE; // TODO: CMEE error mapping is required - dbg("Enter"); - - tcore_check_return_assert(co != NULL); - tcore_check_return_assert(resp_cb_data != NULL); - - ussd_s = tcore_ss_ussd_get_session(co); - tcore_check_return(ussd_s != NULL); - - tcore_ss_ussd_get_session_type(ussd_s, &ussd_resp.type); - - if (at_resp && at_resp->success) - result = TEL_SS_RESULT_SUCCESS; - - dbg("Send Ussd Request: [%s]", - (result == TEL_SS_RESULT_SUCCESS ? "SUCCESS" : "FAIL")); - - tcore_ss_ussd_destroy_session(ussd_s); - - /* Invoke callback */ - if (resp_cb_data->cb) - resp_cb_data->cb(co, (gint)result, &ussd_resp, resp_cb_data->cb_data); - - atmodem_destroy_resp_cb_data(resp_cb_data); -} - -/* SS Operations */ -/* - * Operation - set_barring/get_barring_status - * - * Request - - * AT-Command: AT+CLCK=,[,[,]] - * where, - * - * Barring facility type. Ref #TelSsBarringType - * - * - * 0 unlock - * 1 lock - * 2 query status - * - * - * Barring Password - * - * - * SS class. Ref #TelSsClass - * - * - * 0 not active - * 1 active - * - * Success: when =2: - * OK - * +CLCK: [, [ - * +CLCK: , [...]] - * - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_ss_set_barring(CoreObject *co, - const TelSsBarringInfo *barring_info, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd = NULL; - guint mode; - guint classx; - gchar *facility = NULL; - AtmodemRespCbData *resp_cb_data = NULL; - TelReturn ret = TEL_RETURN_INVALID_PARAMETER; - - if (barring_info->enable == TRUE) - mode = 1; - else - mode = 0; - - if (__atmodem_ss_convert_barring_type_to_facility( - barring_info->type, &facility) == FALSE) { - err("Invalid arguments"); - return ret; - } - - classx = __atmodem_ss_convert_class_to_atmodem_class(barring_info->class); - - dbg("facility: [%s], classx:[%d], mode: [%d]", facility, classx, mode); - - /* AT-Command */ - at_cmd = g_strdup_printf("AT+CLCK=\"%s\",%d,\"%s\",%d", - facility, mode, barring_info->pwd, classx); - - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - at_cmd, NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - on_response_atmodem_ss_set_barring, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Set Barring"); - - g_free(at_cmd); - return ret; -} - -static TelReturn atmodem_ss_get_barring_status(CoreObject *co, - const TelSsBarringGetInfo *get_barring_info, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd = NULL; - guint mode; - guint classx; - gchar *facility = NULL; - AtmodemRespCbData *resp_cb_data = NULL; - TelReturn ret = TEL_RETURN_INVALID_PARAMETER; - - mode = 2; /* query status - mode is fixed to 2 */ - - if (__atmodem_ss_convert_barring_type_to_facility( - get_barring_info->type, &facility) == FALSE) { - err("Invalid arguments"); - return ret; - } - - classx = __atmodem_ss_convert_class_to_atmodem_class(get_barring_info->class); - - dbg("facility: [%s], classx:[%d], mode: [%d]", facility, classx, mode); - - /* AT-Command */ - at_cmd = g_strdup_printf("AT+CLCK=\"%s\",%d,,%d", - facility, mode, classx); - - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, - (void *)get_barring_info, sizeof(TelSsBarringGetInfo)); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - at_cmd, "+CLCK", - TCORE_AT_COMMAND_TYPE_MULTILINE, - NULL, - on_response_atmodem_ss_get_barring_status, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Barring Status"); - - g_free(at_cmd); - return ret; -} - -/* - * Operation - change_barring_password - * - * Request - - * AT-Command: AT+CPWD= ,, - * where, - * - * Barring facility type. Ref #TelSsBarringType - * Eg: "AB" All Barring services - * - * - * Old Barring Password - * - * - * New Barring Password - * - * Success: - * OK - * - * Failure: - * +CME ERROR: - */ -static TelReturn atmodem_ss_change_barring_password(CoreObject *co, - const TelSsBarringPwdInfo *barring_pwd_info, - TcoreObjectResponseCallback cb, void *cb_data) -{ - gchar *at_cmd = NULL; - AtmodemRespCbData *resp_cb_data = NULL; - TelReturn ret = TEL_RETURN_INVALID_PARAMETER; - - if (barring_pwd_info->old_pwd== NULL || barring_pwd_info->new_pwd == NULL) { - err("Invalid data"); - return ret; - } - - dbg("Old password: [%s], New password: [%s]", - barring_pwd_info->old_pwd, barring_pwd_info->new_pwd); - - at_cmd = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", "AB", - barring_pwd_info->old_pwd, barring_pwd_info->new_pwd); - - resp_cb_data = atmodem_create_resp_cb_data(cb, cb_data, NULL, 0); - - /* Send Request to modem */ - ret = tcore_at_prepare_and_send_request(co, - at_cmd, NULL, - TCORE_AT_COMMAND_TYPE_NO_RESULT, - NULL, - on_response_atmodem_ss_change_barring_password, resp_cb_data, - on_send_atmodem_request, NULL); - ATMODEM_CHECK_REQUEST_RET(ret, resp_cb_data, "Change Barring Password"); - - g_free(at_cmd); - return ret; -} - -/* - * Operation - set_forwarding/get_forwarding_status - * - * Request - - * AT-Command: AT+CCFC=,[,[,[,[,[,[,