SET(PREFIX ${CMAKE_INSTALL_PREFIX})
SET(EXEC_PREFIX "\${prefix}")
-SET(LIBDIR "\${prefix}/lib")
+SET(LIBDIR ${LIB_INSTALL_DIR})
SET(INCLUDEDIR "\${prefix}/include")
# Set required packages
INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED glib-2.0 tcore dlog db-util)
+pkg_check_modules(pkgs REQUIRED glib-2.0 tcore dlog db-util libxml-2.0 vconf)
FOREACH(flag ${pkgs_CFLAGS})
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
ENDFOREACH(flag)
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include/)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
+ /usr/include/libxml2
+ )
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Werror -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wdeclaration-after-statement -Wmissing-declarations -Wredundant-decls -Wcast-align")
-ADD_DEFINITIONS("-DFEATURE_DLOG_DEBUG")
+ADD_DEFINITIONS("-DFEATURE_TLOG_DEBUG")
ADD_DEFINITIONS("-DTCORE_LOG_TAG=\"IMC\"")
MESSAGE(${CMAKE_C_FLAGS})
MESSAGE(${CMAKE_EXE_LINKER_FLAGS})
SET(SRCS
- src/desc.c
- src/s_modem.c
- src/s_common.c
- src/s_network.c
- src/s_sim.c
- src/s_sat.c
- src/s_call.c
- src/s_ss.c
- src/s_ps.c
- src/s_sms.c
+ src/desc_imc.c
+ src/imc_modem.c
+ src/imc_common.c
+ src/imc_network.c
+ src/imc_sim.c
+ src/imc_sat.c
+ src/imc_call.c
+ src/imc_ss.c
+ src/imc_ps.c
+ src/imc_sms.c
+ src/imc_phonebook.c
+ src/imc_sap.c
+ src/imc_gps.c
+ src/nvm/nvm.c
)
# install
INSTALL(TARGETS imc-plugin
- LIBRARY DESTINATION lib/telephony/plugins)
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}/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-imc)
--- /dev/null
+Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
+\r
+ Apache License\r
+ Version 2.0, January 2004\r
+ http://www.apache.org/licenses/\r
+\r
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+ 1. Definitions.\r
+\r
+ "License" shall mean the terms and conditions for use, reproduction,\r
+ and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+ "Licensor" shall mean the copyright owner or entity authorized by\r
+ the copyright owner that is granting the License.\r
+\r
+ "Legal Entity" shall mean the union of the acting entity and all\r
+ other entities that control, are controlled by, or are under common\r
+ control with that entity. For the purposes of this definition,\r
+ "control" means (i) the power, direct or indirect, to cause the\r
+ direction or management of such entity, whether by contract or\r
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+ outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+ "You" (or "Your") shall mean an individual or Legal Entity\r
+ exercising permissions granted by this License.\r
+\r
+ "Source" form shall mean the preferred form for making modifications,\r
+ including but not limited to software source code, documentation\r
+ source, and configuration files.\r
+\r
+ "Object" form shall mean any form resulting from mechanical\r
+ transformation or translation of a Source form, including but\r
+ not limited to compiled object code, generated documentation,\r
+ and conversions to other media types.\r
+\r
+ "Work" shall mean the work of authorship, whether in Source or\r
+ Object form, made available under the License, as indicated by a\r
+ copyright notice that is included in or attached to the work\r
+ (an example is provided in the Appendix below).\r
+\r
+ "Derivative Works" shall mean any work, whether in Source or Object\r
+ form, that is based on (or derived from) the Work and for which the\r
+ editorial revisions, annotations, elaborations, or other modifications\r
+ represent, as a whole, an original work of authorship. For the purposes\r
+ of this License, Derivative Works shall not include works that remain\r
+ separable from, or merely link (or bind by name) to the interfaces of,\r
+ the Work and Derivative Works thereof.\r
+\r
+ "Contribution" shall mean any work of authorship, including\r
+ the original version of the Work and any modifications or additions\r
+ to that Work or Derivative Works thereof, that is intentionally\r
+ submitted to Licensor for inclusion in the Work by the copyright owner\r
+ or by an individual or Legal Entity authorized to submit on behalf of\r
+ the copyright owner. For the purposes of this definition, "submitted"\r
+ means any form of electronic, verbal, or written communication sent\r
+ to the Licensor or its representatives, including but not limited to\r
+ communication on electronic mailing lists, source code control systems,\r
+ and issue tracking systems that are managed by, or on behalf of, the\r
+ Licensor for the purpose of discussing and improving the Work, but\r
+ excluding communication that is conspicuously marked or otherwise\r
+ designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+ "Contributor" shall mean Licensor and any individual or Legal Entity\r
+ on behalf of whom a Contribution has been received by Licensor and\r
+ subsequently incorporated within the Work.\r
+\r
+ 2. Grant of Copyright License. Subject to the terms and conditions of\r
+ this License, each Contributor hereby grants to You a perpetual,\r
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+ copyright license to reproduce, prepare Derivative Works of,\r
+ publicly display, publicly perform, sublicense, and distribute the\r
+ Work and such Derivative Works in Source or Object form.\r
+\r
+ 3. Grant of Patent License. Subject to the terms and conditions of\r
+ this License, each Contributor hereby grants to You a perpetual,\r
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+ (except as stated in this section) patent license to make, have made,\r
+ use, offer to sell, sell, import, and otherwise transfer the Work,\r
+ where such license applies only to those patent claims licensable\r
+ by such Contributor that are necessarily infringed by their\r
+ Contribution(s) alone or by combination of their Contribution(s)\r
+ with the Work to which such Contribution(s) was submitted. If You\r
+ institute patent litigation against any entity (including a\r
+ cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+ or a Contribution incorporated within the Work constitutes direct\r
+ or contributory patent infringement, then any patent licenses\r
+ granted to You under this License for that Work shall terminate\r
+ as of the date such litigation is filed.\r
+\r
+ 4. Redistribution. You may reproduce and distribute copies of the\r
+ Work or Derivative Works thereof in any medium, with or without\r
+ modifications, and in Source or Object form, provided that You\r
+ meet the following conditions:\r
+\r
+ (a) You must give any other recipients of the Work or\r
+ Derivative Works a copy of this License; and\r
+\r
+ (b) You must cause any modified files to carry prominent notices\r
+ stating that You changed the files; and\r
+\r
+ (c) You must retain, in the Source form of any Derivative Works\r
+ that You distribute, all copyright, patent, trademark, and\r
+ attribution notices from the Source form of the Work,\r
+ excluding those notices that do not pertain to any part of\r
+ the Derivative Works; and\r
+\r
+ (d) If the Work includes a "NOTICE" text file as part of its\r
+ distribution, then any Derivative Works that You distribute must\r
+ include a readable copy of the attribution notices contained\r
+ within such NOTICE file, excluding those notices that do not\r
+ pertain to any part of the Derivative Works, in at least one\r
+ of the following places: within a NOTICE text file distributed\r
+ as part of the Derivative Works; within the Source form or\r
+ documentation, if provided along with the Derivative Works; or,\r
+ within a display generated by the Derivative Works, if and\r
+ wherever such third-party notices normally appear. The contents\r
+ of the NOTICE file are for informational purposes only and\r
+ do not modify the License. You may add Your own attribution\r
+ notices within Derivative Works that You distribute, alongside\r
+ or as an addendum to the NOTICE text from the Work, provided\r
+ that such additional attribution notices cannot be construed\r
+ as modifying the License.\r
+\r
+ You may add Your own copyright statement to Your modifications and\r
+ may provide additional or different license terms and conditions\r
+ for use, reproduction, or distribution of Your modifications, or\r
+ for any such Derivative Works as a whole, provided Your use,\r
+ reproduction, and distribution of the Work otherwise complies with\r
+ the conditions stated in this License.\r
+\r
+ 5. Submission of Contributions. Unless You explicitly state otherwise,\r
+ any Contribution intentionally submitted for inclusion in the Work\r
+ by You to the Licensor shall be under the terms and conditions of\r
+ this License, without any additional terms or conditions.\r
+ Notwithstanding the above, nothing herein shall supersede or modify\r
+ the terms of any separate license agreement you may have executed\r
+ with Licensor regarding such Contributions.\r
+\r
+ 6. Trademarks. This License does not grant permission to use the trade\r
+ names, trademarks, service marks, or product names of the Licensor,\r
+ except as required for reasonable and customary use in describing the\r
+ origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+ 7. Disclaimer of Warranty. Unless required by applicable law or\r
+ agreed to in writing, Licensor provides the Work (and each\r
+ Contributor provides its Contributions) on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+ implied, including, without limitation, any warranties or conditions\r
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+ PARTICULAR PURPOSE. You are solely responsible for determining the\r
+ appropriateness of using or redistributing the Work and assume any\r
+ risks associated with Your exercise of permissions under this License.\r
+\r
+ 8. Limitation of Liability. In no event and under no legal theory,\r
+ whether in tort (including negligence), contract, or otherwise,\r
+ unless required by applicable law (such as deliberate and grossly\r
+ negligent acts) or agreed to in writing, shall any Contributor be\r
+ liable to You for damages, including any direct, indirect, special,\r
+ incidental, or consequential damages of any character arising as a\r
+ result of this License or out of the use or inability to use the\r
+ Work (including but not limited to damages for loss of goodwill,\r
+ work stoppage, computer failure or malfunction, or any and all\r
+ other commercial damages or losses), even if such Contributor\r
+ has been advised of the possibility of such damages.\r
+\r
+ 9. Accepting Warranty or Additional Liability. While redistributing\r
+ the Work or Derivative Works thereof, You may choose to offer,\r
+ and charge a fee for, acceptance of support, warranty, indemnity,\r
+ or other liability obligations and/or rights consistent with this\r
+ License. However, in accepting such obligations, You may act only\r
+ on Your own behalf and on Your sole responsibility, not on behalf\r
+ of any other Contributor, and only if You agree to indemnify,\r
+ defend, and hold each Contributor harmless for any liability\r
+ incurred by, or claims asserted against, such Contributor by reason\r
+ of your accepting any such warranty or additional liability.\r
+\r
+ END OF TERMS AND CONDITIONS\r
+\r
+ APPENDIX: How to apply the Apache License to your work.\r
+\r
+ To apply the Apache License to your work, attach the following\r
+ boilerplate notice, with the fields enclosed by brackets "[]"\r
+ replaced with your own identifying information. (Don't include\r
+ the brackets!) The text should be enclosed in the appropriate\r
+ comment syntax for the file format. We also recommend that a\r
+ file or class name and description of purpose be included on the\r
+ same "printed page" as the copyright notice for easier\r
+ identification within third-party archives.\r
+\r
+ Copyright [yyyy] [name of copyright owner]\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+++ /dev/null
-tel-plugin-imc (0.1.0) unstable; urgency=low
-
- * Initial
- * Git: slp/pkgs/t/tel-plugin-imc
- * Tag: tel-plugin-imc_0.1.0
-
- -- Inho Oh <inho48.oh@samsung.com> Thu, 17 July 2012 22:37:29 +0900
+++ /dev/null
-Source: tel-plugin-imc
-Section: libs
-Priority: extra
-Maintainer: Jongman Park <jman.park@samsung.com>
-Uploaders: Jayoung Gu <jygu@samsung.com>, Kyeongchul Kim <kyeongchul.kim@samsung.com>, Youngman Park <youngman.park@samsung.com>, Inho Oh <inho48.oh@samsung.com>, DongHoo Park <donghoo.park@samsung.com>
-Build-Depends: debhelper (>= 5), libglib2.0-dev, libtcore-dev, dlog-dev, libslp-db-util-dev
-Standards-Version: 0.0.0
-
-Package: tel-plugin-imc
-Section: libs
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends},
-Description: telephony client API library (Shared Object)
-
-Package: tel-plugin-imc-dbg
-Section: debug
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, tel-plugin-imc (= ${Source-Version})
-Description: telephony client API library (dbg package)
-
+++ /dev/null
-Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License version 2.1.
-
-The full text of the LGPL 2.1 can be found in
-/usr/share/common-licenses.
+++ /dev/null
-usr/bin
-usr/sbin
+++ /dev/null
-#!/usr/bin/make -f
-# -*- makefile -*-
-# Sample debian/rules that uses debhelper.
-# This file was originally written by Joey Hess and Craig Small.
-# As a special exception, when this file is copied by dh-make into a
-# dh-make output file, you may use that output file without restriction.
-# This special exception was added by Craig Small in version 0.37 of dh-make.
-
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-
-CFLAGS ?= -Wall -g
-CXXFLAGS ?= -Wall -g
-LDFLAGS ?=
-PREFIX ?= /usr
-DATADIR ?= /opt
-
-ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
- CFLAGS += -O0
- CXXFLAGS += -O0
-else
- CFLAGS += -O2
- CXXFLAGS += -O2
-endif
-
-#CFLAGS += -fvisibility=hidden -fPIC
-CFLAGS += -fvisibility=default -fPIC
-LDFLAGS += -rdynamic -fPIC -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed
-#LDFLAGS += -Wl,--unresolved-symbols=ignore-in-shared-libs,--as-needed
-
-CMAKE_TMP_DIR = $(CURDIR)/cmake_tmp
-
-configure: configure-stamp
-configure-stamp:
- dh_testdir
- # Add here commands to configure the package.
- mkdir -p $(CMAKE_TMP_DIR);
- cd $(CMAKE_TMP_DIR); CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" cmake .. -DCMAKE_INSTALL_PREFIX=$(PREFIX)
-
- touch configure-stamp
-
-build: build-stamp
-
-build-stamp: configure-stamp
- dh_testdir
-
- # Add here commands to compile the package.
- cd $(CMAKE_TMP_DIR) && $(MAKE) all
-
- for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
- cat $$f > $${f%.in}; \
- sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \
- sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \
- done
-
- touch $@
-
-clean:
- dh_testdir
- dh_testroot
- rm -f build-stamp configure-stamp
-
- # Add here commands to clean up after the build process.
- rm -rf $(CMAKE_TMP_DIR)
-
- for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
- rm -f $${f%.in}; \
- done
-
- dh_clean
-
-install: build
- dh_testdir
- dh_testroot
- dh_clean -k
- dh_installdirs
-
- # Add here commands to install the package into debian/wavplayer.
- cd $(CMAKE_TMP_DIR) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
-
-
-# Build architecture-independent files here.
-binary-indep: build install
-# We have nothing to do by default.
-
-# Build architecture-dependent files here.
-binary-arch: build install
- dh_testdir
- dh_testroot
- dh_installchangelogs
- dh_installdocs
- dh_installexamples
- dh_install --sourcedir=debian/tmp
-# dh_installmenu
-# dh_installdebconf
-# dh_installlogrotate
-# dh_installemacsen
-# dh_installpam
-# dh_installmime
-# dh_python
-# dh_installinit
-# dh_installcron
-# dh_installinfo
- dh_installman
- dh_link
- dh_strip --dbg-package=tel-plugin-imc-dbg
- dh_compress
- dh_fixperms
-# dh_perl
- dh_makeshlibs
- dh_installdeb
- dh_shlibdeps --dpkg-shlibdeps-params="-v"
- dh_gencontrol
- dh_md5sums
- dh_builddeb
-
-binary: binary-indep binary-arch
-.PHONY: build clean binary-indep binary-arch binary install configure
+++ /dev/null
-@PREFIX@/lib/*
-/tmp/mcc_mnc_oper_list.sql
+++ /dev/null
-#!/bin/sh
-
-#create db
-mkdir -p /opt/dbspace
-
-if [ ! -f /opt/dbspace/.mcc_mnc_oper_list.db ]
-then
- 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 /opt/dbspace/.mcc_mnc_oper_list.db ]
-then
- chmod 600 /opt/dbspace/.mcc_mnc_oper_list.db
-fi
-if [ -f /opt/dbspace/.mcc_mnc_oper_list.db-journal ]
-then
- chmod 644 /opt/dbspace/.mcc_mnc_oper_list.db-journal
-fi
-
-vconftool set -t string memory/telephony/productCode "" -i -f
* limitations under the License.
*/
-#ifndef __S_CALL_H__
-#define __S_CALL_H__
+#ifndef __IMC_CALL_H__
+#define __IMC_CALL_H__
-gboolean s_call_init(TcorePlugin *p, TcoreHal *h);
-void s_call_exit(TcorePlugin *p);
+gboolean imc_call_init(TcorePlugin *cp, CoreObject *co_call);
+void imc_call_exit(TcorePlugin *cp, CoreObject *co_call);
-#endif
+#endif // __IMC_CALL_H__
\ No newline at end of file
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hayoon Ko <hayoon.ko@samsung.com>
+ *
+ * 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 __IMC_COMMON_H__
+#define __IMC_COMMON_H__
+
+#include <glib.h>
+
+void util_hex_dump(char *pad, int size, const void *data);
+unsigned char util_hexCharToInt(char c);
+char *util_hex_to_string(const char *src, unsigned int src_len);
+char* util_hexStringToBytes(char *s);
+char* util_removeQuotes(void *data);
+
+#endif // __IMC_COMMON_H__
\ No newline at end of file
* limitations under the License.
*/
-#ifndef __S_PS_H__
-#define __S_PS_H__
+#ifndef __IMC_GPS_H__
+#define __IMC_GPS_H__
-gboolean s_ps_init(TcorePlugin *p, TcoreHal *hal);
-void s_ps_exit(TcorePlugin *p);
+gboolean imc_gps_init(TcorePlugin *cp, CoreObject *co_gps);
+void imc_gps_exit(TcorePlugin *cp, CoreObject *co_gps);
-#endif /*__S_PS_H__*/
+#endif // __IMC_GPS_H__
\ No newline at end of file
* limitations under the License.
*/
-#ifndef __S_MODEM_H__
-#define __S_MODEM_H__
+#ifndef __IMC_MODEM_H__
+#define __IMC_MODEM_H__
-gboolean on_event_modem_power(TcoreAT *at, const char *line, TcorePlugin *p);
-gboolean s_modem_init(TcorePlugin *p, TcoreHal *h);
-void s_modem_exit(TcorePlugin *p);
-gboolean s_modem_send_poweron(TcorePlugin *p);
+gboolean imc_modem_init(TcorePlugin *cp, CoreObject *co_modem);
+void imc_modem_exit(TcorePlugin *cp, CoreObject *co_modem);
-#endif
+gboolean modem_power_on(TcorePlugin *plugin);
+void modem_register_nvm(CoreObject *co_modem);
+
+#endif // __IMC_MODEM_H__
\ No newline at end of file
* limitations under the License.
*/
-#ifndef __S_NETWORK_H__
-#define __S_NETWORK_H__
+#ifndef __IMC_NETWORK_H__
+#define __IMC_NETWORK_H__
-gboolean s_network_init(TcorePlugin *p, TcoreHal *h);
-void s_network_exit(TcorePlugin *p);
+gboolean imc_network_init(TcorePlugin *cp, CoreObject *co_network);
+void imc_network_exit(TcorePlugin *cp, CoreObject *co_network);
-#endif
+#endif // __IMC_NETWORK_H__
\ No newline at end of file
* limitations under the License.
*/
-#ifndef S_PHONEBOOK_H_
-#define S_PHONEBOOK_H_
+#ifndef __IMC_PHONEBOOK_H__
+#define __IMC_PHONEBOOK_H__
-gboolean s_phonebook_init(TcorePlugin *p, TcoreHal *h);
-void s_phonebook_exit(TcorePlugin *p);
+gboolean imc_phonebook_init(TcorePlugin *cp, CoreObject *co_phonebook);
+void imc_phonebook_exit(TcorePlugin *cp, CoreObject *co_phonebook);
-#endif /* S_PHONEBOOK_H_ */
+#endif /* __IMC_PHONEBOOK_H__ */
* limitations under the License.
*/
-#ifndef __S_GPS_H__
-#define __S_GPS_H__
+#ifndef __IMC_PS_H__
+#define __IMC_PS_H__
-gboolean s_gps_init(TcorePlugin *p, TcoreHal *h);
-void s_gps_exit(TcorePlugin *p);
+gboolean imc_ps_init(TcorePlugin *cp, CoreObject *co_ps);
+void imc_ps_exit(TcorePlugin *cp, CoreObject *co_ps);
-#endif
+#endif /*__IMC_PS_H__*/
* limitations under the License.
*/
-#ifndef S_SAP_H_
-#define S_SAP_H_
+#ifndef __IMC_SAP_H__
+#define __IMC_SAP_H__
-gboolean s_sap_init(TcorePlugin *p, TcoreHal *h);
-void s_sap_exit(TcorePlugin *p);
+gboolean imc_sap_init(TcorePlugin *cp, CoreObject *co_sap);
+void imc_sap_exit(TcorePlugin *cp, CoreObject *co_sap);
-#endif /* S_SAP_H_ */
+#endif /* __IMC_SAP_H__ */
*/
-#ifndef S_SAT_H_
-#define S_SAT_H_
+#ifndef __IMC_SAT_H__
+#define __IMC_SAT_H__
-gboolean s_sat_init(TcorePlugin *p, TcoreHal *h);
-void s_sat_exit(TcorePlugin *p);
+gboolean imc_sat_init(TcorePlugin *cp, CoreObject *co_sat);
+void imc_sat_exit(TcorePlugin *cp, CoreObject *co_sat);
-#endif /* S_SAT_H_ */
+#endif /* __IMC_SAT_H__ */
* limitations under the License.
*/
-#ifndef __S_SIM_H__
-#define __S_SIM_H__
+#ifndef __IMC_SIM_H__
+#define __IMC_SIM_H__
-gboolean s_sim_init(TcorePlugin *p, TcoreHal *h);
-void s_sim_exit(TcorePlugin *p);
+gboolean imc_sim_init(TcorePlugin *cp, CoreObject *co_sim);
+void imc_sim_exit(TcorePlugin *cp, CoreObject *co_sim);
-#endif
+#endif // __IMC_SIM_H__
\ No newline at end of file
* limitations under the License.
*/
-#ifndef S_SMS_H_
-#define S_SMS_H_
+#ifndef __IMC_SMS_H__
+#define __IMC_SMS_H__
-gboolean s_sms_init(TcorePlugin *p, TcoreHal *h);
-void s_sms_exit(TcorePlugin *p);
+gboolean imc_sms_init(TcorePlugin *cp, CoreObject *co_sms);
+void imc_sms_exit(TcorePlugin *cp, CoreObject *co_sms);
-#endif // S_SMS_H_
+#endif // __IMC_SMS_H__
\ No newline at end of file
* limitations under the License.
*/
-#ifndef __S_SS_H__
-#define __S_SS_H__
+#ifndef __IMC_SS_H__
+#define __IMC_SS_H__
-gboolean s_ss_init(TcorePlugin *p, TcoreHal *h);
-void s_ss_exit(TcorePlugin *p);
+gboolean imc_ss_init(TcorePlugin *cp, CoreObject *co_ss);
+void imc_ss_exit(TcorePlugin *cp, CoreObject *co_ss);
-#endif
+#endif // __IMC_SS_H__
\ No newline at end of file
--- /dev/null
+/*\r
+ * tel-plugin-imc\r
+ *\r
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: Paresh Agarwal<paresh.agwl@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __NVM_H__\r
+#define __NVM_H__\r
+\r
+/* Priority level for suspension of all updates */\r
+#define UTA_FLASH_PLUGIN_PRIO_SUSPEND_ALL 4294967295 /* 0xFFFFFFFF */\r
+\r
+/* Priority level for suspension of High priority updates */\r
+#define UTA_FLASH_PLUGIN_PRIO_SUSPEND_HIGH 3221225472 /* 0xFFFFFFFF */\r
+\r
+/* Priority level for suspension of all updates of dynamic data */\r
+#define UTA_FLASH_PLUGIN_PRIO_SUSPEND_ALL_DYN 1610612735 /* 0x5FFFFFFF */\r
+\r
+/* Priority level for suspension of Medium all updates */\r
+#define UTA_FLASH_PLUGIN_PRIO_SUSPEND_MEDIUM 2147483648 /* 0x5FFFFFFF */\r
+\r
+/* Priority level for suspension of Low updates of Medium */\r
+#define UTA_FLASH_PLUGIN_PRIO_SUSPEND_LOW 1073741824 /* 0x5FFFFFFF */\r
+\r
+/* Priority level for unsuspension of all updates */\r
+#define UTA_FLASH_PLUGIN_PRIO_UNSUSPEND_ALL 0 /* 0x0 */\r
+\r
+#define NVM_FUNCTION_ID_OFFSET 20\r
+#define XDRV_INDICATION 0x04\r
+\r
+#define XDRV_DISABLE "0"\r
+#define XDRV_ENABLE "1"\r
+#define XDRV_UNSUSPEND "0"\r
+\r
+/* Identifies our group with the xdrv AT command set */\r
+#define IUFP_GROUP "43"\r
+#define IUFP_GROUP_ID 43\r
+\r
+#define IUFP_REGISTER 0\r
+#define IUFP_REGISTER_STR "0"\r
+\r
+#define IUFP_SUSPEND 1\r
+#define IUFP_SUSPEND_STR "1"\r
+\r
+#define IUFP_FLUSH 2\r
+#define IUFP_FLUSH_STR "2"\r
+\r
+#define IUFP_UPDATE_REQ 3\r
+#define IUFP_UPDATE_REQ_STR "3"\r
+\r
+#define IUFP_UPDATE_REQ_ACK 3\r
+#define IUFP_UPDATE_REQ_ACK_STR "3"\r
+\r
+#define IUFP_UPDATE 4\r
+#define IUFP_UPDATE_STR "4"\r
+\r
+#define IUFP_UPDATE_ACK 4\r
+#define IUFP_UPDATE_ACK_STR "4"\r
+\r
+#define IUFP_NO_PENDING_UPDATE 5\r
+#define IUFP_NO_PENDING_UPDATE_STR "5"\r
+\r
+/* XDRV command was executed without any error */\r
+#define XDRV_RESULT_OK 0\r
+\r
+typedef enum uta_common_return_codes {\r
+ UTA_SUCCESS = 0,\r
+ UTA_FAILURE = -1,\r
+ UTA_ERROR_OUT_OF_MEMORY = -2,\r
+ UTA_ERROR_INVALID_HANDLE = -3,\r
+ UTA_ERROR_OUT_OF_RANGE_PARAM = -4,\r
+ UTA_ERROR_INVALID_PARAM = -5,\r
+ UTA_ERROR_TOO_SMALL_BUF_PARAM = -6,\r
+ UTA_ERROR_NOT_SUPPORTED = -7,\r
+ UTA_ERROR_TIMEOUT = -8,\r
+ UTA_ERROR_WRONG_STATE = -9,\r
+ UTA_ERROR_BAD_FORMAT = -10,\r
+ UTA_ERROR_INSUFFICIENT_PERMISSIONS = -11,\r
+ UTA_ERROR_IO_ERROR = -12,\r
+ UTA_ERROR_OUT_OF_HANDLES = -13,\r
+ UTA_ERROR_OPERATION_PENDING = -14,\r
+ UTA_ERROR_SPECIFIC = -100\r
+} nvm_return_codes;\r
+\r
+typedef enum nvm_error_numbers {\r
+ NVM_NO_ERR = 0,\r
+ NVM_CMD_ERR,\r
+ NVM_DATA_ERR,\r
+ NVM_MEM_FULL_ERR,\r
+ NVM_RES_ERR,\r
+ NVM_WRITE_ERR,\r
+ NVM_READ_ERR,\r
+ NVM_RES_LEN_ERR,\r
+ NVM_PCKT_ERR,\r
+ NVM_REG_FAIL_ERR,\r
+ NVM_DATA_LEN_ERR,\r
+ NVM_FILE_ERR,\r
+ NVM_AT_PORT_ERR,\r
+ NVM_READ_AT_ERR,\r
+ NVM_DATA_PORT_ERR,\r
+ NVM_NO_PENDING_UPDATE,\r
+ NVM_UPDATE,\r
+ NVM_REGISTER_ERR,\r
+ NVM_UNKNOWN_ERR\r
+} nvm_error;\r
+\r
+int nvm_sum_4_bytes(const char *pos);\r
+gboolean nvm_create_nvm_data();\r
+nvm_error nvm_process_nv_update(const char *data);\r
+\r
+#endif /* __NVM_H__ */\r
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
- *
- * 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 <tcore.h>
-#include <glib.h>
-#include <user_request.h>
-
-#define EVENT_SYS_NOTI_MODEM_POWER "system_power"
-#define EVENT_NOTI_MODEM_POWER "modem_power"
-#define EVENT_NOTI_MODEM_PHONE_STATE "modem_phone_state"
-#define EVENT_NOTI_MODEM_PIN_CTRL "ps_pin_control"
-
-#define EVENT_NOTI_CALL_STATUS "call_status"
-#define EVENT_NOTI_CALL_INCOMING "call_incoming"
-#define EVENT_NOTI_CALL_WAITING "call_waiting"
-#define EVENT_NOTI_CALL_SOUND_WBAMR_REPORT "call_sound_wbamr_report"
-#define EVENT_NOTI_CALL_SOUND_TWO_MIC "call_sound_two_mic"
-#define EVENT_NOTI_CALL_SOUND_DHA "call_sound_dha"
-
-#define EVENT_NOTI_SS_INFO "ss_info"
-#define EVENT_NOTI_SS_USSD "ss_ussd"
-
-#define EVENT_NOTI_PS_CALL_STATUS "ps_call_status"
-#define EVENT_NOTI_PS_DATA_COUNTER "ps_data_counter"
-#define EVENT_NOTI_PS_IPCONFIGURATION "ps_ipconfiguration"
-#define EVENT_NOTI_PS_HSDPA_STATUS "ps_hsdpa_status"
-#define EVENT_NOTI_PS_ATTACH_DETACH "ps_attach_detach"
-#define EVENT_NOTI_PS_EXTERNAL_CALL "ps_external_call"
-
-#define EVENT_NOTI_SAP_STATUS "sap_status"
-#define EVENT_NOTI_SAP_DISCONNECT "sap_disconnect"
-
-#define EVENT_NOTI_SIM_PIN_STATUS "sim_pin_status"
-
-#define EVENT_NOTI_SAT_ENVELOPE_RESP "sat_envelope_response"
-#define EVENT_NOTI_SAT_REFRESH_STATUS "sat_refresh_status"
-#define EVENT_NOTI_SAT_PROACTIVE_COMMAND "sat_proactive_command"
-#define EVENT_NOTI_SAT_CONTROL_RESULT "sat_control_result"
-
-#define EVENT_NOTI_NETWORK_REGISTRATION "network_regist"
-#define EVENT_NOTI_NETWORK_ICON_INFO "network_icon_info"
-#define EVENT_NOTI_NETWORK_TIME_INFO "network_time_info"
-#define EVENT_NOTI_NETWORK_IDENTITY "network_identity"
-
-#define EVENT_NOTI_SMS_INCOM_MSG "sms_incom_msg"
-#define EVENT_NOTI_SMS_SEND_ACK "sms_send_ack"
-#define EVENT_NOTI_SMS_MEMORY_STATUS "sms_memory_status"
-#define EVENT_NOTI_SMS_CB_INCOM_MSG "sms_cb_incom_msg"
-#define EVENT_NOTI_SMS_DELETE_MSG_CNF "sms_delete_msg_cnf"
-#define EVENT_NOTI_SMS_WRITE_MSG_CNF "sms_write_msg_cnf"
-#define EVENT_NOTI_SMS_DELIVERY_RPT_CNF "sms_deliver_rpt_cnf"
-#define EVENT_NOTI_SMS_DEVICE_READY "sms_device_ready"
-
-#define EVENT_NOTI_PHONEBOOK_STATUS "phonebook_status"
-#define EVENT_NOTI_PHONEBOOK_FIRST_INDEX "phonebook_first_index"
-
-#define EVENT_NOTI_GPS_ASSIST_DATA "gps_assist_data"
-#define EVENT_IND_GPS_MEASURE_POSITION "gps_measure_position"
-#define EVENT_NOTI_RESET_ASSIST_DATA "gps_reset_assist_data"
-
-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;
-
- TcoreHal *hal;
-};
-
-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)
-
-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);
-char* util_removeQuotes(void *data);
-
-#endif
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Ja-young Gu <jygu@samsung.com>
- *
- * 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_DISPATCH_H__
-#define __S_DISPATCH_H__
-
-void do_factory(TcoreHal *h, const ipc_message_type *ipc);
-void do_notification_message(TcorePlugin *p, const ipc_message_type *ipc);
-void do_notification_sys_message(TcorePlugin *p, const void *data);
-
-#endif
-#sbs-git:slp/pkgs/t/tel-plugin-imc
-Name: tel-plugin-imc
-Summary: imc plugin for telephony
-ExclusiveArch: %{arm}
-Version: 0.1.14
-Release: 1
-Group: System/Libraries
-License: Apache
-Source0: tel-plugin-imc-%{version}.tar.gz
-Requires(post): /sbin/ldconfig
+%define major 0
+%define minor 1
+%define patchlevel 72
+
+
+Name: tel-plugin-imc
+Version: %{major}.%{minor}.%{patchlevel}
+Release: 1
+License: Apache-2.0
+Summary: imc-plugin for Telephony
+Group: Development/Libraries
+Source0: tel-plugin-imc-%{version}.tar.gz
+
+%if "%{?tizen_profile_name}" == "mobile" && "%{_repository}" == "target"
+%else
+ExcludeArch: %{arm} %ix86 x86_64
+%endif
+
+BuildRequires: cmake
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(tcore)
+BuildRequires: pkgconfig(db-util)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(libxml-2.0)
+Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
-BuildRequires: cmake
-BuildRequires: pkgconfig(glib-2.0)
-BuildRequires: pkgconfig(dlog)
-BuildRequires: pkgconfig(tcore)
-BuildRequires: pkgconfig(db-util)
%description
IMC plugin for telephony
%setup -q
%build
-cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix}
-make %{?jobs:-j%jobs}
+%cmake .
+make %{?_smp_mflags}
%post
/sbin/ldconfig
%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 tel-plugin-imc.manifest
+
%defattr(-,root,root,-)
-#%doc COPYING
-%{_libdir}/telephony/plugins/*
+
+%{_libdir}/telephony/plugins/modems/*
/tmp/mcc_mnc_oper_list.sql
+/usr/share/license/%{name}
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hayoon Ko <hayoon.ko@samsung.com>
- *
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/utsname.h>
-
-#include <glib.h>
-
-#include <tcore.h>
-#include <plugin.h>
-#include <hal.h>
-#include <server.h>
-#include <at.h>
-#include <core_object.h>
-
-#include "s_common.h"
-#include "s_network.h"
-#include "s_modem.h"
-#include "s_sim.h"
-#include "s_sap.h"
-#include "s_ps.h"
-#include "s_call.h"
-#include "s_ss.h"
-#include "s_sms.h"
-#include "s_sat.h"
-#include "s_phonebook.h"
-#include "s_gps.h"
-
-static char *cp_name;
-static int cp_count = 0;
-
-#define MAX_CP_QUERY_COUNT 60
-
-static gboolean _query_cp_state(gpointer data)
-{
- gboolean power_state = FALSE;
- TcorePlugin *p = NULL;
- CoreObject* obj = NULL;
- TcoreHal* h = NULL;
-
- p = (TcorePlugin*)data;
-
- if(cp_count > MAX_CP_QUERY_COUNT){
- dbg("cp query counter exceeds MAX_CP_QUERY_COUNT");
- return FALSE;
- }
- obj = tcore_plugin_ref_core_object(p, "modem");
- h = tcore_object_get_hal(obj);
- power_state = tcore_hal_get_power_state(h);
-
- if(TRUE == power_state){
- dbg("CP READY");
- s_modem_send_poweron(p);
- return FALSE;
- }
- else{
- dbg("CP NOT READY, cp_count :%d", cp_count);
- cp_count++;
- return TRUE;
- }
-}
-
-static enum tcore_hook_return on_hal_send(TcoreHal *hal, unsigned int data_len, void *data, void *user_data)
-{
- hook_hex_dump(TX, data_len, data);
- return TCORE_HOOK_RETURN_CONTINUE;
-}
-
-static void on_hal_recv(TcoreHal *hal, unsigned int data_len, const void *data, void *user_data)
-{
- msg("=== RX data DUMP =====");
- util_hex_dump(" ", data_len, data);
- msg("=== RX data DUMP =====");
-}
-
-static gboolean on_load()
-{
- dbg("i'm load!");
-
- return TRUE;
-}
-
-static int _get_cp_name(char **name)
-{
- struct utsname u;
-
- char *svnet1_models[] = {
- "F1", "S1", "M2", "H2", "H2_SDK",
- "CRESPO", "STEALTHV", "SLP45", "Kessler", "P1P2",
- "U1SLP", "U1HD", "SLP7_C210", "SLP10_C210", NULL
- };
-
- char *svnet2_models[] = { "SMDK4410", "SMDK4212", "SLP_PQ", "SLP_PQ_LTE", "SLP_NAPLES", "REDWOOD", "TRATS", NULL };
-
- char *tty_models[] = { "QCT MSM8X55 SURF", "QCT MSM7x27a FFA", NULL };
-
- int i = 0;
-
- if (*name) {
- dbg("[ error ] name is not empty");
- return FALSE;
- }
-
- memset(&u, '\0', sizeof(struct utsname));
-
- uname(&u);
-
- dbg("u.nodename : [ %s ]", u.nodename);
-
- for (i = 0; svnet1_models[i]; i++) {
- if (!strcmp(u.nodename, svnet1_models[i])) {
- *name = g_new0(char, 5);
- strcpy(*name, "6260");
- return 5;
- }
- }
-
- for (i = 0; svnet2_models[i]; i++) {
- if (!strcmp(u.nodename, svnet2_models[i])) {
- *name = g_new0(char, 5);
- strcpy(*name, "6262");
- return 5;
- }
- }
-
- for (i = 0; tty_models[i]; i++) {
- if (!strcmp(u.nodename, tty_models[i])) {
- *name = g_new0(char, 6);
- strcpy(*name, "dpram");
- return 6;
- }
- }
-
- dbg("[ error ] unknown model : (%s)", u.nodename);
-
- return 0;
-}
-
-static gboolean on_init(TcorePlugin *p)
-{
- TcoreHal *h;
- struct global_data *gd;
- // char *cp_name = 0;
- int len = 0;
-
- if (!p)
- return FALSE;
-
- gd = calloc(sizeof(struct global_data), 1);
- if (!gd)
- return FALSE;
-
- dbg("i'm init!");
-
- gd->msg_auto_id_current = 0;
- gd->msg_auto_id_start = 1;
- gd->msg_auto_id_end = 255;
-
- len = _get_cp_name(&cp_name);
- if (!len) {
- dbg("[ error ] unsupport cp (name : %s)", cp_name);
- free(gd);
- return FALSE;
- }
-
- /* FIXME: HAL will reside in Co-object.
- * This HAL is just used as default before MUX setup.
- * Each HAL has AT pasre functionality.
- */
- h = tcore_server_find_hal(tcore_plugin_ref_server(p), cp_name);
- if (!h) {
- g_free(cp_name);
- free(gd);
- return FALSE;
- }
-
- // set physical hal into plugin's userdata
- gd->hal = h;
-
- tcore_plugin_link_user_data(p, gd);
-
- tcore_hal_add_send_hook(h, on_hal_send, p);
- tcore_hal_add_recv_callback(h, on_hal_recv, p);
-
- s_modem_init(p, h);
- s_sim_init(p, h);
- s_sat_init(p, h);
- s_network_init(p, h);
- s_ps_init(p, h);
- s_call_init(p, h);
- s_ss_init(p, h);
- s_sms_init(p, h);
-
- g_free(cp_name);
-
- tcore_hal_set_power(h, TRUE);
-//wait until CP is ready
- g_timeout_add_full(G_PRIORITY_HIGH,500,_query_cp_state, p, 0 );
- return TRUE;
-}
-
-static void on_unload(TcorePlugin *p)
-{
- struct global_data *gd;
-
- if (!p)
- return;
-
- dbg("i'm unload");
-
- gd = tcore_plugin_ref_user_data(p);
- if (gd) {
- free(gd);
- }
-}
-
-struct tcore_plugin_define_desc plugin_define_desc = {
- .name = "IMC",
- .priority = TCORE_PLUGIN_PRIORITY_MID,
- .version = 1,
- .load = on_load,
- .init = on_init,
- .unload = on_unload
-};
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hayoon Ko <hayoon.ko@samsung.com>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/utsname.h>
+#include <glib.h>
+#include <tcore.h>
+#include <server.h>
+#include <plugin.h>
+#include <core_object.h>
+#include <hal.h>
+#include <at.h>
+#include <server.h>
+
+#include "imc_network.h"
+#include "imc_modem.h"
+#include "imc_sim.h"
+#include "imc_sap.h"
+#include "imc_ps.h"
+#include "imc_call.h"
+#include "imc_ss.h"
+#include "imc_sms.h"
+#include "imc_sat.h"
+#include "imc_phonebook.h"
+#include "imc_gps.h"
+
+static void on_confirmation_modem_message_send(TcorePending *p,
+ gboolean result,
+ void *user_data)
+{
+ dbg("msg out from queue");
+
+ dbg("%s", result == FALSE ? "SEND FAIL" : "SEND OK");
+}
+
+static void on_response_bootup_subscription(TcorePending *p,
+ int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ dbg("Entry");
+
+ if (resp->success > 0) {
+ dbg("RESULT - OK");
+ } else {
+ err("RESULT - ERROR");
+ }
+}
+
+static void on_response_last_bootup_subscription(TcorePending *p,
+ int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ TcorePlugin *plugin = tcore_pending_ref_plugin(p);
+ gboolean ret;
+ dbg("Last Subscription - COMPLETED");
+
+ if (resp->success) {
+ dbg("RESULT - OK");
+ } else {
+ err("RESULT - FAIL");
+ }
+
+ dbg("Boot-up configration completed for IMC modem. %s",
+ "Bring CP to ONLINE state based on Flightmode status");
+
+ /* Modem Power */
+ ret = modem_power_on(plugin);
+ dbg("Modem Power ON: [%s]", (ret == TRUE ? "SUCCESS" : "FAIL"));
+
+ /* NVM Registration */
+ dbg("Registering modem for NVM manager");
+ modem_register_nvm(tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_MODEM));
+}
+
+static void _modem_subscribe_events(TcorePlugin *plugin)
+{
+ CoreObject *co_call = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL);
+ CoreObject *co_sim = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
+ CoreObject *co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
+ CoreObject *co_network = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_NETWORK);
+ CoreObject *co_ps = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_PS);
+ CoreObject *co_sap = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SAP);
+ CoreObject *co_gps = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_GPS);
+
+ dbg("Entry");
+
+ /* URC Subscriptions per Module */
+
+ /****** SIM subscriptions ******/
+ /* XSIMSTATE */
+ tcore_prepare_and_send_at_request(co_sim, "at+xsimstate=1", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /****** CALL subscriptions ******/
+ /* XCALLSTAT */
+ tcore_prepare_and_send_at_request(co_call, "at+xcallstat=1", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /* CSSN */
+ tcore_prepare_and_send_at_request(co_call, "at+cssn=1,1", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /* CUSD */
+ tcore_prepare_and_send_at_request(co_call, "at+cusd=1", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /* CLIP */
+ tcore_prepare_and_send_at_request(co_call, "at+clip=1", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /****** NETWORK subscriptions ******/
+ /* CREG */
+ tcore_prepare_and_send_at_request(co_network, "at+creg=2", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /* CGREG */
+ tcore_prepare_and_send_at_request(co_network, "at+cgreg=2", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /* Allow Automatic Time Zone updation via NITZ */
+ tcore_prepare_and_send_at_request(co_network, "at+ctzu=1", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /* TZ, Time & Daylight changing event reporting Subscription */
+ tcore_prepare_and_send_at_request(co_network, "at+ctzr=1", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /* XMER */
+ tcore_prepare_and_send_at_request(co_network, "at+xmer=1", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /****** PS subscriptions ******/
+ /* CGEREP */
+ tcore_prepare_and_send_at_request(co_ps, "at+cgerep=1", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /* XDATASTAT */
+ tcore_prepare_and_send_at_request(co_ps, "at+xdatastat=1", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+
+ /* XDNS */
+ tcore_prepare_and_send_at_request(co_ps, "at+xdns=1,1", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /* CMEE */
+ tcore_prepare_and_send_at_request(co_ps, "at+cmee=2", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /****** SMS subscriptions ******/
+ /* CMEE */
+ tcore_prepare_and_send_at_request(co_sms, "at+cmee=2", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /* Incoming SMS, Cell Broadcast, Status Report Subscription */
+ tcore_prepare_and_send_at_request(co_sms, "at+cnmi=1,2,2,1,0", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /* Text/PDU mode Subscription */
+ tcore_prepare_and_send_at_request(co_sms, "at+cmgf=0", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /****** GPS subscriptions ******/
+ /* AGPS- Assist Data and Reset Assist Data Subscription */
+ tcore_prepare_and_send_at_request(co_gps, "at+cposr=1", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ tcore_prepare_and_send_at_request(co_gps, "at+xcposr=1", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ /****** SAP subscriptions ******/
+ /* XBCSTAT */
+ tcore_prepare_and_send_at_request(co_sap, "at+xbcstat=1", NULL, TCORE_AT_NO_RESULT, NULL,
+ on_response_last_bootup_subscription, NULL,
+ on_confirmation_modem_message_send, NULL, 0, NULL, NULL);
+
+ dbg("Exit");
+}
+
+/* Initializer Table */
+struct object_initializer init_table = {
+ .modem_init = imc_modem_init,
+ .sim_init = imc_sim_init,
+ .sat_init = imc_sat_init,
+ .sap_init = imc_sap_init,
+ .network_init = imc_network_init,
+ .ps_init = imc_ps_init,
+ .call_init = imc_call_init,
+ .ss_init = imc_ss_init,
+ .sms_init = imc_sms_init,
+ .phonebook_init = imc_phonebook_init,
+ .gps_init = imc_gps_init,
+};
+
+/* Deinitializer Table */
+struct object_deinitializer deinit_table = {
+ .modem_deinit = imc_modem_exit,
+ .sim_deinit = imc_sim_exit,
+ .sat_deinit = imc_sat_exit,
+ .sap_deinit = imc_sap_exit,
+ .network_deinit = imc_network_exit,
+ .ps_deinit = imc_ps_exit,
+ .call_deinit = imc_call_exit,
+ .ss_deinit = imc_ss_exit,
+ .sms_deinit = imc_sms_exit,
+ .phonebook_deinit = imc_phonebook_exit,
+ .gps_deinit = imc_gps_exit,
+};
+
+static gboolean on_load()
+{
+ dbg("Load!!!");
+
+ return TRUE;
+}
+
+static gboolean on_init(TcorePlugin *p)
+{
+ dbg("Init!!!");
+ if (p == NULL)
+ return FALSE;
+
+ /* Initialize Modules (Core Objects) */
+ if (tcore_object_init_objects(p, &init_table)
+ != TCORE_RETURN_SUCCESS) {
+ err("Failed to initialize Core Objects");
+ return FALSE;
+ }
+
+ /* Subscribe for the Events from CP */
+ _modem_subscribe_events(p);
+
+ dbg("Init - Successful");
+ return TRUE;
+}
+
+static void on_unload(TcorePlugin *p)
+{
+ dbg("Unload!!!");
+
+ if (p == NULL)
+ return;
+
+ /* Deinitialize Modules (Core Objects) */
+ tcore_object_deinit_objects(p, &deinit_table);
+}
+
+/* IMC - Modem Plug-in Descriptor */
+struct tcore_plugin_define_desc plugin_define_desc = {
+ .name = "IMC",
+ .priority = TCORE_PLUGIN_PRIORITY_MID,
+ .version = 1,
+ .load = on_load,
+ .init = on_init,
+ .unload = on_unload
+};
#include <core_object.h>
#include <plugin.h>
#include <queue.h>
+#include <storage.h>
#include <co_call.h>
#include <user_request.h>
#include <server.h>
#include <at.h>
+#include <vconf.h>
-#include "s_common.h"
-#include "s_call.h"
+#include "imc_common.h"
+#include "imc_call.h"
#define STATUS_INCOMING 4
#define STATUS_WAITING 5
#define STATUS_CONNECTED 7
#define COMMA 0X2c
+#define MAX_CALL_DTMF_DIGITS_LEN 32
static gboolean setsoundpath = FALSE;
static gboolean soundvolume = FALSE;
static void _call_status_incoming(TcorePlugin *p, CallObject *co);
static void _call_status_waiting(TcorePlugin *p, CallObject *co);
static TReturn _call_list_get(CoreObject *o, gboolean *event_flag);
-static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur);
+/* Todo Need to check whether this api is required */
+//static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur);
/************************* CONFIRMATION ***************************/
static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data); // from Kernel
static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type);
static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type);
-static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data);
+//static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data);
static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data);
/************************* RESPONSES ***************************/
{ 111, CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED}, {127, CC_CAUSE_INTERWORKING_UNSPECIFIED},
};
-static enum tcore_call_cli_mode _get_clir_status(char *num)
-{
- enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
- dbg("Entry");
-
- if (!strncmp(num, "*31#", 4)) {
- dbg("CLI mode restricted");
- return TCORE_CALL_CLI_MODE_RESTRICT;
- }
-
- if (!strncmp(num, "#31#", 4)) {
- dbg("CLI mode allowed");
- return TCORE_CALL_CLI_MODE_PRESENT;
- }
-
- err("Exit");
- return clir;
-}
-
static enum tcore_call_status _call_status(unsigned int status)
{
dbg("Entry");
static int _compare_call_end_cause(int networkcause)
{
unsigned int count;
+
for (count = 0; count < sizeof(call_end_cause_table) / sizeof(call_end_cause_info); count++) {
if (call_end_cause_table[count].network_cause == networkcause)
return (call_end_cause_table[count].tapi_cause);
{
TcoreHal *hal = NULL;
TReturn ret;
+
dbg("Entry");
tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
UserRequest *ur;
dbg("Entry");
- core_obj = tcore_plugin_ref_core_object(p, "call");
+ core_obj = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL);
dbg("Call ID [%d], Call Status [%d]", tcore_call_object_get_id(co), tcore_call_object_get_status(co));
if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_IDLE) {
// Create new AT-Command request
req = tcore_at_request_new(cmd_str, "+XCEER", TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return;
+ }
+
dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
// Free command string
g_free(cmd_str);
if (!ret) {
err("Failed to send AT-Command request");
+ // free only UserRequest.
+ if (ur) {
+ tcore_user_request_free(ur);
+ ur = NULL;
+ }
return;
}
} else {
static void _call_status_dialing(TcorePlugin *p, CallObject *co)
{
struct tnoti_call_status_dialing data;
+
dbg("Entry");
if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_DIALING) {
// Send notification to TAPI
tcore_server_send_notification(tcore_plugin_ref_server(p),
- tcore_plugin_ref_core_object(p, "call"),
+ tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
TNOTI_CALL_STATUS_DIALING,
sizeof(struct tnoti_call_status_dialing),
(void *) &data);
static void _call_status_alert(TcorePlugin *p, CallObject *co)
{
struct tnoti_call_status_alert data;
+
dbg("Entry");
// Alerting has just 1 data 'CALL ID'
// Send notification to TAPI
tcore_server_send_notification(tcore_plugin_ref_server(p),
- tcore_plugin_ref_core_object(p, "call"),
+ tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
TNOTI_CALL_STATUS_ALERT,
sizeof(struct tnoti_call_status_alert),
(void *) &data);
static void _call_status_active(TcorePlugin *p, CallObject *co)
{
struct tnoti_call_status_active data;
+
dbg("Entry");
if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ACTIVE) {
// Send notification to TAPI
tcore_server_send_notification(tcore_plugin_ref_server(p),
- tcore_plugin_ref_core_object(p, "call"),
+ tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
TNOTI_CALL_STATUS_ACTIVE,
sizeof(struct tnoti_call_status_active),
(void *) &data);
static void _call_status_held(TcorePlugin *p, CallObject *co)
{
struct tnoti_call_status_held data;
+
dbg("Entry");
if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_HELD) {
// Send notification to TAPI
tcore_server_send_notification(tcore_plugin_ref_server(p),
- tcore_plugin_ref_core_object(p, "call"),
+ tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
TNOTI_CALL_STATUS_HELD,
sizeof(struct tnoti_call_status_held),
(void *) &data);
static void _call_status_incoming(TcorePlugin *p, CallObject *co)
{
struct tnoti_call_status_incoming data;
+
dbg("Entry");
if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_INCOMING) {
// Send notification to TAPI
tcore_server_send_notification(tcore_plugin_ref_server(p),
- tcore_plugin_ref_core_object(p, "call"),
+ tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
TNOTI_CALL_STATUS_INCOMING,
sizeof(struct tnoti_call_status_incoming),
(void *) &data);
// Create new Pending Request
pending = tcore_pending_new(o, 0);
req = tcore_at_request_new(cmd_str, "+CLCC", TCORE_AT_MULTILINE);
-
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ if (ur) {
+ tcore_user_request_free(ur);
+ ur = NULL;
+ }
+ return TCORE_RETURN_FAILURE;
+ }
g_free(cmd_str);
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
ret = _call_request_message(pending, o, ur, on_response_call_list_get, event_flag);
if (!ret) {
err("AT request (%s) sending failed", req->cmd);
+ // free only UserRequest.
+ if (ur) {
+ tcore_user_request_free(ur);
+ ur = NULL;
+ }
return TCORE_RETURN_FAILURE;
}
return;
}
+static void call_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
+{
+ TcoreATRequest *req = NULL;
+ TcoreHal *hal = NULL;
+ TcorePending *pending = NULL;
+ TReturn ret;
+
+ hal = tcore_object_get_hal(co);
+ dbg("hal: %p", hal);
+
+ pending = tcore_pending_new(co, 0);
+ if (!pending)
+ return;
+ req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ return;
+ }
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, callback, NULL);
+ tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
+ ret = tcore_hal_send_request(hal, pending);
+ if (ret != TCORE_RETURN_SUCCESS)
+ err("Failed to process request");
+}
+
static void on_confirmation_call_outgoing(TcorePending *p, int data_len, const void *data, void *user_data)
{
UserRequest *ur = NULL;
const char *line = NULL;
const TcoreATResponse *response = data;
struct tresp_call_dial resp;
- int error;
+ enum telephony_call_error error;
dbg("Entry");
ur = tcore_pending_ref_user_request(p);
if (ur) {
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = CALL_ERROR_NONE;
} else {
dbg("RESPONSE NOT OK");
if (g_slist_length(tokens) < 1) {
err("Unspecified error cause OR string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
} else {
error = atoi(g_slist_nth_data(tokens, 0));
-
+ err("Error: [%d]", error);
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
}
// Free tokens
err("User Request is NULL");
}
- dbg("Exit")
+ dbg("Exit");
return;
}
const char *line = NULL;
const TcoreATResponse *response = data;
struct tresp_call_answer resp;
- int error;
+ enum telephony_call_error error;
dbg("Entry");
ur = tcore_pending_ref_user_request(p);
if (ur) {
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = CALL_ERROR_NONE;
} else {
dbg("RESPONSE NOT OK");
if (g_slist_length(tokens) < 1) {
err("Unspecified error cause OR string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
} else {
error = atoi(g_slist_nth_data(tokens, 0));
-
+ err("Error: [%d]", error);
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
}
// Free tokens
const char *line = NULL;
const TcoreATResponse *response = data;
struct tresp_call_answer resp;
- int error;
+ enum telephony_call_error error;
dbg("Entry");
if (ur) {
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = CALL_ERROR_NONE;
} else {
dbg("RESPONSE NOT OK");
line = (const char *) response->final_response;
if (g_slist_length(tokens) < 1) {
err("Unspecified error cause OR string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
} else {
error = atoi(g_slist_nth_data(tokens, 0));
+ err("Error: [%d]", error);
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
}
// Free tokens
const char *line = NULL;
const TcoreATResponse *response = data;
struct tresp_call_answer resp;
- int error;
+ enum telephony_call_error error;
dbg("Entry");
ur = tcore_pending_ref_user_request(p);
if (ur) {
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = CALL_ERROR_NONE;
} else {
dbg("RESPONSE NOT OK");
line = (const char *) response->final_response;
if (g_slist_length(tokens) < 1) {
err("Unspecified error cause OR string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
} else {
error = atoi(g_slist_nth_data(tokens, 0));
+ err("Error: [%d]", error);
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
}
// Free tokens
const char *line = NULL;
const TcoreATResponse *response = data;
struct tresp_call_answer resp;
- int error;
+ enum telephony_call_error error;
dbg("Entry");
if (ur) {
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = CALL_ERROR_NONE;
} else {
err("RESPONSE NOT OK");
line = (const char *) response->final_response;
if (g_slist_length(tokens) < 1) {
err("Unspecified error cause OR string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
} else {
error = atoi(g_slist_nth_data(tokens, 0));
-
+ err("Error: [%d]", error);
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
}
// Free tokens
struct tresp_call_end resp;
GSList *tokens = NULL;
const char *line = NULL;
- int error;
+ enum telephony_call_error error;
const TcoreATResponse *response = data;
dbg("Entry");
if (ur) {
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = CALL_ERROR_NONE;
} else {
err("RESPONSE NOT OK");
if (g_slist_length(tokens) < 1) {
err("Unspecified error cause OR string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
} else {
error = atoi(g_slist_nth_data(tokens, 0));
-
+ err("Error: [%d]", error);
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
}
tcore_at_tok_free(tokens);
}
{
// skip response handling - actual result will be handled in on_confirmation_call_release_all
const TcoreATResponse *response = data;
+
dbg("Entry");
if (response->success > 0) {
GSList *tokens = NULL;
const char *line = NULL;
const TcoreATResponse *response = NULL;
- int error;
+ enum telephony_call_error error;
dbg("Entry");
ur = tcore_pending_ref_user_request(p);
response = (TcoreATResponse *) data;
if (response->success > 0) {
dbg("RESPONSE OK");
- error = TCORE_RETURN_SUCCESS;
+ error = CALL_ERROR_NONE;
} else {
err("RESPONSE NOT OK");
if (g_slist_length(tokens) < 1) {
err("Unspecified error cause OR string corrupted");
- error = TCORE_RETURN_3GPP_ERROR;
+ error = CALL_ERROR_SERVICE_UNAVAIL;
} else {
error = atoi(g_slist_nth_data(tokens, 0));
// TODO: CMEE error mapping is required.
- error = TCORE_RETURN_3GPP_ERROR;
+ error = CALL_ERROR_SERVICE_UNAVAIL;
}
// Free tokens
}
break;
- case TRESP_CALL_SEND_DTMF:
+ case TRESP_CALL_START_CONT_DTMF:
{
struct tresp_call_dtmf resp;
resp.err = error;
dbg("call dtmf response");
// Send reponse to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_SEND_DTMF, sizeof(struct tresp_call_dtmf), &resp);
+ tcore_user_request_send_response(ur, TRESP_CALL_START_CONT_DTMF, sizeof(struct tresp_call_dtmf), &resp);
}
break;
static void on_confirmation_call_dtmf(TcorePending *p, int data_len, const void *data, void *user_data)
{
dbg("Entry");
- _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SEND_DTMF);
+ _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_START_CONT_DTMF);
return;
}
+#if 0
static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data)
{
GSList *tokens = NULL;
const char *line = NULL;
const TcoreATResponse *response = data;
- int error;
+ enum telephony_call_error error;
dbg("Entry");
if (response->success > 0) {
dbg("RESPONSE OK");
- error = TCORE_RETURN_SUCCESS;
+ error = CALL_ERROR_NONE;
} else {
err("RESPONSE NOT OK");
line = (const char *) response->final_response;
tokens = tcore_at_tok_new(line);
if (g_slist_length(tokens) < 1) {
err("err cause not specified or string corrupted");
- error = TCORE_RETURN_3GPP_ERROR;
+ error = CALL_ERROR_SERVICE_UNAVAIL;
} else {
error = atoi(g_slist_nth_data(tokens, 0));
// TODO: CMEE error mapping is required.
dbg("Set dtmf tone duration response - %d", error);
return;
}
+#endif
static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data)
{
if (ur) {
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = CALL_ERROR_NONE;
} else {
err("RESPONSE NOT OK");
line = (const char *) response->final_response;
tokens = tcore_at_tok_new(line);
if (g_slist_length(tokens) < 1) {
err("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
} else {
resp.err = atoi(g_slist_nth_data(tokens, 0));
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
}
// Free tokens
return;
}
+static void on_confirmation_set_sound_path(TcorePending *p, int data_len,
+ const void *data,
+ void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ struct tnoti_call_sound_path *snd_path = user_data;
+ struct tresp_call_set_sound_path resp_set_sound_path;
+ UserRequest *ur = tcore_pending_ref_user_request(p);
+ TcorePlugin *plugin = tcore_pending_ref_plugin(p);
+ CoreObject *co_call;
+
+ if (ur == NULL) {
+ err("User Request is NULL");
+ g_free(user_data);
+ return;
+ }
+
+ if (resp->success <= 0) {
+
+ dbg("RESPONSE NOT OK");
+ resp_set_sound_path.err = TRUE;
+
+ goto out;
+ }
+
+ dbg("RESPONSE OK");
+ resp_set_sound_path.err = FALSE;
+
+ co_call = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL);
+
+ /* Notify control plugin about sound path */
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ co_call, TNOTI_CALL_SOUND_PATH,
+ sizeof(struct tnoti_call_sound_path),
+ snd_path);
+
+out:
+ /* Answer TAPI request */
+ tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH,
+ sizeof(resp_set_sound_path),
+ &resp_set_sound_path);
+
+ g_free(user_data);
+}
+
static void on_confirmation_call_set_source_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
{
UserRequest *ur = NULL;
const char *line = NULL;
const TcoreATResponse *response = data;
char *resp_str = NULL;
- struct tresp_call_sound_set_path resp;
- int error;
+ struct tresp_call_set_sound_path resp;
+ gboolean error;
dbg("Entry");
ur = tcore_pending_ref_user_request(p);
resp_str = g_slist_nth_data(tokens, 0);
if (!g_slist_nth_data(tokens, 0)) {
err("group_id is missing");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
goto OUT;
}
if (!g_slist_nth_data(tokens, 1)) {
err(" function_id is missing");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
goto OUT;
}
error = atoi(resp_str);
if (0 == error) {
dbg("Response is Success");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = FALSE;
} else {
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
}
}
OUT:
if (g_slist_length(tokens) < 1) {
err("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
} else {
error = atoi(g_slist_nth_data(tokens, 0));
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
}
// Free tokens
}
if (ur) {
- if (resp.err != TCORE_RETURN_SUCCESS) { // Send only failed notification . success notification send when destination device is set.
+ if ( resp.err ) { // Send only failed notification . success notification send when destination device is set.
// Send notification to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
+ tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_set_sound_path), &resp);
setsoundpath = TRUE;
}
} else {
GSList *tokens = NULL;
const char *line = NULL;
char *resp_str = NULL;
- struct tresp_call_sound_set_path resp;
+ struct tresp_call_set_sound_path resp;
const TcoreATResponse *response = data;
- int error;
+ gboolean error;
dbg("Entry");
resp_str = g_slist_nth_data(tokens, 0);
if (!g_slist_nth_data(tokens, 0)) {
dbg("group_id is missing");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
goto OUT;
}
if (!g_slist_nth_data(tokens, 1)) {
dbg("function_id is missing");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
goto OUT;
}
error = atoi(resp_str);
if (0 == error) {
dbg("Response is Success");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = FALSE;
} else {
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
}
}
if (g_slist_length(tokens) < 1) {
err("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
} else {
error = atoi(g_slist_nth_data(tokens, 0));
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
}
// Free tokens
setsoundpath = FALSE;
} else {
// Send response to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
+ tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_set_sound_path), &resp);
}
} else {
dbg("User Request is NULL");
const char *line = NULL;
const TcoreATResponse *response = data;
char *resp_str = NULL;
- struct tresp_call_sound_set_volume_level resp;
- int error;
+ struct tresp_call_set_sound_volume_level resp;
+ gboolean error;
ur = tcore_pending_ref_user_request(p);
dbg("Entry");
resp_str = g_slist_nth_data(tokens, 0);
if (!g_slist_nth_data(tokens, 0)) {
err("group_id is missing");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
goto OUT;
}
if (!g_slist_nth_data(tokens, 1)) {
err("function_id is missing");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
goto OUT;
}
if (0 == error) {
dbg("Response is Success ");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = FALSE;
} else {
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
}
}
if (g_slist_length(tokens) < 1) {
err("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
} else {
error = atoi(g_slist_nth_data(tokens, 0));
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
}
// Free tokens
if (ur) {
if (resp.err && soundvolume == FALSE) { // Send only failed notification . success notification send when destination device is set.
// Send reposne to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
+ tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_set_sound_volume_level), &resp);
soundvolume = TRUE;
}
} else {
const char *line = NULL;
char *resp_str = NULL;
const TcoreATResponse *response = data;
- struct tresp_call_sound_set_volume_level resp;
- int error;
+ struct tresp_call_set_sound_volume_level resp;
+ gboolean error;
dbg("Entry");
if (!g_slist_nth_data(tokens, 0)) {
err("group_id is missing");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
goto OUT;
}
if (!g_slist_nth_data(tokens, 1)) {
err("function_id is missing");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
goto OUT;
}
if (0 == error) {
dbg("Response is Success");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = FALSE;
} else {
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
}
}
if (g_slist_length(tokens) < 1) {
err("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
} else {
error = atoi(g_slist_nth_data(tokens, 0));
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
}
tcore_at_tok_free(tokens);
soundvolume = FALSE;
} else {
// Send reposne to TAPI
- tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_sound_set_volume_level), &resp);
+ tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_set_sound_volume_level), &resp);
}
} else {
err("User Request is NULL");
}
-static void on_confirmation_call_mute(TcorePending *p, int data_len, const void *data, void *user_data)
+static void on_confirmation_call_set_sound_mute_status(TcorePending *p, int data_len, const void *data, void *user_data)
{
UserRequest *ur = NULL;
GSList *tokens = NULL;
const char *line = NULL;
char *resp_str = NULL;
- struct tresp_call_mute resp;
+ struct tresp_call_set_sound_mute_status resp;
const TcoreATResponse *response = data;
- int error;
-
- dbg("Entry");
-
- ur = tcore_pending_ref_user_request(p);
-
- if (!response) {
- err("Input data is NULL");
- return;
- }
-
- if (response->success > 0) {
- dbg("RESPONSE OK");
-
- line = (const char *) (((GSList *) response->lines)->data);
- tokens = tcore_at_tok_new(line);
- resp_str = g_slist_nth_data(tokens, 0);
-
- if (!g_slist_nth_data(tokens, 0)) {
- err("group_id is missing");
- resp.err = TCORE_RETURN_3GPP_ERROR;
- goto OUT;
- }
-
- if (!g_slist_nth_data(tokens, 1)) {
- err(" function_id is missing");
- resp.err = TCORE_RETURN_3GPP_ERROR;
- goto OUT;
- }
-
- resp_str = g_slist_nth_data(tokens, 2);
-
- if (resp_str) {
- error = atoi(resp_str);
- if (0 == error) {
- dbg("Response is Success");
- resp.err = TCORE_RETURN_SUCCESS;
- } else {
- resp.err = TCORE_RETURN_3GPP_ERROR;
- }
- }
-OUT:
- // Free tokens
- tcore_at_tok_free(tokens);
- } else {
- dbg("RESPONSE NOT OK");
-
- line = (const char *) response->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- err("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
- } else {
- error = atoi(g_slist_nth_data(tokens, 0));
-
- // TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
- }
-
- // Free tokens
- tcore_at_tok_free(tokens);
- }
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_MUTE, sizeof(struct tresp_call_mute), &resp);
- } else {
- err("User Request is NULL");
- }
-
- dbg("Exit");
- return;
-}
-
-static void on_confirmation_call_unmute(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *response = NULL;
- struct tresp_call_unmute resp;
- GSList *tokens = NULL;
- const char *line = NULL;
- UserRequest *ur = NULL;
- char *resp_str = NULL;
- int error;
+ gboolean error;
dbg("Entry");
- response = (TcoreATResponse *) data;
ur = tcore_pending_ref_user_request(p);
if (!response) {
if (!g_slist_nth_data(tokens, 0)) {
err("group_id is missing");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
goto OUT;
}
if (!g_slist_nth_data(tokens, 1)) {
err(" function_id is missing");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
goto OUT;
}
error = atoi(resp_str);
if (0 == error) {
dbg("Response is Success");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = FALSE;
} else {
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
}
}
OUT:
if (g_slist_length(tokens) < 1) {
err("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
} else {
error = atoi(g_slist_nth_data(tokens, 0));
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = TRUE;
}
// Free tokens
}
if (ur) {
- tcore_user_request_send_response(ur, TRESP_CALL_UNMUTE, sizeof(struct tresp_call_unmute), &resp);
+ tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_MUTE_STATUS, sizeof(struct tresp_call_set_sound_mute_status), &resp);
} else {
err("User Request is NULL");
}
int cllc_info = 0, countCalls = 0, countValidCalls = 0;
int error = 0;
+
dbg("Entry");
plugin = tcore_pending_ref_plugin(p);
if (0 == countCalls) {
err("Call count is zero");
+ if (event_flag) {
+ g_free(event_flag);
+ event_flag = NULL;
+ }
return;
}
tcore_call_object_set_type(co, call_type(call_list[cllc_info].info.type));
tcore_call_object_set_direction(co, call_list[cllc_info].info.direction);
tcore_call_object_set_multiparty_state(co, _call_is_in_mpty(call_list[cllc_info].info.mpty));
- tcore_call_object_set_cli_info(co, CALL_CLI_MODE_DEFAULT, call_list[cllc_info].number);
+ tcore_call_object_set_cli_info(co, CALL_CLI_MODE_DEFAULT, 0, call_list[cllc_info].number, strlen(call_list[cllc_info].number));
tcore_call_object_set_active_line(co, 0);
if (*event_flag) {
}
// Free User data
+ if (event_flag) {
g_free(event_flag);
+ event_flag = NULL;
+ }
dbg("Exit");
return;
unsigned int num_type;
GSList *tokens = NULL;
char *resp = NULL;
+
dbg("Entry");
tokens = tcore_at_tok_new(line);
}
// Strike off double quotes
num = util_removeQuotes(resp);
- dbg("num after removing quotes - %s", num);
-
- p_call->info.num_len = strlen(resp);
- dbg("num_len : [0x%x]\n", p_call->info.num_len);
+ if (num) {
+ dbg("num after removing quotes - %s", num);
+ p_call->info.num_len = strlen(resp);
+ dbg("num_len : [0x%x]\n", p_call->info.num_len);
+ }
// parse <num type>
resp = g_slist_nth_data(tokens, 6);
// international number
p_call->number[0] = '+';
memcpy(&(p_call->number[1]), num, strlen(num));
- } else {
+ } else if (num) {
memcpy(&(p_call->number), num, strlen(num));
}
dbg("incoming number - %s", p_call->number);
ERROR:
err("Invalid CLCC line");
- if (num) {
- g_free(num);
- num = NULL;
- }
+ g_free(num);
// Free tokens
tcore_at_tok_free(tokens);
pId = g_slist_nth_data(tokens, 0);
if (!pId) {
dbg("[error]:Call id is missing from +XCALLSTAT indication");
+ tcore_at_tok_free(tokens);
return;
}
dupco = tcore_call_object_find_by_id(o, call_id);
if (dupco != NULL) {
dbg("co with same id already exist. skip");
+ tcore_at_tok_free(tokens);
return;
}
co = tcore_call_object_new(o, call_id);
if (!co) {
dbg("[ error ] co is NULL");
+ tcore_at_tok_free(tokens);
return;
}
pId = g_slist_nth_data(tokens, 0);
if (!pId) {
dbg("Error:Call id is missing from %XCALLSTAT indication");
+ tcore_at_tok_free(tokens);
return;
}
dupco = tcore_call_object_find_by_id(o, call_id);
if (dupco != NULL) {
dbg("co with same id already exist. skip");
+ tcore_at_tok_free(tokens);
return;
}
co = tcore_call_object_new(o, call_id);
if (!co) {
dbg("[ error ] co is NULL");
+ tcore_at_tok_free(tokens);
return;
}
- dbg("freeing at token")
+ dbg("freeing at token");
tcore_at_tok_free(tokens);
eflag = g_new0(gboolean, 1);
// parse <Call Id>
pCallId = g_slist_nth_data(tokens, 0);
if (!pCallId) {
- dbg("pCallId is missing from %XCALLSTAT indiaction");
+ dbg("CallId is missing from %XCALLSTAT indication");
+ tcore_at_tok_free(tokens);
+ return;
} else {
id = atoi(pCallId);
dbg("call id = %d", id);
break;
case CALL_STATUS_HELD:
+ {
dbg("call(%d) status : [ held ]", id);
- break;
+ co = tcore_call_object_find_by_id(o, id);
+ if (!co) {
+ dbg("co is NULL");
+ return;
+ }
+ _call_status_held(plugin, co);
+ }
+ break;
case CALL_STATUS_DIALING:
{
}
}
-static TReturn s_call_outgoing(CoreObject *o, UserRequest *ur)
+static TReturn imc_call_outgoing(CoreObject *o, UserRequest *ur)
{
struct treq_call_dial *data = 0;
- char *raw_str = NULL;
- char *cmd_str = NULL;
- const char *cclir;
- enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
- TcorePending *pending = NULL;
+ char *cmd_str;
+ const char *clir, *num;
+ TcorePending *pending;
TcoreATRequest *req;
- gboolean ret = FALSE;
+ gboolean ret;
+
+ dbg("Entry");
- dbg("function entrance");
data = (struct treq_call_dial *) tcore_user_request_ref_data(ur, 0);
- clir = _get_clir_status(data->number);
+ if (data->type == CALL_TYPE_VIDEO) {
+ dbg("invalid call type");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ if (!strncmp(data->number, "*31#", 4)) {
+ dbg("clir suppression");
+ clir = "i";
+ num = data->number + 4;
+ } else if (!strncmp(data->number, "#31#", 4)) {
+ dbg("clir invocation");
+ clir = "I";
+ num = data->number + 4;
+ } else {
+ int cli = 0;
- // Compose ATD Cmd string
- switch (clir) {
- case TCORE_CALL_CLI_MODE_PRESENT:
- dbg("CALL_CLI_MODE_PRESENT");
- cclir = "I";
- break; // invocation
+ dbg("no clir string in number");
- case TCORE_CALL_CLI_MODE_RESTRICT:
- dbg("CALL_CLI_MODE_RESTRICT");
- cclir = "i";
- break; // suppression
+ vconf_get_int("db/ciss/show_my_number", &cli);
- case TCORE_CALL_CLI_MODE_DEFAULT:
- default:
- cclir = "";
- dbg("CALL_CLI_MODE_DEFAULT");
- break; // subscription default
+ if (cli == 2){
+ dbg("clir invocation from setting application");
+ clir = "I";
+ } else {
+ dbg("set clir state to default");
+ clir = "";
+ }
+ num = data->number;
}
- dbg("data->number = %s", data->number);
+ dbg("data->number = %s", num);
- raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);
- cmd_str = g_strdup_printf("%s", raw_str);
+ cmd_str = g_strdup_printf("ATD%s%s;", num, clir);
dbg("request command : %s", cmd_str);
pending = tcore_pending_new(o, 0);
req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
ret = _call_request_message(pending, o, ur, on_confirmation_call_outgoing, NULL);
- g_free(raw_str);
g_free(cmd_str);
- if (!ret) {
+ if (ret == FALSE) {
dbg("AT request(%s) sent failed", req->cmd);
return TCORE_RETURN_FAILURE;
}
dbg("AT request(%s) sent success", req->cmd);
+ dbg("Exit");
+
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_call_answer(CoreObject *o, UserRequest *ur)
+static TReturn imc_call_answer(CoreObject *o, UserRequest *ur)
{
char *cmd_str = NULL;
CallObject *co = NULL;
dbg("function entrance");
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
data = (struct treq_call_answer *) tcore_user_request_ref_data(ur, 0);
co = tcore_call_object_find_by_id(o, data->id);
if (data->type == CALL_ANSWER_TYPE_ACCEPT) {
cmd_str = g_strdup_printf("%s", "ATA");
pending = tcore_pending_new(o, 0);
req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_call_release(CoreObject *o, UserRequest *ur)
+static TReturn imc_call_release(CoreObject *o, UserRequest *ur)
{
CallObject *co = NULL;
struct treq_call_end *data = 0;
gboolean ret = FALSE;
dbg("function entrance");
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
data = (struct treq_call_end *) tcore_user_request_ref_data(ur, 0);
co = tcore_call_object_find_by_id(o, data->id);
pending = tcore_pending_new(o, 0);
req = tcore_at_request_new(chld0_cmd, NULL, TCORE_AT_NO_RESULT);
-
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(chld0_cmd);
+ g_free(chld1_cmd);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("input command is %s", chld0_cmd);
dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
if (!ret) {
dbg("AT request %s has failed ", req->cmd);
+ if (ur_dup) {
+ tcore_user_request_free(ur_dup);
+ ur_dup = NULL;
+ }
+ g_free(chld1_cmd);
return TCORE_RETURN_FAILURE;
}
pending1 = tcore_pending_new(o, 0);
req1 = tcore_at_request_new(chld1_cmd, NULL, TCORE_AT_NO_RESULT);
-
+ if (req1 == NULL) {
+ tcore_pending_free(pending1);
+ g_free(chld1_cmd);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("input command is %s", chld1_cmd);
dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_call_hold(CoreObject *o, UserRequest *ur)
+static TReturn imc_call_hold(CoreObject *o, UserRequest *ur)
{
struct treq_call_hold *hold = 0;
CallObject *co = NULL;
dbg("function entrance");
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
hold = (struct treq_call_hold *) tcore_user_request_ref_data(ur, 0);
dbg("call id : [ %d ]", hold->id);
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_call_active(CoreObject *o, UserRequest *ur)
+static TReturn imc_call_active(CoreObject *o, UserRequest *ur)
{
struct treq_call_active *active = 0;
CallObject *co = NULL;
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
active = (struct treq_call_active *) tcore_user_request_ref_data(ur, 0);
dbg("call id : [ %d ]", active->id);
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_call_swap(CoreObject *o, UserRequest *ur)
+static TReturn imc_call_swap(CoreObject *o, UserRequest *ur)
{
struct treq_call_swap *swap = NULL;
CallObject *co = NULL;
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
swap = (struct treq_call_swap *) tcore_user_request_ref_data(ur, 0);
dbg("call id : [ %d ]", swap->id);
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_call_join(CoreObject *o, UserRequest *ur)
+static TReturn imc_call_join(CoreObject *o, UserRequest *ur)
{
struct treq_call_join *join = 0;
CallObject *co = NULL;
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
join = (struct treq_call_join *) tcore_user_request_ref_data(ur, 0);
dbg("call id : [ %d ]", join->id);
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_call_split(CoreObject *o, UserRequest *ur)
+static TReturn imc_call_split(CoreObject *o, UserRequest *ur)
{
struct treq_call_split *split = 0;
CallObject *co = NULL;
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
split = (struct treq_call_split *) tcore_user_request_ref_data(ur, 0);
co = tcore_call_object_find_by_id(o, split->id);
dbg("call id : [ %d ]", split->id);
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_call_deflect(CoreObject *o, UserRequest *ur)
+static TReturn imc_call_deflect(CoreObject *o, UserRequest *ur)
{
struct treq_call_deflect *deflect = 0;
CallObject *co = NULL;
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
deflect = (struct treq_call_deflect *) tcore_user_request_ref_data(ur, 0);
co = tcore_call_object_find_by_number(o, deflect->number);
dbg("deflect number: [ %s ]", deflect->number);
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_call_transfer(CoreObject *o, UserRequest *ur)
+static TReturn imc_call_transfer(CoreObject *o, UserRequest *ur)
{
struct treq_call_transfer *transfer = 0;
CallObject *co = NULL;
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
transfer = (struct treq_call_transfer *) tcore_user_request_ref_data(ur, 0);
dbg("call id : [ %d ]", transfer->id);
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_call_send_dtmf(CoreObject *o, UserRequest *ur)
+static TReturn imc_call_start_cont_dtmf(CoreObject *o, UserRequest *ur)
{
char *cmd_str = NULL;
- TcorePending *pending = NULL;
- TcoreATRequest *req;
- UserRequest *dup;
gboolean ret = FALSE;
- struct treq_call_dtmf *dtmf = 0;
+ TcoreATRequest *req;
+ struct treq_call_start_cont_dtmf *dtmf = 0;
char *dtmfstr = NULL, *tmp_dtmf = NULL;
- unsigned int dtmf_count;
+ TcorePending *pending = NULL;
+ //unsigned int dtmf_count;
dbg("Function enter");
- dup = tcore_user_request_new(NULL, NULL);
- (void) _set_dtmf_tone_duration(o, dup);
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
- dtmf = (struct treq_call_dtmf *) tcore_user_request_ref_data(ur, 0);
+ dtmf = (struct treq_call_start_cont_dtmf *) tcore_user_request_ref_data(ur, 0);
dtmfstr = g_malloc0((MAX_CALL_DTMF_DIGITS_LEN * 2) + 1); // DTMF digits + comma for each dtmf digit.
if (dtmfstr == NULL) {
dbg("Memory allocation failed");
- return TCORE_RETURN_FAILURE;
+ return TCORE_RETURN_ENOMEM;
}
tmp_dtmf = dtmfstr;
- for (dtmf_count = 0; dtmf_count < strlen(dtmf->digits); dtmf_count++) {
- *tmp_dtmf = dtmf->digits[dtmf_count];
+#if 1
+ *tmp_dtmf = dtmf->dtmf_digit;
+#else
+ for (dtmf_count = 0; dtmf_count < (unsigned int)strlen((const char *)dtmf->dtmf_digit); dtmf_count++) {
+ *tmp_dtmf = dtmf->dtmf_digit;
tmp_dtmf++;
*tmp_dtmf = COMMA;
// last digit is having COMMA , overwrite it with '\0' .
*(--tmp_dtmf) = '\0';
+#endif
dbg("Input DTMF string(%s)", dtmfstr);
// AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>
pending = tcore_pending_new(o, 0);
req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ g_free(dtmfstr);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
g_free(cmd_str);
if (!ret) {
- dbg("AT request sent failed")
+ dbg("AT request sent failed");
return TCORE_RETURN_FAILURE;
}
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_call_set_sound_path(CoreObject *o, UserRequest *ur)
+static TReturn imc_call_set_sound_path(CoreObject *o, UserRequest *ur)
{
UserRequest *ur_dup = NULL;
TcorePending *pending = NULL, *pending1 = NULL;
TcoreATRequest *req, *req1;
char *cmd_str = NULL, *cmd_str1 = NULL;
+ int device_type = -1;
+ struct treq_call_set_sound_path *sound_path = 0;
gboolean ret = FALSE;
+ TcorePlugin *plugin = tcore_object_ref_plugin(o);
+ const char *cp_name = tcore_server_get_cp_name_by_plugin(plugin);
dbg("function entrance");
- // hard coded value for speaker.
- cmd_str = g_strdup_printf("%s", "AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,1"); // source type.
- cmd_str1 = g_strdup_printf("%s", "AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,1"); // destination type
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+ sound_path = (struct treq_call_set_sound_path *) tcore_user_request_ref_data(ur, 0);
+ if (sound_path == NULL) {
+ dbg("invaling user request");
+ return TCORE_RETURN_FAILURE;
+ }
+ dbg("audio device type - 0x%x", sound_path->path);
+ switch (sound_path->path) {
+ case CALL_SOUND_PATH_HANDSET:
+ device_type = 1;
+ break;
+
+ case CALL_SOUND_PATH_HEADSET:
+ device_type = 2;
+ break;
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+ case CALL_SOUND_PATH_HEADSET_3_5PI:
+ device_type = 3;
+ break;
- tcore_pending_set_request_data(pending, 0, req);
- ur_dup = tcore_user_request_ref(ur);
+ case CALL_SOUND_PATH_SPEAKER:
+ device_type = 4;
+ break;
- ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_set_source_sound_path, NULL);
+ case CALL_SOUND_PATH_HANDFREE:
+ device_type = 5;
+ break;
- g_free(cmd_str);
+ case CALL_SOUND_PATH_HEADSET_HAC:
+ device_type = 6;
+ break;
- if (!ret) {
- dbg("At request(%s) sent failed", req->cmd);
+ case CALL_SOUND_PATH_BLUETOOTH:
+ case CALL_SOUND_PATH_STEREO_BLUETOOTH:
+ device_type = 7;
+ break;
+
+ case CALL_SOUND_PATH_BT_NSEC_OFF:
+ case CALL_SOUND_PATH_MIC1:
+ case CALL_SOUND_PATH_MIC2:
+ default:
+ dbg("unsupported device type");
return TCORE_RETURN_FAILURE;
}
- pending1 = tcore_pending_new(o, 0);
- req1 = tcore_at_request_new(cmd_str1, "+XDRV", TCORE_AT_SINGLELINE);
- dbg("input command is %s", cmd_str1);
- dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
+ if (g_str_has_prefix(cp_name, "mfld_blackbay") == TRUE) {
+ struct tnoti_call_sound_path *tnoti_snd_path;
- tcore_pending_set_request_data(pending1, 0, req1);
- ret = _call_request_message(pending1, o, ur, on_confirmation_call_set_destination_sound_path, NULL);
+ tnoti_snd_path = g_try_new0(struct tnoti_call_sound_path, 1);
+ if (!tnoti_snd_path)
+ return TCORE_RETURN_ENOMEM;
- g_free(cmd_str1);
+ tnoti_snd_path->path = sound_path->path;
- if (!ret) {
- dbg("AT request %s has failed ", req1->cmd);
- return TCORE_RETURN_FAILURE;
+ /* Configure modem I2S1 to 8khz, mono, PCM if routing to bluetooth */
+ if (sound_path->path == CALL_SOUND_PATH_BLUETOOTH || sound_path->path == CALL_SOUND_PATH_STEREO_BLUETOOTH) {
+ call_prepare_and_send_pending_request(o, "AT+XDRV=40,4,3,0,1,0,0,0,0,0,0,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
+ call_prepare_and_send_pending_request(o, "AT+XDRV=40,5,2,0,1,0,0,0,0,0,0,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
+ }
+ else {
+ call_prepare_and_send_pending_request(o, "AT+XDRV=40,4,3,0,1,0,8,0,1,0,2,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
+ call_prepare_and_send_pending_request(o, "AT+XDRV=40,5,2,0,1,0,8,0,1,0,2,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
+ }
+
+ /* Configure modem I2S2 and do the modem routing */
+ call_prepare_and_send_pending_request(o, "AT+XDRV=40,4,4,0,0,0,8,0,1,0,2,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
+ call_prepare_and_send_pending_request(o, "AT+XDRV=40,5,3,0,0,0,8,0,1,0,2,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
+ call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,0,4", NULL, TCORE_AT_NO_RESULT, NULL);
+ call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,3,0", NULL, TCORE_AT_NO_RESULT, NULL);
+ call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,4,2", NULL, TCORE_AT_NO_RESULT, NULL);
+ call_prepare_and_send_pending_request(o, "AT+XDRV=40,6,5,2", NULL, TCORE_AT_NO_RESULT, NULL);
+
+ /* amc enable */
+ call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,4", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S2_RX
+ call_prepare_and_send_pending_request(o, "AT+XDRV=40,2,3", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S1_RX
+ /* amc route: AMC_RADIO_RX => AMC_I2S1_TX */
+
+ pending = tcore_pending_new(o, 0);
+ req = tcore_at_request_new("AT+XDRV=40,6,0,2", "+XDRV", TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ return TCORE_RETURN_FAILURE;
+ }
+ dbg("XDRV req-cmd for source type : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+ tcore_pending_set_request_data(pending, 0, req);
+ ur_dup = tcore_user_request_ref(ur);
+ ret = _call_request_message(pending, o, ur_dup, on_confirmation_set_sound_path, tnoti_snd_path);
+
+ } else {
+
+ cmd_str = g_strdup_printf("AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,%d",device_type); // source type.
+ pending = tcore_pending_new(o, 0);
+ req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
+ dbg("XDRV req-cmd for source type : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+ tcore_pending_set_request_data(pending, 0, req);
+ ur_dup = tcore_user_request_ref(ur);
+ ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_set_source_sound_path, NULL);
+ g_free(cmd_str);
+
+ if (!ret) {
+ dbg("At request(%s) sent failed", req->cmd);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ cmd_str1 = g_strdup_printf("AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,%d",device_type); // destination type
+ pending1 = tcore_pending_new(o, 0);
+ req1 = tcore_at_request_new(cmd_str1, "+XDRV", TCORE_AT_SINGLELINE);
+ if (req1 == NULL) {
+ tcore_pending_free(pending1);
+ g_free(cmd_str1);
+ return TCORE_RETURN_FAILURE;
+ }
+ dbg("XDRV req-cmd for destination type : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
+ tcore_pending_set_request_data(pending1, 0, req1);
+ ret = _call_request_message(pending1, o, ur, on_confirmation_call_set_destination_sound_path, NULL);
+ g_free(cmd_str1);
+
+ if (!ret) {
+ dbg("AT request %s has failed ", req1->cmd);
+ return TCORE_RETURN_FAILURE;
+ }
}
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_call_set_sound_volume_level(CoreObject *o, UserRequest *ur)
+static TReturn imc_call_set_sound_volume_level(CoreObject *o, UserRequest *ur)
{
UserRequest *src_ur = NULL;
UserRequest *dest_ur = NULL;
TcoreATRequest *dest_req = NULL;
char *cmd_str = NULL, *volume_level = NULL;
gboolean ret = FALSE;
+ struct treq_call_set_sound_volume_level *data = NULL;
- struct treq_call_sound_set_volume_level *data = NULL;
- data = (struct treq_call_sound_set_volume_level *) tcore_user_request_ref_data(ur, 0);
dbg("Entry");
+
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ data = (struct treq_call_set_sound_volume_level *) tcore_user_request_ref_data(ur, 0);
+
// Hard-coded values for MIC & Speakers
// Source volume
dbg("Set Source volume");
// Create new AT-Command request
src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ if (src_req == NULL) {
+ tcore_pending_free(src_pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
// Free Command string
// Create new AT-Command request
src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ if (src_req == NULL) {
+ tcore_pending_free(src_pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
// Free Command string
// Create new AT-Command request
dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ if (dest_req == NULL) {
+ tcore_pending_free(dest_pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
// Free Command string
// Create new AT-Command request
dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ if (dest_req == NULL) {
+ tcore_pending_free(dest_pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
// Free Command string
return TCORE_RETURN_SUCCESS;
}
-
-static TReturn s_call_get_sound_volume_level(CoreObject *o, UserRequest *ur)
-{
- dbg("Entry");
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_call_mute(CoreObject *o, UserRequest *ur)
+static TReturn imc_call_set_sound_mute_status(CoreObject *o, UserRequest *ur)
{
+ struct treq_call_set_sound_mute_status *data = NULL;
char *cmd_str = NULL;
+ TReturn ret;
TcorePending *pending = NULL;
TcoreATRequest *req = NULL;
- gboolean ret = FALSE;
-
- dbg("Entry");
- cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,0");
-
- dbg("Request command string: %s", cmd_str);
-
- // Create new Pending request
- pending = tcore_pending_new(o, 0);
- // Create new AT-Command request
- req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
- dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
-
- // Free command string
- g_free(cmd_str);
-
- // Set request data (AT command) to Pending request
- tcore_pending_set_request_data(pending, 0, req);
+ dbg("function entrance");
- // Send request
- ret = _call_request_message(pending, o, ur, on_confirmation_call_mute, NULL);
- if (!ret) {
- err("Failed to send AT-Command request");
- return TCORE_RETURN_FAILURE;
- }
+ data = (struct treq_call_set_sound_mute_status *) tcore_user_request_ref_data(ur, 0);
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
+ if (data->status == CALL_SOUND_MUTE_STATUS_ON)
+ cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,0");
+ else if (data->status == CALL_SOUND_MUTE_STATUS_OFF)
+ cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,88");
-static TReturn s_call_unmute(CoreObject *o, UserRequest *ur)
-{
- char *cmd_str = NULL;
- TcorePending *pending = NULL;
- TcoreATRequest *req = NULL;
- gboolean ret = FALSE;
- dbg("Entry");
+ dbg("Request command : [%s]", cmd_str);
- cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,88");
- dbg("Request command string: %s", cmd_str);
-
- // Create new Pending request
pending = tcore_pending_new(o, 0);
- // Create new AT-Command request
req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
- // Free command string
g_free(cmd_str);
// Set request data (AT command) to Pending request
tcore_pending_set_request_data(pending, 0, req);
// Send request
- ret = _call_request_message(pending, o, ur, on_confirmation_call_unmute, NULL);
+ ret = _call_request_message(pending, o, ur, on_confirmation_call_set_sound_mute_status, NULL);
if (!ret) {
err("Failed to send AT-Command request");
return TCORE_RETURN_FAILURE;
return TCORE_RETURN_SUCCESS;
}
-
-static TReturn s_call_get_mute_status(CoreObject *o, UserRequest *ur)
-{
- dbg("Entry");
-
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
-}
-
+#if 0
static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur)
{
char *cmd_str = NULL;
TcorePending *pending = NULL;
TcoreATRequest *req = NULL;
gboolean ret = FALSE;
+
dbg("Entry");
cmd_str = g_strdup_printf("%s", "AT+VTD=3"); // ~300 mili secs. +VTD= n, where n = (0 - 255) * 1/10 secs.
ret = _call_request_message(pending, o, ur, _on_confirmation_dtmf_tone_duration, NULL);
if (!ret) {
err("Failed to send AT-Command request");
+ if (ur) {
+ tcore_user_request_free(ur);
+ ur = NULL;
+ }
return TCORE_RETURN_FAILURE;
}
dbg("Exit");
return TCORE_RETURN_SUCCESS;
}
+#endif
// Call Operations
static struct tcore_call_operations call_ops = {
- .dial = s_call_outgoing,
- .answer = s_call_answer,
- .end = s_call_release,
- .hold = s_call_hold,
- .active = s_call_active,
- .swap = s_call_swap,
- .join = s_call_join,
- .split = s_call_split,
- .deflect = s_call_deflect,
- .transfer = s_call_transfer,
- .send_dtmf = s_call_send_dtmf,
- .set_sound_path = s_call_set_sound_path,
- .set_sound_volume_level = s_call_set_sound_volume_level,
- .get_sound_volume_level = s_call_get_sound_volume_level,
- .mute = s_call_mute,
- .unmute = s_call_unmute,
- .get_mute_status = s_call_get_mute_status,
- .set_sound_recording = NULL,
+ .dial = imc_call_outgoing,
+ .answer = imc_call_answer,
+ .end = imc_call_release,
+ .hold = imc_call_hold,
+ .active = imc_call_active,
+ .swap = imc_call_swap,
+ .join = imc_call_join,
+ .split = imc_call_split,
+ .deflect = imc_call_deflect,
+ .transfer = imc_call_transfer,
+ .start_cont_dtmf = imc_call_start_cont_dtmf,
+ .stop_cont_dtmf = NULL,
+ .set_sound_path = imc_call_set_sound_path,
+ .set_sound_volume_level = imc_call_set_sound_volume_level,
+ .get_sound_volume_level = NULL,
+ .set_sound_mute_status = imc_call_set_sound_mute_status,
+ .get_sound_mute_status = NULL,
.set_sound_equalization = NULL,
.set_sound_noise_reduction = NULL,
};
-static void s_call_info_mo_waiting(CoreObject *o)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_current_on_mo_processing(o);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_WAITING,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_mo_forwarded(CoreObject *o)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_current_on_mo_processing(o);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_FORWARDED,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_mo_barred_incoming(CoreObject *o)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_current_on_mo_processing(o);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_BARRED_INCOMING,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_mo_barred_outgoing(CoreObject *o)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_current_on_mo_processing(o);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_BARRED_OUTGOING,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_mo_deflected(CoreObject *o)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_current_on_mo_processing(o);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_DEFLECTED,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_mo_clir_suppression_reject(CoreObject *o)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_current_on_mo_processing(o);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_CLIR_SUPPRESSION_REJECT,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_mo_cfu(CoreObject *o)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_current_on_mo_processing(o);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_FORWARD_UNCONDITIONAL,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_mo_cfc(CoreObject *o)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_current_on_mo_processing(o);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_FORWARD_CONDITIONAL,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_mt_cli(CoreObject *o, enum tcore_call_cli_mode mode, char *number)
-{
- CallObject *co = NULL;
- dbg("Entry");
-
- // Call Core object
- co = tcore_call_object_current_on_mt_processing(o);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Set CLI information
- tcore_call_object_set_cli_info(co, mode, number);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_mt_cna(CoreObject *o, enum tcore_call_cna_mode mode, char *name, int dcs)
-{
- CallObject *co = NULL;
- dbg("Entry");
-
- // Call Core object
- co = tcore_call_object_current_on_mt_processing(o);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Set CNA information
- tcore_call_object_set_cna_info(co, mode, name, dcs);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_mt_forwarded_call(CoreObject *o, char *number)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_find_by_number(o, number);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_FORWARDED_CALL,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_mt_deflected_call(CoreObject *o, char *number)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_find_by_number(o, number);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_DEFLECTED_CALL,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_mt_transfered(CoreObject *o, char *number)
+gboolean imc_call_init(TcorePlugin *cp, CoreObject *co_call)
{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
dbg("Entry");
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
+ /* Set operations */
+ tcore_call_set_ops(co_call, &call_ops);
- // Call Core object
- co = tcore_call_object_find_by_number(o, number);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_TRANSFERED_CALL,
- sizeof(unsigned int),
- (void *) &id);
+ /* Add Callbacks */
+ tcore_object_add_callback(co_call, "+XCALLSTAT", on_notification_call_info, NULL);
+ tcore_object_add_callback(co_call, "+CLIP", on_notification_call_clip_info, NULL);
dbg("Exit");
- return;
-}
-static void s_call_info_held(CoreObject *o, char *number)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_find_by_number(o, number);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_HELD,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_active(CoreObject *o, char *number)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_find_by_number(o, number);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_ACTIVE,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_joined(CoreObject *o, char *number)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_find_by_number(o, number);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_JOINED,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_released_on_hold(CoreObject *o, char *number)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_find_by_number(o, number);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_RELEASED_ON_HOLD,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_transfer_alert(CoreObject *o, char *number)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_find_by_number(o, number);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_TRANSFER_ALERT,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_transfered(CoreObject *o, char *number)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_find_by_number(o, number);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_TRANSFERED,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-static void s_call_info_cf_check_message(CoreObject *o, char *number)
-{
- TcorePlugin *plugin = NULL;
- CallObject *co = NULL;
- int id = 0;
- dbg("Entry");
-
- // Parent plugin
- plugin = tcore_object_ref_plugin(o);
-
- // Call Core object
- co = tcore_call_object_find_by_number(o, number);
- if (!co) {
- err("Failed to find Call Core object!");
- return;
- }
-
- // Call ID
- id = tcore_call_object_get_id(co);
-
- // Send notification to TAPI
- tcore_server_send_notification(tcore_plugin_ref_server(plugin),
- tcore_plugin_ref_core_object(plugin, "call"),
- TNOTI_CALL_INFO_CF_CHECK_MESSAGE,
- sizeof(unsigned int),
- (void *) &id);
-
- dbg("Exit");
- return;
-}
-
-// Call Information Operations
-static struct tcore_call_information_operations call_information_ops = {
- .mo_call_col = 0,
- .mo_call_waiting = s_call_info_mo_waiting,
- .mo_call_cug = 0,
- .mo_call_forwarded = s_call_info_mo_forwarded,
- .mo_call_barred_incoming = s_call_info_mo_barred_incoming,
- .mo_call_barred_outgoing = s_call_info_mo_barred_outgoing,
- .mo_call_deflected = s_call_info_mo_deflected,
- .mo_call_clir_suppression_reject = s_call_info_mo_clir_suppression_reject,
- .mo_call_cfu = s_call_info_mo_cfu,
- .mo_call_cfc = s_call_info_mo_cfc,
- .mt_call_cli = s_call_info_mt_cli,
- .mt_call_cna = s_call_info_mt_cna,
- .mt_call_forwarded_call = s_call_info_mt_forwarded_call,
- .mt_call_cug_call = 0,
- .mt_call_deflected_call = s_call_info_mt_deflected_call,
- .mt_call_transfered = s_call_info_mt_transfered,
- .call_held = s_call_info_held,
- .call_active = s_call_info_active,
- .call_joined = s_call_info_joined,
- .call_released_on_hold = s_call_info_released_on_hold,
- .call_transfer_alert = s_call_info_transfer_alert,
- .call_transfered = s_call_info_transfered,
- .call_cf_check_message = s_call_info_cf_check_message,
-};
-
-gboolean s_call_init(TcorePlugin *p, TcoreHal *h)
-{
- CoreObject *o = NULL;
- struct property_call_info *data = NULL;
- dbg("Entry");
-
- // Creating Call COre object
- o = tcore_call_new(p, "call", &call_ops, h);
- if (!o) {
- err("Failed to create Call Core Object");
- return FALSE;
- }
-
- // Set Call Operations
- tcore_call_information_set_operations(o, &call_information_ops);
-
- // Add Callbacks
- tcore_object_add_callback(o, "+XCALLSTAT", on_notification_call_info, NULL);
- tcore_object_add_callback(o, "+CLIP", on_notification_call_clip_info, NULL);
-
- // User Data
- data = calloc(sizeof(struct property_call_info *), 1);
- tcore_plugin_link_property(p, "CALL", data);
-
- dbg("Exit");
return TRUE;
}
-void s_call_exit(TcorePlugin *p)
+void imc_call_exit(TcorePlugin *cp, CoreObject *co_call)
{
- CoreObject *o = NULL;
- struct property_network_info *data = NULL;
- dbg("Entry");
-
- o = tcore_plugin_ref_core_object(p, "call");
-
- // Free Call Core Object */
- tcore_call_free(o);
-
- // Free 'CALL' property */
- data = tcore_plugin_ref_property(p, "CALL");
- if (data) {
- g_free(data);
- }
-
dbg("Exit");
- return;
}
#include <stdlib.h>
#include <glib.h>
+#include <log.h>
-#include "s_common.h"
-
-#include <plugin.h>
+#include "imc_common.h"
#undef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
MASK((width), (offset), (data)) << -(shift) : \
MASK((width), (offset), (data)) >> (((signed) (shift)))) \
+#define TAB_SPACE " "
+
char _util_unpackb(const char *src, int pos, int len);
char _util_convert_byte_hexChar(char val);
gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
snprintf(buf, 255, "%s%04X: ", pad, 0);
for (i = 0; i < size; i++) {
snprintf(hex, 4, "%02X ", p[i]);
- strcat(buf, hex);
+ strncat(buf, hex, strlen(hex));
if ((i + 1) % 8 == 0) {
if ((i + 1) % 16 == 0) {
memset(buf, 0, 255);
snprintf(buf, 255, "%s%04X: ", pad, i + 1);
} else {
- strcat(buf, " ");
+ strncat(buf, TAB_SPACE, strlen(TAB_SPACE));
}
}
}
msg("%s", buf);
}
-void hook_hex_dump(enum direction_e d, int size, const void *data)
-{
- msg("=== TX data DUMP =====");
- util_hex_dump(" ", size, data);
- msg("=== TX data DUMP =====");
-}
-
-unsigned int util_assign_message_sequence_id(TcorePlugin *p)
+unsigned char util_hexCharToInt(char c)
{
- struct global_data *gd;
-
- if (!p) {
- dbg("plugin is NULL");
- return -1;
- }
-
- gd = tcore_plugin_ref_user_data(p);
- if (!gd) {
- dbg("global data is NULL");
+ if (c >= '0' && c <= '9')
+ return (c - '0');
+ else if (c >= 'A' && c <= 'F')
+ return (c - 'A' + 10);
+ else if (c >= 'a' && c <= 'f')
+ return (c - 'a' + 10);
+ else {
+ dbg("invalid charater!!");
return -1;
}
-
- if (gd->msg_auto_id_current == 0) {
- gd->msg_auto_id_current = gd->msg_auto_id_start;
- dbg("pending_auto_id_current is 0, reset to start");
- } else if (gd->msg_auto_id_current >= gd->msg_auto_id_end) {
- gd->msg_auto_id_current = gd->msg_auto_id_start;
- dbg("pending_auto_id_current is over, reset to start");
- } else {
- gd->msg_auto_id_current++;
- }
-
- dbg("message_sequence_id = %d", gd->msg_auto_id_current);
-
- return gd->msg_auto_id_current;
-}
-
-gboolean util_add_waiting_job(GQueue *queue, unsigned int id, UserRequest *ur)
-{
- struct work_queue_data *wqd;
-
- if (!queue)
- return FALSE;
-
- wqd = calloc(sizeof(struct work_queue_data), 1);
- if (!wqd)
- return FALSE;
-
- wqd->id = id;
- wqd->ur = tcore_user_request_ref(ur);
- g_queue_push_tail(queue, wqd);
-
- dbg("id = %d, ur = 0x%x", wqd->id, wqd->ur);
- return TRUE;
}
-UserRequest* util_pop_waiting_job(GQueue *queue, unsigned int id)
+char *util_hex_to_string(const char *src, unsigned int src_len)
{
- int i = 0;
- UserRequest *ur;
- struct work_queue_data *wqd;
+ char *dest;
+ unsigned int i;
- if (!queue)
+ if (src == NULL)
return NULL;
-
- dbg("before waiting job count: %d", g_queue_get_length(queue));
-
- do {
- wqd = g_queue_peek_nth(queue, i);
- if (!wqd)
- return NULL;
-
- if (wqd->id == id) {
- wqd = g_queue_pop_nth(queue, i);
- break;
- }
-
- i++;
- } while (wqd != NULL);
-
- dbg("after waiting job count: %d", g_queue_get_length(queue));
-
- if (!wqd)
+ dest = g_malloc0(src_len * 2 + 1);
+ if (dest == NULL) {
+ err("Memory allocation failed!!");
return NULL;
+ }
- ur = wqd->ur;
- free(wqd);
+ for (i = 0; i < src_len; i++) {
+ snprintf(dest + (i * 2), (src_len * 2 + 1) - (i * 2),
+ "%02x", (unsigned char)src[i]);
+ }
- return ur;
-}
+ dest[src_len * 2] = '\0';
-unsigned char util_hexCharToInt(char c)
-{
- if (c >= '0' && c <= '9')
- return (c - '0');
- else if (c >= 'A' && c <= 'F')
- return (c - 'A' + 10);
- else if (c >= 'a' && c <= 'f')
- return (c - 'a' + 10);
- else {
- dbg("invalid charater!!");
- return -1;
- }
+ return dest;
}
char* util_hexStringToBytes(char *s)
sz = strlen(s);
- ret = calloc((sz / 2) + 1, 1);
+ ret = g_malloc0((sz / 2) + 1);
+ if (ret == NULL) {
+ err("Memory allocation failed!!");
+ return NULL;
+ }
dbg("Convert String to Binary!!");
for (i = 0; i < sz; i += 2) {
ret[i / 2] = (char) ((util_hexCharToInt(s[i]) << 4) | util_hexCharToInt(s[i + 1]));
- dbg("[%02x]", ret[i / 2]);
+ msg(" [%02x]", ret[i / 2]);
}
return ret;
rshift = MAX(8 - (pos + len), 0);
if (rshift > 0) {
- result = MASK_AND_SHIFT(len, pos, rshift, *src);
+ result = MASK_AND_SHIFT(len, pos, rshift, (unsigned char)*src);
} else {
- result = MASK(8 - pos, pos, *src);
+ result = MASK(8 - pos, pos, (unsigned char)*src);
src++;
len -= 8 - pos;
if (data_len <= 0) {
return NULL;
}
- tmp = calloc(1, data_len - 1);
+
+ tmp = g_malloc0(data_len - 1);
+ if (tmp == NULL) {
+ err("Memory allocation failed!!");
+ return NULL;
+ }
memcpy(tmp, data + 1, data_len - 2);
- dbg("tmp: %s", tmp);
+ dbg("tmp: [%s]", tmp);
return tmp;
}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: sharanayya mathapati <sharan.m@samsung.com>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <glib.h>
+
+#include <tcore.h>
+#include <hal.h>
+#include <core_object.h>
+#include <plugin.h>
+#include <queue.h>
+#include <co_gps.h>
+#include <user_request.h>
+#include <util.h>
+#include <server.h>
+#include <at.h>
+#include <libxml/xmlreader.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include "imc_common.h"
+#include "imc_gps.h"
+
+
+#define FILE_NAME "/opt/home/root/sample.xml"
+#define POSITION_NODE "pos"
+#define POSITION_NODE_ATTR_XSI "xsi:noNamespaceSchemaLocation"
+#define POSITION_NODE_ATTR_VAL_XSI "pos.xsd"
+#define POSITION_NODE_ATTR_XMLNS "xmlns:xsi"
+#define POSITION_NODE_ATTR_VAL_XMLNS "http://www.w3.org/2001/XMLSchema-instance"
+
+#define MAX_NUM_OF_GPS_REF_TIME_ELEMENT 12 // max number of gps satalite
+#define MAX_NUM_OF_GPS_NAV_ELEMENT 16 // max num of navigation gps element.
+#define MAX_NUM_OF_GPS_ALMANC_ELEMENTS 64 // Max num of almanc elements.
+
+#define NUM_OF_ELEMENTS(array) (sizeof(array) / sizeof(*(array)))
+
+#define NODE_SIZE 128
+
+static char node_name[128]; // max len of xml node
+static char node_value[128]; // max len of xml node value.
+
+// node type of gps assist data
+enum gps_assist_element_type {
+ REF_TIME = 1,
+ LOCATION_PARM,
+ DGPS_CORRECTION,
+ NAV_MODEL_ELEM,
+ IONOSPHERIC_MODEL,
+ UTC_MODEL,
+ ALMANAC,
+ ACQU_ASSIST,
+};
+
+// Ref_time
+typedef struct {
+ unsigned char valid;
+ unsigned short bcchCarrier;
+ unsigned short bsic;
+ unsigned long int frameNumber;
+ unsigned short timeSlot;
+ unsigned short bitNumber;
+} __attribute__((packed)) gps_gsm_time_t;
+
+typedef struct {
+ unsigned char valid;
+ unsigned long int gpsTimeUncertainty;
+} __attribute__((packed)) gps_utran_gps_unc_t;
+
+typedef struct {
+ unsigned char valid;
+ signed long int driftRate;
+} __attribute__((packed)) gps_drift_rate_t;
+
+typedef struct {
+ unsigned char valid;
+ unsigned long int cellFrames;
+ unsigned char choice_mode;
+ unsigned long int UtranFdd; // FDD Primary Scrambling Code
+ unsigned long int UtranTdd; // TDD Cell Parameter ID
+ unsigned long int sfn; // SFN
+} __attribute__((packed)) gps_utran_gps_ref_time_t;
+
+typedef struct {
+ gps_utran_gps_ref_time_t UtranGpsRefTime;
+ gps_utran_gps_unc_t UtranGpsUncertainty;
+ unsigned char UtranSfnUncertainty;
+ gps_drift_rate_t UtranDriftRate;
+} __attribute__((packed)) gps_utran_time_t;
+
+typedef struct {
+ unsigned short satID;
+ unsigned short tlmWord;
+ unsigned char antiSpoofFlag;
+ unsigned char alertFlag;
+ unsigned char tmlReservedBits;
+} __attribute__((packed)) gps_gps_tow_assist_t;
+
+typedef struct {
+ unsigned long int gpsTow;
+ unsigned long int gpsWeek;
+ unsigned char nrOfSats;
+ union { // Not supported.
+ gps_gsm_time_t gsm_time;
+ gps_utran_time_t UtranTime;
+ } networkTimeInfo;
+ gps_gps_tow_assist_t GpsTowAssist[12];
+} __attribute__((packed)) gps_ref_time_t;
+
+
+// Ref - Location.
+typedef struct {
+ unsigned char shapeType;
+ unsigned char hemisphere;
+ unsigned short altitude;
+ unsigned long int latitude;
+ signed long int longitude;
+ unsigned char directionOfAlt;
+ unsigned char semiMajorUncert;
+ unsigned char semiMinorUncert;
+ unsigned char majorAxis;
+ unsigned char altUncert;
+ unsigned char confidence;
+} __attribute__((packed)) gps_ref_loc_t;
+
+// DGPS corrections
+typedef enum {
+ GPS_DGPS_INVALID,
+ GPS_DGPS_UDRE_SCALE_1_0,
+ GPS_DGPS_UDRE_SCALE_0_75,
+ GPS_DGPS_UDRE_SCALE_0_5,
+ GPS_DGPS_UDRE_SCALE_0_3,
+ GPS_DGPS_UDRE_SCALE_0_2,
+ GPS_DGPS_UDRE_SCALE_0_1,
+ GPS_DGPS_NO_DATA
+} __attribute__((packed)) gps_dgps_status_e_type;
+
+typedef struct {
+ unsigned char satId; // Satellite ID
+ unsigned short iode;
+ unsigned char udre;
+ signed short pseudoRangeCor;
+ signed short rangeRateCor;
+} gps_dgps_sat_list_t;
+
+typedef struct {
+ unsigned long int gpsTow;
+ gps_dgps_status_e_type status;
+ unsigned long int numberOfSat;
+ gps_dgps_sat_list_t seqOfSatElement[16];
+} __attribute__((packed)) gps_dgps_correction_t;
+
+// Navi model
+typedef struct {
+ unsigned long int rsv1; // 0~838860
+ unsigned long int rsv2; // 0~16777215
+ unsigned long int rsv3; // 0~16777215
+ unsigned long int rsv4; // 0~65535
+} __attribute__((packed)) gps_navi_subframe_rsv_t;
+
+typedef struct {
+ unsigned char ephemCodeOnL2; // 0~3
+ unsigned char ephemUra; // 0~15
+ unsigned char ephemSvHealth; // 0~63
+ unsigned short ephemIodc; // 0~1023
+ unsigned char ephemL2PFlag; // 0~1
+ gps_navi_subframe_rsv_t NavigationSubFrameRsv;
+ signed char ephemTgd; // -128~127
+ unsigned short ephemToc; // 0~37799
+ signed char ephemAf2; // -128~12
+ signed short ephemAf1; // -32768~32767
+ signed long int ephemAf0; // -2097152~2097151
+ signed short ephemCrs; // -32768~32767
+ signed short ephemDeltaN; // -32768~32767
+ signed long int ephemM0; // -2147483648~2147483647
+ signed short ephemCuc; // -32768~32767
+ unsigned long int ephemE; // 0~4294967295
+ signed short ephemCus; // -32768~32767
+ unsigned long int ephemAPowrHalf; // 0~4294967295
+ unsigned short ephemToe; // 0~37799
+ signed char ephemFitFlag; // 0~1
+ unsigned char ephemAoda; // 0~31
+ signed short ephemCic; // -32768~32767
+ signed long int ephemOmegaA0; // -2147483648~2147483647
+ signed short ephemCis; // -32768~32767
+ signed long int ephemI0; // -2147483648~2147483647
+ signed short ephemCrc; // -32768~32767
+ signed long int ephemW; // -2147483648~2147483647
+ signed long int ephemOmegaADot; // -8388608~8388607
+ signed short ephemIDot; // -8192~8191
+} __attribute__((packed)) gps_navi_ephe_t;
+
+typedef enum {
+ GPS_NAVIGATION_MODEL_NEW_SATELLITE_NEW_NAVIGATION,
+ GPS_NAVIGATION_MODEL_EXIST_SATELLITE_EXIST_NAVIGATION,
+ GPS_NAVIGATION_MODEL_EXIST_SATELLITE_NEW_NAVIGATION,
+ GPS_NAVIGATION_MODEL_RESERVED
+} gps_navigation_sat_status_e_type;
+
+typedef struct {
+ unsigned char satId;
+ gps_navigation_sat_status_e_type NavigationSatStatus;
+ gps_navi_ephe_t NavigationEphemeris;
+} __attribute__((packed)) gps_navi_sat_info_t;
+
+typedef struct {
+ unsigned long int numberOfSat;
+ gps_navi_sat_info_t NavigationSatInfo[16];
+} __attribute__((packed)) gps_navi_model_t;
+
+// Iono_model
+typedef struct {
+ signed char alfa0; // -128~127
+ signed char alfa1; // -128~127
+ signed char alfa2; // -128~127
+ signed char alfa3; // -128~127
+ signed char beta0; // -128~127
+ signed char beta1; // -128~127
+ signed char beta2; // -128~127
+ signed char beta3; // -128~127
+} __attribute__((packed)) gps_iono_model_t;
+
+// UTC_model
+typedef struct {
+ signed long int utcA1; // -8388608~8388607
+ signed long int utcA0; // -2147483648~2147483647
+ unsigned char utcTot; // 0~255
+ unsigned char utcWNt; // 0~255
+ signed char utcDeltaTls; // -128~127
+ unsigned char utcWNlsf; // 0~255
+ signed char utcDN; // -128~127
+ signed char utcDeltaTlsf; // -128~127
+} __attribute__((packed)) gps_utc_model_t;
+
+// Almanac-model
+typedef struct {
+ signed char dataId; // only for 3G, 0~3, if this value is -1, it means this value is invalid
+ unsigned char satId;
+ unsigned short almanacE; // 0~65536
+ unsigned char almanacToa; // 0~255
+ signed short almanacKsii; // -32768~3276
+ signed short almanacOmegaDot; // -32768~3276
+ unsigned char almanacSvHealth; // 0~255
+ unsigned long int almanacAPowerHalf; // 0~16777215
+ signed long int almanacOmega0; // -8388608~8388607
+ signed long int almanacW; // -8388608~8388607
+ signed long int almanacM0; // -8388608~8388607
+ signed short almanacAf0; // -1024~1023
+ signed short almanacAf1; // -1024~1023
+} __attribute__((packed)) gps_almanac_sat_info_t;
+
+typedef struct {
+ unsigned char almanacWNa; // 0~255
+ unsigned long int numberOfSat;
+ gps_almanac_sat_info_t AlmanacSatInfo[64];
+} __attribute__((packed)) gps_almanac_model_t;
+
+// acq_assist
+typedef struct {
+ unsigned char satId;
+ signed short doppler0; // -2048~2047 (real value is from -5120 to 5117.5 by step of 2.5)
+ unsigned char doppler1; // 0~63 (real value is from -0.966 to 0.483 by step of 0.023)
+ unsigned char dopplerUncertainty; // 0~7 (12.5, 25, 50, 100, 200)
+ unsigned short codePhase; // 0~1022
+ unsigned char intCodePhase; // 0~19
+ unsigned char gpsBitNumber; // 0~3
+ unsigned char codePhaseSearchWindow; // 0~15 (1023, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192)
+ unsigned char azimuth; // 0~31, 11.25 degree resolution
+ unsigned char elevation; // 0~7, 11.25 degree resolution
+} __attribute__((packed)) gps_acq_sat_info_t;
+
+typedef struct {
+ gps_utran_gps_ref_time_t AcqUtranGpsRefTime;
+ gps_utran_gps_unc_t AcqUtranGpsUncertainty;
+} __attribute__((packed)) gps_acq_utran_time_t;
+
+typedef struct {
+ unsigned long int gpsTow;
+ union {
+ gps_gsm_time_t gsm_time;
+ gps_acq_utran_time_t AcqUtranTime;
+ } acquisitionTimeInfo; // --- not supported.
+ unsigned long int numberOfSat;
+ gps_acq_sat_info_t lcsAcquisitionSatInfo[16];
+} __attribute__((packed)) gps_acq_assist_t;
+
+typedef struct {
+ unsigned char satId[16];
+ unsigned char numOfSat;
+} __attribute__((packed)) gps_r_time_int_t;
+
+
+// Assist-data
+typedef struct {
+ unsigned long int flag;
+ gps_ref_time_t ref_time;
+ gps_ref_loc_t ref_loc;
+ gps_dgps_correction_t dgps_corrections;
+ gps_navi_model_t navi_model;
+ gps_iono_model_t iono_model;
+ gps_utc_model_t utc_model;
+ gps_almanac_model_t almanac;
+ gps_acq_assist_t acq_assist;
+ gps_r_time_int_t r_time_int; // not supported
+} __attribute__((packed)) gps_assist_data_noti_t; // APGPS - GPS Assist Data Message - Notification
+
+typedef struct {
+ char *psat_status;
+ int stat_status;
+} __attribute__((packed)) sat_status_info_t;
+
+const sat_status_info_t sat_status_info_table[] = {
+ { "NS_NN-U", 0}, {"NS_NN", 0}, {"ES_NN-U", 1}, {"ES_SN", 2},
+ { "REVD", 3},
+};
+
+typedef struct {
+ char *pdoppler_status;
+ int doppler_status;
+} __attribute__((packed)) doppler_status_info_t;
+
+const doppler_status_info_t doppler_status_info_table[] = {
+ { "hz12-5", 12.5}, {"hz25", 25}, {"hz50", 50}, {"hz100", 100},
+ {"hz200", 200},
+};
+
+// postion measurement data structure.
+// gps_method_e_type
+typedef enum {
+ GPS_METHODTYPE_INVALID,
+ GPS_METHODTYPE_MS_ASSISTED,
+ GPS_METHODTYPE_MS_BASED,
+ GPS_METHODTYPE_MS_BASED_PREF,
+ GPS_METHODTYPE_MS_ASSISTED_PREF
+} gps_method_e_type;
+
+// gps_accuracy_t
+typedef struct {
+ unsigned int flag;
+ unsigned char horizontalAccuracy;
+ unsigned char vertcalAccuracy;
+} __attribute__((packed)) gps_accuracy_t;
+
+// gps_use_multi_sets_e_type
+typedef enum {
+ GPS_MULTIPLESETS_INVALID,
+ GPS_MULTIPLESETS_MULTIPLESETS,
+ GPS_MULTIPLESETS_ONESET
+} gps_use_multi_sets_e_type;
+
+// gps_env_char_e_type
+typedef enum {
+ GPS_ENVIRONMENT_INVALID,
+ GPS_ENVIRONMENT_BAD_AREA,
+ GPS_ENVIRONMENT_NOT_BAD_AREA,
+ GPS_ENVIRONMENT_MIXED_AREA
+} gps_env_char_e_type;
+
+// gps_cell_timing_wnt_e_type
+typedef enum {
+ GPS_CELLTIMING_INVALID,
+ GPS_CELLTIMING_WANTED,
+ GPS_CELLTIMING_NOT_WANTED
+} gps_cell_timing_wnt_e_type;
+
+// gps_add_assit_req_e_type
+typedef enum {
+ GPS_ADDITIONAL_ASSISREQ_INVALID,
+ GPS_ADDITIONAL_ASSISREQ_REQ,
+ GPS_ADDITIONAL_ASSISREQ_NOT_REQ
+} gps_add_assit_req_e_type;
+
+// gps measure position.
+typedef struct {
+ gps_method_e_type method_type;
+ gps_accuracy_t accuracy;
+ unsigned char rsp_time;
+ gps_use_multi_sets_e_type use_multi_sets;
+ gps_env_char_e_type environment_char;
+ gps_cell_timing_wnt_e_type cell_timing_wnt;
+ gps_add_assit_req_e_type add_assist_req;
+} __attribute__((packed)) gps_measure_position_indi_t;
+
+
+// APGPS - Measure Position message - confirm
+typedef enum {
+ GPS_MSR_POS_RES_LOCATION,
+ GPS_MSR_POS_RES_GPS_MEASUREMENTS,
+ GPS_MSR_POS_RES_AID_REQ,
+ GPS_MSR_POS_RES_ERROR
+} gps_msr_pos_res_e_type;
+
+typedef struct {
+ unsigned char sat_id;
+ unsigned char iode;
+} __attribute__((packed)) gps_sat_info_t;
+
+typedef struct {
+ unsigned char beginWeek;
+ unsigned char endWeek;
+ unsigned char beginTow;
+ unsigned char endTow;
+} __attribute__((packed)) gps_ext_ephe_chk_t;
+
+typedef struct {
+ unsigned long int assistanceFlag;
+ unsigned short gpsWeek;
+ unsigned char gpsToe;
+ unsigned char nSat;
+ unsigned char toeLimit;
+ gps_sat_info_t satInfo[15];
+ unsigned char gpsExtendedEphemeris;
+ gps_ext_ephe_chk_t extEphemerisChk;
+} __attribute__((packed)) gps_assistance_data_t;
+
+// Measure Position message
+typedef struct {
+ unsigned char satId; // Satellite ID
+ unsigned char cno; // 0~63, unit of dB-Hz
+ signed short doppler; // -32768~32767, Hz and scale factor 0.2
+ unsigned short wholeChips; // 0~1022
+ unsigned short fracChips; // 0~1024
+ unsigned char lcsMultiPath;
+ unsigned char pseuRangeRmsErr; // 0~63
+} __attribute__((packed)) gps_measuremet_element_t;
+
+typedef struct {
+ unsigned long int gpsTow; // /< GPS time of week [msec]
+ unsigned short gpsWeek; // /< GPS week [0 .. 1023]
+ unsigned char nrOfSats; // /< number of satellites [1 .. 16]
+ gps_measuremet_element_t GpsMeasure[16];
+} __attribute__((packed)) gps_measure_t;
+
+typedef struct {
+ signed long int latitude;
+ signed long int longitude;
+} __attribute__((packed)) gps_ellipsoid_po_t;
+
+typedef struct {
+ gps_ellipsoid_po_t point;
+ unsigned char uncertainRadius;
+} __attribute__((packed)) gps_po_unc_circle_t;
+
+typedef struct {
+ gps_ellipsoid_po_t point;
+ unsigned char semiMajorAxis;
+ unsigned char semiMinorAxis;
+ unsigned char orientationAngle;
+ unsigned char confidence;
+} __attribute__((packed)) gps_po_unc_ellipse_t;
+
+typedef struct {
+ gps_ellipsoid_po_t point;
+ signed short altitude;
+ unsigned char semiMajorAxis;
+ unsigned char semiMinorAxis;
+ unsigned char orientationAngle;
+ unsigned char uncertainAltitude;
+ unsigned char confidence;
+} __attribute__((packed)) gps_po_alt_unc_ellipse_t;
+
+typedef struct {
+ gps_ellipsoid_po_t point;
+ unsigned short innerRadius;
+ unsigned char uncertainRadius;
+ unsigned char offsetAngle;
+ unsigned char includedAngle;
+ unsigned char confidence;
+} __attribute__((packed)) gps_ellipsoid_arc_t;
+
+typedef struct {
+ gps_ellipsoid_po_t point;
+ signed short altitude;
+} __attribute__((packed)) gps_ellipsoid_alt_t;
+
+typedef struct {
+ unsigned char noOfPoints;
+ gps_ellipsoid_po_t points[15];
+} __attribute__((packed)) gps_polygon_t;
+
+
+typedef struct {
+ unsigned char shape_type;
+ gps_po_unc_circle_t p_unc_clrcle;
+ gps_po_unc_ellipse_t p_unc_ellipse;
+ gps_po_alt_unc_ellipse_t p_alt_unc_ellipse;
+ gps_ellipsoid_arc_t ellipsoid_arc;
+ gps_ellipsoid_po_t ellipsoid_po;
+ gps_ellipsoid_alt_t ellipsoid_alt;
+ gps_polygon_t polygon;
+} __attribute__((packed)) gps_loc_info_t;
+
+
+typedef struct {
+ unsigned long int gpsTow; // /< GPS time of week [msec]
+ unsigned short gpsWeek; // /< GPS week [0 .. 1023]
+ unsigned char fixType; // /< Fix type. 2D(0x01) or 3D(0x02)
+ gps_loc_info_t measured_loc_info;
+} __attribute__((packed)) gps_measure_loc_info_t;
+
+typedef struct {
+ unsigned char valid;
+ unsigned long int cellFrames;
+ unsigned char choice_mode;
+ unsigned long int UtranFdd; // FDD Primary Scrambling Code
+ unsigned long int UtranTdd; // TDD Cell Parameter ID
+ unsigned long int sfn; // SFN
+} __attribute__((packed)) gps_utrangps_ref_time_t;
+
+typedef struct {
+ unsigned char result; // 0x00 : SUCCESS, 0x01 : Fail
+ gps_msr_pos_res_e_type response_type; // should be 4 byte
+ gps_measure_t gps_measure;
+ gps_measure_loc_info_t loc_info;
+ gps_assistance_data_t measured_assit_data;
+ gps_utrangps_ref_time_t UtranGpsRefTime; // only for 3G
+} __attribute__((packed)) gps_measure_position_confirm_t; // APGPS - Measure Position message - confirm
+
+typedef struct {
+ char *name;
+ int type;
+} t_element;
+
+static t_element elements[] = {
+ {"ref_time", REF_TIME},
+ {"location_parameters", LOCATION_PARM},
+ {"DGPS_corrections", DGPS_CORRECTION},
+ {"nav_model_elem", NAV_MODEL_ELEM},
+ {"ionospheric_model", IONOSPHERIC_MODEL},
+ {"UTC_model", UTC_MODEL},
+ {"almanac", ALMANAC},
+ {"acqu_assist", ACQU_ASSIST},
+};
+
+
+/**************************************************************************
+* Local Function Prototypes
+**************************************************************************/
+
+static inline int _modem_sat_status_info_2_tel_sat_info(char *sat_info);
+
+static inline int _modem_acqa_assit_doppler_2_tel_doppler(char *doppler_info);
+
+static int _gps_element_compare(char *element[], char *element_str, int nelem);
+
+static enum gps_assist_element_type _get_element_type(char *element_str);
+
+static void _parse_ref_time_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist, gboolean GPS_TOW_assist, int count);
+
+static void _parse_location_parameters(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist);
+
+static void _parse_dgps_correction_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist);
+
+static void _parse_ionospheric_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist);
+
+static void _parse_utc_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist);
+
+static void _parse_almanc_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist, gboolean alm_elem, int count);
+
+static void _parse_acqu_assist_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist);
+
+static void _parse_nav_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist, gboolean ephem_and_clock, int element_count);
+
+static void _set_coordinate(xmlNodePtr node, gps_ellipsoid_po_t *point, int isalt, int altitude);
+
+static void _set_loc_info_ellipse_elements(xmlNodePtr node, void *elliplse, int is_unc_ellipse);
+
+static xmlChar* _generate_confirm_measure_pos_xml_text(gps_measure_position_confirm_t *gps_measure_position_confirm);
+
+static gboolean on_notification_gps_measure_position_from_modem(CoreObject *o, char *file_name, void *user_data);
+
+/**************************************************************************
+* Local Function Definitions
+ **************************************************************************/
+
+static inline int _modem_sat_status_info_2_tel_sat_info(char *sat_info)
+{
+ int count;
+
+ for (count = 0; count < (int) (sizeof(sat_status_info_table) / sizeof(sat_status_info_t)); count++) {
+ if (strcmp(sat_status_info_table[count].psat_status, sat_info) == 0)
+ return (sat_status_info_table[count].stat_status);
+ }
+ return (-1);
+}
+
+static inline int _modem_acqa_assit_doppler_2_tel_doppler(char *doppler_info)
+{
+ int count;
+
+ for (count = 0; count < (int) (sizeof(doppler_status_info_table) / sizeof(doppler_status_info_t)); count++) {
+ if (strcmp(doppler_status_info_table[count].pdoppler_status, doppler_info) == 0)
+ return (doppler_status_info_table[count].doppler_status);
+ }
+ return (-1);
+}
+
+static int _gps_element_compare(char *element[], char *element_str, int nelem)
+{
+ int count;
+
+ for (count = 0; count < nelem; count++) {
+ if (strcmp(element[count], element_str) == 0)
+ return count;
+ }
+
+ return -1;
+}
+
+
+static enum gps_assist_element_type _get_element_type(char *element_str)
+{
+ unsigned int index;
+
+ for (index = 0; index < sizeof(elements) / sizeof(t_element); index++) {
+ if (strcmp(elements[index].name, element_str) == 0)
+ return elements[index].type;
+ }
+ return -1;
+}
+
+static void _parse_ref_time_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist, gboolean GPS_TOW_assist, int count)
+{
+ int node_count;
+ int nelem;
+ static char *element[] = {"GPS_TOW_msec", "GPS_week", "sat_id", "tlm_word", "anti_sp", "alert", "tlm_res"};
+
+ dbg("Enter");
+ if (count < 0 || count >= MAX_NUM_OF_GPS_REF_TIME_ELEMENT) {
+ dbg("invalid count");
+ return;
+ }
+ nelem = (int) NUM_OF_ELEMENTS(element);
+ node_count = _gps_element_compare(element, element_str, nelem);
+
+ if (node_count == 0) {
+ gpsdata_assist->ref_time.gpsTow = atoi(element_value);
+ dbg("gpsTow - %d\n", gpsdata_assist->ref_time.gpsTow);
+ gpsdata_assist->dgps_corrections.gpsTow = gpsdata_assist->ref_time.gpsTow;
+ return;
+ } else if (node_count == 1) {
+ gpsdata_assist->ref_time.gpsWeek = atoi(element_value);
+ dbg("gpsWeek - %d\n", gpsdata_assist->ref_time.gpsWeek);
+ return;
+ }
+
+ if (GPS_TOW_assist) {
+ switch (node_count) {
+ case 2:
+ {
+ gpsdata_assist->ref_time.GpsTowAssist[count].satID = atoi(element_value);
+ dbg("GpsTowAssist[%d].satID = %d\n", count, gpsdata_assist->ref_time.GpsTowAssist[count].satID);
+ gpsdata_assist->ref_time.nrOfSats = count + 1;
+ }
+ break;
+
+ case 3:
+ {
+ gpsdata_assist->ref_time.GpsTowAssist[count].tlmWord = atoi(element_value);
+ dbg("GpsTowAssist[%d]-tlmWord = %d\n", count, gpsdata_assist->ref_time.GpsTowAssist[count].tlmWord);
+ gpsdata_assist->ref_time.nrOfSats = count + 1;
+ }
+ break;
+
+ case 4:
+ {
+ gpsdata_assist->ref_time.GpsTowAssist[count].antiSpoofFlag = *element_value;
+ dbg("GpsTowAssist[%d]-antiSpoofFlag = 0x%X\n", count, gpsdata_assist->ref_time.GpsTowAssist[count].antiSpoofFlag);
+ gpsdata_assist->ref_time.nrOfSats = count + 1;
+ }
+ break;
+
+ case 5:
+ {
+ gpsdata_assist->ref_time.GpsTowAssist[count].alertFlag = *element_value;
+ dbg("GpsTowAssist[%d]-alertFlag = 0x%X\n", count, gpsdata_assist->ref_time.GpsTowAssist[count].alertFlag);
+ gpsdata_assist->ref_time.nrOfSats = count + 1;
+ }
+ break;
+
+ case 6:
+ {
+ gpsdata_assist->ref_time.GpsTowAssist[count].tmlReservedBits = *element_value;
+ dbg("GpsTowAssist[%d]-tmlReservedBits = 0x%X\n", count, gpsdata_assist->ref_time.GpsTowAssist[count].tmlReservedBits);
+ gpsdata_assist->ref_time.nrOfSats = count + 1;
+ }
+ break;
+
+ default:
+ dbg("Invalid gps element");
+ }
+ }
+}
+
+static void _parse_location_parameters(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist)
+{
+ // unsigned char shapeType; and unsigned char hemisphere not supported.
+
+ static char *element[] = {
+ "north", "degrees", "height_above_surface", "height", "longitude", "uncert_semi_major", "uncert_semi_minor",
+ "orient_major", "confidence", "uncert_alt"
+ };
+
+ int nelem = (int) NUM_OF_ELEMENTS(element);
+ int count;
+
+ count = _gps_element_compare(element, element_str, nelem);
+
+ dbg("Enter");
+
+ switch (count) {
+ case 0:
+ {
+ // gpsdata_assist.ref_loc.latitude_data.north = atoi(element_str_text);
+ // dbg("gpsdata_assist.ref_loc.latitude_data.north - %d\n",gpsdata_assist.ref_loc.latitude_data.north);
+ }
+ break;
+
+ case 1:
+ {
+ gpsdata_assist->ref_loc.latitude = atoi(element_value);
+ dbg("latitude_data.degrees - %d\n", gpsdata_assist->ref_loc.latitude);
+ }
+ break;
+
+ case 2:
+ {
+ // gpsdata_assist.ref_loc.altitude_data.height_above_surface = atoi(element_str_text);
+ // dbg("altitude_data.height_above_surface - %d\n",gpsdata_assist.ref_loc.altitude_data.height_above_surface);
+ }
+ break;
+
+ case 3:
+ {
+ gpsdata_assist->ref_loc.altitude = atoi(element_value); // todo- need to confirm
+ dbg("altitude_data.height - %d\n", gpsdata_assist->ref_loc.altitude);
+ }
+ break;
+
+ case 4:
+ {
+ gpsdata_assist->ref_loc.longitude = atoi(element_value);
+ dbg("longitude - %d\n", gpsdata_assist->ref_loc.longitude);
+ }
+ break;
+
+ case 5:
+ {
+ gpsdata_assist->ref_loc.semiMajorUncert = *element_value;
+ dbg("semiMajorUncert - 0x%X\n", gpsdata_assist->ref_loc.semiMajorUncert);
+ }
+ break;
+
+ case 6:
+ {
+ gpsdata_assist->ref_loc.semiMinorUncert = *element_value;
+ dbg("uncert_semi_minor - 0x%X\n", gpsdata_assist->ref_loc.semiMinorUncert);
+ }
+ break;
+
+ case 7:
+ {
+ gpsdata_assist->ref_loc.majorAxis = *element_value;
+ dbg("orient_major - 0x%X\n", gpsdata_assist->ref_loc.majorAxis);
+ }
+ break;
+
+ case 8:
+ {
+ gpsdata_assist->ref_loc.confidence = *element_value;
+ dbg("confidence - 0x%X\n", gpsdata_assist->ref_loc.confidence);
+ }
+ break;
+
+ case 9:
+ {
+ gpsdata_assist->ref_loc.altUncert = *element_value;
+ dbg("altUncert - 0x%X\n", gpsdata_assist->ref_loc.altUncert);
+ }
+ break;
+
+ default:
+ dbg("invalid element");
+ }
+}
+
+static void _parse_dgps_correction_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist)
+{
+ dbg("Enter");
+
+ if (strcmp(element_str, "sat_id") == 0) {
+ gpsdata_assist->dgps_corrections.seqOfSatElement[0].satId = *element_value;
+ dbg("seqOfSatElement[0].satId - %d\n", gpsdata_assist->dgps_corrections.seqOfSatElement[0].satId);
+ } else if (strcmp(element_str, "IODE") == 0) {
+ gpsdata_assist->dgps_corrections.seqOfSatElement[0].iode = atoi(element_value);
+ dbg("seqOfSatElement[0].iode - %d\n", gpsdata_assist->dgps_corrections.seqOfSatElement[0].iode);
+ } else if (strcmp(element_str, "UDRE") == 0) {
+ gpsdata_assist->dgps_corrections.seqOfSatElement[0].udre = *element_value;
+ dbg("seqOfSatElement[0].udre- %d\n", gpsdata_assist->dgps_corrections.seqOfSatElement[0].udre);
+ } else if (strcmp(element_str, "PRC") == 0) {
+ gpsdata_assist->dgps_corrections.seqOfSatElement[0].pseudoRangeCor = atoi(element_value);
+ dbg("seqOfSatElement[0].pseudoRangeCor - %d\n", gpsdata_assist->dgps_corrections.seqOfSatElement[0].pseudoRangeCor);
+ } else if (strcmp(element_str, "RRC") == 0) {
+ gpsdata_assist->dgps_corrections.seqOfSatElement[0].rangeRateCor = atoi(element_value);
+ dbg("seqOfSatElement[0].rangeRateCor - %d\n", gpsdata_assist->dgps_corrections.seqOfSatElement[0].rangeRateCor);
+ }
+}
+
+static void _parse_ionospheric_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist)
+{
+ static char *element[] = {"alfa0", "alfa1", "alfa2", "alfa3", "beta0", "beta1", "beta2", "beta3" };
+ int nelem = (int) NUM_OF_ELEMENTS(element);
+ int count;
+
+ count = _gps_element_compare(element, element_str, nelem);
+ dbg("enter");
+ switch (count) {
+ case 0:
+ {
+ gpsdata_assist->iono_model.alfa0 = *element_value;
+ dbg("alfa0 - 0x%X\n", gpsdata_assist->iono_model.alfa0);
+ }
+ break;
+
+ case 1:
+ {
+ gpsdata_assist->iono_model.alfa1 = *element_value;
+ dbg("alfa1 - 0x%X\n", gpsdata_assist->iono_model.alfa1);
+ }
+ break;
+
+ case 2:
+ {
+ gpsdata_assist->iono_model.alfa2 = *element_value;
+ dbg("alfa2 - 0x%X\n", gpsdata_assist->iono_model.alfa2);
+ }
+ break;
+
+ case 3:
+ {
+ gpsdata_assist->iono_model.alfa3 = *element_value;
+ dbg("alfa3 - 0x%X\n", gpsdata_assist->iono_model.alfa3);
+ }
+ break;
+
+ case 4:
+ {
+ gpsdata_assist->iono_model.beta0 = *element_value;
+ dbg("beta0 - 0x%X\n", gpsdata_assist->iono_model.beta0);
+ }
+ break;
+
+ case 5:
+ {
+ gpsdata_assist->iono_model.beta1 = *element_value;
+ dbg("beta1 -0x%X\n", gpsdata_assist->iono_model.beta1);
+ }
+ break;
+
+ case 6:
+ {
+ gpsdata_assist->iono_model.beta2 = *element_value;
+ dbg("beta2 - 0x%X\n", gpsdata_assist->iono_model.beta2);
+ }
+ break;
+
+ case 7:
+ {
+ gpsdata_assist->iono_model.beta3 = *element_value;
+ dbg("beta3 - 0x%X\n", gpsdata_assist->iono_model.beta3);
+ }
+ break;
+
+ default:
+ dbg("invalid gps element");
+ }
+}
+
+void _parse_utc_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist)
+{
+ static char *element[] = {"a1", "a0", "tot", "wnt", "dtls", "wnlsf", "dn", "dtlsf"};
+ int nelem = (int) NUM_OF_ELEMENTS(element);
+ int count;
+
+ count = _gps_element_compare(element, element_str, nelem);
+ dbg("Enter");
+
+ switch (count) {
+ case 0:
+ {
+ gpsdata_assist->utc_model.utcA1 = atoi(element_value);
+ dbg("utcA1 - %d\n", gpsdata_assist->utc_model.utcA1);
+ }
+ break;
+
+ case 1:
+ {
+ gpsdata_assist->utc_model.utcA0 = atoi(element_value);
+ dbg("utcA0 - %d\n", gpsdata_assist->utc_model.utcA0);
+ }
+ break;
+
+ case 2:
+ {
+ gpsdata_assist->utc_model.utcTot = *element_value;
+ dbg("utcTot - 0x%X\n", gpsdata_assist->utc_model.utcTot);
+ }
+ break;
+
+ case 3:
+ {
+ gpsdata_assist->utc_model.utcWNt = *element_value;
+ dbg("utcWNt - 0x%X\n", gpsdata_assist->utc_model.utcWNt);
+ }
+ break;
+
+ case 4:
+ {
+ gpsdata_assist->utc_model.utcDeltaTls = *element_value;
+ dbg("utcDeltaTls -0x%X\n", gpsdata_assist->utc_model.utcDeltaTls);
+ }
+ break;
+
+ case 5:
+ {
+ gpsdata_assist->utc_model.utcWNlsf = *element_value;
+ dbg("utcWNlsf - 0x%X\n", gpsdata_assist->utc_model.utcWNlsf);
+ }
+ break;
+
+ case 6:
+ {
+ gpsdata_assist->utc_model.utcDN = *element_value;
+ dbg("utcDN - 0x%X\n", gpsdata_assist->utc_model.utcDN);
+ }
+ break;
+
+ case 7:
+ {
+ gpsdata_assist->utc_model.utcDeltaTlsf = *element_value;
+ dbg("utcDeltaTlsf - 0x%X\n", gpsdata_assist->utc_model.utcDeltaTlsf);
+ }
+ break;
+
+ default:
+ dbg("invalid gps element");
+ }
+}
+
+static void _parse_almanc_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist,
+ gboolean alm_elem, int count)
+{
+ int nelem;
+ int node_count;
+ static char *element[] = {
+ "wna", "data_id", "sat_id", "alm_ecc", "alm_toa", "alm_ksii", "alm_omega_dot", "alm_sv_health", "alm_power_half",
+ "alm_omega0", "alm_omega", "alm_m0", "alm_af0", "alm_af1"
+ };
+
+ dbg("Enter");
+ if (count < 0 || count >= MAX_NUM_OF_GPS_ALMANC_ELEMENTS) {
+ dbg("invalid count");
+ return;
+ }
+ nelem = (int) NUM_OF_ELEMENTS(element);
+
+ node_count = _gps_element_compare(element, element_str, nelem);
+ if (node_count == 0) {
+ gpsdata_assist->almanac.almanacWNa = *element_value;
+ dbg("almanacWNa - %d\n", gpsdata_assist->almanac.almanacWNa);
+ return;
+ }
+
+ if (alm_elem) {
+ switch (node_count) {
+ case 1:
+ {
+ gpsdata_assist->almanac.AlmanacSatInfo[count].dataId = *element_value;
+ dbg("AlmanacSatInfo[%d].data_id - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].dataId);
+ }
+ break;
+
+ case 2:
+ {
+ gpsdata_assist->almanac.AlmanacSatInfo[count].satId = *element_value;
+ dbg("AlmanacSatInfo[%d].sat_id - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].satId);
+ }
+ break;
+
+ case 3:
+ {
+ gpsdata_assist->almanac.AlmanacSatInfo[count].almanacE = atoi(element_value);
+ dbg("AlmanacSatInfo[%d].almanacE - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacE);
+ }
+ break;
+
+ case 4:
+ {
+ gpsdata_assist->almanac.AlmanacSatInfo[count].almanacToa = *element_value;
+ dbg("AlmanacSatInfo[%d].almanacToa - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacToa);
+ }
+ break;
+
+ case 5:
+ {
+ gpsdata_assist->almanac.AlmanacSatInfo[count].almanacKsii = *element_value;
+ dbg("AlmanacSatInfo[%d].almanacKsii - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacKsii);
+ }
+ break;
+
+ case 6:
+ {
+ gpsdata_assist->almanac.AlmanacSatInfo[count].almanacOmegaDot = *element_value;
+ dbg("AlmanacSatInfo[%d].almanacOmegaDot - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacOmegaDot);
+ }
+ break;
+
+ case 7:
+ {
+ gpsdata_assist->almanac.AlmanacSatInfo[count].almanacSvHealth = *element_value;
+ dbg("AlmanacSatInfo[%d].almanacSvHealth - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacSvHealth);
+ }
+ break;
+
+ case 8:
+ {
+ gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAPowerHalf = atoi(element_value);
+ dbg("AlmanacSatInfo[%d].almanacAPowerHalf - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAPowerHalf);
+ }
+ break;
+
+ case 9:
+ {
+ gpsdata_assist->almanac.AlmanacSatInfo[count].almanacOmega0 = atoi(element_value);
+ dbg("AlmanacSatInfo[%d].almanacOmega0 - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacOmega0);
+ }
+ break;
+
+ case 10:
+ {
+ gpsdata_assist->almanac.AlmanacSatInfo[count].almanacW = atoi(element_value);
+ dbg("AlmanacSatInfo[%d].almanacW - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacW);
+ }
+ break;
+
+ case 11:
+ {
+ gpsdata_assist->almanac.AlmanacSatInfo[count].almanacM0 = atoi(element_value);
+ dbg("AlmanacSatInfo[%d].almanacM0 - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacM0);
+ }
+ break;
+
+ case 12:
+ {
+ gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAf0 = atoi(element_value);
+ dbg("AlmanacSatInfo[%d].almanacAf0 - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAf0);
+ }
+ break;
+
+ case 13:
+ {
+ gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAf1 = atoi(element_value);
+ dbg("AlmanacSatInfo[%d].almanacAf1 - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAf1);
+ }
+ break;
+
+ default:
+ dbg("invalid gps element");
+ }
+ }
+ return;
+}
+
+static void _parse_acqu_assist_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist)
+{
+ static char *element[] = {"tow_msec", "sat_id", "dopl0", "dopl1", "code_ph", "code_ph_int", "GPS_bitno", "srch_w", "az", "elev"};
+ int nelem = (int) NUM_OF_ELEMENTS(element);
+ int count;
+
+ count = _gps_element_compare(element, element_str, nelem);
+ dbg("Enter");
+
+ switch (count) {
+ case 0:
+ gpsdata_assist->acq_assist.gpsTow = atoi(element_value);
+ dbg("acq_assist.gpsTow - %d\n", gpsdata_assist->acq_assist.gpsTow);
+ break;
+
+ case 1:
+ gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].satId = *element_value;
+ dbg("lcsAcquisitionSatInfo[0].satId - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].satId);
+ break;
+
+ case 2:
+ gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].doppler0 = atoi(element_value);
+ dbg("lcsAcquisitionSatInfo[0].dopl0 - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].doppler0);
+ break;
+
+ case 3:
+ gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].doppler1 = *element_value;
+ dbg("lcsAcquisitionSatInfo[0].doppler1 - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].doppler1);
+ break;
+
+ case 4:
+ gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].codePhase = atoi(element_value);
+ dbg("lcsAcquisitionSatInfo[0].codePhase - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].codePhase);
+ break;
+
+ case 5:
+ gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].intCodePhase = *element_value;
+ dbg("lcsAcquisitionSatInfo[0].intCodePhase - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].intCodePhase);
+ break;
+
+ case 6:
+ gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].gpsBitNumber = *element_value;
+ dbg("lcsAcquisitionSatInfo[0].GPS_bitno - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].gpsBitNumber);
+ break;
+
+ case 7:
+ gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].codePhaseSearchWindow = *element_value;
+ dbg("lcsAcquisitionSatInfo[0].codePhaseSearchWindow - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].codePhaseSearchWindow);
+ break;
+
+ case 8:
+ gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].azimuth = *element_value;
+ dbg("lcsAcquisitionSatInfo[0].azimuth - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].azimuth);
+ break;
+
+ case 9:
+ gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].elevation = *element_value;
+ dbg("lcsAcquisitionSatInfo[0].elevation - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].elevation);
+ break;
+
+ default:
+ dbg("invalid gps element");
+ }
+}
+
+static void _parse_nav_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t
+ *gpsdata_assist, gboolean ephem_and_clock, int element_count)
+{
+ static char *element[] = {
+ "sat_id", "l2_code", "ura", "sv_health", "iodc", "l2p_flag", "esr1", "esr2", "esr3", "esr4", "tgd", "toc", "af2", "af0",
+ "crs", "delta_n", "m0", "cuc", "ecc", "cus", "power_half", "toe", "fit_flag", "aoda", "cic", "omega0", "cis", "i0", "crc", "omega", "idot", "omega_dot"
+ };
+
+ int nelem = (int) NUM_OF_ELEMENTS(element);
+ int count;
+
+ if (element_count < 0 || element_count >= MAX_NUM_OF_GPS_NAV_ELEMENT) {
+ dbg("invalid count");
+ return;
+ }
+ count = _gps_element_compare(element, element_str, nelem);
+
+ dbg("Enter");
+ if (count == 0) {
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].satId = *element_value;
+ dbg("NavigationSatInfo[%d].satId - 0x%X\n", element_count, gpsdata_assist->navi_model.NavigationSatInfo[element_count].satId);
+ return;
+ }
+
+ if (ephem_and_clock) {
+ switch (count) {
+ case 1:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemCodeOnL2 = *element_value;
+ break;
+
+ case 2:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemUra = *element_value;
+ break;
+
+ case 3:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemSvHealth = *element_value;
+ break;
+
+ case 4:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemIodc = atoi(element_value);
+ break;
+
+ case 5:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemL2PFlag = *element_value;
+ break;
+
+ case 6:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.NavigationSubFrameRsv.rsv1 = atoi(element_value);
+ break;
+
+ case 7:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.NavigationSubFrameRsv.rsv2 = atoi(element_value);
+ break;
+
+ case 8:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.NavigationSubFrameRsv.rsv3 = atoi(element_value);
+ break;
+
+ case 9:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.NavigationSubFrameRsv.rsv4 = atoi(element_value);
+ break;
+
+ case 10:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemTgd = *element_value;
+ break;
+
+ case 11:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemToc = atoi(element_value);
+ break;
+
+ case 12:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemAf2 = *element_value;
+ break;
+
+ case 13:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemAf1 = atoi(element_value);
+ break;
+
+ case 14:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemAf0 = atoi(element_value);
+ break;
+
+ case 15:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemCrs = atoi(element_value);
+ break;
+
+ case 16:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemDeltaN = atoi(element_value);
+ break;
+
+ case 17:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemM0 = atoi(element_value);
+ break;
+
+ case 18:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemCuc = atoi(element_value);
+ break;
+
+ case 19:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemE = atoi(element_value);
+ break;
+
+ case 20:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemCus = atoi(element_value);
+ break;
+
+ case 21:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemAPowrHalf = atoi(element_value);
+ break;
+
+ case 22:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemToe = atoi(element_value);
+ break;
+
+ case 23:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemFitFlag = *element_value;
+ break;
+
+ case 24:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemAoda = *element_value;
+ break;
+
+ case 25:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemCic = atoi(element_value);
+ break;
+
+ case 26:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemI0 = atoi(element_value);
+ break;
+
+ case 27:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemCrc = atoi(element_value);
+ break;
+
+ case 28:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemW = atoi(element_value);
+ break;
+
+ case 29:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemIDot = atoi(element_value);
+ break;
+
+ case 30:
+ gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemOmegaADot = atoi(element_value);
+ dbg("NavigationSatInfo[%d].NavigationEphemeris.ephemOmegaADot - 0x%X\n", element_count, gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemOmegaADot);
+ break;
+
+ default:
+ dbg("invalid gps element");
+ }
+ }
+}
+
+
+// Set coordinate elements : <latitude> <longitude> <altitude>
+static void _set_coordinate(xmlNodePtr node, gps_ellipsoid_po_t *point, int isalt, int altitude)
+{
+ // <parent_node> .. .. (xmlNodePtr node)
+ // <coordinate> <latitude> <north>0</north> <degrees>0</degrees> </latitude> <longitude>0</longitude> </coordinate>
+ // <altitude> <height_above_surface>0</height_above_surface> <height>0</height> </altitude>
+ // .. .. <\parent_node>
+
+ xmlNodePtr coordinate_node = NULL, temp_node = NULL;
+
+ memset(node_name, 0x00, sizeof(node_name));
+ memset(node_value, 0x00, sizeof(node_value));
+
+ snprintf(node_name, NODE_SIZE, "%s", "coordinate");
+ coordinate_node = xmlNewChild(node, NULL, BAD_CAST node_name, NULL);
+
+ snprintf(node_name, NODE_SIZE, "%s", "latitude");
+ temp_node = xmlNewChild(coordinate_node, NULL, BAD_CAST node_name, NULL);
+
+ snprintf(node_name, NODE_SIZE, "%s", "north");
+ snprintf(node_value, NODE_SIZE, "%d", 0);
+ xmlNewChild(temp_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ snprintf(node_name, NODE_SIZE, "%s", "degrees");
+ snprintf(node_value, NODE_SIZE, "%d", (int) point->latitude);
+ xmlNewChild(temp_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ snprintf(node_name, NODE_SIZE, "%s", "longitude");
+ snprintf(node_value, NODE_SIZE, "%d", (int) point->longitude);
+ xmlNewChild(coordinate_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ if (isalt) {
+ snprintf(node_name, NODE_SIZE, "%s", "altitude");
+ temp_node = xmlNewChild(node, NULL, BAD_CAST node_name, NULL);
+ snprintf(node_name, NODE_SIZE, "%s", "height_above_surface");
+ snprintf(node_value, NODE_SIZE, "%d", 0);
+ xmlNewChild(temp_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+ snprintf(node_name, NODE_SIZE, "%s", "height");
+ snprintf(node_value, NODE_SIZE, "%d", altitude);
+ xmlNewChild(temp_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+ }
+ return;
+}
+
+static void _set_loc_info_ellipse_elements(xmlNodePtr node, void *elliplse, int is_unc_ellipse)
+{
+ gps_po_unc_ellipse_t *p_unc_ellipse;
+ gps_po_alt_unc_ellipse_t *p_alt_unc_ellipse;
+ unsigned char semiMajorAxis, semiMinorAxis, orientationAngle, confidence;
+
+ memset(node_name, 0x00, sizeof(node_name));
+ memset(node_value, 0x00, sizeof(node_value));
+
+ if (is_unc_ellipse) {
+ p_unc_ellipse = (gps_po_unc_ellipse_t *) elliplse;
+ semiMajorAxis = p_unc_ellipse->semiMajorAxis;
+ semiMinorAxis = p_unc_ellipse->semiMinorAxis;
+ orientationAngle = p_unc_ellipse->orientationAngle;
+ confidence = p_unc_ellipse->confidence;
+ } else {
+ p_alt_unc_ellipse = (gps_po_alt_unc_ellipse_t *) elliplse;
+ semiMajorAxis = p_alt_unc_ellipse->semiMajorAxis;
+ semiMinorAxis = p_alt_unc_ellipse->semiMinorAxis;
+ orientationAngle = p_alt_unc_ellipse->orientationAngle;
+ confidence = p_alt_unc_ellipse->confidence;
+ }
+
+ snprintf(node_name, NODE_SIZE, "%s", "uncert_semi_major");
+ snprintf(node_value, NODE_SIZE, "%d", semiMajorAxis);
+ xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ snprintf(node_name, NODE_SIZE, "%s", "uncert_semi_minor");
+ snprintf(node_value, NODE_SIZE, "%d", semiMinorAxis);
+ xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ snprintf(node_name, NODE_SIZE, "%s", "orient_major");
+ snprintf(node_value, NODE_SIZE, "%d", orientationAngle);
+ xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ snprintf(node_name, NODE_SIZE, "%s", "confidence");
+ snprintf(node_value, NODE_SIZE, "%d", confidence);
+ xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+}
+
+static xmlChar* _generate_confirm_measure_pos_xml_text(gps_measure_position_confirm_t *gps_measure_position_confirm)
+{
+ xmlDocPtr doc = NULL;
+ xmlNodePtr root_node = NULL, node = NULL;
+ xmlNodePtr gps_msr_node = NULL, shape_data_node = NULL, loc_child_node = NULL;
+ xmlChar *xml = NULL;
+ int count = 0, altitude, size;
+
+/*
+ Creates a new XML document
+================================================================================================================================
+
+
+ <?xml version="1.0"?>
+ <pos xsi:noNamespaceSchemaLocation="pos.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <GPS_meas>
+ <ref_time_only>
+ <tow_msec></tow_msec>
+ </ref_time_only>
+ <meas_params>
+ <sat_id></sat_id><carr2_noise></carr2_noise><dopl></dopl><whole_chips></whole_chips><fract_chips></fract_chips>
+ <multi_path literal="xx"></multi_path> <psr_rms_err></psr_rms_err>
+ </meas_params>
+ </GPS_meas>
+ <location>
+ <time_of_fix></time_of_fix><
+ <location_parameters>
+ <shape_data>
+ <ellipsoid_point>
+ <coordinate>
+ <latitude><north></north><degrees></degrees></latitude><longitude></longitude>
+ </coordinate>
+ </ellipsoid_point>
+ <ellipsoid_point_uncert_circle>
+ <uncert_circle></uncert_circle>
+ <coordinate>
+ <latitude> <> <\> ...</latitude> <longitude></longitude>
+ </coordinate>
+ </ellipsoid_point_uncert_circle>
+ <ellipsoid_point_uncert_ellipse>
+ <coordinate>
+ <latitude><> <\>..<longitude></longitude>
+ </coordinate>
+ <uncert_ellipse><uncert_semi_major></uncert_semi_major><uncert_semi_minor></uncert_semi_minor>
+ <orient_major></orient_major><confidence></confidence></uncert_ellipse>
+ </ellipsoid_point_uncert_ellipse>
+ <polygon>
+ <coordinate*>
+ <latitude><> <\>...</latitude><longitude></longitude>
+ </coordinate>
+ </polygon>
+ <ellipsoid_point_alt>
+ <coordinate>
+ <latitude><> <\>..</latitude><longitude></longitude>
+ </coordinate>
+ <altitude>
+ <height_above_surface></height_above_surface><height></height>
+ </altitude>
+ </ellipsoid_point_alt>
+ <ellipsoid_point_alt_uncertellipse>
+ <coordinate>
+ <latitude> <> <\>.. ..</latitude><longitude></longitude>
+ </coordinate>
+ <altitude>
+ <height_above_surface></height_above_surface><height></height>
+ </altitude>
+ <uncert_semi_major></uncert_semi_major><uncert_semi_minor></uncert_semi_minor><orient_major></orient_major>
+ <confidence></confidence><uncert_alt></uncert_alt>
+ </ellipsoid_point_alt_uncertellipse>
+ <ellips_arc>
+ <coordinate>
+ <latitude><> <\> .. </latitude><longitude></longitude>
+ </coordinate><
+ <inner_rad></inner_rad>
+ <uncert_rad></uncert_rad><offset_angle></offset_angle><included_angle></included_angle>
+ <confidence></confidence>
+ </ellips_arc>
+ </shape_data>
+ </location_parameters>
+ </location>
+ <assist_data>
+ <msr_assist_data/>
+ </assist_data>
+ </pos>
+ ================================================================================================================================
+ */
+
+ doc = xmlNewDoc(BAD_CAST "1.0");
+ dbg("Enter");
+
+ memset(node_name, 0x00, sizeof(node_name));
+ memset(node_value, 0x00, sizeof(node_value));
+ // root element
+ snprintf(node_name, NODE_SIZE, "%s", POSITION_NODE);
+ // Creation of a new node element
+ root_node = xmlNewNode(NULL, BAD_CAST node_name);
+ // Set the root element of the document
+ xmlDocSetRootElement(doc, root_node);
+ snprintf(node_name, NODE_SIZE, "%s", POSITION_NODE_ATTR_XSI);
+ snprintf(node_value, NODE_SIZE, "%s", POSITION_NODE_ATTR_VAL_XSI);
+ // Create a new property carried by a node
+ xmlNewProp(root_node, BAD_CAST node_name, BAD_CAST node_value);
+
+ snprintf(node_name, NODE_SIZE, "%s", POSITION_NODE_ATTR_XMLNS);
+ snprintf(node_value, NODE_SIZE, "%s", POSITION_NODE_ATTR_VAL_XMLNS);
+ xmlNewProp(root_node, BAD_CAST node_name, BAD_CAST node_value);
+
+ // 1.GPS measure.
+ // Creation of a new child element, added at the end of @parent children list
+ snprintf(node_name, NODE_SIZE, "%s", "GPS_meas");
+ gps_msr_node = xmlNewChild(root_node, NULL, BAD_CAST node_name, NULL);
+
+ snprintf(node_name, NODE_SIZE, "%s", "ref_time_only");
+ node = xmlNewChild(gps_msr_node, NULL, BAD_CAST node_name, NULL);
+
+ snprintf(node_name, NODE_SIZE, "%s", "tow_msec");
+ snprintf(node_value, NODE_SIZE, "%d", (int) gps_measure_position_confirm->gps_measure.gpsTow);
+ xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ // creatation of <meas_params> elements.
+ for (count = 0; count < gps_measure_position_confirm->gps_measure.nrOfSats; count++) {
+ xmlNodePtr multipath_node = NULL;
+ snprintf(node_name, NODE_SIZE, "%s", "meas_params");
+ node = xmlNewChild(gps_msr_node, NULL, BAD_CAST node_name, NULL);
+
+ snprintf(node_name, NODE_SIZE, "%s", "sat_id");
+ snprintf(node_value, NODE_SIZE, "%d", gps_measure_position_confirm->gps_measure.GpsMeasure[count].satId);
+ xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ snprintf(node_name, NODE_SIZE, "%s", "carr2_noise");
+ snprintf(node_value, NODE_SIZE, "%d", gps_measure_position_confirm->gps_measure.GpsMeasure[count].cno);
+ xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ snprintf(node_name, NODE_SIZE, "%s", "dopl");
+ snprintf(node_value, NODE_SIZE, "%d", gps_measure_position_confirm->gps_measure.GpsMeasure[count].doppler);
+ xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ snprintf(node_name, NODE_SIZE, "%s", "whole_chips");
+ snprintf(node_value, NODE_SIZE, "%d", gps_measure_position_confirm->gps_measure.GpsMeasure[count].wholeChips);
+ xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ snprintf(node_name, NODE_SIZE, "%s", "fract_chips");
+ snprintf(node_value, NODE_SIZE, "%d", gps_measure_position_confirm->gps_measure.GpsMeasure[count].fracChips);
+ xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ snprintf(node_name, NODE_SIZE, "%s", "multi_path");
+ snprintf(node_value, NODE_SIZE, "%d", gps_measure_position_confirm->gps_measure.GpsMeasure[count].lcsMultiPath);
+ multipath_node = xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+ xmlNewProp(multipath_node, BAD_CAST "literal", BAD_CAST "not_measured");
+
+ snprintf(node_name, NODE_SIZE, "%s", "psr_rms_err");
+ snprintf(node_value, NODE_SIZE, "%d", gps_measure_position_confirm->gps_measure.GpsMeasure[count].pseuRangeRmsErr);
+ xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+ }
+
+ // 2.Location.
+ snprintf(node_name, NODE_SIZE, "%s", "location");
+ node = xmlNewChild(root_node, NULL, BAD_CAST node_name, NULL);
+
+ snprintf(node_name, NODE_SIZE, "%s", "time_of_fix");
+ snprintf(node_value, NODE_SIZE, "%d", gps_measure_position_confirm->loc_info.fixType);
+ xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ // location_parameters
+ snprintf(node_name, NODE_SIZE, "%s", "location_parameters");
+ node = xmlNewChild(node, NULL, BAD_CAST node_name, NULL);
+
+ // shape_data
+ snprintf(node_name, NODE_SIZE, "%s", "shape_data");
+ shape_data_node = xmlNewChild(node, NULL, BAD_CAST node_name, NULL);
+
+ // ellipsoid_point
+ snprintf(node_name, NODE_SIZE, "%s", "ellipsoid_point");
+ node = xmlNewChild(shape_data_node, NULL, BAD_CAST node_name, NULL);
+ // set coordinate.
+ _set_coordinate(node, &(gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_po), 0, 0);
+
+ // ellipsoid_point_uncert_circle
+ snprintf(node_name, NODE_SIZE, "%s", "ellipsoid_point_uncert_circle");
+ node = xmlNewChild(shape_data_node, NULL, BAD_CAST node_name, NULL);
+ snprintf(node_name, NODE_SIZE, "%s", "uncert_circle");
+ snprintf(node_value, NODE_SIZE, "%d", gps_measure_position_confirm->loc_info.measured_loc_info.p_unc_clrcle.uncertainRadius);
+ xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+ // set coordinate parameters.
+ _set_coordinate(node, &(gps_measure_position_confirm->loc_info.measured_loc_info.p_unc_clrcle.point), 0, 0);
+
+ // ellipsoid_point_uncert_ellipse
+ snprintf(node_name, NODE_SIZE, "%s", "ellipsoid_point_uncert_ellipse");
+ loc_child_node = xmlNewChild(shape_data_node, NULL, BAD_CAST node_name, NULL);
+ // set coordinate parameters.
+ _set_coordinate(loc_child_node, &(gps_measure_position_confirm->loc_info.measured_loc_info.p_unc_clrcle.point), 0, 0);
+
+ snprintf(node_name, NODE_SIZE, "%s", "uncert_ellipse");
+ node = xmlNewChild(loc_child_node, NULL, BAD_CAST node_name, NULL);
+ // set location ellipse parametes.
+ _set_loc_info_ellipse_elements(node, &(gps_measure_position_confirm->loc_info.measured_loc_info.p_unc_ellipse), 1);
+
+ snprintf(node_name, NODE_SIZE, "%s", "polygon");
+ loc_child_node = xmlNewChild(shape_data_node, NULL, BAD_CAST node_name, NULL);
+ for (count = 0; count < gps_measure_position_confirm->loc_info.measured_loc_info.polygon.noOfPoints; count++) {
+ // set coordinate parameters.
+ _set_coordinate(loc_child_node, &(gps_measure_position_confirm->loc_info.measured_loc_info.polygon.points[count]), 0, 0);
+ }
+
+ // ellipsoid_point_alt
+ snprintf(node_name, NODE_SIZE, "%s", "ellipsoid_point_alt");
+ loc_child_node = xmlNewChild(shape_data_node, NULL, BAD_CAST node_name, NULL);
+ altitude = gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_alt.altitude;
+ // set coordinate parameters.
+ _set_coordinate(loc_child_node, &(gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_alt.point), 1, altitude);
+
+ // ellipsoid_point_alt_uncertellipse
+ snprintf(node_name, NODE_SIZE, "%s", "ellipsoid_point_alt_uncertellipse");
+ loc_child_node = xmlNewChild(shape_data_node, NULL, BAD_CAST node_name, NULL);
+ altitude = gps_measure_position_confirm->loc_info.measured_loc_info.p_alt_unc_ellipse.altitude;
+ // set coordinate parameters.
+ _set_coordinate(loc_child_node, &(gps_measure_position_confirm->loc_info.measured_loc_info.p_alt_unc_ellipse.point), 1, altitude);
+ // set location ellipse parametes.
+ _set_loc_info_ellipse_elements(loc_child_node, &(gps_measure_position_confirm->loc_info.measured_loc_info.p_alt_unc_ellipse), 0);
+
+ snprintf(node_name, NODE_SIZE, "%s", "uncert_alt");
+ snprintf(node_value, NODE_SIZE, "%d", gps_measure_position_confirm->loc_info.measured_loc_info.p_alt_unc_ellipse.uncertainAltitude);
+ xmlNewChild(loc_child_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ // ellipsoid_point_alt_uncertellipse
+ snprintf(node_name, NODE_SIZE, "%s", "ellips_arc");
+ loc_child_node = xmlNewChild(shape_data_node, NULL, BAD_CAST node_name, NULL);
+ _set_coordinate(loc_child_node, &(gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_arc.point), 0, 0);
+
+ snprintf(node_name, NODE_SIZE, "%s", "inner_rad");
+ snprintf(node_value, NODE_SIZE, "%d", gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_arc.innerRadius);
+ xmlNewChild(loc_child_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ snprintf(node_name, NODE_SIZE, "%s", "uncert_rad");
+ snprintf(node_value, NODE_SIZE, "%d", gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_arc.uncertainRadius);
+ xmlNewChild(loc_child_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ snprintf(node_name, NODE_SIZE, "%s", "offset_angle");
+ snprintf(node_value, NODE_SIZE, "%d", gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_arc.offsetAngle);
+ xmlNewChild(loc_child_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ snprintf(node_name, NODE_SIZE, "%s", "included_angle");
+ snprintf(node_value, NODE_SIZE, "%d", gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_arc.includedAngle);
+ xmlNewChild(loc_child_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ snprintf(node_name, NODE_SIZE, "%s", "confidence");
+ snprintf(node_value, NODE_SIZE, "%d", gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_arc.confidence);
+ xmlNewChild(loc_child_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
+
+ // 3. assist data /msr_assist_data
+ snprintf(node_name, NODE_SIZE, "%s", "assist_data");
+ node = xmlNewChild(root_node, NULL, BAD_CAST node_name, NULL);
+ snprintf(node_name, NODE_SIZE, "%s", "msr_assist_data");
+ xmlNewChild(node, NULL, BAD_CAST node_name, NULL);
+
+ // Dump an XML document in memory and return the #xmlChar * and it's size in bytes
+ xmlDocDumpMemory(doc, &xml, &size);
+ dbg("xmlcontetnt:\n");
+ dbg("%s", (char *) xml);
+ // Free up all the structures used by a document, tree included.
+ xmlFreeDoc(doc);
+ xmlCleanupParser();
+ return xml;
+}
+
+static gboolean on_notification_gps_assist_data(CoreObject *o, const void *event_info, void *user_data)
+{
+ int fd;
+ gps_assist_data_noti_t gps_data_assist;
+ char *node = NULL, *node_value = NULL;
+ char *attribute = NULL, *attr_value = NULL;
+ enum gps_assist_element_type node_type = -1, set_element_type = -1;
+ int nav_model_node_count = 0;
+ int alm_node_count = -1;
+ int gps_tow_assist_count = -1;
+ char *line = NULL, *pos = NULL;
+ char *xml_line = NULL;
+ gboolean ret;
+ xmlTextReaderPtr reader;
+ gboolean _gps_assist_data = FALSE, gps_tow_assist = FALSE;
+ gboolean ephem_and_clock = FALSE, alm_elem = FALSE;
+
+ dbg("enter");
+
+/*
+ Example:GPS assist XML data will be in below format.
+================================================================================================================================
+ +CPOSR:<?xml version="1.0" encoding="UTF-8"?>
+ <pos xsi:noNamespaceSchemaLocation="pos.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <assist_data>
+ <GPS_assist>
+ <ref_time>
+ <GPS_time> <> <\>..<\GPS_time> <GPS_TOW_assist*> <> <\> ..<\GPS_TOW_assist>
+ </ref_time>
+
+ <location_parameters>
+ <shape_data> <ellipsoid_point_alt_uncertellipse> </coordinate> <> <\>...</coordinate> <altitude> <\altitude>
+ <uncert_semi_major> </uncert_semi_major> <uncert_semi_minor> </uncert_semi_minor> <orient_major> </orient_major> <confidence> </confidence>
+ <uncert_alt> </uncert_alt> </ellipsoid_point_alt_uncertellipse> </shape_data>
+ </location_parameters>
+
+ <DGPS_corrections>
+ <sat_id> </sat_id> <IODE> </IODE> <UDRE></UDRE> <PRC></PRC> <RRC></RRC>
+ </DGPS_corrections>
+
+ <nav_model_elem*>
+ <sat_id> </sat_id> <sat_status literal="xx"></sat_status>
+ <ephem_and_clock?> <l2_code></l2_code> <> <\> .. .. <\ephem_and_clock>
+ </nav_model_elem>
+
+ <ionospheric_model> <alfa0> </alfa0> <alfa1> </alfa1> <alfa2> </alfa2> <alfa3></alfa3>
+ <beta0></beta0> <beta1></beta1> <beta2></beta2> <beta3> </beta3>
+ </ionospheric_model>
+
+ <UTC_model>
+ <a1></a1><a0></a0><tot></tot><wnt></wnt> <dtls></dtls> <wnlsf></wnlsf> <dn></dn><dtlsf></dtlsf>
+ </UTC_model>
+ <almanac>
+ <wna>0</wna> <alm_elem*> <> <\> ...<\alm_elem>
+ </almanac>
+
+ <acqu_assist>
+ <tow_msec></tow_msec> <sat_info> <> <\> ... <\sat_info>
+ </acqu_assist>
+
+ </GPS_assist>
+ </assist_data>
+ </pos>
+================================================================================================================================
+*/
+
+ memset((void *) &gps_data_assist, 0x00, sizeof(gps_data_assist));
+ xml_line = (char *) ((GSList *) event_info)->data;
+
+ if (g_str_has_prefix((char *) xml_line, "+CPOSR:")) {
+ dbg("notification line with prefix");
+ pos = (char *) xml_line + strlen("+CPOSR:");
+ } else {
+ pos = (char *) xml_line;
+ }
+ line = g_strdup((char *) pos);
+ // open file.
+ if ((fd = open(FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, S_IRWXU)) == -1) {
+ dbg("Cannot open file\n");
+ g_free(line);
+ return FALSE;
+ }
+ // write gps xml data into file.
+ if (write(fd, (const void *) line, strlen(line)) == -1) {
+ dbg("Cannot write into file\n");
+ close(fd);
+ g_free(line);
+ return FALSE;
+ }
+ // free the memory pointed to by line.
+ g_free(line);
+
+ dbg("read xml file");
+ reader = xmlReaderForFile(FILE_NAME, NULL, 0);
+
+ while (xmlTextReaderRead(reader)) {
+ // Get the node type of the current node
+ switch (xmlTextReaderNodeType(reader)) {
+ case XML_READER_TYPE_ELEMENT:
+ {
+ // Read the qualified name of the node.
+ node = (char *) xmlTextReaderConstName(reader);
+ dbg("Element: %s\n ", node);
+ if (node != NULL) {
+ // check type of sub element of <GPS_assist>
+ set_element_type = _get_element_type(node);
+ if ((int) set_element_type != -1) // ignore negative value as excepted element type not set.
+ node_type = set_element_type;
+
+ dbg("xml node type : %d", node_type);
+
+ // Check for position measurement data.
+ if (strcmp(node, "pos_meas") == 0) {
+ // Deallocate all the resources associated to the reader
+ xmlFreeTextReader(reader);
+ xmlCleanupParser();
+ dbg("gps postion measurement notification ");
+ // GPS position measurement notification.
+ ret = on_notification_gps_measure_position_from_modem(o, FILE_NAME, user_data);
+ // remove file.
+ close(fd);
+ if (access(FILE_NAME, F_OK) == 0) {
+ if (remove(FILE_NAME))
+ dbg("file removed");
+ }
+ return ret;
+ }
+
+ // Moves the position of the current instance to the next attribute associated with the current node.
+ while (xmlTextReaderMoveToNextAttribute(reader)) {
+ // Read the qualified name of the node
+ attribute = (char *) xmlTextReaderConstName(reader);
+ dbg("attribute value - %s\n", attribute);
+
+ // Provides the text value of the node if present.
+ attr_value = (char *) xmlTextReaderConstValue(reader);
+ dbg("=\"%s\"\n", attr_value);
+
+ // Read attribute value of <nav_model_elem>
+ if (node_type == NAV_MODEL_ELEM) {
+ if (strcmp(node, "sat_status") == 0 && strcmp(attribute, "literal") == 0) {
+ gps_data_assist.navi_model.NavigationSatInfo[nav_model_node_count].NavigationSatStatus = _modem_sat_status_info_2_tel_sat_info(attr_value);
+ dbg("navigation sat status of nav model element - %d\n", gps_data_assist.navi_model.NavigationSatInfo[nav_model_node_count].NavigationSatStatus);
+ }
+ }
+ // Read attribute value of <acqu_assist>
+ else if (node_type == ACQU_ASSIST) {
+ if (strcmp(node, "dopl1_uncert") == 0 && strcmp(attribute, "literal") == 0) {
+ gps_data_assist.acq_assist.lcsAcquisitionSatInfo[0].dopplerUncertainty = _modem_acqa_assit_doppler_2_tel_doppler(attr_value);
+ dbg("doppler uncertainty of acqu assist data- %d", gps_data_assist.acq_assist.lcsAcquisitionSatInfo[0].dopplerUncertainty);
+ }
+ }
+ } // end of attribute check.
+
+ // check GPS data is having GPS_assist data.
+ if (strcmp(node, "GPS_assist") == 0) {
+ _gps_assist_data = TRUE;
+ }
+
+ if (_gps_assist_data == TRUE) {
+ // number of GPS_TOW_assist elements.
+ if (strcmp(node, "GPS_TOW_assist") == 0) {
+ gps_tow_assist_count++;
+ gps_tow_assist = TRUE;
+ } else if (strcmp(node, "nav_model_elem") == 0) {
+ // number of nav_model_elem.
+ nav_model_node_count++;
+ } else if (strcmp(node, "alm_elem") == 0) {
+ // number of alm_elem elements.
+ alm_node_count++;
+ dbg("alm_elem_count - %d", alm_node_count);
+ if (node_type == ALMANAC)
+ alm_elem = TRUE;
+ } else if (strcmp(node, "ephem_and_clock") == 0 && node_type == NAV_MODEL_ELEM) {
+ ephem_and_clock = TRUE;
+ }
+ }
+ }
+ xmlTextReaderMoveToElement(reader);
+ } // end of reading node type.
+ break;
+
+ case XML_READER_TYPE_TEXT:
+ {
+ // Provides the text value of the node if present
+ node_value = (char *) xmlTextReaderConstValue(reader);
+ dbg("node_value: %s\n", node_value);
+
+ if (node_value != NULL) {
+ switch (node_type) {
+ case REF_TIME:
+ _parse_ref_time_gps_elements(node, node_value, &gps_data_assist, gps_tow_assist, gps_tow_assist_count);
+ break;
+
+ case LOCATION_PARM:
+ _parse_location_parameters(node, node_value, &gps_data_assist);
+ break;
+
+ case DGPS_CORRECTION:
+ _parse_dgps_correction_gps_elements(node, node_value, &gps_data_assist);
+ break;
+
+ case NAV_MODEL_ELEM:
+ _parse_nav_model_gps_elements(node, node_value, &gps_data_assist, ephem_and_clock, nav_model_node_count);
+ break;
+
+ case IONOSPHERIC_MODEL:
+ _parse_ionospheric_model_gps_elements(node, node_value, &gps_data_assist);
+ break;
+
+ case UTC_MODEL:
+ _parse_utc_model_gps_elements(node, node_value, &gps_data_assist);
+ break;
+
+ case ALMANAC:
+ _parse_almanc_model_gps_elements(node, node_value, &gps_data_assist, alm_elem, alm_node_count);
+ break;
+
+ case ACQU_ASSIST:
+ _parse_acqu_assist_gps_elements(node, node_value, &gps_data_assist);
+ break;
+
+ default:
+ dbg("invalid element");
+ }
+ }
+ } // end of reading node value.
+ break;
+ }
+ } // end of parsing.
+
+ // Deallocate all the resources associated to the reader
+ xmlFreeTextReader(reader);
+ xmlCleanupParser();
+
+ // remove xml file.
+ close(fd);
+ if (access(FILE_NAME, F_OK) == 0) {
+ if (remove(FILE_NAME))
+ dbg("file removed");
+ }
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
+ o, TNOTI_GPS_ASSIST_DATA, sizeof(gps_data_assist), &gps_data_assist);
+ return TRUE;
+}
+
+static gboolean on_notification_gps_measure_position_from_modem(CoreObject *o, char *file_name, void *user_data)
+{
+ char *node = NULL, *node_value = NULL;
+ char *attribute = NULL;
+ char *attr_value = NULL;
+ gps_measure_position_indi_t gps_measure_position_indi;
+ gboolean rep_quant = FALSE;
+ xmlTextReaderPtr reader;
+
+ memset(&gps_measure_position_indi, 0x00, sizeof(gps_measure_position_indi));
+ reader = xmlReaderForFile(file_name, NULL, 0);
+
+ while (xmlTextReaderRead(reader)) {
+ switch (xmlTextReaderNodeType(reader)) {
+ case XML_READER_TYPE_ELEMENT:
+ {
+ node = (char *) xmlTextReaderConstName(reader);
+ if (!node)
+ return FALSE;
+
+ dbg("Element: %s", node);
+ if (node != NULL) {
+ // Read attribute value.
+ while (xmlTextReaderMoveToNextAttribute(reader)) {
+ attribute = (char *) xmlTextReaderConstName(reader);
+ dbg("Attribute value - %s\n", attribute);
+ attr_value = (char *) xmlTextReaderConstValue(reader);
+ dbg("=\"%s\"\n", attr_value);
+
+ if (strcmp(node, "mult_sets") == 0) {
+ if (strcmp(attribute, "literal") == 0) {
+ if (strcmp(attr_value, "one") == 0)
+ gps_measure_position_indi.use_multi_sets = GPS_MULTIPLESETS_ONESET;
+ else if (strcmp(attr_value, "multiple") == 0)
+ gps_measure_position_indi.use_multi_sets = GPS_MULTIPLESETS_MULTIPLESETS;
+ }
+ dbg("gps_measure_position_indi.use_multi_sets - 0x%x\n", gps_measure_position_indi.use_multi_sets);
+ } else if (strcmp(node, "rep_quant") == 0) {
+ rep_quant = TRUE;
+ if (strcmp(attribute, "addl_assist_data_req") == 0) {
+ if (strcmp(attr_value, "true") == 0)
+ gps_measure_position_indi.add_assist_req = GPS_ADDITIONAL_ASSISREQ_REQ;
+ else
+ gps_measure_position_indi.add_assist_req = GPS_ADDITIONAL_ASSISREQ_NOT_REQ;
+ } else if (strcmp(attribute, "gps_timing_of_cell_wanted") == 0) {
+ if (strcmp(attr_value, "true") == 0)
+ gps_measure_position_indi.cell_timing_wnt = GPS_CELLTIMING_WANTED;
+ else
+ gps_measure_position_indi.cell_timing_wnt = GPS_CELLTIMING_NOT_WANTED;
+ }
+ }
+ } // end of attribute check
+
+ if (strcmp(node, "ms_assisted") == 0) {
+ gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_ASSISTED;
+ } else if (strcmp(node, "ms_assisted_no_accuracy") == 0) {
+ gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_ASSISTED;
+ } else if (strcmp(node, "ms_based") == 0) {
+ gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_BASED;
+ } else if (strcmp(node, "ms_based_pref") == 0) {
+ gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_BASED_PREF;
+ } else if (strcmp(node, "ms_assisted_pref") == 0) {
+ gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_ASSISTED_PREF;
+ }
+ }
+ xmlTextReaderMoveToElement(reader);
+ }
+ break;
+
+ case XML_READER_TYPE_TEXT:
+ {
+ node_value = (char *) xmlTextReaderConstValue(reader);
+ dbg("element-value: %s", node_value);
+ if (node_value != NULL) {
+ if (strcmp(node_value, "resp_time_seconds") == 0) {
+ gps_measure_position_indi.rsp_time = *node_value;
+ dbg("gps_measure_position_indi.rsp_time - 0x%x", gps_measure_position_indi.rsp_time);
+ }
+ if (rep_quant == TRUE) {
+ if (strcmp(node_value, "hor_acc") == 0)
+ gps_measure_position_indi.accuracy.horizontalAccuracy = *node_value;
+ else if (strcmp(node_value, "vert_acc") == 0)
+ gps_measure_position_indi.accuracy.vertcalAccuracy = *node_value;
+ }
+ }
+ }
+ break;
+ }
+ }
+ xmlFreeTextReader(reader);
+ xmlCleanupParser();
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
+ o, TNOTI_GPS_MEASURE_POSITION, sizeof(gps_measure_position_indi), &gps_measure_position_indi);
+ return TRUE;
+}
+
+
+// CONFIRMATION
+static void on_confirmation_gps_message_send(TcorePending *p, gboolean result, void *user_data)
+{
+ dbg("Entry");
+
+ if (result == FALSE) { // Fail
+ dbg("SEND FAIL");
+ } else {
+ dbg("SEND OK");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static gboolean on_notification_reset_assist_data(CoreObject *o, const void *event_info, void *user_data)
+{
+ dbg("enter!\n");
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
+ o, TNOTI_GPS_RESET_ASSIST_DATA, 0, NULL);
+
+ return TRUE;
+}
+static void on_confirmation_gps_measure_position(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ //GPS server does not except confirmation for GPS measure position request.
+ dbg("enter");
+
+ dbg("exit");
+}
+
+static TReturn gps_confirm_measure_pos(CoreObject *o, UserRequest *ur)
+{
+ char *raw_str = NULL;
+ char *cmd_str = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req = NULL;
+ TcoreHal *hal = NULL;
+ gboolean ret = FALSE;
+ xmlChar *xml = NULL;
+ unsigned char *data = NULL;
+ unsigned int data_len;
+ gps_measure_position_confirm_t gps_measure_pos_confirm;
+
+ dbg("enter!");
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ data = (unsigned char *) tcore_user_request_ref_data(ur, &data_len);
+ memcpy(&gps_measure_pos_confirm, data, data_len);
+
+ // make confirm measure postion request in xml format.
+ xml = _generate_confirm_measure_pos_xml_text(&gps_measure_pos_confirm);
+ if (!xml) {
+ err("xml text generation failed");
+ return TCORE_RETURN_EINVAL;
+ }
+
+ // AT+CPOS<cr>text is entered<ctrl-z/esc>
+ raw_str = g_strdup_printf("AT+CPOS%s", "\r");
+ cmd_str = g_strdup_printf("%s%s\x1A", raw_str, xml);
+
+ dbg("command string : %s", cmd_str);
+ pending = tcore_pending_new(o, 0);
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ g_free(raw_str);
+ return TCORE_RETURN_EINVAL;
+ }
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+ tcore_pending_set_request_data(pending, strlen(cmd_str), req);
+ tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
+ tcore_pending_set_send_callback(pending, on_confirmation_gps_message_send, NULL);
+ tcore_pending_set_response_callback(pending, on_confirmation_gps_measure_position, NULL);
+ tcore_pending_link_user_request(pending, ur);
+
+ // HAL
+ hal = tcore_object_get_hal(o);
+ // Send request to HAL
+ ret = tcore_hal_send_request(hal, pending);
+ if (TCORE_RETURN_SUCCESS != ret) {
+ err("Request send failed");
+ ret = FALSE;
+ }
+
+ dbg("exit");
+ g_free(raw_str);
+ g_free(cmd_str);
+ xmlFree(xml);
+ return ret;
+}
+
+static struct tcore_gps_operations gps_ops = {
+ .confirm_measure_pos = gps_confirm_measure_pos,
+};
+
+gboolean imc_gps_init(TcorePlugin *cp, CoreObject *co_gps)
+{
+ dbg("Enter");
+
+ /* Set operations */
+ tcore_gps_set_ops(co_gps, &gps_ops);
+
+ tcore_object_add_callback(co_gps, "+CPOSR", on_notification_gps_assist_data, NULL);
+ tcore_object_add_callback(co_gps, "+XCPOSR", on_notification_reset_assist_data, NULL);
+
+ dbg("Exit");
+
+ return TRUE;
+}
+
+void imc_gps_exit(TcorePlugin *cp, CoreObject *co_gps)
+{
+ dbg("Exit");
+}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Harish Bishnoi <hbishnoi@samsung.com>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <glib.h>
+
+#include <tcore.h>
+#include <hal.h>
+#include <core_object.h>
+#include <plugin.h>
+#include <user_request.h>
+#include <queue.h>
+#include <co_modem.h>
+#include <storage.h>
+#include <server.h>
+#include <at.h>
+#include <mux.h>
+
+#include "imc_common.h"
+#include "imc_modem.h"
+#include "nvm/nvm.h"
+
+
+#define ID_RESERVED_AT 0x0229
+
+#define MAX_VERSION_LEN 32
+#define TAPI_MISC_ME_SN_LEN_MAX 32
+#define TAPI_MISC_PRODUCT_CODE_LEN_MAX 32
+#define TAPI_MISC_MODEL_ID_LEN_MAX 17
+#define TAPI_MISC_PRL_ERI_VER_LEN_MAX 17
+
+#define CPAS_RES_READY 0
+#define CPAS_RES_UNAVAIL 1
+#define CPAS_RES_UNKNOWN 2
+#define CPAS_RES_RINGING 3
+#define CPAS_RES_CALL_PROGRESS 4
+#define CPAS_RES_ASLEEP 5
+#define AT_VER_LEN 20
+
+
+enum cp_state {
+ CP_STATE_OFFLINE,
+ CP_STATE_CRASH_RESET,
+ CP_STATE_CRASH_EXIT,
+ CP_STATE_BOOTING,
+ CP_STATE_ONLINE,
+ CP_STATE_NV_REBUILDING,
+ CP_STATE_LOADER_DONE,
+};
+
+typedef enum {
+ TAPI_MISC_ME_IMEI = 0x00, /**< 0x00: IMEI, GSM/UMTS device */
+ TAPI_MISC_ME_ESN = 0x01, /**< 0x01: ESN(Electronic Serial Number), It`s essentially run out. CDMA device */
+ TAPI_MISC_ME_MEID = 0x02, /**< 0x02: MEID, This value can have hexa decimal digits. CDMA device */
+ TAPI_MISC_ME_MAX = 0xff /**< 0xff: reserved */
+} TelMiscSNIndexType_t;
+
+typedef struct {
+ TelMiscSNIndexType_t sn_index; /**< serial number index */
+ int sn_len; /**< Length */
+ unsigned char szNumber[TAPI_MISC_ME_SN_LEN_MAX]; /**< Number */
+} TelMiscSNInformation;
+
+/**
+ * Mobile Equipment Version Information
+ */
+typedef struct {
+ unsigned char ver_mask; /**< version mask - 0x01:SW_ver, 0x02:HW_ver, 0x04:RF_CAL_date, 0x08:Product_code, 0x10:Model_ID, 0x20:PRL, 0x04:ERI, 0xff:all */
+ unsigned char szSwVersion[MAX_VERSION_LEN]; /**< Software version, null termination */
+ unsigned char szHwVersion[MAX_VERSION_LEN]; /**< Hardware version, null termination */
+ unsigned char szRfCalDate[MAX_VERSION_LEN]; /**< Calculation Date, null termination */
+ unsigned char szProductCode[TAPI_MISC_PRODUCT_CODE_LEN_MAX]; /**< product code, null termination */
+ unsigned char szModelId[TAPI_MISC_MODEL_ID_LEN_MAX]; /**< model id (only for CDMA), null termination */
+ unsigned char prl_nam_num; /**< number of PRL NAM fields */
+ unsigned char szPrlVersion[TAPI_MISC_PRL_ERI_VER_LEN_MAX * 3]; /**< prl version (only for CDMA), null termination */
+ unsigned char eri_nam_num; /**< number of PRL NAM fields */
+ unsigned char szEriVersion[TAPI_MISC_PRL_ERI_VER_LEN_MAX * 3]; /**< eri version (only for CDMA), null termination */
+} TelMiscVersionInformation;
+
+
+static void prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback);
+static void on_confirmation_modem_message_send(TcorePending *p, gboolean result, void *user_data);
+static void on_response_network_registration(TcorePending *p, int data_len, const void *data, void *user_data);
+static void on_response_enable_proactive_command(TcorePending *p, int data_len, const void *data, void *user_data);
+
+/* NVM */
+static gboolean on_event_nvm_update(CoreObject *o, const void *event_info, void *user_data);
+static void modem_unsuspend_nvm_updates(CoreObject *o);
+static void modem_send_nvm_update_ack(CoreObject *o);
+static void modem_send_nvm_update_request_ack(CoreObject *o);
+
+static void on_confirmation_modem_message_send(TcorePending *p, gboolean result, void *user_data)
+{
+ dbg("on_confirmation_modem_message_send - msg out from queue.\n");
+
+ if (result == FALSE) {
+ /* Fail */
+ dbg("SEND FAIL");
+ } else {
+ dbg("SEND OK");
+ }
+}
+
+static void on_response_enable_proactive_command(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK proactive command enabled");
+ } else {
+ dbg("RESPONSE NOK proactive command disabled");
+ }
+}
+
+static void on_response_network_registration(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+
+ if (resp->success > 0) {
+ dbg("registration attempt OK");
+ } else {
+ dbg("registration attempt failed");
+ }
+}
+
+void prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
+{
+ TcoreATRequest *req = NULL;
+ TcoreHal *hal = NULL;
+ TcorePending *pending = NULL;
+ TReturn ret;
+
+ hal = tcore_object_get_hal(co);
+ dbg("hal: %p", hal);
+
+ pending = tcore_pending_new(co, 0);
+ if (!pending) {
+ dbg("Pending is NULL");
+ return;
+ }
+ req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ return;
+ }
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, callback, NULL);
+ tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
+ ret = tcore_hal_send_request(hal, pending);
+
+ if (ret != TCORE_RETURN_SUCCESS)
+ err("Failed to send AT request - ret: [0x%x]", ret);
+
+}
+
+static void on_response_power_off(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ CoreObject *o = 0;
+ TcoreHal *h = 0;
+
+ o = tcore_pending_ref_core_object(p);
+ h = tcore_object_get_hal(o);
+
+ dbg("modem power off");
+
+ tcore_hal_set_power_state(h, FALSE);
+}
+
+static void on_response_set_flight_mode(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ CoreObject *o = NULL;
+ UserRequest *ur = NULL;
+ const TcoreATResponse *ATresp = data;
+ struct tresp_modem_set_flightmode res = {0};
+ int response = 0;
+ struct tnoti_modem_flight_mode modem_flight_mode = {0};
+
+ o = tcore_pending_ref_core_object(p);
+ ur = tcore_pending_ref_user_request(p);
+
+ if (ATresp->success > 0) {
+ dbg("RESPONSE OK - flight mode operation finished");
+ res.result = TCORE_RETURN_SUCCESS;
+ } else {
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ dbg("RESPONSE NOK");
+
+ line = (const char *) ATresp->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ dbg("err cause not specified or string corrupted");
+ } else {
+ response = atoi(g_slist_nth_data(tokens, 0));
+ err("error response: %d", response);
+ /* TODO: CMEE error mapping is required. */
+ }
+ tcore_at_tok_free(tokens);
+ res.result = TCORE_RETURN_3GPP_ERROR;
+ }
+
+ if (NULL == ur) {
+ dbg("No user request. Internal request created during boot-up sequence");
+
+ if (ATresp->success > 0) {
+ modem_flight_mode.enable = tcore_modem_get_flight_mode_state(o);
+ dbg("sucess case - Sending Flight Mode Notification (%d) to Telephony Server", modem_flight_mode.enable);
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_MODEM_FLIGHT_MODE,
+ sizeof(struct tnoti_modem_flight_mode), &modem_flight_mode);
+ }
+ } else {
+ const struct treq_modem_set_flightmode *req_data = NULL;
+
+ dbg("Sending response for Flight mode operation");
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ if (TCORE_RETURN_SUCCESS == res.result) {
+ if (TRUE == req_data->enable){
+ tcore_modem_set_flight_mode_state(o, TRUE);
+ } else {
+ tcore_modem_set_flight_mode_state(o, FALSE);
+ }
+ }
+ tcore_user_request_send_response(ur, TRESP_MODEM_SET_FLIGHTMODE, sizeof(struct tresp_modem_set_flightmode), &res);
+
+ modem_flight_mode.enable = tcore_modem_get_flight_mode_state(o);
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_MODEM_FLIGHT_MODE,
+ sizeof(struct tnoti_modem_flight_mode), &modem_flight_mode);
+
+ if (req_data->enable == 0) {
+ dbg("Flight mode is disabled, trigger COPS to register on network");
+ /* Trigger Network registration (for the moment automatic) */
+ prepare_and_send_pending_request(o, "AT+COPS=0", NULL, TCORE_AT_NO_RESULT, NULL);
+ }
+ }
+}
+
+static void on_response_imei(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ TcorePlugin *plugin = NULL;
+ struct tresp_modem_get_imei res;
+ TelMiscSNInformation *imei_property = NULL;
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line;
+ int response = 0;
+
+ memset(&res, 0, sizeof(struct tresp_modem_get_imei));
+
+ 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) != 1) {
+ msg("invalid message");
+ goto OUT;
+ }
+ }
+ res.result = TCORE_RETURN_SUCCESS;
+ strncpy(res.imei, g_slist_nth_data(tokens, 0), 16);
+
+ dbg("imei = [%s]", res.imei);
+
+ plugin = tcore_pending_ref_plugin(p);
+ imei_property = tcore_plugin_ref_property(plugin, "IMEI");
+ if (imei_property) {
+ imei_property->sn_index = TAPI_MISC_ME_IMEI;
+ imei_property->sn_len = strlen(res.imei);
+ memcpy(imei_property->szNumber, res.imei, imei_property->sn_len);
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ if (resp->lines) {
+ line = (const char *) resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ }
+
+
+ if (g_slist_length(tokens) < 1) {
+ dbg("err cause not specified or string corrupted");
+ res.result = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ response = atoi(g_slist_nth_data(tokens, 0));
+ err("error response: %d", response);
+ /* TODO: CMEE error mapping is required. */
+ res.result = TCORE_RETURN_3GPP_ERROR;
+ }
+ }
+
+ ur = tcore_pending_ref_user_request(p);
+ tcore_user_request_send_response(ur, TRESP_MODEM_GET_IMEI,
+ sizeof(struct tresp_modem_get_imei), &res);
+
+OUT:
+ if (tokens != NULL)
+ tcore_at_tok_free(tokens);
+
+ return;
+}
+
+static void on_response_version(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ TcorePlugin *plugin = NULL;
+ struct tresp_modem_get_version res = {0};
+ TelMiscVersionInformation *vi_property = NULL;
+ TelMiscVersionInformation *vi = NULL;
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ char *swver = NULL;
+ char *hwver = NULL;
+ char *caldate = NULL;
+ char *pcode = NULL;
+ char *id = NULL;
+ int response = 0;
+
+ 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) == 1) {
+ swver = g_slist_nth_data(tokens, 0);
+ dbg("version: sw=[%s]", swver);
+ } else if (g_slist_length(tokens) == 5) {
+ swver = g_slist_nth_data(tokens, 0);
+ hwver = g_slist_nth_data(tokens, 1);
+ caldate = g_slist_nth_data(tokens, 2);
+ pcode = g_slist_nth_data(tokens, 3);
+ id = g_slist_nth_data(tokens, 4);
+
+ dbg("version: sw=[%s], hw=[%s], rf_cal=[%s], product_code=[%s], model_id=[%s]",
+ swver, hwver, caldate, pcode, id);
+ } else {
+ msg("invalid message");
+ goto OUT;
+ }
+ }
+
+ vi = g_try_new0(TelMiscVersionInformation, 1);
+ if (NULL != swver)
+ memcpy(vi->szSwVersion, swver, strlen(swver));
+ if (NULL != hwver)
+ memcpy(vi->szHwVersion, hwver, strlen(hwver));
+ if (NULL != caldate)
+ memcpy(vi->szRfCalDate, caldate, strlen(caldate));
+ if (NULL != pcode)
+ memcpy(vi->szProductCode, pcode, strlen(pcode));
+ if (NULL != id)
+ memcpy(vi->szModelId, id, strlen(id));
+
+ memset(&res, 0, sizeof(struct tresp_modem_get_version));
+
+ if (NULL != swver) {
+ snprintf(res.software,
+ (AT_VER_LEN > strlen(swver) ? strlen(swver) : AT_VER_LEN),
+ "%s", swver);
+ }
+
+ if (NULL != hwver) {
+ snprintf(res.hardware,
+ (AT_VER_LEN > strlen(hwver) ? strlen(hwver) : AT_VER_LEN),
+ "%s", hwver);
+ }
+
+ plugin = tcore_pending_ref_plugin(p);
+ vi_property = tcore_plugin_ref_property(plugin, "VERSION");
+ if (vi_property) {
+ memcpy(vi_property, vi, sizeof(TelMiscVersionInformation));
+ }
+ g_free(vi);
+ } else {
+ dbg("RESPONSE NOK");
+ if (resp->lines) {
+ line = (const char *) resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ }
+
+ memset(&res, 0, sizeof(struct tresp_modem_get_version));
+
+
+ if (g_slist_length(tokens) < 1) {
+ dbg("err cause not specified or string corrupted");
+ res.result = TCORE_RETURN_3GPP_ERROR;
+ } else {
+ response = atoi(g_slist_nth_data(tokens, 0));
+ err("error response: %d", response);
+ /* TODO: CMEE error mapping is required. */
+ res.result = TCORE_RETURN_3GPP_ERROR;
+ }
+ }
+
+ ur = tcore_pending_ref_user_request(p);
+ tcore_user_request_send_response(ur, TRESP_MODEM_GET_VERSION,
+ sizeof(struct tresp_modem_get_version), &res);
+
+OUT:
+ if (tokens != NULL)
+ tcore_at_tok_free(tokens);
+
+ return;
+}
+
+static enum tcore_hook_return on_hook_sim_status(Server *s,
+ CoreObject *source, enum tcore_notification_command command,
+ unsigned int data_len, void *data, void *user_data)
+{
+ TcorePlugin *plugin;
+ const struct tnoti_sim_status *noti_sim_status;
+ CoreObject *co_sat;
+ CoreObject *co_network;
+
+ plugin = tcore_object_ref_plugin(source);
+ co_sat = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SAT);
+ if (co_sat == NULL)
+ return TCORE_HOOK_RETURN_CONTINUE;
+
+ co_network = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_NETWORK);
+ if (co_network == NULL)
+ return TCORE_HOOK_RETURN_CONTINUE;
+
+ dbg("Get SIM status");
+ noti_sim_status = data;
+ if (noti_sim_status == NULL)
+ return TCORE_HOOK_RETURN_CONTINUE;
+
+ /* If SIM is initialized, Enable STK and and attach to Network */
+ dbg("SIM Status: [%d]", noti_sim_status->sim_status);
+ if (noti_sim_status->sim_status == SIM_STATUS_INIT_COMPLETED) {
+ dbg("SIM ready for attach!!! Enable STK and attach to Network");
+
+ /* Sending AT+CFUN=6 */
+ prepare_and_send_pending_request(co_sat, "AT+CFUN=6", NULL,
+ TCORE_AT_NO_RESULT, on_response_enable_proactive_command);
+
+ /* Sending AT+COPS */
+ prepare_and_send_pending_request(co_network, "AT+COPS=0", NULL,
+ TCORE_AT_NO_RESULT, on_response_network_registration);
+ }
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+gboolean modem_power_on(TcorePlugin *plugin)
+{
+ CoreObject *co_modem = NULL;
+ struct treq_modem_set_flightmode flight_mode_set = {0};
+ struct tnoti_modem_power modem_power = {0};
+ Storage *strg = NULL;
+
+ co_modem = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_MODEM);
+ if (co_modem == NULL) {
+ err("Modem Core object is NULL");
+ return FALSE;
+ }
+
+ /* Set Modem Power State to 'ON' */
+ tcore_modem_set_powered(co_modem, TRUE);
+
+ /* Get Flight mode from VCONFKEY */
+ strg = tcore_server_find_storage(tcore_plugin_ref_server(plugin), "vconf");
+ flight_mode_set.enable = tcore_storage_get_bool(strg, STORAGE_KEY_FLIGHT_MODE_BOOL);
+
+ /* Set Flight mode as per AP settings */
+ if (flight_mode_set.enable) { /* Radio OFF */
+ prepare_and_send_pending_request(co_modem, "AT+CFUN=4", NULL,
+ TCORE_AT_NO_RESULT, on_response_set_flight_mode);
+
+ /* Set Flight mode TRUE */
+ tcore_modem_set_flight_mode_state(co_modem, TRUE);
+ } else { /* Radio ON */
+ prepare_and_send_pending_request(co_modem, "AT+CFUN=1", NULL,
+ TCORE_AT_NO_RESULT, on_response_set_flight_mode);
+
+ /* Set Flight mode FALSE */
+ tcore_modem_set_flight_mode_state(co_modem, FALSE);
+ }
+
+ /* Get IMEI */
+ prepare_and_send_pending_request(co_modem, "AT+CGSN", NULL,
+ TCORE_AT_NUMERIC, on_response_imei);
+
+ /* Get Version Number */
+ prepare_and_send_pending_request(co_modem, "AT+CGMR", NULL,
+ TCORE_AT_SINGLELINE, on_response_version);
+
+ /* Send Notification to TAPI - MODEM_POWER */
+ modem_power.state = MODEM_STATE_ONLINE;
+
+ dbg("Sending notification - Modem Power state: [ONLINE]");
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ co_modem, TNOTI_MODEM_POWER, sizeof(modem_power), &modem_power);
+
+ return TRUE;
+}
+
+static TReturn power_off(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+
+ hal = tcore_object_get_hal(o);
+ pending = tcore_pending_new(o, 0);
+
+ req = tcore_at_request_new("AT+CFUN=0", NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ return TCORE_RETURN_FAILURE;
+ }
+ dbg("Command: [%s], Prefix(if any): [%s], Command Length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_power_off, hal);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn get_imei(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal;
+ TcoreATRequest *req;
+ TcorePending *pending = NULL;
+
+ hal = tcore_object_get_hal(o);
+ if (FALSE == tcore_hal_get_power_state(hal)) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+ pending = tcore_pending_new(o, 0);
+
+ req = tcore_at_request_new("AT+CGSN", NULL, TCORE_AT_NUMERIC);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("Command: [%s], Prefix(if any): [%s], Command Length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_imei, hal);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
+
+ return tcore_hal_send_request(hal, pending);
+}
+
+
+static TReturn get_version(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal;
+ TcoreATRequest *req;
+ TcorePending *pending = NULL;
+
+ hal = tcore_object_get_hal(o);
+ if (FALSE == tcore_hal_get_power_state(hal)) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+ pending = tcore_pending_new(o, 0);
+
+ req = tcore_at_request_new("AT+CGMR", NULL, TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("Command: [%s], Prefix(if any): [%s], Command Length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_version, hal);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
+
+ return tcore_hal_send_request(hal, pending);
+}
+
+static TReturn set_flight_mode(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ const struct treq_modem_set_flightmode *req_data = NULL;
+ char *cmd_str = NULL;
+
+ hal = tcore_object_get_hal(o);
+ if (FALSE == tcore_hal_get_power_state(hal)) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+ pending = tcore_pending_new(o, 0);
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ if (req_data->enable) {
+ dbg("Flight mode on/n");
+ cmd_str = g_strdup("AT+CFUN=4");
+ } else {
+ dbg("Flight mode off/n");
+ cmd_str = g_strdup("AT+CFUN=1");
+ }
+
+ req = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
+ g_free(cmd_str);
+
+ dbg("Command: [%s], Prefix(if any): [%s], Command Length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_set_flight_mode, hal);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
+
+ return tcore_hal_send_request(hal, pending);
+}
+
+static TReturn get_flight_mode(CoreObject *co_modem, UserRequest *ur)
+{
+ struct tresp_modem_get_flightmode resp_data;
+ TReturn ret;
+
+ memset(&resp_data, 0x0, sizeof(struct tresp_modem_get_flightmode));
+
+ resp_data.enable = tcore_modem_get_flight_mode_state(co_modem);
+ resp_data.result = TCORE_RETURN_SUCCESS;
+ dbg("Get Flight mode: Flight mdoe: [%s]", (resp_data.enable ? "ON" : "OFF"));
+
+ ret = tcore_user_request_send_response(ur,
+ TRESP_MODEM_GET_FLIGHTMODE,
+ sizeof(struct tresp_modem_get_flightmode), &resp_data);
+ dbg("ret: [0x%x]", ret);
+
+ return ret;
+}
+
+static struct tcore_modem_operations modem_ops = {
+ .power_on = NULL,
+ .power_off = power_off,
+ .power_reset = NULL,
+ .set_flight_mode = set_flight_mode,
+ .get_flight_mode = get_flight_mode,
+ .get_imei = get_imei,
+ .get_version = get_version,
+ .get_sn = NULL,
+ .dun_pin_ctrl = NULL,
+};
+
+gboolean imc_modem_init(TcorePlugin *cp, CoreObject *co_modem)
+{
+ TelMiscVersionInformation *vi_property;
+ TelMiscSNInformation *imei_property;
+ TelMiscSNInformation *sn_property;
+
+ dbg("Enter");
+
+ /* Set operations */
+ tcore_modem_set_ops(co_modem, &modem_ops);
+
+ vi_property = g_try_new0(TelMiscVersionInformation, 1);
+ tcore_plugin_link_property(cp, "VERSION", vi_property);
+
+ imei_property = g_try_new0(TelMiscSNInformation, 1);
+ tcore_plugin_link_property(cp, "IMEI", imei_property);
+
+ sn_property = g_try_new0(TelMiscSNInformation, 1);
+ tcore_plugin_link_property(cp, "SN", sn_property);
+
+ tcore_server_add_notification_hook(tcore_plugin_ref_server(cp),
+ TNOTI_SIM_STATUS, on_hook_sim_status, NULL);
+ dbg("Registering for +XDRVI event");
+ tcore_object_add_callback(co_modem, "+XDRVI", on_event_nvm_update, NULL);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void imc_modem_exit(TcorePlugin *cp, CoreObject *co_modem)
+{
+ TelMiscVersionInformation *vi_property;
+ TelMiscSNInformation *imei_property;
+ TelMiscSNInformation *sn_property;
+ TcorePlugin *plugin = tcore_object_ref_plugin(co_modem);
+
+ vi_property = tcore_plugin_ref_property(plugin, "VERSION");
+ g_free(vi_property);
+
+ imei_property = tcore_plugin_ref_property(plugin, "IMEI");
+ g_free(imei_property);
+
+ sn_property = tcore_plugin_ref_property(plugin, "SN");
+ g_free(sn_property);
+
+ dbg("Exit");
+}
+
+/*
+ * NV Manager - Support for Remote File System
+ */
+/* NVM Hook */
+static gboolean modem_rfs_hook(const char *data)
+{
+ if (data != NULL)
+ if (data[NVM_FUNCTION_ID_OFFSET] == XDRV_INDICATION)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* NVM event Notification */
+static gboolean on_event_nvm_update(CoreObject *o, const void *event_info, void *user_data)
+{
+ GSList *tokens = NULL;
+ GSList *lines;
+ const char *line;
+ int function_id;
+
+ gboolean ret = TRUE;
+ dbg("Entered");
+
+ lines = (GSList *)event_info;
+ line = lines->data;
+ dbg("Line: [%s]", line);
+
+ function_id = nvm_sum_4_bytes(&line[NVM_FUNCTION_ID_OFFSET]);
+ dbg("Function ID: [%d]", function_id);
+ if (IUFP_UPDATE == function_id) {
+ dbg("Calling process nvm_update");
+
+ /*
+ * Process NV Update indication
+ *
+ * +XDRVI: IUFP_GROUP, IUFP_UPDATE, <xdrv_result>, <data>
+ */
+ if (NVM_NO_ERR == nvm_process_nv_update(line)) {
+ dbg("NV data processed successfully");
+
+ /* Acknowledge NV Update */
+ modem_send_nvm_update_ack(o);
+
+ return ret;
+ } else {
+ err("NV data processing failed");
+ ret = FALSE;
+ }
+ } else {
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 3) {
+ err("XDRVI event with less number of tokens, Ignore!!!");
+ ret = FALSE;
+ }
+ else if (IUFP_GROUP_ID != atoi(g_slist_nth_data(tokens, 0))) {
+ err("Group ID mismatch, Ignore!!!");
+ ret = FALSE;
+ }
+ else {
+ switch (atoi(g_slist_nth_data(tokens, 1))) {
+ case IUFP_UPDATE_REQ:
+ dbg("NV Update Request");
+
+ /* Acknowledge the Update Request */
+ modem_send_nvm_update_request_ack(o);
+ break;
+
+ case IUFP_NO_PENDING_UPDATE:
+ dbg("NO pending NV Update(s)!!!");
+ /* Can send FLUSH request to get fresh updates */
+ break;
+
+ default:
+ err("Unspported Function ID [%d], Ignore", atoi(g_slist_nth_data(tokens, 1)));
+ ret = FALSE;
+ }
+ }
+
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("Exit");
+ return ret;
+}
+
+/* NVM Responses */
+static gboolean __modem_check_nvm_response(const void *data, int command)
+{
+ const TcoreATResponse *resp = data;
+ const char *line;
+ char *resp_str;
+ GSList *tokens = NULL;
+ gboolean ret = FALSE;
+ dbg("Entered");
+
+ /* +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>] */
+ if (NULL == resp) {
+ err("Input data is NULL");
+ return FALSE;
+ }
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ line = (const char *) (((GSList *) resp->lines)->data);
+ tokens = tcore_at_tok_new(line);
+
+ /* Group ID */
+ resp_str = g_slist_nth_data(tokens, 0);
+ if (NULL == resp_str) {
+ err("Group ID is missing ");
+ goto OUT;
+ }
+ else if (IUFP_GROUP_ID != atoi(resp_str)) {
+ err("Group ID mismatch");
+ goto OUT;
+ }
+
+ /* Function ID */
+ resp_str = g_slist_nth_data(tokens, 1);
+ if (NULL == resp_str) {
+ err("Function ID is missing ");
+ goto OUT;
+ }
+ else if (command != atoi(resp_str)) {
+ err("Function ID mismatch");
+ goto OUT;
+ }
+
+ /* XDRV Result */
+ resp_str = g_slist_nth_data(tokens, 2);
+ if (NULL == resp_str) {
+ err("XDRV result is missing ");
+ goto OUT;
+ }
+ else if (XDRV_RESULT_OK != atoi(resp_str)) {
+ err("XDRV result[%d] ", atoi(resp_str));
+ goto OUT;
+ }
+
+ /* Result code */
+ resp_str = g_slist_nth_data(tokens, 3);
+ if (NULL == resp_str) {
+ err("UTA result is missing ");
+ goto OUT;
+ }
+ else if (UTA_SUCCESS != atoi(resp_str)) {
+ err("uta result[%d] ", atoi(resp_str));
+ goto OUT;
+ }
+
+ ret = TRUE;
+ } else {
+ dbg("Response NOK");
+ }
+
+OUT:
+ tcore_at_tok_free(tokens);
+
+ dbg("Exit");
+ return ret;
+}
+
+static void _on_response_modem_unsuspend_nvm_updates(TcorePending *p,
+ int data_len, const void *data, void *user_data)
+{
+ /* Check NVM response */
+ if (TRUE == __modem_check_nvm_response(data, IUFP_SUSPEND)) {
+ dbg("Priority level is set to get all updates since Boot-up");
+
+ /* Create NV data file */
+ if (nvm_create_nvm_data() == FALSE) {
+ err("Failed to Create NV data file");
+ }
+
+ return;
+ }
+
+ err("Response NOT OK");
+}
+
+static void _on_response_modem_send_nvm_update_ack(TcorePending *p,
+ int data_len, const void *data, void *user_data)
+{
+ /* Check NVM response */
+ if (TRUE == __modem_check_nvm_response(data, IUFP_UPDATE_ACK)) {
+ dbg("[UPDATE ACK] OK");
+ return;
+ }
+
+ err("[UPDATE ACK] NOT OK");
+}
+
+static void _on_response_modem_send_nvm_update_request_ack(TcorePending *p,
+ int data_len, const void *data, void *user_data)
+{
+ /* Check NVM response */
+ if (TRUE == __modem_check_nvm_response(data, IUFP_UPDATE_REQ_ACK)) {
+ dbg("[REQUEST ACK] OK");
+ return;
+ }
+
+ err("[REQUEST ACK] NOT OK");
+}
+
+static void _on_response_modem_register_nvm(TcorePending *p,
+ int data_len, const void *data, void *user_data)
+{
+ /* Check NVM response */
+ if (TRUE == __modem_check_nvm_response(data, IUFP_REGISTER)) {
+ dbg("Registering successful");
+
+ /* Send SUSPEND_UPDATE for all UPDATES */
+ modem_unsuspend_nvm_updates(tcore_pending_ref_core_object(p));
+
+ dbg("Exit");
+ return;
+ }
+
+ err("Response NOT OK");
+}
+
+/* NVM Requests */
+static void modem_unsuspend_nvm_updates(CoreObject *o)
+{
+ TcorePending *pending = NULL;
+ char *cmd_str;
+ dbg("Entered");
+
+ /* Prepare AT-Command */
+ cmd_str = g_strdup_printf("AT+XDRV=%d, %d, %d, %d",
+ IUFP_GROUP_ID, IUFP_SUSPEND,
+ 0, UTA_FLASH_PLUGIN_PRIO_UNSUSPEND_ALL);
+
+ /* Prepare pending request */
+ pending = tcore_at_pending_new(o,
+ cmd_str,
+ "+XDRV:",
+ TCORE_AT_SINGLELINE,
+ _on_response_modem_unsuspend_nvm_updates,
+ NULL);
+ if (pending == NULL) {
+ err("Failed to form pending request");
+ }
+ else if (tcore_hal_send_request(tcore_object_get_hal(o), pending)
+ != TCORE_RETURN_SUCCESS) {
+ err("IUFP_SUSPEND - Unable to send AT-Command");
+ }
+ else {
+ dbg("IUFP_SUSPEND - Successfully sent AT-Command");
+ }
+
+ g_free(cmd_str);
+}
+
+static void modem_send_nvm_update_ack(CoreObject *o)
+{
+ TcorePending *pending = NULL;
+ char *cmd_str;
+ dbg("Entered");
+
+ /* Prepare AT-Command */
+ cmd_str = g_strdup_printf("AT+XDRV=%s, %s", IUFP_GROUP, IUFP_UPDATE_ACK_STR);
+
+ /* Prepare pending request */
+ pending = tcore_at_pending_new(o,
+ cmd_str,
+ "+XDRV:",
+ TCORE_AT_SINGLELINE,
+ _on_response_modem_send_nvm_update_ack,
+ NULL);
+ if (pending == NULL) {
+ err("Failed to form pending request");
+ }
+ else if (tcore_hal_send_request(tcore_object_get_hal(o), pending)
+ != TCORE_RETURN_SUCCESS) {
+ err("IUFP_UPDATE_ACK - Unable to send AT-Command");
+ }
+ else {
+ dbg("IUFP_UPDATE_ACK - Successfully sent AT-Command");
+ }
+
+ g_free(cmd_str);
+}
+
+static void modem_send_nvm_update_request_ack(CoreObject *o)
+{
+ TcorePending *pending = NULL;
+ char *cmd_str;
+ dbg("Entered");
+
+ /* Prepare AT-Command */
+ cmd_str = g_strdup_printf("AT+XDRV=%s, %s", IUFP_GROUP, IUFP_UPDATE_REQ_ACK_STR);
+
+ /* Prepare pending request */
+ pending = tcore_at_pending_new(o,
+ cmd_str,
+ "+XDRV:",
+ TCORE_AT_SINGLELINE,
+ _on_response_modem_send_nvm_update_request_ack,
+ NULL);
+
+
+ if (pending == NULL) {
+ err("Failed to form pending request");
+ }
+ else if (tcore_hal_send_request(tcore_object_get_hal(o), pending)
+ != TCORE_RETURN_SUCCESS) {
+ err("IUFP_UPDATE_REQ_ACK - Unable to send AT-Ccommand");
+ }
+ else {
+ dbg("IUFP_UPDATE_REQ_ACK - Successfully sent AT-Command");
+ }
+
+ g_free(cmd_str);
+}
+
+void modem_register_nvm(CoreObject *co_modem)
+{
+ TcorePending *pending = NULL;
+ char *cmd_str;
+ dbg("Entered");
+
+ /* Prepare AT-Command */
+ cmd_str = g_strdup_printf("AT+XDRV=%s, %s, %s",
+ IUFP_GROUP, IUFP_REGISTER_STR, XDRV_ENABLE);
+
+ /* Prepare pending request */
+ pending = tcore_at_pending_new(co_modem,
+ cmd_str,
+ "+XDRV:",
+ TCORE_AT_SINGLELINE,
+ _on_response_modem_register_nvm,
+ NULL);
+ if (pending == NULL) {
+ err("Failed to form pending request");
+ }
+ else if (tcore_hal_send_request(tcore_object_get_hal(co_modem), pending)
+ != TCORE_RETURN_SUCCESS) {
+ err("IUFP_REGISTER (Enable) -Unable to send AT-Command");
+ }
+ else {
+ dbg("IUFP_REGISTER (Enable) -Successfully sent AT-Command");
+
+ /* Add RFS hook */
+ /* Todo unblock this api */
+ tcore_at_add_hook(tcore_object_get_hal(co_modem), modem_rfs_hook);
+ }
+
+ g_free(cmd_str);
+}
#include <hal.h>
#include <core_object.h>
#include <plugin.h>
+#include <user_request.h>
#include <queue.h>
#include <co_network.h>
#include <co_ps.h>
#include <util.h>
#include <at.h>
-#include "s_common.h"
-#include "s_network.h"
+#include "imc_common.h"
+#include "imc_network.h"
#define AT_CREG_STAT_NOT_REG 0 /* not registered, MT is not currently searching a new operator to register to */
#define AT_CREG_STAT_REG_HOME 1 /* registered, home network */
#define MAX_NETWORKS_PREF_PLMN_SUPPORT 150
#define MAX_NETWORKS_MANUAL_SEARCH_SUPPORT 20
+typedef enum {
+ IMC_NETWORK_SEARCH_STATE_NO_SEARCH,
+ IMC_NETWORK_SEARCH_STATE_IN_PROGRESS,
+ IMC_NETWORK_SEARCH_STATE_CANCELLED
+} ImcNetworkSearchState;
+
+typedef struct {
+ ImcNetworkSearchState search_state;
+} CustomData;
+
static unsigned int lookup_tbl_net_status[] = {
[AT_CREG_STAT_NOT_REG] = NETWORK_SERVICE_DOMAIN_STATUS_NO,
[AT_CREG_STAT_REG_HOME] = NETWORK_SERVICE_DOMAIN_STATUS_FULL,
}
}
-static void nwk_prepare_and_send_pending_request(TcorePlugin *plugin, char *co_name, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, UserRequest *ur, TcorePendingResponseCallback callback)
+static void nwk_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, UserRequest *ur, TcorePendingResponseCallback callback)
{
TcoreATRequest *req = NULL;
TcoreHal *hal;
- CoreObject *o = NULL;
TcorePending *pending = NULL;
TReturn ret;
- o = tcore_plugin_ref_core_object(plugin, co_name);
- hal = tcore_object_get_hal(o);
+ hal = tcore_object_get_hal(co);
- pending = tcore_pending_new(o, 0);
+ pending = tcore_pending_new(co, 0);
req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
-
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ return;
+ }
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
ret = tcore_hal_send_request(hal, pending);
+
+ if (ret != TCORE_RETURN_SUCCESS) {
+ err("Failed to send AT request - ret: [0x%x]", ret);
+ tcore_pending_free(pending);
+ tcore_at_request_free(req);
+ }
return;
}
row = value;
noi = calloc(sizeof(struct tcore_network_operator_info), 1);
-
+ if (!noi) {
+ dbg("Memory allocation failed");
+ return;
+ }
snprintf(noi->mcc, 4, "%s", (char *) g_hash_table_lookup(row, "1"));
snprintf(noi->mnc, 4, "%s", (char *) g_hash_table_lookup(row, "2"));
snprintf(noi->name, 41, "%s", (char *) g_hash_table_lookup(row, "3"));
snprintf(noi->country, 4, "%s", (char *) g_hash_table_lookup(row, "0"));
tcore_network_operator_info_add(o, noi);
+ g_free(noi);
+ noi = NULL;
count++;
}
static void _ps_set(TcorePlugin *p, int status)
{
- GSList *co_list = NULL;
+ CoreObject *co_ps;
- co_list = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_PS);
- do {
- CoreObject *o = NULL;
- o = (CoreObject *) co_list->data;
- if (!o)
- break;
-
- if (status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
- tcore_ps_set_online(o, TRUE);
- } else {
- tcore_ps_set_online(o, FALSE);
- }
- } while ((co_list = g_slist_next(co_list)));
+ co_ps = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_PS);
+ if (co_ps == NULL) {
+ err("No PS Core Object on plugin");
+ return;
+ }
- g_slist_free(co_list);
+ if (status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
+ tcore_ps_set_online(co_ps, TRUE);
+ else
+ tcore_ps_set_online(co_ps, FALSE);
}
+static void on_timeout_search_network(TcorePending *p, void *user_data)
+{
+ UserRequest *ur;
+ struct tresp_network_search resp;
+ CustomData *custom_data;
+
+ dbg("TIMEOUT !!!!! pending=%p", p);
+
+ memset(&resp, 0, sizeof(struct tresp_network_search));
+
+ resp.result = TCORE_RETURN_FAILURE;
+ resp.list_count = 0;
+
+ custom_data = tcore_object_ref_user_data(tcore_pending_ref_core_object(p));
+ custom_data->search_state = IMC_NETWORK_SEARCH_STATE_NO_SEARCH;
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &resp);
+ }
+}
static void on_response_set_plmn_selection_mode(TcorePending *p, int data_len, const void *data, void *user_data)
{
switch (mode) {
case AT_COPS_MODE_AUTOMATIC:
- resp.mode = NETWORK_SELECT_MODE_GLOBAL_AUTOMATIC;
+ resp.mode = NETWORK_SELECT_MODE_AUTOMATIC;
break;
case AT_COPS_MODE_MANUAL:
case AT_COPS_MODE_MANUAL_AUTOMATIC:
- resp.mode = NETWORK_SELECT_MODE_GSM_MANUAL;
+ resp.mode = NETWORK_SELECT_MODE_MANUAL;
break;
case AT_COPS_MODE_DEREGISTER:
GSList *network_token = NULL;
int AcT = 0;
char *temp_plmn_info = NULL;
+ char *alpha_name = NULL;
char *pResp = NULL;
int num_network_avail = 0;
+ CustomData *custom_data;
memset(&resp, 0, sizeof(struct tresp_network_search));
resp.result = TCORE_RETURN_FAILURE;
resp.list_count = 0;
+ custom_data = tcore_object_ref_user_data(tcore_pending_ref_core_object(p));
+ if (!custom_data) {
+ err("Network Search Custom Data is Null");
+ return;
+ }
+
if (atResp->success > 0) {
dbg("RESPONSE OK");
+
+ /* If Request is Cancelled then return back SUCCESS/SEARCH_CANCELLED */
+ if (custom_data->search_state
+ == IMC_NETWORK_SEARCH_STATE_CANCELLED) {
+ dbg("Network Search has been Cancelled!!!");
+ goto OUT;
+ }
+
if (atResp->lines) {
line = (char *) atResp->lines->data;
tokens = tcore_at_tok_new(line);
}
resp.result = TCORE_RETURN_SUCCESS;
- /*
- * +COPS: [list of supported (<stat>,long alphanumeric <oper>,short alphanumeric <oper>,numeric <oper>[,<AcT>])s]
- * [,,(list of supported <mode>s),(list of supported <format>s)]
- */
-
- /* (2,"IND airtel","airtel","40445",2,),(1,"IND airtel","airtel","40445",0,),(3,"TATA DOCOMO","TATA DO","405034",2,) */
+ /*
+ * +COPS: [list of supported (<stat>,long alphanumeric <oper>,
+ * short alphanumeric <oper>,numeric <oper>[,<AcT>])s]
+ * [,,(list of supported <mode>s),(list of supported <format>s)]
+ */
for (i = 0; ((i < num_network_avail) && (i < MAX_NETWORKS_MANUAL_SEARCH_SUPPORT)); i++) {
- /* (2,"IND airtel","airtel","40445",2,) */
network_token = tcore_at_tok_new(g_slist_nth_data(tokens, i));
pResp = (tcore_at_tok_nth(network_token, 0));
resp.list[i].status = (enum telephony_network_plmn_status) atoi(pResp);
}
- if ((pResp = tcore_at_tok_nth(network_token, 1))) { /* Long Aplha name */
- dbg("Long Aplha name : %s", pResp);
+ if ((pResp = tcore_at_tok_nth(network_token, 1))) { /* Long Alpha name */
+ dbg("Long Alpha name : %s", pResp);
- if (strlen(pResp) > 0)
+ if (strlen(pResp) > 0) {
/* Strip off starting quote & ending quote */
strncpy(resp.list[i].name, pResp + 1, strlen(pResp) - 2);
- } else if ((pResp = tcore_at_tok_nth(network_token, 2))) {
- dbg("Short Aplha name : %s", pResp);
- /* Short Aplha name */
- /* Strip off starting quote & ending quote */
- if (strlen(pResp) > 0)
- strncpy(resp.list[i].name, pResp + 1, strlen(pResp) - 2);
+ } else if ((pResp = tcore_at_tok_nth(network_token, 2))) {
+ dbg("Short Aplha name : %s", pResp);
+ /* Short Aplha name */
+ /* Strip off starting quote & ending quote */
+ if (strlen(pResp) > 0)
+ strncpy(resp.list[i].name, pResp + 1, strlen(pResp) - 2);
+ }
}
/* PLMN ID */
pResp = tcore_at_tok_nth(network_token, 3);
if (pResp != NULL) {
dbg("PLMN ID : %s", pResp);
- temp_plmn_info = util_removeQuotes(pResp);
+ temp_plmn_info = tcore_at_tok_extract((const char *)pResp);
+ strncpy(resp.list[i].plmn, temp_plmn_info, 6);
+ resp.list[i].plmn[6] = '\0';
}
- memcpy(resp.list[i].plmn, temp_plmn_info, 6);
- if (resp.list[i].plmn[5] == '#')
- resp.list[i].plmn[5] = '\0';
-
/* Parse Access Technology */
- if ((pResp = tcore_at_tok_nth(tokens, 4))) {
+ if ((pResp = tcore_at_tok_nth(network_token, 4))) {
if (strlen(pResp) > 0) {
AcT = atoi(pResp);
resp.list_count++;
tcore_at_tok_free(network_token);
+ g_free(alpha_name);
+ g_free(temp_plmn_info);
}
} else {
dbg("RESPONSE NOK");
}
OUT:
+ custom_data->search_state = IMC_NETWORK_SEARCH_STATE_NO_SEARCH;
+
ur = tcore_pending_ref_user_request(p);
if (ur) {
- tcore_user_request_send_response(ur, TRESP_NETWORK_SEARCH, sizeof(struct tresp_network_search), &resp);
+ tcore_user_request_send_response(ur,
+ TRESP_NETWORK_SEARCH,
+ sizeof(struct tresp_network_search), &resp);
}
- if (tokens)
- tcore_at_tok_free(tokens);
-
- if (temp_plmn_info)
- free(temp_plmn_info);
-
- return;
+ /* Free tokens */
+ tcore_at_tok_free(tokens);
}
static void on_response_set_umts_band(TcorePending *p, int data_len, const void *data, void *user_data)
dup_ur = tcore_user_request_ref(ur); /* duplicate user request for AT+XUBANDSEL */
cmd_str = g_strdup_printf("AT+XUBANDSEL?");
atreq = tcore_at_request_new(cmd_str, "+XUBANDSEL", TCORE_AT_SINGLELINE);
+ if (atreq == NULL) {
+ g_free(cmd_str);
+ goto OUT;
+ }
pending = tcore_pending_new(o, 0);
tcore_pending_set_request_data(pending, 0, atreq);
tcore_pending_set_response_callback(pending, on_response_get_umts_band, NULL);
tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
tcore_hal_send_request(h, pending);
g_free(cmd_str);
- } else if ((cp_xrat == AT_XRAT_UMTS)) {
+ } else if ((cp_xrat == AT_XRAT_GSM)) {
/* Get GSM Band Information */
dup_ur = tcore_user_request_ref(ur); /* duplicate user request for AT+XBANDSEL */
cmd_str = g_strdup_printf("AT+XBANDSEL?");
int count = 0;
int net_name_type = 0;
char *pResp = NULL;
+ char *net_name = NULL;
dbg("Entry on_response_get_nitz_name (+XCOPS)");
o = tcore_pending_ref_core_object(p);
goto OUT;
}
+ memset(¬i, 0, sizeof(struct tnoti_network_identity));
+
for (count = 0; count < nol; count++) {
// parse each line
line = g_slist_nth_data(atResp->lines, count);
dbg("Net name type : %d", net_name_type);
switch (net_name_type) {
- case 0: /* plmn_id (mcc, mnc) */
+ case 0: /* plmn_id (mcc, mnc) */
if ((pResp = tcore_at_tok_nth(tokens, 1))) {
- strncpy(noti.plmn, pResp + 1, strlen(pResp) - 2); /* skip quotes (") while copying */
+ if (strlen(pResp) > 0) {
+ net_name = tcore_at_tok_extract((const char *)pResp);
+ strncpy(noti.plmn, net_name, 6);
+ noti.plmn[6] = '\0';
+ }
}
break;
- case 5: /* Short Nitz name*/
+ case 5: /* Short NITZ name*/
+ case 3: /* Short Network Name (CPHS) */
if ((pResp = tcore_at_tok_nth(tokens, 1))) {
- strncpy(noti.short_name, pResp + 1, strlen(pResp) - 2); /* skip quotes (") while copying */
+ if (strlen(pResp) > 0) {
+ net_name = tcore_at_tok_extract((const char *)pResp);
+ strncpy(noti.short_name, net_name, 16);
+ noti.short_name[16] = '\0';
+ }
}
break;
- case 6: /* Full Nitz name */
+ case 6: /* Full NITZ name */
+ case 4: /* Long Network Name (CPHS) */
if ((pResp = tcore_at_tok_nth(tokens, 1))) {
- strncpy(noti.full_name, pResp + 1, strlen(pResp) - 2); /* skip quotes (") while copying */
+ if (strlen(pResp) > 0) {
+ net_name = tcore_at_tok_extract((const char *)pResp);
+ strncpy(noti.full_name, net_name, 32);
+ noti.full_name[32] = '\0';
+ }
}
break;
default:
break;
}
+
+ g_free(net_name);
+ net_name = NULL;
}
- if (tokens != NULL)
- tcore_at_tok_free(tokens);
+
+ tcore_at_tok_free(tokens);
}
+ dbg("plmn <%s> short NITZ name<%s> full NITZ name<%s>",
+ noti.plmn, noti.short_name, noti.full_name);
tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_IDENTITY,
sizeof(struct tnoti_network_identity), ¬i);
}
char *line = NULL;
const TcoreATResponse *atResp = data;
GSList *tokens = NULL;
- char temp_plmn_info[17] = {0};
char *pResp = NULL;
int plmn_format = 0;
int total_lines = 0;
int GSM_AcT2 = 0, GSM_Compact_AcT2 = 0, UTRAN_AcT2 = 0;
- dbg("Entry on_response_get_preferred_plmn");
+ dbg("Entry");
if (atResp->success > 0) {
dbg("RESPONSE OK");
total_lines = MAX_NETWORKS_PREF_PLMN_SUPPORT;
/*
-+COPL: <index1>,<format>,<oper1>[,<GSM_AcT1>,<GSM_Compact_AcT1>,<UTRAN_AcT1>,<E-UTRAN_AcT1>] [<CR><LF>
++CPOL: <index1>,<format>,<oper1>[,<GSM_AcT1>,<GSM_Compact_AcT1>,<UTRAN_AcT1>,<E-UTRAN_AcT1>] [<CR><LF>
+CPOL: <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>,<E-UTRAN_AcT2>]
*/
-
resp.result = TCORE_RETURN_SUCCESS;
for (i = 0; i < total_lines; i++) {
dbg("plmn ID : %s", pResp);
if (strlen(pResp) > 0) {
- strncpy(temp_plmn_info, pResp + 1, (strlen(pResp)) - 2);
+ char *oper;
+
+ oper = tcore_at_tok_extract((const char *)pResp);
+ dbg("operator <%s>", oper);
// Get only PLMN ID
if (plmn_format == 2) {
- // cp_plmn = util_hexStringToBytes(temp_plmn_info);
-
- if (strncmp((char *) temp_plmn_info, "000000", 6) == 0)
- continue;
-
- memcpy(resp.list[i].plmn, temp_plmn_info, 6);
- if (resp.list[i].plmn[5] == '#')
- resp.list[i].plmn[5] = '\0';
-
- // free(cp_plmn);
+ strncpy(resp.list[i].plmn, oper, 6);
+ resp.list[i].plmn[6] = '\0';
}
+
+ g_free (oper);
}
}
tcore_at_tok_free(tokens);
}
}
+ } else {
+ dbg("RESPONSE NOT OK");
+ // TODO: CMEE error mapping is required.
+ resp.result = TCORE_RETURN_FAILURE;
}
+
OUT:
ur = tcore_pending_ref_user_request(p);
if (ur) {
const TcoreATResponse *resp = data;
UserRequest *ur;
struct tresp_network_get_serving_network Tresp = {0};
- char plmn[7] = {0};
char *long_plmn_name = NULL;
char *short_plmn_name = NULL;
+ char *plmn_id = NULL;
CoreObject *o;
GSList *tokens = NULL;
const char *line;
if ((pResp = tcore_at_tok_nth(tokens, 2))) {
dbg("long PLMN : %s", pResp);
if (strlen(pResp) > 0) {
- long_plmn_name = util_removeQuotes(pResp);
+ long_plmn_name = tcore_at_tok_extract((const char *)pResp);
// set network name into po
tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_FULL, long_plmn_name);
if ((pResp = tcore_at_tok_nth(tokens, 2))) {
dbg("short PLMN : %s", pResp);
if (strlen(pResp) > 0) {
- short_plmn_name = util_removeQuotes(pResp);
+ short_plmn_name = tcore_at_tok_extract((const char *)pResp);
// set network name into po
tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_SHORT, short_plmn_name);
if ((pResp = tcore_at_tok_nth(tokens, 2))) {
dbg("numeric : %s", pResp);
if (strlen(pResp) > 0) {
- memset(plmn, 0, 7);
+ plmn_id = tcore_at_tok_extract((const char *)pResp);
- /* Strip off starting quotes & ending quotes */
- strncpy(plmn, pResp + 1, strlen(pResp) - 2);
- tcore_network_set_plmn(o, plmn);
+ // set plmn id into po
+ tcore_network_set_plmn(o, plmn_id);
}
}
break;
tcore_at_tok_free(tokens);
}
- memcpy(Tresp.plmn, plmn, 7);
+ if(plmn_id)
+ memcpy(Tresp.plmn, plmn_id, strlen(plmn_id));
tcore_network_get_access_technology(o, &(Tresp.act));
tcore_network_get_lac(o, &(Tresp.gsm.lac));
struct tnoti_network_change network_change;
memset(&network_change, 0, sizeof(struct tnoti_network_change));
- memcpy(network_change.plmn, plmn, 7);
+ if(plmn_id)
+ memcpy(network_change.plmn, plmn_id, strlen(plmn_id));
tcore_network_get_access_technology(o, &(network_change.act));
tcore_network_get_lac(o, &(network_change.gsm.lac));
tcore_server_send_notification(tcore_plugin_ref_server(tcore_pending_ref_plugin(p)), tcore_pending_ref_core_object(p),
- TNOTI_NETWORK_CHANGE, sizeof(struct tnoti_network_change), &network_change);
+ TNOTI_NETWORK_CHANGE, sizeof(struct tnoti_network_change), &network_change);
dbg("dbg.. network_change.plmn : %s", network_change.plmn);
dbg("dbg.. network_change.act : %d", network_change.act);
dbg("dbg.. network_change.gsm.lac : %d", network_change.gsm.lac);
if ((AT_COPS_MODE_DEREGISTER != network_mode) &&
(AT_COPS_MODE_SET_ONLY != network_mode)) {
/*Network identity noti*/
- memset(¬i, 0x0, sizeof(struct tnoti_network_change));
+ memset(¬i, 0x0, sizeof(struct tnoti_network_identity));
if (long_plmn_name)
- memcpy(noti.full_name, long_plmn_name, MIN(33, strlen(long_plmn_name)));
+ memcpy(noti.full_name, long_plmn_name, MIN(32, strlen(long_plmn_name)));
if (short_plmn_name)
- memcpy(noti.short_name, short_plmn_name, MIN(17, strlen(long_plmn_name)));
- memcpy(noti.plmn, plmn, 7);
+ memcpy(noti.short_name, short_plmn_name, MIN(16, strlen(short_plmn_name)));
+ if (plmn_id)
+ memcpy(noti.plmn, plmn_id, strlen(plmn_id)); // plmn_id length is necessarily <= 6
+
tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
- o, TNOTI_NETWORK_IDENTITY, sizeof(struct tnoti_network_identity), ¬i);
+ o, TNOTI_NETWORK_IDENTITY, sizeof(struct tnoti_network_identity), ¬i);
dbg("dbg.. noti.short_name : %s", noti.short_name);
dbg("dbg.. noti.full_name : %s", noti.full_name);
dbg("dbg.. noti.plmn : %s", noti.plmn);
}
}
- if (long_plmn_name)
- free(long_plmn_name);
- if (short_plmn_name)
- free(short_plmn_name);
+
+ g_free(long_plmn_name);
+ g_free(short_plmn_name);
+ g_free(plmn_id);
}
return;
}
+static void on_response_network_set_mode(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ struct tresp_network_set_mode resp = {0};
+ const TcoreATResponse *atResp = data;
+
+ dbg("ENTER on_response_network_set_mode");
+
+ if (atResp && atResp->success) {
+ dbg("RESPONSE OK");
+ resp.result = TCORE_RETURN_SUCCESS;
+ } else {
+ err("RESPONSE NOK");
+ resp.result = TCORE_RETURN_FAILURE;
+ }
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur,
+ TRESP_NETWORK_SET_MODE,
+ sizeof(struct tresp_network_set_mode), &resp);
+ }
+}
+
+static void on_response_network_get_mode(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ struct tresp_network_get_mode resp = {0};
+ const TcoreATResponse *atResp = data;
+ GSList *tokens = NULL;
+
+ dbg("ENTER on_response_network_get_mode");
+
+ resp.result = TCORE_RETURN_FAILURE;
+
+ if (atResp && atResp->success) {
+ const gchar *line;
+ gint net_mode;
+
+ if (!atResp->lines) {
+ err("invalid response received");
+ goto END;
+ }
+
+ line = (char *) atResp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ err("invalid message");
+ goto END;
+ }
+
+ dbg("RESPONSE OK");
+
+ net_mode = atoi(tcore_at_tok_nth(tokens, 0));
+ dbg("mode = %d", net_mode);
+
+ switch (net_mode) {
+ case 0:
+ resp.mode = NETWORK_MODE_GSM;
+ break;
+ case 1:
+ resp.mode = NETWORK_MODE_AUTO;
+ break;
+ case 2:
+ resp.mode = NETWORK_MODE_WCDMA;
+ break;
+ default:
+ err("Unsupported mode [%d]", net_mode);
+ goto END;
+ }
+
+ resp.result = TCORE_RETURN_SUCCESS;
+ } else {
+ err("RESPONSE NOK");
+ }
+
+END:
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur,
+ TRESP_NETWORK_GET_MODE,
+ sizeof(struct tresp_network_get_mode), &resp);
+ }
+
+ /* Free resource*/
+ tcore_at_tok_free(tokens);
+}
+
+static void on_response_cancel_manual_search(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ struct tresp_network_set_cancel_manual_search resp = {0};
+ const TcoreATResponse *atResp = data;
+ CustomData *custom_data;
+
+ dbg("ENTER on_response_cancel_manual_search");
+
+ if (atResp->success > 0) {
+ dbg("Response OK");
+ resp.result = TCORE_RETURN_SUCCESS;
+ } else {
+ dbg("Response NOK");
+ resp.result = TCORE_RETURN_FAILURE;
+ }
+
+ custom_data = tcore_object_ref_user_data(tcore_pending_ref_core_object(p));
+ custom_data->search_state = IMC_NETWORK_SEARCH_STATE_NO_SEARCH;
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur,
+ TRESP_NETWORK_SET_CANCEL_MANUAL_SEARCH,
+ sizeof(struct tresp_network_set_cancel_manual_search), &resp);
+ }
+
+ dbg("Exit on_response_cancel_manual_search");
+}
+
static gboolean on_event_ps_network_regist(CoreObject *o, const void *data, void *user_data)
{
struct tnoti_network_registration_status regist_status;
goto OUT;
} else {
stat = atoi(pResp);
- if ((pResp = g_slist_nth_data(tokens, 1)))
- lac = atoi(pResp);
+ if ((pResp = g_slist_nth_data(tokens, 1))) {
+ pResp = util_removeQuotes(pResp);
+ if (pResp) {
+ lac = strtol(pResp, NULL, 16);
+ g_free(pResp);
+ }
+ }
- if ((pResp = g_slist_nth_data(tokens, 2)))
- ci = atoi(pResp);
- else
+ if ((pResp = g_slist_nth_data(tokens, 2))) {
+ pResp = util_removeQuotes(pResp);
+ if (pResp) {
+ ci = strtol(pResp, NULL, 16);
+ g_free(pResp);
+ }
+ } else {
dbg("No ci in +CGREG");
+ }
if ((pResp = g_slist_nth_data(tokens, 3)))
AcT = atoi(pResp);
else
dbg("No AcT in +CGREG");
- if ((pResp = g_slist_nth_data(tokens, 4)))
- rac = atoi(pResp);
- else
+ if ((pResp = g_slist_nth_data(tokens, 4))) {
+ pResp = util_removeQuotes(pResp);
+ if (pResp) {
+ rac = strtol(pResp, NULL, 16);
+ g_free(pResp);
+ }
+ } else {
dbg("No rac in +CGREG");
+ }
}
act = lookup_tbl_access_technology[AcT];
tcore_network_set_access_technology(o, act);
- if (stat == AT_CREG_STAT_REG_ROAM)
- tcore_network_set_roaming_state(o, TRUE);
- else
- tcore_network_set_roaming_state(o, FALSE);
-
tcore_network_get_service_type(o, &service_type);
dbg("prev_service_type = 0x%x", service_type);
service_type = _get_service_type(service_type, svc_domain, act, cs_status, ps_status);
regist_status.roaming_status = tcore_network_get_roaming_state(o);
tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
- TNOTI_NETWORK_REGISTRATION_STATUS, sizeof(struct tnoti_network_registration_status), ®ist_status);
-
+ TNOTI_NETWORK_REGISTRATION_STATUS, sizeof(regist_status), ®ist_status);
+#if 0
if (service_type == NETWORK_SERVICE_TYPE_HSDPA)
noti.status = TELEPHONY_HSDPA_ON;
else
noti.status = TELEPHONY_HSDPA_OFF;
-
+#else
+ switch(AcT){
+ case AT_COPS_ACT_GSM:/*Fall Through*/
+ case AT_COPS_ACT_GSM_COMPACT:/*Fall Through*/
+ case AT_COPS_ACT_UTRAN:/*Fall Through*/
+ case AT_COPS_ACT_GSM_EGPRS:/*Fall Through*/
+ case AT_COPS_ACT_E_UTRAN:
+ {
+ dbg("Not required for Protocol Status Notification");
+ goto OUT;
+ }
+ case AT_COPS_ACT_UTRAN_HSDPA:
+ {
+ dbg("HSDPA");
+ noti.status = TELEPHONY_HSDPA_ON;
+ break;
+ }
+ case AT_COPS_ACT_UTRAN_HSUPA:
+ {
+ dbg("HSUPA");
+ noti.status = TELEPHONY_HSUPA_ON;
+ break;
+ }
+ case AT_COPS_ACT_UTRAN_HSDPA_HSUPA:
+ {
+ dbg("HSPA");
+ noti.status = TELEPHONY_HSPA_ON;
+ break;
+ }
+ default:
+ {
+ dbg("Ignore");
+ goto OUT;
+ }
+ }
+#endif
tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_PS_PROTOCOL_STATUS,
sizeof(struct tnoti_ps_protocol_status), ¬i);
goto OUT;
} else {
stat = atoi(pResp);
- if ((pResp = g_slist_nth_data(tokens, 1)))
- lac = atoi(pResp);
+ if ((pResp = g_slist_nth_data(tokens, 1))) {
+ pResp = util_removeQuotes(pResp);
+ if (pResp) {
+ lac = strtol(pResp, NULL, 16);
+ g_free(pResp);
+ }
+ }
- if ((pResp = g_slist_nth_data(tokens, 2)))
- ci = atoi(pResp);
- else
+ if ((pResp = g_slist_nth_data(tokens, 2))) {
+ pResp = util_removeQuotes(pResp);
+ if (pResp) {
+ ci = strtol(pResp, NULL, 16);
+ g_free(pResp);
+ }
+ } else {
dbg("No ci in +CREG");
+ }
if ((pResp = g_slist_nth_data(tokens, 3)))
AcT = atoi(pResp);
act = lookup_tbl_access_technology[AcT];
tcore_network_set_access_technology(o, act);
- if (stat == AT_CREG_STAT_REG_ROAM)
+ if (stat == AT_CREG_STAT_REG_ROAM) {
tcore_network_set_roaming_state(o, TRUE);
- else
+ }else if ((stat == AT_CREG_STAT_REG_DENIED) && (TRUE == tcore_network_get_roaming_state(o))) {
+ dbg("Ignore roaming set with REG_DENIED when previous state is REG_ROAM");
+ }else {
tcore_network_set_roaming_state(o, FALSE);
+ }
tcore_network_get_service_type(o, &service_type);
dbg("prev_service_type = 0x%x", service_type);
/*
+CTZV: <tz>,<time>
<tz> integer value indicating the time zone (e.g. -22 or +34)
-<time> string type value; format is \1cyy/MM/dd,hh:mms\1d, wherein characters indicates year, month, day, hour,
-minutes, seconds.
-*/
+<time> string type value; format is yy/MM/dd,hh:mms, wherein characters indicates year, month, day, hour,
+minutes, seconds.*/
+
dbg("Network time info (+CTZV) recieved");
if (line != NULL) {
+ gchar *plmn_str = NULL;
dbg("Response OK");
dbg("noti line is %s", line);
net_time_info.gmtoff = atoi(time_zone) * 15; /* TZ in minutes */
}
- if (tcore_network_get_plmn(o) != NULL)
- strcpy(net_time_info.plmn, tcore_network_get_plmn(o));
+ plmn_str = tcore_network_get_plmn(o);
+ if (plmn_str != NULL) {
+ g_strlcpy(net_time_info.plmn, plmn_str, sizeof(net_time_info.plmn));
+ g_free(plmn_str);
+ }
if ((time = g_slist_nth_data(tokens, 1)) && (strlen(time) > 18)) {
strncpy(ptime_param, time + 1, 2); /* skip past initial quote (") */
dbg("new pending(AT+XOPS=0/5/6 for Nitz PLMN name)");
/* Get NITZ name and plmn_id via AT+XCOPS = 0/5/6 */
- nwk_prepare_and_send_pending_request(tcore_object_ref_plugin(o), "umts_network", "AT+XCOPS=0;+XCOPS=5;+XCOPS=6", "+XCOPS", TCORE_AT_MULTILINE, ur, on_response_get_nitz_name);
+ nwk_prepare_and_send_pending_request(o, "AT+XCOPS=0;+XCOPS=5;+XCOPS=6", "+XCOPS", TCORE_AT_MULTILINE, ur, on_response_get_nitz_name);
} else {
dbg("line is NULL");
}
if ((resp->data.spn.display_condition & 0x03) == 0x01) {
tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_ANY);
}
+
+ // fallback in case no SPN name is provided
+ if (resp->data.spn.spn[0] == '\0')
+ tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_NETWORK);
}
}
TcoreHal *h = NULL;
TcorePending *pending = NULL;
TcoreATRequest *atreq = NULL;
-
+ CustomData *custom_data;
char *cmd_str = NULL;
+
dbg("search_network - ENTER!!");
if (!o || !ur)
return TCORE_RETURN_EINVAL;
+ custom_data = tcore_object_ref_user_data(o);
+ if (custom_data->search_state
+ == IMC_NETWORK_SEARCH_STATE_IN_PROGRESS) {
+ warn("Network Search: [ALREADY IN PROGRESS]");
+ return TCORE_RETURN_FAILURE;
+ }
+
h = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(h)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
pending = tcore_pending_new(o, 0);
cmd_str = g_strdup_printf("AT+COPS=?");
atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_SINGLELINE);
tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_timeout(pending, 150);
tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
tcore_pending_set_response_callback(pending, on_response_search_network, NULL);
+ tcore_pending_set_timeout_callback(pending, on_timeout_search_network, NULL);
tcore_pending_link_user_request(pending, ur);
tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
tcore_hal_send_request(h, pending);
g_free(cmd_str);
+
+ custom_data->search_state = IMC_NETWORK_SEARCH_STATE_IN_PROGRESS;
+ dbg("Search State: [IN PROGRESS]");
+
return TCORE_RETURN_SUCCESS;
}
req_data = tcore_user_request_ref_data(ur, NULL);
h = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(h)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
pending = tcore_pending_new(o, 0);
// Command Format - AT+COPS=[<mode>[,<format>[,<oper>[,< AcT>]]]]
act = 2;
switch (req_data->mode) {
- case NETWORK_SELECT_MODE_GSM_MANUAL:
+ case NETWORK_SELECT_MODE_MANUAL:
{
mode = AT_COPS_MODE_MANUAL;
format = AT_COPS_FORMAT_NUMERIC;
}
break;
- case NETWORK_SELECT_MODE_GLOBAL_AUTOMATIC:
+ case NETWORK_SELECT_MODE_AUTOMATIC:
default:
cmd_str = g_strdup("AT+COPS=0");
break;
return TCORE_RETURN_EINVAL;
h = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(h)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
pending = tcore_pending_new(o, 0);
cmd_str = g_strdup_printf("AT+COPS?");
req_data = tcore_user_request_ref_data(ur, NULL);
h = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(h)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
dbg("set_band - called with band = %d", req_data->band);
{
TcoreHal *h = NULL;
TcorePending *pending = NULL;
-
TcoreATRequest *atreq;
char *cmd_str = NULL;
dbg("get_band - ENTER!!");
return TCORE_RETURN_EINVAL;
h = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(h)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
/* Get RAT Information Information. Based on RAT read response, we will get specific RAT bands only */
cmd_str = g_strdup_printf("AT+XRAT?");
static TReturn set_preferred_plmn(CoreObject *o, UserRequest *ur)
{
TcoreHal *h = NULL;
- TcorePlugin *p = NULL;
TcorePending *pending = NULL;
TcoreATRequest *atreq = NULL;
struct treq_network_set_preferred_plmn *req_data = NULL;
if (!o || !ur)
return TCORE_RETURN_EINVAL;
+ h = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(h)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
req_data = (struct treq_network_set_preferred_plmn *) tcore_user_request_ref_data(ur, NULL);
pending = tcore_pending_new(o, 0);
dbg("Entry set_preferred_plmn");
-
- p = tcore_object_ref_plugin(o);
- h = tcore_object_get_hal(o);
-
/*
AT+CPOL=
[<index>][,<format>[,<oper>[,<GSM_AcT>,
return TCORE_RETURN_EINVAL;
h = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(h)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
pending = tcore_pending_new(o, 0);
- cmd_str = g_strdup_printf("AT+CPOL?");
+ cmd_str = g_strdup_printf("AT+CPOL=,2;+CPOL?");
atreq = tcore_at_request_new(cmd_str, "+CPOL", TCORE_AT_MULTILINE);
tcore_pending_set_request_data(pending, 0, atreq);
return TCORE_RETURN_SUCCESS;
}
+static TReturn cancel_manual_search (CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *h = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *atreq = NULL;
+ CustomData *custom_data;
+
+ dbg("cancel_manual_search - ENTER!!");
+
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ h = tcore_object_get_hal(o);
+ if (FALSE == tcore_hal_get_power_state(h)) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ custom_data = tcore_object_ref_user_data(o);
+ if (custom_data->search_state
+ == IMC_NETWORK_SEARCH_STATE_IN_PROGRESS) {
+ dbg("Search in Progress...");
+
+ pending = tcore_pending_new(o, 0);
+ atreq = tcore_at_request_new("\e", NULL, TCORE_AT_NO_RESULT);
+
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_response_callback(pending, on_response_cancel_manual_search, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
+
+ tcore_hal_send_request(h, pending);
+
+ /*Set the Search State to Cancelled*/
+ custom_data->search_state = IMC_NETWORK_SEARCH_STATE_CANCELLED;
+ dbg("Search State: [CANCELLED]");
+ } else {
+ dbg("No Search in Progress...");
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
static TReturn get_serving_network(CoreObject *o, UserRequest *ur)
{
dbg("get_serving_network - ENTER!!");
if (!o)
return TCORE_RETURN_EINVAL;
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
dbg("new pending(AT+COPS?)");
- nwk_prepare_and_send_pending_request(tcore_object_ref_plugin(o), "umts_network", "AT+COPS=3,2;+COPS?;+COPS=3,0;+COPS?", "+COPS", TCORE_AT_MULTILINE, ur, on_response_get_serving_network);
+ nwk_prepare_and_send_pending_request(o, "AT+COPS=3,2;+COPS?;+COPS=3,0;+COPS?", "+COPS", TCORE_AT_MULTILINE, ur, on_response_get_serving_network);
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn network_set_mode(CoreObject *o, UserRequest *ur)
+{
+ struct treq_network_set_mode *set_mode = NULL;
+ TReturn ret = TCORE_RETURN_EINVAL;
+ int act;
+ gchar *at_cmd;
+
+ dbg("network_set_mode - ENTER!!");
+
+ set_mode = (struct treq_network_set_mode *)tcore_user_request_ref_data(ur, NULL);
+
+ switch (set_mode->mode) {
+ case NETWORK_MODE_AUTO:
+ act = 1;
+ break;
+ case NETWORK_MODE_GSM:
+ act = 0;
+ break;
+ case NETWORK_MODE_WCDMA:
+ act = 2;
+ break;
+ case NETWORK_MODE_LTE:
+ default:
+ err("Unsupported mode: [%d]", set_mode->mode);
+ return ret;
+ }
+
+ if (act == 1)
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+XRAT=%d,2", act); //PreferredAct is UMTS
+ else
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+XRAT=%d", act);
+
+ /* Send Request to modem */
+ ret = tcore_prepare_and_send_at_request(o,
+ at_cmd, NULL,
+ TCORE_AT_NO_RESULT,
+ ur,
+ on_response_network_set_mode, NULL,
+ on_confirmation_network_message_send, NULL,
+ 0, NULL, NULL);
+
+ g_free(at_cmd);
+ return ret;
+}
+
+static TReturn network_get_mode(CoreObject *o, UserRequest *ur)
+{
+ TReturn ret;
+
+ dbg("network_get_mode - ENTER!!");
+
+ /* Send Request to modem */
+ ret = tcore_prepare_and_send_at_request(o,
+ "AT+XRAT?", "+XRAT",
+ TCORE_AT_SINGLELINE,
+ ur,
+ on_response_network_get_mode, NULL,
+ on_confirmation_network_message_send, NULL,
+ 0, NULL, NULL);
+
+ return ret;
+}
+
+static TReturn get_default_data_subscription(CoreObject *co, UserRequest *ur)
+{
+ struct tresp_network_get_default_data_subs resp = {0,};
+
+ dbg("Enter");
+
+ resp.result = TCORE_RETURN_SUCCESS;
+ resp.default_subs = NETWORK_DEFAULT_DATA_SUBS_SIM1;
+
+ if( TCORE_RETURN_SUCCESS == tcore_user_request_send_response(ur,
+ TRESP_NETWORK_GET_DEFAULT_DATA_SUBSCRIPTION,
+ sizeof(struct tresp_network_get_default_data_subs), &resp)){
+ tcore_user_request_unref(ur);
+ }
return TCORE_RETURN_SUCCESS;
}
.get_order = NULL,
.set_power_on_attach = NULL,
.get_power_on_attach = NULL,
- .set_cancel_manual_search = NULL,
+ .set_cancel_manual_search = cancel_manual_search,
.get_serving_network = get_serving_network,
+ .set_mode = network_set_mode,
+ .get_mode = network_get_mode,
+ .set_default_data_subscription = NULL,
+ .get_default_data_subscription =get_default_data_subscription,
};
-gboolean s_network_init(TcorePlugin *p, TcoreHal *h)
+gboolean imc_network_init(TcorePlugin *cp, CoreObject *co_network)
{
- CoreObject *o = NULL;
+ CustomData *custom_data;
+ dbg("Enter");
- o = tcore_network_new(p, "umts_network", &network_ops, h);
- if (!o)
+ /* Set operations */
+ tcore_network_set_ops(co_network, &network_ops);
+
+ /* Custom data */
+ custom_data = g_malloc0(sizeof(CustomData));
+ if (custom_data == NULL) {
+ err("Memory allocation failed!!");
return FALSE;
+ }
+ custom_data->search_state = IMC_NETWORK_SEARCH_STATE_NO_SEARCH;
+
+ tcore_object_link_user_data(co_network, custom_data);
- tcore_object_add_callback(o, "+CREG", on_event_cs_network_regist, NULL);
- tcore_object_add_callback(o, "+CGREG", on_event_ps_network_regist, NULL);
- tcore_object_add_callback(o, "+XCIEV", on_event_network_icon_info, NULL);
+ tcore_object_add_callback(co_network, "+CREG", on_event_cs_network_regist, NULL);
+ tcore_object_add_callback(co_network, "+CGREG", on_event_ps_network_regist, NULL);
+ tcore_object_add_callback(co_network, "+XCIEV", on_event_network_icon_info, NULL);
/* +CTZV: <tz>,<time> */
- tcore_object_add_callback(o, "+CTZV", on_event_network_ctzv_time_info, NULL);
+ tcore_object_add_callback(co_network, "+CTZV", on_event_network_ctzv_time_info, NULL);
- tcore_server_add_notification_hook(tcore_plugin_ref_server(p), TNOTI_SIM_STATUS, on_hook_sim_init, o);
+ tcore_server_add_notification_hook(tcore_plugin_ref_server(cp), TNOTI_SIM_STATUS, on_hook_sim_init, co_network);
- _insert_mcc_mnc_oper_list(p, o);
+ _insert_mcc_mnc_oper_list(cp, co_network);
+
+ dbg("Exit");
return TRUE;
}
-void s_network_exit(TcorePlugin *p)
+void imc_network_exit(TcorePlugin *cp, CoreObject *co_network)
{
- CoreObject *o;
+ CustomData *custom_data;
- o = tcore_plugin_ref_core_object(p, "umts_network");
+ custom_data = tcore_object_ref_user_data(co_network);
+ if (custom_data != NULL)
+ g_free(custom_data);
- tcore_network_free(o);
+ dbg("Exit");
}
--- /dev/null
+/**
+ * tel-plugin-imc
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Ankit Jogi <ankit.jogi@samsung.com>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <tcore.h>
+#include <server.h>
+#include <core_object.h>
+#include <plugin.h>
+#include <hal.h>
+#include <user_request.h>
+#include <at.h>
+
+#include <co_phonebook.h>
+#include <co_sim.h>
+
+#include "imc_phonebook.h"
+
+/* Constants */
+#define VAL_ZERO 0
+#define VAL_ONE 1
+#define VAL_TWO 2
+#define VAL_THREE 3
+#define VAL_FOUR 4
+#define VAL_FIVE 5
+#define VAL_SIX 6
+#define VAL_SEVEN 7
+#define VAL_EIGHT 8
+#define VAL_NINE 9
+
+/* Type Of Number and Number Plan */
+#define IMC_TON_INTERNATIONAL 145
+#define IMC_TON_UNKNOWN 129
+#define IMC_NUM_PLAN_INTERNATIONAL 0x0070
+#define IMC_NUM_PLAN_UNKNOWN 0x0060
+
+#define IMC_PB_INFO_LENGTH 5
+
+typedef struct {
+ GSList *used_index_fdn;
+ gboolean used_index_fdn_valid;
+
+ GSList *used_index_adn;
+ gboolean used_index_adn_valid;
+
+ GSList *used_index_sdn;
+ gboolean used_index_sdn_valid;
+
+ GSList *used_index_usim;
+ gboolean used_index_usim_valid;
+} PrivateInfo;
+
+/******************************************************************************
+ * Internal functions
+ *****************************************************************************/
+static gint __phonebook_compare_index(gconstpointer a, gconstpointer b)
+{
+ guint index1 = (guint)a;
+ guint index2 = (guint)b;
+
+ return index1 - index2;
+}
+
+static enum tel_phonebook_field_type __phonebook_convert_field_type(int field_type)
+{
+ switch (field_type) {
+ case 1:
+ return PB_FIELD_NUMBER;
+ case 2:
+ return PB_FIELD_NAME;
+ case 3:
+ return PB_FIELD_GRP;
+ case 4:
+ return PB_FIELD_SNE;
+ case 5:
+ return PB_FIELD_EMAIL1;
+ default:
+ return 0;
+ }
+}
+
+static enum tel_phonebook_ton __phonebook_find_num_plan(int number_plan)
+{
+ enum tel_phonebook_ton result;
+ dbg("number_plan : 0x%04x", number_plan);
+
+ if (number_plan & IMC_NUM_PLAN_INTERNATIONAL) {
+ result = PB_TON_INTERNATIONAL;
+ }
+ else {
+ result = PB_TON_UNKNOWN;
+ }
+ dbg("result : %d", result);
+
+ return result;
+}
+
+static gboolean __phonebook_get_pb_type_str(enum tel_phonebook_type pb_type,
+ gchar **req_type_str)
+{
+ g_assert(req_type_str != NULL);
+
+ switch (pb_type) {
+ case PB_TYPE_FDN:
+ *req_type_str = g_strdup("FD");
+ break;
+ case PB_TYPE_ADN:
+ case PB_TYPE_USIM:
+ *req_type_str = g_strdup("SM");
+ break;
+ case PB_TYPE_SDN:
+ *req_type_str = g_strdup("SN");
+ break;
+ default:
+ warn("Unsupported Phonebook type");
+ *req_type_str = g_strdup("NS");
+ break;
+ }
+
+ return TRUE;
+}
+
+static gboolean __phonebook_check_and_select_type(CoreObject *co,
+ enum tel_phonebook_type req_pb_type, gchar **set_pb_cmd)
+{
+ struct tel_phonebook_support_list *support_list;
+ enum tel_phonebook_type current_type;
+
+ /* Check whether pb_type is supported or not */
+ support_list = tcore_phonebook_get_support_list(co);
+ if (support_list) {
+ if ((req_pb_type == PB_TYPE_FDN && support_list->b_fdn == FALSE)
+ || (req_pb_type == PB_TYPE_ADN && support_list->b_adn == FALSE)
+ || (req_pb_type == PB_TYPE_SDN && support_list->b_sdn == FALSE)
+ || (req_pb_type == PB_TYPE_USIM && support_list->b_usim == FALSE)) {
+ err("Not supported Phonebook type");
+
+ g_free(support_list);
+ return FALSE;
+ }
+ g_free(support_list);
+ }
+
+ /* Check Current type & Request type */
+ current_type = tcore_phonebook_get_selected_type(co);
+ if (current_type != req_pb_type) {
+ gchar *req_pb_type_str = NULL;
+
+ __phonebook_get_pb_type_str(req_pb_type, &req_pb_type_str);
+ dbg("Add AT-Command to change [%s] Type", req_pb_type_str);
+
+ /* Select Phonebook type */
+ *set_pb_cmd = g_strdup_printf("AT+CPBS=\"%s\";", req_pb_type_str);
+
+ g_free(req_pb_type_str);
+ } else {
+ *set_pb_cmd = g_strdup_printf("AT");
+ }
+
+ return TRUE;
+}
+
+static gboolean __phonebook_update_index_list_by_type(CoreObject *co,
+ enum tel_phonebook_type pb_type, guint req_index)
+{
+ GSList *list = NULL;
+ PrivateInfo *private_info = tcore_object_ref_user_data(co);
+ g_assert(private_info != NULL);
+
+ switch (pb_type) {
+ case PB_TYPE_FDN:
+ list = private_info->used_index_fdn;
+ break;
+
+ case PB_TYPE_ADN:
+ list = private_info->used_index_adn;
+ break;
+
+ case PB_TYPE_SDN:
+ list = private_info->used_index_sdn;
+ break;
+
+ case PB_TYPE_USIM:
+ list = private_info->used_index_usim;
+ break;
+
+ default:
+ warn("Unsupported Phonebook type: [%d]", pb_type);
+ return FALSE;
+ }
+
+ /*
+ * Check if 'index' is already available (UPDATE operation).
+ */
+ while (list) {
+ if ((guint)list->data == req_index) {
+ /*
+ * index 'present', no need to update
+ */
+ dbg("Index: [%d] present in Phonebook type: [%d]",
+ req_index, pb_type);
+
+ return TRUE;
+ }
+ list = g_slist_next(list);
+ }
+
+ /*
+ * 'index' is NOT available (ADD operation),
+ * insert 'index' to corresponding index list.
+ */
+ switch (pb_type) {
+ case PB_TYPE_FDN:
+ private_info->used_index_fdn = g_slist_insert_sorted(
+ private_info->used_index_fdn,
+ (gpointer)req_index,
+ __phonebook_compare_index);
+
+ /* Update Phonebook list valid */
+ if (private_info->used_index_fdn_valid != TRUE)
+ private_info->used_index_fdn_valid = TRUE;
+ break;
+
+ case PB_TYPE_ADN:
+ private_info->used_index_adn = g_slist_insert_sorted(
+ private_info->used_index_adn,
+ (gpointer)req_index,
+ __phonebook_compare_index);
+
+ /* Update Phonebook list valid */
+ if (private_info->used_index_adn_valid != TRUE)
+ private_info->used_index_adn_valid = TRUE;
+ break;
+
+ case PB_TYPE_SDN:
+ private_info->used_index_sdn = g_slist_insert_sorted(
+ private_info->used_index_sdn,
+ (gpointer)req_index,
+ __phonebook_compare_index);
+
+ /* Update Phonebook list valid */
+ if (private_info->used_index_sdn_valid != TRUE)
+ private_info->used_index_sdn_valid = TRUE;
+ break;
+
+ case PB_TYPE_USIM:
+ private_info->used_index_usim = g_slist_insert_sorted(
+ private_info->used_index_usim,
+ (gpointer)req_index,
+ __phonebook_compare_index);
+
+ /* Update Phonebook list valid */
+ if (private_info->used_index_usim_valid != TRUE)
+ private_info->used_index_usim_valid = TRUE;
+ break;
+
+ default:
+ warn("Unexpected Phonebook type: [%d]", pb_type);
+ g_assert_not_reached();
+ break;
+ }
+
+ return TRUE;
+}
+
+static gboolean __phonebook_get_index_list_by_type(CoreObject *co,
+ enum tel_phonebook_type pb_type, GSList **list)
+{
+ PrivateInfo *private_info = tcore_object_ref_user_data(co);
+ g_assert(private_info != NULL);
+
+ switch (pb_type) {
+ case PB_TYPE_FDN:
+ if (private_info->used_index_fdn_valid != TRUE)
+ return FALSE;
+ *list = private_info->used_index_fdn;
+ break;
+
+ case PB_TYPE_ADN:
+ if (private_info->used_index_adn_valid != TRUE)
+ return FALSE;
+ *list = private_info->used_index_adn;
+ break;
+
+ case PB_TYPE_SDN:
+ if (private_info->used_index_sdn_valid != TRUE)
+ return FALSE;
+ *list = private_info->used_index_sdn;
+ break;
+
+ case PB_TYPE_USIM:
+ if (private_info->used_index_usim_valid != TRUE)
+ return FALSE;
+ *list = private_info->used_index_usim;
+ break;
+
+ default:
+ warn("Unsupported Phonebook type");
+ return FALSE;
+ break;
+ }
+
+ return TRUE;
+}
+
+static void __phonebook_check_used_index(CoreObject *co,
+ enum tel_phonebook_type pb_type, guint req_index, guint *used_index)
+{
+ GSList *list = NULL;
+
+ /* Get used_index list by req_type */
+ if (__phonebook_get_index_list_by_type(co, pb_type, &list) != TRUE) {
+ err("used_index list is NOT valid");
+ *used_index = req_index;
+ return;
+ }
+
+ /* Use first used_index in case req_index is not used */
+ *used_index = (guint)g_slist_nth_data(list, VAL_ZERO);
+ while (list) {
+ if ((guint)list->data == req_index) {
+ /*
+ * req_index is equal to one of used_index
+ */
+ *used_index = req_index;
+ return;
+ }
+ list = g_slist_next(list);
+ }
+}
+
+static void __on_resp_phonebook_get_support_list(TcorePending *p,
+ int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+
+ CoreObject *co_phonebook = tcore_pending_ref_core_object(p);
+ TcorePlugin *plugin = tcore_object_ref_plugin(co_phonebook);
+
+ struct tnoti_phonebook_status noti_data = {0, };
+
+ dbg("Entry");
+
+ noti_data.b_init = FALSE;
+
+ if (resp && resp->success > VAL_ZERO) {
+ const char *line;
+ char *temp = NULL;
+ char *ptr = NULL;
+
+ GSList *tokens = NULL;
+ char *pb_type = NULL;
+
+ dbg("RESPONSE OK");
+
+ if (resp->lines == NULL) {
+ warn("Invalid notification");
+ goto EXIT;
+ }
+
+ line = (const char*)resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < VAL_ONE) {
+ warn("Invalid notification - 'number' of tokens: [%d]",
+ g_slist_length(tokens));
+
+ /* Free resources */
+ tcore_at_tok_free(tokens);
+
+ goto EXIT;
+ }
+
+ temp = (char*)g_slist_nth_data(tokens, VAL_ZERO);
+ pb_type = strtok_r(temp, "(,)", &ptr);
+
+ while (pb_type != NULL) {
+ temp = tcore_at_tok_extract(pb_type);
+ dbg("pbtype %s", temp);
+
+ if (VAL_ZERO == g_strcmp0(temp, "FD")) {
+ dbg("SIM fixed-dialing Phonebook");
+ noti_data.support_list.b_fdn = TRUE;
+ }
+ else if (VAL_ZERO == g_strcmp0(temp, "SN")) {
+ dbg("Service Dialing Number");
+ noti_data.support_list.b_sdn = TRUE;
+ }
+ else if (VAL_ZERO == g_strcmp0(temp, "SM")) {
+ CoreObject *co_sim = NULL;
+ enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
+
+ /* Fecth SIM type */
+ co_sim = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
+ if (co_sim == NULL) {
+ err("SIM Core object is NULL");
+
+ /* Free resources */
+ tcore_at_tok_free(tokens);
+ g_free(temp);
+
+ goto EXIT;
+ }
+
+ sim_type = tcore_sim_get_type(co_sim);
+ dbg("SIM type: [%d]", sim_type);
+ if (sim_type == SIM_TYPE_USIM) { /* 3G SIM */
+ noti_data.support_list.b_usim = TRUE;
+ dbg("3G SIM - USIM Phonebook");
+ }
+ else { /* 2G SIM */
+ noti_data.support_list.b_adn = TRUE;
+ dbg("2G SIM - ADN Phonebook");
+ }
+ }
+ else if (VAL_ZERO == g_strcmp0(temp, "LD")) {
+ dbg("SIM/UICC - last-dialling-phonebook");
+ }
+ else if (VAL_ZERO == g_strcmp0(temp, "ON")) {
+ dbg("SIM (or MT) own numbers (MSISDNs) list");
+ }
+ else if (VAL_ZERO == g_strcmp0(temp, "BL")) {
+ dbg("Blacklist phonebook");
+ }
+ else if (VAL_ZERO == g_strcmp0(temp, "EC")) {
+ dbg("SIM emergency-call-codes phonebook");
+ }
+ else if (VAL_ZERO == g_strcmp0(temp, "AP")) {
+ dbg("Selected application phonebook");
+ }
+ else if (VAL_ZERO == g_strcmp0(temp, "BN")) {
+ dbg("SIM barred-dialling-number");
+ }
+
+ pb_type = strtok_r(NULL, "(,)", &ptr);
+
+ g_free(temp);
+ }
+
+ /* Free resources */
+ tcore_at_tok_free(tokens);
+
+ dbg("FDN: [%s] ADN: [%s] SDN: [%s] USIM: [%s]",
+ noti_data.support_list.b_fdn ? "TRUE" : "FALSE",
+ noti_data.support_list.b_adn ? "TRUE" : "FALSE",
+ noti_data.support_list.b_sdn ? "TRUE" : "FALSE",
+ noti_data.support_list.b_usim ? "TRUE" : "FALSE");
+
+ /* Phonebook initialized */
+ noti_data.b_init = TRUE;
+
+ /* Update states */
+ tcore_phonebook_set_support_list(co_phonebook, ¬i_data.support_list);
+ tcore_phonebook_set_status(co_phonebook, noti_data.b_init);
+ }
+ else {
+ dbg("RESPONSE NOK");
+
+ /* Update state */
+ tcore_phonebook_set_status(co_phonebook, noti_data.b_init);
+ }
+
+EXIT:
+ /*
+ * Send notification
+ *
+ * Phonebook status (TNOTI_PHONEBOOK_STATUS)
+ */
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ co_phonebook,
+ TNOTI_PHONEBOOK_STATUS,
+ sizeof(struct tnoti_phonebook_status), ¬i_data);
+
+ dbg("Exit");
+}
+
+/*
+ * Operation - get_support_list
+ *
+ * Request -
+ * AT-Command: AT+CPBS=?
+ *
+ * Response -
+ * Success: (Single line)
+ * (list of supported <storage>s)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static void __phonebook_get_support_list(CoreObject *co_phonebook)
+{
+ TReturn ret;
+
+ dbg("Entry");
+
+ if (!co_phonebook) {
+ err("Core object is NULL");
+ return;
+ }
+
+ ret = tcore_prepare_and_send_at_request(co_phonebook,
+ "AT+CPBS=?", "+CPBS",
+ TCORE_AT_SINGLELINE,
+ NULL,
+ __on_resp_phonebook_get_support_list, NULL,
+ NULL, NULL,
+ 0, NULL, NULL);
+ dbg("ret: [0x%x]", ret);
+}
+
+static void __on_resp_phonebook_get_used_index(TcorePending *p,
+ int data_len, const void *data, void *user_data)
+{
+ const struct tcore_at_response *at_resp = data;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+
+ g_assert(at_resp != NULL);
+
+ dbg("Entry");
+
+ if (at_resp->success > VAL_ZERO) {
+ dbg("Response OK");
+
+ if (at_resp->lines == NULL) {
+ err("at_resp->lines is NULL");
+ } else {
+ GSList *lines = at_resp->lines;
+ enum tel_phonebook_type req_pb_type;
+ GSList **list = NULL;
+ PrivateInfo *private_info = tcore_object_ref_user_data(co);
+
+ g_assert(private_info != NULL);
+
+ req_pb_type = (enum tel_phonebook_type)GPOINTER_TO_INT(user_data);
+
+ /* Select used_index_list by req_type */
+ switch (req_pb_type) {
+ case PB_TYPE_FDN:
+ list = &private_info->used_index_fdn;
+ private_info->used_index_fdn_valid = TRUE;
+ break;
+
+ case PB_TYPE_ADN:
+ list = &private_info->used_index_adn;
+ private_info->used_index_adn_valid = TRUE;
+ break;
+
+ case PB_TYPE_SDN:
+ list = &private_info->used_index_sdn;
+ private_info->used_index_sdn_valid = TRUE;
+ break;
+
+ case PB_TYPE_USIM:
+ list = &private_info->used_index_usim;
+ private_info->used_index_usim_valid = TRUE;
+ break;
+
+ default:
+ warn("Unsupported phonebook: [%d]", req_pb_type);
+ return;
+ }
+
+ while (lines) {
+ const gchar *line = lines->data;
+ GSList *tokens = NULL;
+ gchar *temp;
+
+ dbg("Line: [%s]", line);
+
+ tokens = tcore_at_tok_new(line);
+ if (tokens == NULL) {
+ err("tokens is NULL");
+ return;
+ }
+
+ /* Get only used_index */
+ temp = g_slist_nth_data(tokens, VAL_ZERO);
+ if (temp) {
+ /* Insert used_index in PrivateInfo sorted in ascending */
+ *list = g_slist_insert_sorted(*list,
+ (gpointer)atoi(temp),
+ __phonebook_compare_index);
+ }
+ tcore_at_tok_free(tokens);
+
+ /* Get next lines */
+ lines = g_slist_next(lines);
+ }
+
+ dbg("pb_type: [%d], used_index Length: [%d]",
+ req_pb_type, g_slist_length(*list));
+ }
+ }
+ else {
+ err("Response NOK");
+ }
+}
+
+static void __phonebook_get_used_index(CoreObject *co,
+ enum tel_phonebook_type pb_type, guint max_index)
+{
+ gchar *at_cmd;
+ TReturn ret;
+
+ dbg("Entry");
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("AT+CPBR=1,%d", max_index);
+
+ /* Send Request to Modem */
+ ret = tcore_prepare_and_send_at_request(co,
+ at_cmd, "+CPBR",
+ TCORE_AT_MULTILINE,
+ NULL,
+ __on_resp_phonebook_get_used_index, GINT_TO_POINTER(pb_type),
+ NULL, NULL,
+ 0, NULL, NULL);
+ dbg("ret: [0x%x]", ret);
+
+ /* Free resources */
+ g_free(at_cmd);
+}
+
+/******************************************************************************
+ * Phonebook Response functions
+ *****************************************************************************/
+static void on_resp_get_count(TcorePending *p,
+ int data_len, const void *data, void *user_data)
+{
+ const struct treq_phonebook_get_count *req_data = NULL;
+ struct tresp_phonebook_get_count resp_get_count;
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+ if (!ur) {
+ dbg("ur is NULL");
+ return;
+ }
+
+ req_data = (const struct treq_phonebook_get_count *)tcore_user_request_ref_data(ur, NULL);
+
+ memset(&resp_get_count, 0x00, sizeof(struct tresp_phonebook_get_count));
+ resp_get_count.result = PB_FAIL;
+ resp_get_count.type = req_data->phonebook_type;
+
+ if (resp && resp->success > VAL_ZERO) {
+ PrivateInfo *private_info;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ enum tel_phonebook_type pb_type;
+
+ GSList *tokens=NULL;
+ char *temp = NULL;
+
+ dbg("RESPONSE OK");
+
+ if (resp->lines == NULL) {
+ err("invalid message");
+ goto EXIT;
+ }
+
+ temp = (char *)resp->lines->data;
+ tokens = tcore_at_tok_new(temp);
+ if (g_slist_length(tokens) < VAL_THREE) {
+ /*
+ * No of tokens must be three.
+ * We cannot proceed without used and total count.
+ */
+ err("Invalid response - 'number' of tokens: [%d]", g_slist_length(tokens));
+
+ /* Free resources */
+ tcore_at_tok_free(tokens);
+
+ goto EXIT;
+ }
+
+ resp_get_count.result = PB_SUCCESS;
+
+ /* Fetch <used> */
+ temp = g_slist_nth_data(tokens, VAL_ONE);
+ if (temp)
+ resp_get_count.used_count = atoi(temp);
+
+ /* Fetch <total> */
+ temp = g_slist_nth_data(tokens, VAL_TWO);
+ if (temp)
+ resp_get_count.total_count = atoi(temp);
+
+ dbg("Used count [%d] Total count: [%d]", resp_get_count.used_count, resp_get_count.total_count);
+
+ /* Free resources */
+ tcore_at_tok_free(tokens);
+
+ pb_type = resp_get_count.type;
+
+ /* Updated selected Phonebook type */
+ tcore_phonebook_set_selected_type(co, pb_type);
+
+ /*
+ * Cache 'used_index' by req_type if valid used_index is NOT TRUE.
+ */
+ private_info = tcore_object_ref_user_data(co);
+ if ((pb_type == PB_TYPE_FDN && private_info->used_index_fdn_valid == FALSE)
+ || (pb_type == PB_TYPE_ADN && private_info->used_index_adn_valid == FALSE)
+ || (pb_type == PB_TYPE_SDN && private_info->used_index_sdn_valid == FALSE)
+ || (pb_type == PB_TYPE_USIM && private_info->used_index_usim_valid == FALSE)) {
+ /* Cache 'used' index list */
+ __phonebook_get_used_index(co, pb_type, resp_get_count.total_count);
+ }
+ }
+ else {
+ dbg("RESPONSE NOK");
+ }
+EXIT:
+ /* Send Response */
+ tcore_user_request_send_response(ur,
+ TRESP_PHONEBOOK_GETCOUNT,
+ sizeof(struct tresp_phonebook_get_count), &resp_get_count);
+
+ dbg("Exit");
+}
+
+static void on_resp_get_info(TcorePending *p,
+ int data_len, const void *data, void *user_data)
+{
+ const struct treq_phonebook_get_info *req_data = NULL;
+ struct tresp_phonebook_get_info resp_get_info;
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+ if (!ur) {
+ dbg("ur is NULL");
+ return;
+ }
+
+ req_data = (const struct treq_phonebook_get_info *)tcore_user_request_ref_data(ur, NULL);
+
+ memset(&resp_get_info, 0x00, sizeof(struct tresp_phonebook_get_info));
+
+ resp_get_info.result = PB_FAIL;
+ resp_get_info.type = req_data->phonebook_type;
+ dbg("Phonebook type: [%d]", resp_get_info.type);
+
+ if (resp && resp->success > VAL_ZERO) {
+ PrivateInfo *private_info;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ enum tel_phonebook_type pb_type;
+
+ GSList *tokens = NULL;
+ const char *line;
+ GSList *lines = resp->lines;
+ gchar *temp;
+
+ dbg("RESPONSE OK");
+
+ if (resp->lines == NULL) {
+ err("invalid message");
+ goto EXIT;
+ }
+
+ /*
+ * +CPBS: <storage>[,<used>][,total]
+ */
+ line = g_slist_nth_data(lines, VAL_ZERO);
+ dbg("First Line: [%s]", line);
+ tokens = tcore_at_tok_new(line);
+ if (tokens == NULL) {
+ err("invalid message");
+ goto EXIT;
+ }
+
+ /* Fetch <used> */
+ temp = g_slist_nth_data(tokens, VAL_ONE);
+ if (temp)
+ resp_get_info.used_count = atoi(temp);
+
+ /* Fetch <total> */
+ temp = g_slist_nth_data(tokens, VAL_TWO);
+ if (temp)
+ resp_get_info.index_max = atoi(temp);
+
+ resp_get_info.index_min = 1;
+
+ dbg("Used count: [%d] Total count (index_max): [%d] " \
+ "Minimum count (index_min): [%d]",
+ resp_get_info.used_count, resp_get_info.index_max,
+ resp_get_info.index_min);
+
+ /* Free resources */
+ tcore_at_tok_free(tokens);
+
+ resp_get_info.result = PB_SUCCESS;
+
+ /*
+ * +CPBF: [<nlength>],[<tlength>],[<glength>],[<slength>],[<elength>]
+ */
+ line = g_slist_nth_data(lines, VAL_ONE);
+ dbg("Second Line: [%s]", line);
+ tokens = tcore_at_tok_new(line);
+ if (tokens == NULL) {
+ err("invalid message");
+ goto EXIT;
+ }
+
+ /* Fetch <nlength> */
+ temp = g_slist_nth_data(tokens, VAL_ONE);
+ if (temp)
+ resp_get_info.number_length_max = atoi(temp);
+
+ /* Fetch <tlength> */
+ temp = g_slist_nth_data(tokens, VAL_ONE);
+ if (temp)
+ resp_get_info.text_length_max = atoi(temp);
+
+ dbg("Number length: [%d] Test length: [%d]",
+ resp_get_info.number_length_max, resp_get_info.text_length_max);
+
+ /* Free resources */
+ tcore_at_tok_free(tokens);
+
+ pb_type = resp_get_info.type;
+
+ /* Updated selected Phonebook type */
+ tcore_phonebook_set_selected_type(co, pb_type);
+
+ /*
+ * Cache 'used_index' by req_type if valid used_index is NOT TRUE.
+ */
+ private_info = tcore_object_ref_user_data(co);
+ if ((pb_type == PB_TYPE_FDN && private_info->used_index_fdn_valid == FALSE)
+ || (pb_type == PB_TYPE_ADN && private_info->used_index_adn_valid == FALSE)
+ || (pb_type == PB_TYPE_SDN && private_info->used_index_sdn_valid == FALSE)
+ || (pb_type == PB_TYPE_USIM && private_info->used_index_usim_valid == FALSE)) {
+ /* Cache 'used' index list */
+ __phonebook_get_used_index(co, pb_type, resp_get_info.index_max);
+ }
+ }
+ else {
+ dbg("RESPONSE NOK");
+ }
+
+EXIT:
+ /* Send Response */
+ tcore_user_request_send_response(ur,
+ TRESP_PHONEBOOK_GETMETAINFO,
+ sizeof(struct tresp_phonebook_get_info), &resp_get_info);
+
+ dbg("Exit");
+}
+
+static void on_resp_get_usim_info(TcorePending *p,
+ int data_len, const void *data, void *user_data)
+{
+ struct tresp_phonebook_get_usim_info res_get_usim_info;
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+ if (!ur) {
+ dbg("error - current ur is NULL");
+ return;
+ }
+
+ memset(&res_get_usim_info, 0x00, sizeof(struct tresp_phonebook_get_usim_info));
+ res_get_usim_info.result = PB_FAIL;
+
+ if (resp && resp->success > VAL_ZERO) {
+ PrivateInfo *private_info;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+
+ GSList *tokens = NULL;
+ const char *line;
+ GSList *lines = resp->lines;
+ int used = 0, total = 0;
+ int nlen = 0, tlen = 0, glen = 0, slen = 0, elen = 0;
+ enum tel_phonebook_field_type phonebook_field_type;
+ int field_type;
+ gchar *temp;
+
+ dbg("RESPONSE OK");
+
+ if (resp->lines == NULL) {
+ err("invalid message");
+ goto EXIT;
+ }
+
+ /*
+ * +CPBS: <storage>[,<used>][,total]
+ */
+ line = g_slist_nth_data(lines, VAL_ZERO);
+ dbg("First Line: [%s]", line);
+ tokens = tcore_at_tok_new(line);
+ if (tokens == NULL) {
+ err("invalid message");
+ goto EXIT;
+ }
+
+ /* Fetch <used> */
+ temp = g_slist_nth_data(tokens, VAL_ONE);
+ if (temp)
+ used = atoi(temp);
+
+ /* Fetch <total> */
+ temp = g_slist_nth_data(tokens, VAL_TWO);
+ if (temp)
+ total = atoi(temp);
+
+ dbg("used_count %d index_max %d", used, total);
+
+ /* Free resources */
+ tcore_at_tok_free(tokens);
+
+ /*
+ * +CPBF: [<nlength>],[<tlength>],[<glength>],[<slength>],[<elength>]
+ */
+ line = g_slist_nth_data(lines, VAL_ONE);
+ dbg("Second Line: [%s]", line);
+ tokens = tcore_at_tok_new(line);
+ if (tokens == NULL) {
+ err("invalid message");
+ goto EXIT;
+ }
+
+ /* Fetch <nlength> */
+ temp = g_slist_nth_data(tokens, VAL_ZERO);
+ if (temp)
+ nlen = atoi(temp);
+
+ /* Fetch <tlength> */
+ temp = g_slist_nth_data(tokens, VAL_ONE);
+ if (temp)
+ tlen = atoi(temp);
+
+ /* Fetch <glength> */
+ temp = g_slist_nth_data(tokens, VAL_TWO);
+ if (temp)
+ glen = atoi(temp);
+
+ /* Fetch <slength> */
+ temp = g_slist_nth_data(tokens, VAL_THREE);
+ if (temp)
+ slen = atoi(temp);
+
+ /* Fetch <elength> */
+ temp = g_slist_nth_data(tokens, VAL_FOUR);
+ if (temp)
+ elen = atoi(temp);
+
+ dbg("Length - Number: [%d] Test: [%d] Group: [%d] " \
+ "Second name: [%d] e-mail: [%d]",
+ nlen, tlen, glen, slen, elen);
+
+ for (field_type = 1; field_type <= IMC_PB_INFO_LENGTH; field_type++) {
+ phonebook_field_type = __phonebook_convert_field_type(field_type);
+
+ res_get_usim_info.field_list[field_type-1].field = phonebook_field_type;
+ res_get_usim_info.field_list[field_type-1].used_count = used;
+ res_get_usim_info.field_list[field_type-1].index_max = total;
+
+ switch (phonebook_field_type) {
+ case PB_FIELD_NUMBER:
+ res_get_usim_info.field_list[field_type-1].text_max = nlen;
+ break;
+
+ case PB_FIELD_NAME:
+ res_get_usim_info.field_list[field_type-1].text_max = tlen;
+ break;
+
+ case PB_FIELD_GRP:
+ res_get_usim_info.field_list[field_type-1].text_max = glen;
+ break;
+
+ case PB_FIELD_SNE:
+ res_get_usim_info.field_list[field_type-1].text_max = slen;
+ break;
+
+ case PB_FIELD_EMAIL1:
+ res_get_usim_info.field_list[field_type-1].text_max = elen;
+ break;
+
+ default:
+ warn("Unsupported Phonebook field type: [%d]", phonebook_field_type);
+ break;
+ }
+ }
+
+ res_get_usim_info.field_count = IMC_PB_INFO_LENGTH;
+ res_get_usim_info.result = PB_SUCCESS;
+
+ /* Free resources */
+ tcore_at_tok_free(tokens);
+
+ /* Updated selected Phonebook type */
+ tcore_phonebook_set_selected_type(co, PB_TYPE_USIM);
+
+ /*
+ * Cache 'used_index' for PB_TYPE_USIM if valid used_index is NOT TRUE.
+ */
+ private_info = tcore_object_ref_user_data(co);
+ if (private_info->used_index_usim_valid == FALSE) {
+ /* Cache 'used' index list */
+ __phonebook_get_used_index(co, PB_TYPE_USIM, total);
+ }
+ }
+
+EXIT:
+ /* Send Response */
+ tcore_user_request_send_response(ur,
+ TRESP_PHONEBOOK_GETUSIMINFO,
+ sizeof(struct tresp_phonebook_get_usim_info), &res_get_usim_info);
+ dbg("Exit");
+}
+
+static void on_resp_read_record(TcorePending *p,
+ int data_len, const void *data, void *user_data)
+{
+ const struct treq_phonebook_read_record *req_data = NULL;
+ struct tresp_phonebook_read_record resp_read_record;
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+ if (!ur) {
+ dbg("error - current ur is NULL");
+ return;
+ }
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ memset(&resp_read_record, 0x00, sizeof(struct tresp_phonebook_read_record));
+
+ resp_read_record.result = PB_FAIL;
+ resp_read_record.phonebook_type = req_data->phonebook_type;
+
+ if (resp && resp->success > VAL_ZERO) {
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ GSList *list = NULL;
+
+ GSList *tokens = NULL;
+ const char *line;
+
+ int num_plan = VAL_ZERO;
+ char *number = NULL, *name = NULL, *additional_number = NULL;
+ char *sne = NULL, *email = NULL;
+ char *temp = NULL;
+
+ dbg("RESPONSE OK");
+
+ if (resp->lines == NULL) {
+ err("invalid message");
+ goto EXIT;
+ }
+
+ /*
+ * +CPBR: <index>,<number>,<type>,<text>[,<hidden>][,<group>]
+ * [,<adnumber>][,<adtype>][,<secondtext>][,<email>]]
+ */
+ line = (const char*)resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < VAL_ONE) {
+ err("invalid message");
+ goto EXIT;
+ }
+
+ /* Fetch <index> */
+ temp = g_slist_nth_data(tokens, VAL_ZERO);
+ if (temp == NULL) {
+ err("No index");
+ goto EXIT;
+ }
+ resp_read_record.index = atoi(temp);
+
+ /* Fetch <number> */
+ temp = g_slist_nth_data(tokens, VAL_ONE);
+ if (temp == NULL) {
+ err("No number");
+ goto EXIT;
+ }
+ number = tcore_at_tok_extract(temp);
+ g_strlcpy((char *)resp_read_record.number,
+ (const gchar *)number, PHONEBOOK_NUMBER_BYTE_MAX+1);
+ g_free(number);
+
+ /* Fetch <type> */
+ temp = g_slist_nth_data(tokens, VAL_TWO);
+ if (temp == NULL) {
+ err("No type");
+ goto EXIT;
+ }
+ num_plan = atoi(temp);
+ resp_read_record.ton = __phonebook_find_num_plan(num_plan);
+
+ /* Fetch <text> */
+ temp = g_slist_nth_data(tokens, VAL_THREE);
+ if (temp == NULL) {
+ err("No text");
+ goto EXIT;
+ }
+ name = tcore_at_tok_extract(temp);
+ if (name) {
+ g_strlcpy((char *)resp_read_record.name,
+ (const gchar *)name, PHONEBOOK_NAME_BYTE_MAX+1);
+ resp_read_record.name_len = strlen((const char*)resp_read_record.name);
+ resp_read_record.dcs = PB_TEXT_ASCII;
+ g_free(name);
+ }
+
+ /* All 'mandatory' fields are extracted */
+ resp_read_record.result = PB_SUCCESS;
+
+ /* Updated selected Phonebook type */
+ tcore_phonebook_set_selected_type(co, req_data->phonebook_type);
+
+ /* Get used_index list by req_type */
+ if (__phonebook_get_index_list_by_type(co,
+ req_data->phonebook_type, &list) == TRUE) {
+ while (list) {
+ if ((guint)list->data == resp_read_record.index) {
+ if ((list = g_slist_next(list)) != NULL) {
+ /* If exist, set next_index */
+ resp_read_record.next_index = (guint)list->data;
+ dbg("next_index is [%u]", resp_read_record.next_index);
+ } else {
+ /* read_record.index is the end of used_index */
+ resp_read_record.next_index = 0;
+ dbg("End of used_index");
+ }
+ break;
+ }
+ list = g_slist_next(list);
+ }
+ } else {
+ /* No PrivateInfo */
+ resp_read_record.next_index = 0;
+ }
+
+ /* Fetch <hidden> */
+ temp = g_slist_nth_data(tokens, VAL_FOUR);
+ if (temp) {
+ dbg("Phonebook entry is hidden");
+ }
+
+ /* Fetch <adnumber> */
+ temp = g_slist_nth_data(tokens, VAL_SIX);
+ additional_number = tcore_at_tok_extract(temp);
+ if (additional_number) {
+ g_strlcpy((char *)resp_read_record.anr1,
+ (const gchar *)additional_number, PHONEBOOK_NUMBER_BYTE_MAX+1);
+ g_free(additional_number);
+ }
+
+ /* Fetch <adtype> */
+ temp = g_slist_nth_data(tokens, VAL_SEVEN);
+ name = tcore_at_tok_extract(temp);
+ if (temp) {
+ num_plan = atoi(temp);
+ resp_read_record.anr1_ton = __phonebook_find_num_plan(num_plan);
+ }
+
+ /* Fetch <secondtext> */
+ temp = g_slist_nth_data(tokens, VAL_EIGHT);
+ if (temp == NULL) {
+ err("No text");
+ goto EXIT;
+ }
+ sne = tcore_at_tok_extract(temp);
+ if (sne) {
+ g_strlcpy((char *)resp_read_record.sne,
+ (const gchar *)sne, PHONEBOOK_NAME_BYTE_MAX+1);
+ resp_read_record.sne_len = strlen((const char*)resp_read_record.sne);
+ resp_read_record.sne_dcs = PB_TEXT_ASCII;
+ g_free(sne);
+ }
+
+ /* Fetch <email> */
+ temp = g_slist_nth_data(tokens, VAL_NINE);
+ if (temp == NULL) {
+ err("No text");
+ goto EXIT;
+ }
+ email = tcore_at_tok_extract(temp);
+ if (email) {
+ g_strlcpy((char *)resp_read_record.email1,
+ (const gchar *)email, PHONEBOOK_EMAIL_BYTE_MAX+1);
+ resp_read_record.email1_len = strlen((const char*)resp_read_record.email1);
+ g_free(email);
+ }
+
+EXIT:
+ /* Free resources */
+ tcore_at_tok_free(tokens);
+ }
+ else {
+ dbg("RESPONSE NOK");
+ }
+
+ /* Send Response */
+ tcore_user_request_send_response(ur,
+ TRESP_PHONEBOOK_READRECORD,
+ sizeof(struct tresp_phonebook_read_record), &resp_read_record);
+
+ dbg("Exit");
+}
+
+static void on_resp_update_record(TcorePending *p,
+ int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ struct tresp_phonebook_update_record resp_update_record;
+
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+
+ if (resp && resp->success > VAL_ZERO) {
+ const struct treq_phonebook_update_record *req_data = NULL;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+
+ dbg("RESPONSE OK");
+
+ resp_update_record.result = PB_SUCCESS;
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ /* Updated selected Phonebook type */
+ tcore_phonebook_set_selected_type(co, req_data->phonebook_type);
+
+ /*
+ * Need to update the corresponding index list.
+ *
+ * in case 'not available' (ADD operation) - ADD index
+ * in case 'available' (UPDATE operation) - NO change
+ */
+ __phonebook_update_index_list_by_type(co,
+ req_data->phonebook_type, req_data->index);
+ }
+ else {
+ dbg("RESPONSE NOK");
+ resp_update_record.result = PB_FAIL;
+ }
+
+ if (ur) {
+ /* Send Response */
+ tcore_user_request_send_response(ur,
+ TRESP_PHONEBOOK_UPDATERECORD,
+ sizeof(struct tresp_phonebook_update_record), &resp_update_record);
+ }
+ else {
+ err("ur is NULL");
+ }
+
+ dbg("Exit");
+}
+
+static void on_resp_delete_record(TcorePending *p,
+ int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ struct tresp_phonebook_delete_record resp_delete_record;
+
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+
+ if (resp && resp->success > VAL_ZERO) {
+ const struct treq_phonebook_delete_record *req_data = NULL;
+ CoreObject *co = tcore_pending_ref_core_object(p);
+ GSList *list = NULL;
+
+ dbg("RESPONSE OK");
+
+ resp_delete_record.result = PB_SUCCESS;
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ /* Updated selected Phonebook type */
+ tcore_phonebook_set_selected_type(co, req_data->phonebook_type);
+
+ /* Get used_index list by req_type */
+ if (__phonebook_get_index_list_by_type(co,
+ req_data->phonebook_type, &list) != TRUE) {
+ err("used_index list is NOT valid");
+ }
+ else {
+ const int del_index = (const int)req_data->index;
+ list = g_slist_remove(list, (gconstpointer)del_index);
+ dbg("Remove index: [%u] list: [0x%x]", req_data->index, list);
+ }
+ }
+ else {
+ dbg("RESPONSE NOK");
+ resp_delete_record.result = PB_FAIL;
+ }
+
+ if (ur) {
+ tcore_user_request_send_response(ur,
+ TRESP_PHONEBOOK_DELETERECORD,
+ sizeof(struct tresp_phonebook_delete_record), &resp_delete_record);
+ }
+ else {
+ err("ur is NULL");
+ }
+
+ dbg("Exit");
+}
+
+/******************************************************************************
+ * Phonebook Request functions
+ *****************************************************************************/
+/*
+ * Operation - get_count
+ *
+ * Request -
+ * AT-Command: AT+CPBS?
+ *
+ * Response -
+ * Success: (Single line)
+ * +CPBS: <storage>[,<used>][,total]
+ * OK
+ * where,
+ * <storage> Phonebook storage type
+ * <used> Number of records 'used'
+ * <total> 'total' number of records available
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TReturn imc_get_count(CoreObject *co, UserRequest *ur)
+{
+ struct treq_phonebook_get_count *req_data = NULL;
+ gchar *at_cmd;
+ gchar *set_pb_cmd;
+
+ TReturn ret = TCORE_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ req_data = (struct treq_phonebook_get_count *)tcore_user_request_ref_data(ur, NULL);
+
+ /* Check whether pb_type is supported or not, and Select pb_type */
+ if (__phonebook_check_and_select_type(co,
+ req_data->phonebook_type, &set_pb_cmd) != TRUE) {
+ warn("Requested phonebok type '%d' is NOT supported",
+ req_data->phonebook_type);
+ return ret;
+ }
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s+CPBS?", set_pb_cmd);
+
+ /* Send Request to Modem */
+ ret = tcore_prepare_and_send_at_request(co,
+ at_cmd, "+CPBS",
+ TCORE_AT_SINGLELINE,
+ ur,
+ on_resp_get_count, NULL,
+ NULL, NULL,
+ 0, NULL, NULL);
+
+ /* Free resources */
+ g_free(at_cmd);
+ g_free(set_pb_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - get_info
+ *
+ * Request -
+ * AT-Command: AT+CPBS?;+CPBF=?
+ *
+ * Response -
+ * Success: (Multi line)
+ * +CPBS: <storage>[,<used>][,total]
+ * +CPBF: [<nlength>],[<tlength>],[<glength>],[<slength>],[<elength>]
+ * OK
+ * where,
+ * <storage> Phonebook storage type
+ * <used> Number of records 'used'
+ * <total> 'total' number of records available
+ * <nlength> Maximum length of field <number>
+ * <tlength> Maximum length of field <text>
+ * <glength> Maximum length of field <group>
+ * <slength> Maximum length of field <secondtext>
+ * <elength> Maximum length of field <email>
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TReturn imc_get_info(CoreObject *co, UserRequest *ur)
+{
+ struct treq_phonebook_get_info *req_data = NULL;
+ gchar *at_cmd;
+ gchar *set_pb_cmd;
+
+ TReturn ret = TCORE_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ req_data = (struct treq_phonebook_get_info *)tcore_user_request_ref_data(ur, NULL);
+
+ /* Check whether pb_type is supported or not, and Select pb_type */
+ if (__phonebook_check_and_select_type(co,
+ req_data->phonebook_type, &set_pb_cmd) != TRUE) {
+ warn("Requested phonebok type '%d' is NOT supported",
+ req_data->phonebook_type);
+ return ret;
+ }
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s+CPBS?;+CPBF=?", set_pb_cmd);
+
+ /* Send Request to Modem */
+ ret = tcore_prepare_and_send_at_request(co,
+ at_cmd, "+CPB",
+ TCORE_AT_MULTILINE,
+ ur,
+ on_resp_get_info, NULL,
+ NULL, NULL,
+ 0, NULL, NULL);
+
+ /* Free resources */
+ g_free(at_cmd);
+ g_free(set_pb_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - get_usim_info
+ *
+ * Request -
+ * AT-Command: AT+CPBS?;+CPBF=?
+ *
+ * Response -
+ * Success: (Multi line)
+ * +CPBS: <storage>[,<used>][,total]
+ * +CPBF: [<nlength>],[<tlength>],[<glength>],[<slength>],[<elength>]
+ * OK
+ * where,
+ * <storage> Phonebook storage type
+ * <used> Number of records 'used'
+ * <total> 'total' number of records available
+ * <nlength> Maximum length of field <number>
+ * <tlength> Maximum length of field <text>
+ * <glength> Maximum length of field <group>
+ * <slength> Maximum length of field <secondtext>
+ * <elength> Maximum length of field <email>
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TReturn imc_get_usim_info(CoreObject *co, UserRequest *ur)
+{
+ gchar *at_cmd;
+ gchar *set_pb_cmd;
+
+ TReturn ret = TCORE_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ /* Check whether pb_type is supported or not, and Select pb_type */
+ if (__phonebook_check_and_select_type(co, PB_TYPE_USIM, &set_pb_cmd) != TRUE) {
+ warn("Requested phonebok type '%d' is NOT supported", PB_TYPE_USIM);
+ return ret;
+ }
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s+CPBS?;+CPBF=?", set_pb_cmd);
+
+ /* Send Request to Modem */
+ ret = tcore_prepare_and_send_at_request(co,
+ at_cmd, "+CPB",
+ TCORE_AT_MULTILINE,
+ ur,
+ on_resp_get_usim_info, NULL,
+ NULL, NULL,
+ 0, NULL, NULL);
+
+ /* Free resources */
+ g_free(at_cmd);
+ g_free(set_pb_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - read_record
+ *
+ * Request -
+ * AT-Command: AT+CPBR=<index>
+ * where,
+ * <index>
+ * 1 Integer type values in range of location numbers of phonebook memory
+ * ...
+ *
+ * Response -
+ * Success: (Single line);
+ * +CPBR: <index>,<number>,<type>,<text>[,<hidden>][,<group>]
+ * [,<adnumber>][,<adtype>][,<secondtext>][,<email>]]
+ * OK
+ * where,
+ * <number> String type phone number of format <type>
+ * <type> Type of address octet in integer format
+ * <text> String type field of maximum length <tlength>
+ * <hidden> Indicates if the entry is hidden or not – only available,
+ * if a UICC with an active USIM application is present
+ * 0 Phonebook entry not hidden
+ * 1 Phonebook entry hidden
+ * <group> String type field of maximum length <glength>
+ * <adnumber> String type phone number of format <adtype>
+ * <adtype> Type of address octet in integer format
+ * <secondtext> String type field of maximum length <slength>
+ * <email> String type field of maximum length <elength>
+ *
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TReturn imc_read_record(CoreObject *co, UserRequest *ur)
+{
+ const struct treq_phonebook_read_record *req_data = NULL;
+ gchar *at_cmd;
+ gchar *set_pb_cmd;
+ guint used_index = 0;
+
+ TReturn ret = TCORE_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ /* Check whether pb_type is supported or not, and Select pb_type */
+ if (__phonebook_check_and_select_type(co,
+ req_data->phonebook_type, &set_pb_cmd) != TRUE) {
+ warn("Requested phonebok type '%d' is NOT supported",
+ req_data->phonebook_type);
+ return ret;
+ }
+
+ /* Check whether index is used or not */
+ __phonebook_check_used_index(co,
+ req_data->phonebook_type, req_data->index, &used_index);
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s+CPBR=%u", set_pb_cmd, used_index);
+
+ /* Send Request to Modem */
+ ret = tcore_prepare_and_send_at_request(co,
+ at_cmd, "+CPBR",
+ TCORE_AT_SINGLELINE,
+ ur,
+ on_resp_read_record, NULL,
+ NULL, NULL,
+ 0, NULL, NULL);
+
+ /* Free resources */
+ g_free(at_cmd);
+ g_free(set_pb_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - update_record
+ *
+ * Request -
+ * AT-Command: AT+CPBW=[<index>][,<number>[,<type>[,<text>[,<group>[,<adnumber>
+ * [,<adtype>[,<secondtext>[,<email>[,<hidden>]]]]]]]]]
+ * where,
+ * ... same read_record Operation
+ *
+ * Response -
+ * Success: (No Result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TReturn imc_update_record(CoreObject *co, UserRequest *ur)
+{
+ const struct treq_phonebook_update_record *req_data = NULL;
+ gchar *at_cmd;
+ gchar *set_pb_cmd;
+
+ TReturn ret = TCORE_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ /* Check whether pb_type is supported or not, and Select pb_type */
+ if (__phonebook_check_and_select_type(co,
+ req_data->phonebook_type, &set_pb_cmd) != TRUE) {
+ warn("Requested phonebok type '%d' is NOT supported",
+ req_data->phonebook_type);
+ return ret;
+ }
+
+ /* Set AT-Command according pb_type */
+ if (req_data->phonebook_type == PB_TYPE_USIM) {
+ at_cmd = g_strdup_printf("%s+CPBW=%u,\"%s\",%d,\"%s\",,\"%s\",,\"%s\",\"%s\"",
+ set_pb_cmd, req_data->index,
+ req_data->number,
+ ((PB_TON_INTERNATIONAL == req_data->ton) ? IMC_TON_INTERNATIONAL: IMC_TON_UNKNOWN),
+ req_data->name, req_data->anr1,
+ req_data->sne, req_data->email1);
+ } else {
+ at_cmd = g_strdup_printf("%s+CPBW=%u,\"%s\",,\"%s\"",
+ set_pb_cmd, req_data->index,
+ req_data->number, req_data->name);
+ }
+
+ /* Send Request to Modem */
+ ret = tcore_prepare_and_send_at_request(co,
+ at_cmd, NULL,
+ TCORE_AT_NO_RESULT,
+ ur,
+ on_resp_update_record, NULL,
+ NULL, NULL,
+ 0, NULL, NULL);
+
+ /* Free resources */
+ g_free(at_cmd);
+ g_free(set_pb_cmd);
+
+ return ret;
+}
+
+/*
+ * Operation - delete_record
+ *
+ * Request -
+ * AT-Command: AT+CPBW=<index>
+ * where,
+ * <index>
+ * 1 Integer type values in range of location numbers of phonebook memory
+ * ...
+ *
+ * Response -
+ * Success: (No Result)
+ * OK
+ * Failure:
+ * +CME ERROR: <error>
+ */
+static TReturn imc_delete_record(CoreObject *co, UserRequest *ur)
+{
+ const struct treq_phonebook_delete_record *req_data;
+ gchar *at_cmd;
+ gchar *set_pb_cmd;
+
+ TReturn ret = TCORE_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ /* Check whether pb_type is supported or not, and Select pb_type */
+ if (__phonebook_check_and_select_type(co,
+ req_data->phonebook_type, &set_pb_cmd) != TRUE) {
+ warn("Requested phonebok type '%d' is NOT supported",
+ req_data->phonebook_type);
+ return ret;
+ }
+
+ /* AT-Command */
+ at_cmd = g_strdup_printf("%s+CPBW=%u", set_pb_cmd, req_data->index);
+
+ /* Send Request to Modem */
+ ret = tcore_prepare_and_send_at_request(co,
+ at_cmd, NULL,
+ TCORE_AT_NO_RESULT,
+ ur,
+ on_resp_delete_record, NULL,
+ NULL, NULL,
+ 0, NULL, NULL);
+
+ /* Free resources */
+ g_free(at_cmd);
+ g_free(set_pb_cmd);
+
+ return ret;
+}
+
+/******************************************************************************
+ * Phonebook Notification function(s)
+ *****************************************************************************/
+static gboolean on_noti_phonebook_status(CoreObject *co_phonebook,
+ const void *event_info, void *user_data)
+{
+ dbg("Received [+PBREADY]");
+
+ /*
+ * Get supported list of Phonebook types
+ */
+ __phonebook_get_support_list(co_phonebook);
+
+ return TRUE;
+}
+
+/* Phonebook operations */
+static struct tcore_phonebook_operations phonebook_ops = {
+ .get_count = imc_get_count,
+ .get_info = imc_get_info,
+ .get_usim_info = imc_get_usim_info,
+ .read_record = imc_read_record,
+ .update_record = imc_update_record,
+ .delete_record = imc_delete_record,
+};
+
+gboolean imc_phonebook_init(TcorePlugin *cp, CoreObject *co_phonebook)
+{
+ PrivateInfo *private_info;
+
+ dbg("Entry");
+
+ /* Set operations */
+ tcore_phonebook_set_ops(co_phonebook, &phonebook_ops);
+
+ /* Set PrivateInfo */
+ private_info = g_malloc0(sizeof(PrivateInfo));
+ tcore_object_link_user_data(co_phonebook, private_info);
+
+ /* Add Callbacks */
+ tcore_object_add_callback(co_phonebook,
+ "+PBREADY",
+ on_noti_phonebook_status, co_phonebook);
+
+ dbg("Exit");
+
+ return TRUE;
+}
+
+void imc_phonebook_exit(TcorePlugin *cp, CoreObject *co_phonebook)
+{
+ PrivateInfo *private_info;
+
+ private_info = tcore_object_ref_user_data(co_phonebook);
+ g_assert(private_info != NULL);
+
+ /* Free PrivateInfo */
+ g_slist_free_full(private_info->used_index_fdn, g_free);
+ g_slist_free_full(private_info->used_index_adn, g_free);
+ g_slist_free_full(private_info->used_index_sdn, g_free);
+ g_slist_free_full(private_info->used_index_usim, g_free);
+ g_free(private_info);
+
+ /* Remove Callbacks */
+ tcore_object_del_callback(co_phonebook,
+ "+PBREADY", on_noti_phonebook_status);
+
+ dbg("Exit");
+}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Arun Shukla <arun.shukla@samsung.com>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include <tcore.h>
+#include <hal.h>
+#include <core_object.h>
+#include <plugin.h>
+#include <queue.h>
+#include <co_ps.h>
+#include <co_context.h>
+#include <storage.h>
+#include <server.h>
+#include <at.h>
+#include <util.h>
+#include <type/ps.h>
+
+#include "imc_common.h"
+#include "imc_ps.h"
+
+/*Invalid Session ID*/
+#define PS_INVALID_CID 999 /*Need to check */
+
+/*Maximum String length Of the Command*/
+#define MAX_AT_CMD_STR_LEN 150
+
+/*Command for PDP activation and Deactivation*/
+#define AT_PDP_ACTIVATE 1
+#define AT_PDP_DEACTIVATE 0
+
+#define AT_XDNS_ENABLE 1
+#define AT_XDNS_DISABLE 0
+#define AT_SESSION_DOWN 0
+
+enum ps_data_call_status {
+ PS_DATA_CALL_CTX_DEFINED,
+ PS_DATA_CALL_CONNECTED,
+ PS_DATA_CALL_NOT_CONNECTED = 3,
+};
+
+struct ps_user_data {
+ CoreObject *ps_context;
+ struct tnoti_ps_pdp_ipconfiguration data_call_conf;
+};
+
+static void __convert_ipv4_atoi(unsigned char *ip4, const char *str)
+{
+ char *token = NULL;
+ char *temp = NULL;
+ char *ptr = NULL;
+ int local_index = 0;
+
+ temp = g_strdup(str);
+ token = strtok_r(temp, ".", &ptr);
+ while (token != NULL) {
+ ip4[local_index++] = atoi(token);
+ msg(" [%d]", ip4[local_index-1]);
+ token = strtok_r(NULL, ".", &ptr);
+ }
+ g_free(temp);
+}
+static void _unable_to_get_pending(CoreObject *co_ps, CoreObject *ps_context)
+{
+ struct tnoti_ps_call_status data_resp = {0};
+ dbg("Entry");
+
+ data_resp.context_id = tcore_context_get_id(ps_context);
+ data_resp.state = PS_DATA_CALL_NOT_CONNECTED;
+ dbg("Sending Call Status Notification - Context ID: [%d] Context State: [NOT CONNECTED]",
+ data_resp.context_id);
+
+ /* Send CALL Status Notification */
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)),
+ co_ps, TNOTI_PS_CALL_STATUS, sizeof(data_resp), &data_resp);
+
+ /* Set PS State to Deactivated */
+ (void) tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
+ dbg("Exit");
+}
+
+/*
+ * Notification - GPRS event reporting
+ *
+ * Notification -
+ * +CGEV: NW DEACT <PDP_type>, <PDP_addr>, [<cid>]
+ * The network has forced a context deactivation. The <cid> that was used to activate the context is provided if
+ * known to the MT
+ */
+static gboolean on_cgev_notification(CoreObject *co_ps,
+ const void *data, void *user_data)
+{
+ GSList *tokens = NULL;
+ GSList *lines = (GSList *)data;
+ const gchar *line = lines->data;
+ gchar *noti_data;
+ guint context_id;
+ TcoreHal *hal;
+ struct tnoti_ps_call_status noti = {0};
+ Server *server;
+
+ dbg("Entry");
+
+ if (line == NULL) {
+ err("Ignore, No data present in notification received for CGEV");
+ return TRUE;
+ }
+
+ dbg("Lines->data :%s", line);
+
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) != 3) {
+ err("Ignore, sufficient data not present for deactivation");
+ goto out;
+
+ }
+ noti_data = g_slist_nth_data(tokens, 0);
+
+ /* Only care about NW context deactivation */
+ if (g_str_has_prefix(noti_data, "NW DEACT") == FALSE) {
+ err("Ignore, only care about nw deactivation");
+ goto out;
+ }
+
+ noti_data = g_slist_nth_data(tokens, 1);
+ dbg("PDP Address: %s", noti_data);
+
+ noti_data = g_slist_nth_data(tokens, 2);
+ /*TODO: Need to handle context id with multiple PDP*/
+ if (noti_data != NULL)
+ context_id = (guint)atoi(noti_data);
+ else{
+ err("No Context ID!");
+ goto out;
+ }
+
+ dbg("Context %d deactivated", context_id);
+
+ /* Set State - CONNECTED */
+ noti.context_id = context_id;
+ noti.state = PS_DATA_CALL_NOT_CONNECTED;
+ dbg("Sending Call Status Notification - Context ID: [%d] Context State: [ NOT CONNECTED]", noti.context_id);
+
+ /* Send Notification */
+ server = tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps));
+ tcore_server_send_notification(server, co_ps,
+ TNOTI_PS_CALL_STATUS,
+ sizeof(struct tnoti_ps_call_status),
+ ¬i);
+
+ hal = tcore_object_get_hal(co_ps);
+ if (tcore_hal_setup_netif(hal, co_ps, NULL, NULL, context_id,
+ FALSE) != TCORE_RETURN_SUCCESS)
+ err("Failed to disable network interface");
+
+out:
+
+ tcore_at_tok_free(tokens);
+ return TRUE;
+}
+
+static gboolean on_event_dun_call_notification(CoreObject *o, const void *data, void *user_data)
+{
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ int value = 0;
+ GSList *lines = NULL;
+ dbg("Entry");
+
+ lines = (GSList *) data;
+ if (g_slist_length(lines) != 1) {
+ dbg("Unsolicited message BUT multiple lines");
+ goto OUT;
+ }
+
+ line = (char *) (lines->data);
+ tokens = tcore_at_tok_new(line);
+ value = atoi(g_slist_nth_data(tokens, 0));
+
+ /*
+ * <status> may be
+ * 0: DUN Activation in progress
+ * 1: DUN Deactivation in progress
+ * 2: DUN Activated
+ * 3: DUN Deactivated
+ */
+ switch (value) {
+ case 0: /* FALL THROUGH */
+ case 1:
+ {
+ break;
+ }
+
+ case 2:
+ {
+ /* TODO:- Fill Data structure: 'data' */
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
+ TNOTI_PS_EXTERNAL_CALL, sizeof(struct tnoti_ps_external_call), &data);
+ }
+ break;
+
+ case 3:
+ {
+ /* TODO:- Fill Data structure: 'data' */
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
+ TNOTI_PS_EXTERNAL_CALL, sizeof(struct tnoti_ps_external_call), &data);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+OUT:
+ /* Free tokens */
+ tcore_at_tok_free(tokens);
+
+ return TRUE;
+}
+static void on_response_undefine_context_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ CoreObject *co_ps = NULL;
+ const TcoreATResponse *resp = data;
+ CoreObject *ps_context = user_data;
+ dbg("Entry");
+
+ co_ps = tcore_pending_ref_core_object(p);
+ if (resp->success) {
+ dbg("Response Ok");
+ goto exit;
+ }
+ dbg("Response NOk");
+
+exit:
+ _unable_to_get_pending(co_ps, ps_context);
+ return;
+}
+
+static void send_undefine_context_cmd(CoreObject *co_ps, CoreObject *ps_context)
+{
+ TcoreHal *hal = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ int cid = 0;
+
+ dbg("Entry");
+
+ /* FIXME: Before MUX setup, use PHY HAL directly. */
+ hal = tcore_object_get_hal(co_ps);
+
+ /*Getting Context ID from Core Object*/
+ cid = tcore_context_get_id(ps_context);
+
+ cmd_str = g_strdup_printf("AT+CGDCONT=%d", cid);
+
+ dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
+
+ pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
+ on_response_undefine_context_cmd, ps_context);
+ if (NULL == pending) {
+ err("Unable to get the create a AT request ");
+ goto error;
+ }
+ tcore_hal_send_request(hal, pending);
+ g_free(cmd_str);
+ dbg("Exit: Successfully");
+ return;
+error:
+ {
+ dbg("Exit: With error");
+ _unable_to_get_pending(co_ps, ps_context);
+ g_free(cmd_str);
+ return;
+ }
+}
+
+static void on_setup_pdp(CoreObject *co_ps, int result,
+ const char *netif_name, void *user_data)
+{
+ struct ps_user_data *ps_data = user_data;
+ struct tnoti_ps_call_status data_status = {0};
+ Server *server;
+
+ dbg("Entry");
+
+ if (!ps_data ) {
+ err("PS_data unavailable. Exiting.");
+ return;
+ }
+
+ if (result < 0) {
+ /* Deactivate PDP context */
+ tcore_ps_deactivate_context(co_ps, ps_data->ps_context, NULL);
+ return;
+ }
+
+ dbg("Device name: [%s]", netif_name);
+ if (tcore_util_netif_up(netif_name) != TCORE_RETURN_SUCCESS) {
+ err("util_netif_up() failed. errno=%d", errno);
+ /* Deactivate PDP context */
+ tcore_ps_deactivate_context(co_ps, ps_data->ps_context, NULL);
+ return;
+ } else {
+ dbg("tcore_util_netif_up() PASS...");
+ }
+
+ /* Set Device name */
+ //tcore_context_set_ipv4_devname(ps_context, netif_name);
+ g_strlcpy(ps_data->data_call_conf.devname, netif_name, sizeof(ps_data->data_call_conf.devname));
+
+ ps_data->data_call_conf.context_id = (int)tcore_context_get_id(ps_data->ps_context);
+
+ dbg("Sending IP Configuration Notification - Context ID: [%d] Context State: [CONNECTED]", ps_data->data_call_conf.context_id);
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)),
+ co_ps,
+ TNOTI_PS_PDP_IPCONFIGURATION,
+ sizeof(struct tnoti_ps_pdp_ipconfiguration),
+ &ps_data->data_call_conf);
+
+ /* Set State - CONNECTED */
+ data_status.context_id = tcore_context_get_id(ps_data->ps_context);
+ data_status.state = PS_DATA_CALL_CONNECTED;
+ dbg("Sending Call Status Notification - Context ID: [%d] Context State: [CONNECTED]", data_status.context_id);
+
+ /* Send Notification */
+ server = tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps));
+ tcore_server_send_notification(server, co_ps,
+ TNOTI_PS_CALL_STATUS,
+ sizeof(struct tnoti_ps_call_status),
+ &data_status);
+
+ g_free(ps_data);
+ dbg("Exit");
+}
+
+static void on_response_get_dns_cmnd(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ GSList *tokens = NULL;
+ GSList *pRespData;
+ const char *line = NULL;
+ char *dns_prim = NULL;
+ char *dns_sec = NULL;
+ char *token_dns = NULL;
+ int no_pdp_active = 0;
+ struct ps_user_data *ps_data = user_data;
+ const TcoreATResponse *resp = data;
+ CoreObject *co_ps = tcore_pending_ref_core_object(p);
+ int cid = tcore_context_get_id(ps_data->ps_context);
+ TcoreHal *h = tcore_object_get_hal(co_ps);
+
+ dbg("Entry");
+
+ if (resp->final_response) {
+ dbg("Response OK");
+ if (resp->lines) {
+ dbg("DNS data present in the Response");
+ pRespData = (GSList *) resp->lines;
+ no_pdp_active = g_slist_length(pRespData);
+ dbg("Total Number of Active PS Context: [%d]", no_pdp_active);
+ if (0 == no_pdp_active) {
+ goto exit_fail;
+ }
+
+ while (pRespData) {
+ line = (const char *) pRespData->data;
+ dbg("Received Data: [%s]", line);
+ tokens = tcore_at_tok_new(line);
+
+ /* Check if Context ID is matching */
+ if (cid == atoi(g_slist_nth_data(tokens, 0))) {
+ dbg("Found the DNS details for the Current Context - Context ID: [%d]", cid);
+ break;
+ }
+
+ /* Free tokens */
+ tcore_at_tok_free(tokens);
+ tokens = NULL;
+
+ /* Move to next line */
+ pRespData = pRespData->next;
+ }
+
+ /* Read primary DNS */
+ {
+ token_dns = g_slist_nth_data(tokens, 1);
+
+ /* Strip off starting " and ending " from this token to read actual PDP address */
+ dns_prim = util_removeQuotes((void *)token_dns);
+ dbg("Primary DNS: [%s]", dns_prim);
+ }
+
+ /* Read Secondary DNS */
+ {
+ token_dns = g_slist_nth_data(tokens, 2);
+
+ /* Strip off starting " and ending " from this token to read actual PDP address */
+ dns_sec = util_removeQuotes((void *)token_dns);
+ dbg("Secondary DNS: [%s]", dns_sec);
+ }
+
+ if ((g_strcmp0("0.0.0.0", dns_prim) == 0)
+ && (g_strcmp0("0.0.0.0", dns_sec) == 0)) {
+ dbg("Invalid DNS");
+
+ g_free(dns_prim);
+ g_free(dns_sec);
+
+ tcore_at_tok_free(tokens);
+ tokens = NULL;
+
+ goto exit_fail;
+ }
+
+ __convert_ipv4_atoi(ps_data->data_call_conf.primary_dns, dns_prim);
+ __convert_ipv4_atoi(ps_data->data_call_conf.secondary_dns, dns_sec);
+
+ util_hex_dump(" ", 4, ps_data->data_call_conf.primary_dns);
+ util_hex_dump(" ", 4, ps_data->data_call_conf.secondary_dns);
+
+ /* Set DNS Address */
+ tcore_context_set_dns1(ps_data->ps_context, dns_prim);
+ tcore_context_set_dns1(ps_data->ps_context, dns_sec);
+
+ g_free(dns_prim);
+ g_free(dns_sec);
+
+ tcore_at_tok_free(tokens);
+ tokens = NULL;
+ goto exit_success;
+ } else {
+ dbg("No data present in the Response");
+ }
+ }
+ dbg("Response NOK");
+
+exit_fail:
+ dbg("Adding default DNS");
+
+ __convert_ipv4_atoi(ps_data->data_call_conf.primary_dns, "8.8.8.8");
+ __convert_ipv4_atoi(ps_data->data_call_conf.secondary_dns, "8.8.4.4");
+
+ tcore_context_set_dns1(ps_data->ps_context, (const char *)ps_data->data_call_conf.primary_dns);
+ tcore_context_set_dns1(ps_data->ps_context, (const char *)ps_data->data_call_conf.secondary_dns);
+
+exit_success:
+ /* Mount network interface */
+ if (tcore_hal_setup_netif(h, co_ps, on_setup_pdp, (void *)ps_data, cid, TRUE)
+ != TCORE_RETURN_SUCCESS) {
+ err("Setup network interface failed");
+ return;
+ }
+
+ dbg("EXIT : Without error");
+}
+
+static TReturn send_get_dns_cmd(CoreObject *co_ps, struct ps_user_data *ps_data)
+{
+ TcoreHal *hal = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+
+ dbg("Entry");
+ hal = tcore_object_get_hal(co_ps);
+
+ cmd_str = g_strdup("AT+XDNS?");
+ dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
+
+ pending = tcore_at_pending_new(co_ps, cmd_str, "+XDNS", TCORE_AT_MULTILINE,
+ on_response_get_dns_cmnd, (void *)ps_data);
+ if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
+ g_free(cmd_str);
+ return TCORE_RETURN_SUCCESS;
+ }
+ _unable_to_get_pending(co_ps, ps_data->ps_context);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+}
+
+static void on_response_get_pdp_address(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ CoreObject *co_ps = tcore_pending_ref_core_object(p);
+ GSList *tokens = NULL;
+ const char *line;
+ char *token_pdp_address = NULL;
+ char *token_address = NULL;
+ CoreObject *ps_context = user_data;
+ struct ps_user_data *ps_data = {0, };
+
+ dbg("Enetered");
+
+ if (resp->final_response) {
+ ps_data = g_try_malloc(sizeof (struct ps_user_data));
+ if (ps_data == NULL) {
+ err("Memory allocation failed!!");
+ return;
+ }
+ ps_data->ps_context = ps_context;
+ dbg("RESPONSE OK");
+ if (resp->lines != NULL) {
+ line = (const char *) resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 2) {
+ msg("Invalid message");
+ goto error;
+ }
+ dbg("Received Data: [%s]", line);
+
+ /* CID is already stored in ps_context, skip over & read PDP address */
+ token_address = g_slist_nth_data(tokens, 1);
+ token_pdp_address = util_removeQuotes((void *)token_address);
+ dbg("IP Address: [%s]", token_pdp_address);
+
+ __convert_ipv4_atoi(ps_data->data_call_conf.ip_address, token_pdp_address);
+
+ util_hex_dump(" ", 4, ps_data->data_call_conf.ip_address);
+
+ /* Strip off starting " and ending " from this token to read actual PDP address */
+ /* Set IP Address */
+ (void)tcore_context_set_address(ps_context, (const char *)ps_data->data_call_conf.ip_address);
+
+ g_free(token_pdp_address);
+ }
+
+ /* Get DNS Address */
+ (void) send_get_dns_cmd(co_ps, ps_data);
+ } else {
+ dbg("Response NOK");
+
+ /*without PDP address we will not be able to start packet service*/
+ tcore_ps_deactivate_context(co_ps, ps_context, NULL);
+ }
+error:
+ tcore_at_tok_free(tokens);
+ return;
+}
+
+static TReturn send_get_pdp_address_cmd(CoreObject *co_ps, CoreObject *ps_context)
+{
+ TcoreHal *hal = NULL;
+ TcorePending *pending = NULL;
+ unsigned int cid = PS_INVALID_CID;
+ char *cmd_str = NULL;
+
+ dbg("Entry");
+ hal = tcore_object_get_hal(co_ps);
+
+ cid = tcore_context_get_id(ps_context);
+ cmd_str = g_strdup_printf("AT+CGPADDR=%d", cid);
+
+ dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
+
+ pending = tcore_at_pending_new(co_ps, cmd_str, "+CGPADDR", TCORE_AT_SINGLELINE,
+ on_response_get_pdp_address, ps_context);
+ if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
+ g_free(cmd_str);
+ return TCORE_RETURN_SUCCESS;
+ }
+ _unable_to_get_pending(co_ps, ps_context);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+}
+
+static void on_response_send_pdp_activate_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ CoreObject *co_ps = NULL;
+ const TcoreATResponse *resp = data;
+ CoreObject *ps_context = user_data;
+
+ int cid;
+ cid = tcore_context_get_id(ps_context);
+
+
+ dbg("Entry");
+ if (!p) {
+ goto error;
+ }
+ co_ps = tcore_pending_ref_core_object(p);
+
+ if (resp->success) {
+ dbg("Response OK");
+
+ /* Getting the IP address and DNS from the modem */
+ dbg("Getting IP Address");
+ (void) send_get_pdp_address_cmd(co_ps, ps_context);
+ return;
+ } else {
+ dbg("Unable to activate PDP context - Context ID: [%d]", cid);
+ dbg("Undefining PDP context");
+ (void) tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
+ send_undefine_context_cmd(co_ps, ps_context);
+ return;
+ }
+error:
+ {
+ _unable_to_get_pending(co_ps, ps_context);
+ return;
+ }
+}
+
+static TReturn send_pdp_activate_cmd(CoreObject *co_ps, CoreObject *ps_context)
+{
+ TcoreHal *hal = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ int cid = 0;
+
+ dbg("Entry");
+
+ /* FIXME: Before MUX setup, use PHY HAL directly. */
+ hal = tcore_object_get_hal(co_ps);
+
+ /*Getting Context ID from Core Object*/
+ cid = tcore_context_get_id(ps_context);
+ cmd_str = g_strdup_printf("AT+CGACT=%d,%d", AT_PDP_ACTIVATE, cid);
+
+ dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
+
+ pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
+ on_response_send_pdp_activate_cmd, ps_context);
+ if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
+ g_free(cmd_str);
+ return TCORE_RETURN_SUCCESS;
+ }
+ _unable_to_get_pending(co_ps, ps_context);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+}
+
+static TReturn activate_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
+{
+ dbg("Entry");
+ return send_pdp_activate_cmd(co_ps, ps_context);
+}
+
+static void on_response_send_pdp_deactivate_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ CoreObject *co_ps = NULL;
+ const TcoreATResponse *resp = data;
+ CoreObject *ps_context = user_data;
+ TcoreHal *hal = NULL;
+ unsigned char context_id = 0;
+
+ dbg("Entry");
+ if (resp->success) {
+ dbg("Response Ok");
+ if (!p) {
+ err("Invalid pending data");
+ goto OUT;
+ }
+ co_ps = tcore_pending_ref_core_object(p);
+ hal = tcore_object_get_hal(co_ps);
+ context_id = tcore_context_get_id(ps_context);
+ dbg("Context ID : %d", context_id);
+ goto OUT;
+ } else {
+ /* Since PDP deactivation failed, no need to move to
+ * PS_DATA_CALL_NOT_CONNECTED state
+ */
+ err("Response NOk");
+ return;
+ }
+OUT:
+ _unable_to_get_pending(co_ps, ps_context);
+
+ if (tcore_hal_setup_netif(hal, co_ps, NULL, NULL, context_id, FALSE) != TCORE_RETURN_SUCCESS)
+ err("Failed to disable network interface");
+}
+
+static TReturn send_pdp_deactivate_cmd(CoreObject *co_ps, CoreObject *ps_context)
+{
+ TcoreHal *hal = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ int cid = 0;
+
+ dbg("Entry");
+
+ hal = tcore_object_get_hal(co_ps);
+
+ /*Getting Context ID from Core Object*/
+ cid = tcore_context_get_id(ps_context);
+ cmd_str = g_strdup_printf("AT+CGACT=%d,%u", AT_PDP_DEACTIVATE, cid);
+
+ dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
+
+ pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
+ on_response_send_pdp_deactivate_cmd, ps_context);
+ if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
+ g_free(cmd_str);
+ return TCORE_RETURN_SUCCESS;
+ }
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+}
+
+static TReturn deactivate_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
+{
+ dbg("Entry");
+ return send_pdp_deactivate_cmd(co_ps, ps_context);
+}
+static void on_response_xdns_enable_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ TcoreATResponse *resp = (TcoreATResponse *) data;
+ CoreObject *co_ps = tcore_pending_ref_core_object(p);
+ CoreObject *ps_context = user_data;
+ struct tnoti_ps_call_status noti = {0};
+ int cid = -1;
+
+ dbg("Entry");
+
+ cid = tcore_context_get_id(ps_context);
+
+ if (resp->success) {
+ dbg("Response OK");
+ dbg("DNS address getting is Enabled");
+ noti.context_id = cid;
+ noti.state = PS_DATA_CALL_CTX_DEFINED;
+ } else {
+ dbg("Response NOK");
+ noti.context_id = cid;
+ noti.state = PS_DATA_CALL_NOT_CONNECTED;
+ /*If response to enable the DNS NOK then we will use google DNS for the PDP context*/
+ }
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,
+ TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), ¬i);
+ return;
+}
+
+static TReturn send_xdns_enable_cmd(CoreObject *co_ps, CoreObject *ps_context)
+{
+ TcoreHal *hal = NULL;
+ TcorePending *pending = NULL;
+ int cid = -1;
+ char *cmd_str = NULL;
+
+ dbg("Entry");
+
+ hal = tcore_object_get_hal(co_ps);
+ cid = tcore_context_get_id(ps_context);
+
+ cmd_str = g_strdup_printf("AT+XDNS=%d,%d", cid, AT_XDNS_ENABLE);
+ dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
+
+ pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
+ on_response_xdns_enable_cmd, ps_context);
+ if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
+ g_free(cmd_str);
+ return TCORE_RETURN_SUCCESS;
+ }
+ _unable_to_get_pending(co_ps, ps_context);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+}
+
+static void on_response_define_pdp_context(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ CoreObject *ps_context = (CoreObject *) user_data;
+ CoreObject *co_ps = tcore_pending_ref_core_object(p);
+
+ dbg("Entry");
+ if (resp->success) {
+ dbg("Response OK");
+ send_xdns_enable_cmd(co_ps, ps_context);
+ } else {
+ dbg("response NOK");
+ _unable_to_get_pending(co_ps, ps_context);
+ dbg("Exiting");
+ }
+ return;
+}
+
+static TReturn define_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
+{
+ TcoreHal *hal = NULL;
+ TcorePending *pending = NULL;
+ char *apn = NULL;
+ char *cmd_str = NULL;
+ char *pdp_type_str = NULL;
+ unsigned int cid = PS_INVALID_CID;
+ enum co_context_type pdp_type;
+ enum co_context_d_comp d_comp;
+ enum co_context_h_comp h_comp;
+
+ dbg("Entry");
+
+ cid = tcore_context_get_id(ps_context);
+ pdp_type = tcore_context_get_type(ps_context);
+ d_comp = tcore_context_get_data_compression(ps_context);
+ h_comp = tcore_context_get_header_compression(ps_context);
+ apn = tcore_context_get_apn(ps_context);
+
+ hal = tcore_object_get_hal(co_ps);
+ switch (pdp_type) {
+ case CONTEXT_TYPE_X25:
+ {
+ dbg("CONTEXT_TYPE_X25");
+ pdp_type_str = g_strdup_printf("X.25");
+ }
+ break;
+
+ case CONTEXT_TYPE_IP:
+ {
+ dbg("CONTEXT_TYPE_IP");
+ pdp_type_str = g_strdup_printf("IP");
+ }
+ break;
+
+ case CONTEXT_TYPE_PPP:
+ {
+ dbg("CONTEXT_TYPE_PPP");
+ pdp_type_str = g_strdup_printf("PPP");
+ }
+ break;
+
+ case CONTEXT_TYPE_IPV6:
+ {
+ dbg("CONTEXT_TYPE_IPV6");
+ pdp_type_str = g_strdup_printf("IPV6");
+ break;
+ }
+
+ default:
+ {
+ /*PDP Type not supported supported*/
+ dbg("Unsupported PDP type: %d returning ", pdp_type);
+ g_free(apn);
+ return TCORE_RETURN_FAILURE;
+ }
+ }
+ dbg("Define context for CID: %d", cid);
+ cmd_str = g_strdup_printf("AT+CGDCONT=%d,\"%s\",\"%s\",,%d,%d",
+ cid, pdp_type_str, apn, d_comp, h_comp);
+
+ dbg("Command: [%s] Command Length: [%d]", cmd_str, strlen(cmd_str));
+ g_free(apn);
+
+ pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
+ on_response_define_pdp_context, ps_context);
+ if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
+ g_free(cmd_str);
+ g_free(pdp_type_str);
+ return TCORE_RETURN_SUCCESS;
+ }
+ _unable_to_get_pending(co_ps, ps_context);
+ g_free(cmd_str);
+ g_free(pdp_type_str);
+ return TCORE_RETURN_FAILURE;
+}
+
+static struct tcore_ps_operations ps_ops = {
+ .define_context = define_ps_context,
+ .activate_context = activate_ps_context,
+ /* Use AT_standard entry point */
+ .deactivate_context = deactivate_ps_context,
+};
+
+gboolean imc_ps_init(TcorePlugin *cp, CoreObject *co_ps)
+{
+ TcorePlugin *plugin = tcore_object_ref_plugin(co_ps);
+
+ dbg("Entry");
+
+ /* Set operations */
+ tcore_ps_set_ops(co_ps, &ps_ops);
+
+ tcore_object_add_callback(co_ps, "+CGEV", on_cgev_notification, NULL);
+ tcore_object_add_callback(co_ps, "+XNOTIFYDUNSTATUS", on_event_dun_call_notification, plugin);
+
+ dbg("Exit");
+
+ return TRUE;
+}
+
+void imc_ps_exit(TcorePlugin *cp, CoreObject *co_ps)
+{
+ dbg("Exit");
+}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Ankit Jogi <ankit.jogi@samsung.com>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <tcore.h>
+#include <hal.h>
+#include <core_object.h>
+#include <plugin.h>
+#include <queue.h>
+#include <co_sap.h>
+#include <co_sim.h>
+#include <user_request.h>
+#include <server.h>
+#include <at.h>
+
+#include "imc_common.h"
+#include "imc_sap.h"
+
+
+static void on_confirmation_sap_message_send(TcorePending *p, gboolean result, void *user_data)
+{
+ dbg("on_confirmation_sap_message_send - msg out from queue.\n");
+
+ if (result == FALSE) {
+ /* Fail */
+ dbg("SEND FAIL");
+ } else {
+ dbg("SEND OK");
+ }
+}
+
+static gboolean on_event_sap_status(CoreObject *o, const void *event_info, void *user_data)
+{
+ struct tnoti_sap_status_changed noti;
+ GSList *tokens = NULL;
+ GSList *lines = NULL;
+ const char *line = NULL;
+ int status = 0;
+
+ dbg(" Function entry ");
+
+ lines = (GSList *) event_info;
+ if (1 != g_slist_length(lines)) {
+ dbg("unsolicited msg but multiple line");
+ return FALSE;
+ }
+ line = (char *) (lines->data);
+
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) != 1) {
+ msg("invalid message");
+ tcore_at_tok_free(tokens);
+ return FALSE;
+ }
+ status = atoi(g_slist_nth_data(tokens, 0));
+
+ switch(status){
+ case 0:
+ noti.status = SAP_CARD_STATUS_UNKNOWN;
+ break;
+ case 1:
+ noti.status = SAP_CARD_STATUS_RESET;
+ break;
+ case 2:
+ noti.status = SAP_CARD_STATUS_NOT_ACCESSIBLE;
+ break;
+ case 3:
+ noti.status = SAP_CARD_STATUS_REMOVED;
+ break;
+ case 4:
+ noti.status = SAP_CARD_STATUS_INSERTED;
+ break;
+ case 5:
+ noti.status = SAP_CARD_STATUS_RECOVERED;
+ break;
+ default:
+ noti.status = SAP_CARD_STATUS_NOT_ACCESSIBLE;
+ break;
+ }
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAP_STATUS,
+ sizeof(struct tnoti_sap_status_changed), ¬i);
+ return TRUE;
+}
+
+/*static void on_event_sap_disconnect(CoreObject *o, const void *event_info, void *user_data)
+{
+ //ToDo - Indication not present
+
+ const ipc_sap_disconnect_noti_type *ipc = event_info;
+ struct tnoti_sap_disconnect noti;
+
+ dbg("NOTI RECEIVED");
+
+ noti.type = ipc->disconnect_type;
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAP_DISCONNECT,
+ sizeof(struct tnoti_sap_disconnect), ¬i);
+}*/
+
+static void on_response_connect(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ struct tresp_sap_req_connect res;
+ int *max_msg_size = (int *)user_data;
+
+ dbg(" Function entry ");
+
+ memset(&res, 0x00, sizeof(struct tresp_sap_req_connect));
+ ur = tcore_pending_ref_user_request(p);
+
+ if(resp->success > 0)
+ {
+ dbg("RESPONSE OK");
+
+ res.status = SAP_CONNECTION_STATUS_OK;
+ res.max_msg_size = *max_msg_size;
+
+ }else{
+ dbg("RESPONSE NOK");
+ res.status = SAP_CONNECTION_STATUS_UNABLE_TO_ESTABLISH;
+ res.max_msg_size = 0;
+ }
+
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_SAP_REQ_CONNECT, sizeof(struct tresp_sap_req_connect), &res);
+ }
+ dbg(" Function exit");
+}
+
+static void on_response_disconnect(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ struct tresp_sap_req_disconnect res;
+
+ dbg(" Function entry ");
+ memset(&res, 0x00, sizeof(struct tresp_sap_req_disconnect));
+ ur = tcore_pending_ref_user_request(p);
+
+ if(resp->success > 0)
+ {
+ dbg("RESPONSE OK");
+
+ res.result = SAP_RESULT_CODE_OK;
+
+ }else{
+ dbg("RESPONSE NOK");
+ //ToDo - Error mapping
+ }
+
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_SAP_REQ_DISCONNECT, sizeof(struct tresp_sap_req_disconnect), &res);
+ }
+ dbg(" Function exit");
+}
+
+static void on_response_req_status(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ struct tresp_sap_req_status res;
+
+ dbg(" Function entry ");
+
+ ur = tcore_pending_ref_user_request(p);
+
+ if(resp->success > 0)
+ {
+ dbg("RESPONSE OK");
+ //ToDo - No AT command present
+ //res.status = NULL;
+
+ }else{
+ dbg("RESPONSE NOK");
+ //ToDo - Error mapping
+ }
+
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_SAP_REQ_STATUS, sizeof(struct tresp_sap_req_status), &res);
+ }
+ dbg(" Function exit");
+}
+
+static void on_response_set_transfort_protocol(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ struct tresp_sap_set_protocol res;
+
+ dbg(" Function entry ");
+
+ ur = tcore_pending_ref_user_request(p);
+
+ if(resp->success > 0)
+ {
+ dbg("RESPONSE OK");
+ //ToDo - No AT command present
+ //res.result = NULL;
+
+ }else{
+ dbg("RESPONSE NOK");
+ //ToDo - Error mapping
+ }
+
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_SAP_SET_PROTOCOL, sizeof(struct tresp_sap_set_protocol), &res);
+ }
+ dbg(" Function exit");
+}
+
+static void on_response_set_power(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ struct tresp_sap_set_power res;
+ GSList *tokens=NULL;
+ const char *line;
+ int sap_status = -1;
+
+ dbg(" Function entry ");
+
+ ur = tcore_pending_ref_user_request(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) < 1) {
+ msg("invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+ sap_status = atoi(g_slist_nth_data(tokens, 0));
+
+ switch(sap_status){
+ case 0:
+ res.result = SAP_RESULT_CODE_OK;
+ break;
+ case 1:
+ res.result = SAP_RESULT_CODE_NO_REASON;
+ break;
+ case 2:
+ res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
+ break;
+ case 3:
+ res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
+ break;
+ case 4:
+ res.result = SAP_RESULT_CODE_CARD_REMOVED;
+ break;
+ case 5:
+ res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
+ break;
+ case 6:
+ res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
+ break;
+ case 7:
+ res.result = SAP_RESULT_CODE_NOT_SUPPORT;
+ break;
+ default:
+ res.result = SAP_RESULT_CODE_NOT_SUPPORT;
+ break;
+ }
+
+ }else{
+ dbg("RESPONSE NOK");
+ res.result = SAP_RESULT_CODE_NOT_SUPPORT;
+ }
+
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_SAP_SET_POWER, sizeof(struct tresp_sap_set_power), &res);
+ }
+ tcore_at_tok_free(tokens);
+ dbg(" Function exit");
+}
+
+static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ struct tresp_sap_req_atr res;
+ GSList *tokens=NULL;
+ const char *line;
+ int sap_status = -1;
+ char *atr_data = NULL;
+
+ dbg(" Function entry ");
+
+ ur = tcore_pending_ref_user_request(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) < 1) {
+ msg("invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+ sap_status = atoi(g_slist_nth_data(tokens, 0));
+ atr_data = (char *) g_slist_nth_data(tokens, 1);
+
+ res.atr_length = strlen(atr_data);
+ if( res.atr_length > 256 ) {
+ dbg(" Memory overflow handling");
+ return;
+ }
+ memcpy(res.atr, atr_data, res.atr_length);
+
+ switch(sap_status){
+ case 0:
+ res.result = SAP_RESULT_CODE_OK;
+ break;
+ case 1:
+ res.result = SAP_RESULT_CODE_NO_REASON;
+ break;
+ case 2:
+ res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
+ break;
+ case 3:
+ res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
+ break;
+ case 4:
+ res.result = SAP_RESULT_CODE_CARD_REMOVED;
+ break;
+ case 5:
+ res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
+ break;
+ case 6:
+ res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
+ break;
+ case 7:
+ res.result = SAP_RESULT_CODE_NOT_SUPPORT;
+ break;
+ default:
+ res.result = SAP_RESULT_CODE_NOT_SUPPORT;
+ break;
+ }
+
+ }else{
+ dbg("RESPONSE NOK");
+ res.result = SAP_RESULT_CODE_NOT_SUPPORT;
+ }
+
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_SAP_REQ_ATR, sizeof(struct tresp_sap_req_atr), &res);
+ }
+ dbg(" Function exit");
+}
+
+static void on_response_transfer_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ struct tresp_sap_transfer_apdu res;
+ GSList *tokens=NULL;
+ const char *line;
+ int sap_status = -1;
+ char *apdu_data = NULL;
+
+ dbg(" Function entry ");
+
+ ur = tcore_pending_ref_user_request(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) < 1) {
+ msg("invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+ sap_status = atoi(g_slist_nth_data(tokens, 0));
+ apdu_data = (char *) g_slist_nth_data(tokens, 1);
+
+ res.resp_apdu_length = strlen(apdu_data);
+ if( res.resp_apdu_length > 256 ) {
+ dbg(" Memory overflow handling");
+ return;
+ }
+ memcpy(res.resp_adpdu, apdu_data, res.resp_apdu_length);
+
+ switch(sap_status){
+ case 0:
+ res.result = SAP_RESULT_CODE_OK;
+ break;
+ case 1:
+ res.result = SAP_RESULT_CODE_NO_REASON;
+ break;
+ case 2:
+ res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
+ break;
+ case 3:
+ res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
+ break;
+ case 4:
+ res.result = SAP_RESULT_CODE_CARD_REMOVED;
+ break;
+ case 5:
+ res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
+ break;
+ case 6:
+ res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
+ break;
+ case 7:
+ res.result = SAP_RESULT_CODE_NOT_SUPPORT;
+ break;
+ default:
+ res.result = SAP_RESULT_CODE_NOT_SUPPORT;
+ break;
+ }
+
+ }else{
+ dbg("RESPONSE NOK");
+ res.result = SAP_RESULT_CODE_NOT_SUPPORT;
+ }
+
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_SAP_TRANSFER_APDU, sizeof(struct tresp_sap_transfer_apdu), &res);
+ }
+ dbg(" Function exit");
+}
+
+static void on_response_get_cardreader_status(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ struct tresp_sap_req_cardreaderstatus res;
+ GSList *tokens=NULL;
+ const char *line;
+ int sap_status = -1;
+ char *card_reader_status = NULL;
+
+ dbg(" Function entry ");
+
+ ur = tcore_pending_ref_user_request(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) < 1) {
+ msg("invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+ sap_status = atoi(g_slist_nth_data(tokens, 0));
+ card_reader_status = (char *) g_slist_nth_data(tokens, 1);
+
+ res.reader_status = *card_reader_status;
+
+ switch(sap_status){
+ case 0:
+ res.result = SAP_RESULT_CODE_OK;
+ break;
+ case 1:
+ res.result = SAP_RESULT_CODE_NO_REASON;
+ break;
+ case 2:
+ res.result = SAP_RESULT_CODE_CARD_NOT_ACCESSIBLE;
+ break;
+ case 3:
+ res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_OFF;
+ break;
+ case 4:
+ res.result = SAP_RESULT_CODE_CARD_REMOVED;
+ break;
+ case 5:
+ res.result = SAP_RESULT_CODE_CARD_ALREADY_POWER_ON;
+ break;
+ case 6:
+ res.result = SAP_RESULT_CODE_DATA_NOT_AVAILABLE;
+ break;
+ case 7:
+ res.result = SAP_RESULT_CODE_NOT_SUPPORT;
+ break;
+ default:
+ res.result = SAP_RESULT_CODE_NOT_SUPPORT;
+ break;
+ }
+
+ }else{
+ dbg("RESPONSE NOK");
+ res.result = SAP_RESULT_CODE_NOT_SUPPORT;
+ }
+
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_SAP_REQ_CARDREADERSTATUS, sizeof(struct tresp_sap_req_cardreaderstatus), &res);
+ }
+ dbg(" Function exit");
+}
+
+static TReturn imc_connect(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal;
+ TcoreATRequest *req;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_sap_req_connect *req_data;
+ int *usr_data = NULL;
+
+ dbg(" Function entry");
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+ hal = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+ req_data = tcore_user_request_ref_data(ur, NULL);
+ usr_data = (int*)malloc(sizeof(int));
+ if (!usr_data)
+ return TCORE_RETURN_ENOMEM;
+
+ *usr_data = req_data->max_msg_size;
+ cmd_str = g_strdup_printf("AT+XBCON=0,0,0");
+
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ g_free(cmd_str);
+ g_free(usr_data);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_connect, usr_data);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn imc_disconnect(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal;
+ TcoreATRequest *req;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ //const struct treq_sap_req_disconnect *req_data;
+
+ dbg(" Function entry");
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+ hal = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ //req_data = tcore_user_request_ref_data(ur, NULL);
+
+ cmd_str = g_strdup_printf("AT+ XBDISC");
+
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_disconnect, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn imc_req_status(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal;
+ TcoreATRequest *req;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ //const struct treq_sap_req_status *req_data;
+
+ dbg(" Function entry");
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+ hal = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ //req_data = tcore_user_request_ref_data(ur, NULL);
+
+ //cmd_str = g_strdup_printf("");//ToDo - No AT command present.
+
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_req_status, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn imc_set_transport_protocol(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal;
+ TcoreATRequest *req;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ //const struct treq_sap_set_protocol *req_data;
+
+ dbg(" Function entry");
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+ hal = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ //req_data = tcore_user_request_ref_data(ur, NULL);
+
+ //cmd_str = g_strdup_printf("");//ToDo - No AT command present.
+
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_set_transfort_protocol, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn imc_set_power(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal;
+ TcoreATRequest *req;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_sap_set_power *req_data;
+ int action = -1;
+
+ dbg(" Function entry");
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+ hal = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ if(req_data->mode == SAP_POWER_ON) {
+ action = 0;
+ } else if ( req_data->mode == SAP_POWER_OFF ) {
+ action = 1;
+ } else if ( req_data->mode == SAP_POWER_RESET ) {
+ action = 2;
+ } else {
+ action = -1;;
+ }
+
+ cmd_str = g_strdup_printf("AT+ XBPWR=%d", action);
+
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_set_power, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn imc_get_atr(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal;
+ TcoreATRequest *req;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ //const struct treq_sap_req_atr *req_data;
+
+ dbg(" Function entry");
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+ hal = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ //req_data = tcore_user_request_ref_data(ur, NULL);
+
+ cmd_str = g_strdup_printf("AT+ XBATR");
+
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_get_atr, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn imc_transfer_apdu(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal;
+ TcoreATRequest *req;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_sap_transfer_apdu *req_data;
+
+ dbg(" Function entry");
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+ hal = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ cmd_str = g_strdup_printf("AT+ XBAPDU=\"%s\"", req_data->apdu_data); //ToDo - Need to check passing input as a string.
+
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_transfer_apdu, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn imc_get_cardreader_status(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal;
+ TcoreATRequest *req;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ //const struct treq_sap_req_cardreaderstatus *req_data;
+
+ dbg(" Function entry");
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+ hal = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ //req_data = tcore_user_request_ref_data(ur, NULL);
+
+ cmd_str = g_strdup_printf("AT+ XBCRDSTAT");
+
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_get_cardreader_status, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_sap_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static struct tcore_sap_operations sap_ops =
+{
+ .connect = imc_connect,
+ .disconnect = imc_disconnect,
+ .req_status = imc_req_status,
+ .set_transport_protocol = imc_set_transport_protocol,
+ .set_power = imc_set_power,
+ .get_atr = imc_get_atr,
+ .transfer_apdu = imc_transfer_apdu,
+ .get_cardreader_status = imc_get_cardreader_status,
+};
+
+
+gboolean imc_sap_init(TcorePlugin *cp, CoreObject *co_sap)
+{
+ dbg("Entry");
+
+ /* Set operations */
+ tcore_sap_set_ops(co_sap, &sap_ops);
+
+ tcore_object_add_callback(co_sap,"+XBCSTAT", on_event_sap_status, NULL);
+
+ dbg("Exit");
+
+ return TRUE;
+}
+
+void imc_sap_exit(TcorePlugin *cp, CoreObject *co_sap)
+{
+ dbg("Exit");
+}
#include <user_request.h>
#include <at.h>
-#include "s_common.h"
-#include "s_sat.h"
+#include "imc_common.h"
+#include "imc_sat.h"
#define ENVELOPE_CMD_LEN 256
-static TReturn s_terminal_response(CoreObject *o, UserRequest *ur);
+static TReturn imc_terminal_response(CoreObject *o, UserRequest *ur);
static void on_confirmation_sat_message_send(TcorePending *p, gboolean result, void *user_data); // from Kernel
static void on_confirmation_sat_message_send(TcorePending *p, gboolean result, void *user_data)
line = (char *) lines->data;
tokens = tcore_at_tok_new(line);
if (g_slist_length(tokens) != 1) {
- dbg("invalid message");
+ err("Invalid message");
tcore_at_tok_free(tokens);
return FALSE;
}
- hexData = (char *) g_slist_nth_data(tokens, 0);
- dbg("hexdata %s ", hexData);
- dbg("hexdata length %d", strlen(hexData));
+ hexData = (char *)g_slist_nth_data(tokens, 0);
+ dbg("SAT data: [%s] SAT data length: [%d]", hexData, strlen(hexData));
tmp = util_removeQuotes(hexData);
recordData = util_hexStringToBytes(tmp);
+ if (!recordData) {
+ err("util_hexStringToBytes Failed!!");
+ tcore_at_tok_free(tokens);
+ return FALSE;
+ }
dbg("recordData: %x", recordData);
- free(tmp);
+ g_free(tmp);
util_hex_dump(" ", strlen(hexData) / 2, recordData);
len_proactive_cmd = strlen(recordData);
dbg("len_proactive_cmd = %d", len_proactive_cmd);
tcore_sat_decode_proactive_command((unsigned char *) recordData, (strlen(hexData) / 2) - 1, &decoded_data);
- free(recordData);
+ g_free(recordData);
proactive_noti.cmd_number = decoded_data.cmd_num;
proactive_noti.cmd_type = decoded_data.cmd_type;
dbg("wrong input");
break;
}
- if ((decoded_data.cmd_type == SAT_PROATV_CMD_REFRESH) || (decoded_data.cmd_type == SAT_PROATV_CMD_SETUP_EVENT_LIST)) {
+ if (decoded_data.cmd_type == SAT_PROATV_CMD_REFRESH) {
/*Not supported*/
dbg("Not suported Proactive command");
return FALSE;
GSList *tokens = NULL;
struct tresp_sat_envelop_data res;
const char *line = NULL;
- const char *env_res = NULL;
+ //const char *env_res = NULL;
int sw2 = -1;
ur = tcore_pending_ref_user_request(p);
return;
}
}
- env_res = g_slist_nth_data(tokens, 0);
+ //env_res = g_slist_nth_data(tokens, 0);
res.result = 0x8000;
res.envelop_resp = ENVELOPE_SUCCESS;
dbg("RESPONSE OK 3");
dbg("Function Exit");
}
-static TReturn s_envelope(CoreObject *o, UserRequest *ur)
+static TReturn imc_envelope(CoreObject *o, UserRequest *ur)
{
TcoreHal *hal;
TcoreATRequest *req = NULL;
pbuffer = envelope_cmdhex;
hal = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
pending = tcore_pending_new(o, 0);
req_data = tcore_user_request_ref_data(ur, NULL);
dbg("new pending sub cmd(%d)", req_data->sub_cmd);
return TCORE_RETURN_EINVAL;
}
for (count = 0; count < envelope_cmd_len; count++) {
- dbg("envelope_cmd %02x", envelope_cmd[count]);
- sprintf(pbuffer, "%02x", envelope_cmd[count]);
+ dbg("envelope_cmd %02x", (unsigned char)envelope_cmd[count]);
+ snprintf(pbuffer, 256, "%02x", (unsigned char)envelope_cmd[count]);
pbuffer += 2;
}
dbg("pbuffer %s", envelope_cmdhex);
cmd_str = g_strdup_printf("AT+SATE=\"%s\"", envelope_cmdhex);
req = tcore_at_request_new(cmd_str, "+SATE:", TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ g_free(cmd_str);
+ tcore_pending_free(pending);
+ return TCORE_RETURN_FAILURE;
+ }
+
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_terminal_response(CoreObject *o, UserRequest *ur)
+static TReturn imc_terminal_response(CoreObject *o, UserRequest *ur)
{
TcoreHal *hal = NULL;
TcoreATRequest *req = NULL;
int proactive_resp_len = 0;
char proactive_resp[ENVELOPE_CMD_LEN];
char proactive_resphex[ENVELOPE_CMD_LEN * 2];
- char *pbuffer = NULL;
int i = 0;
char *hexString = NULL;
dbg("Function Entry");
memset(&proactive_resphex, 0x00, sizeof(proactive_resphex));
- pbuffer = proactive_resphex;
hal = tcore_object_get_hal(o);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
pending = tcore_pending_new(o, 0);
req_data = tcore_user_request_ref_data(ur, NULL);
dbg("proactive_resp %s", proactive_resp);
dbg("proactive_resp length %d", strlen(proactive_resp));
if (proactive_resp_len == 0) {
+ tcore_pending_free(pending);
return TCORE_RETURN_EINVAL;
}
hexString = calloc((proactive_resp_len * 2) + 1, 1);
+ if (hexString == NULL) {
+ tcore_pending_free(pending);
+ return TCORE_RETURN_FAILURE;
+ }
for (i = 0; i < proactive_resp_len * 2; i += 2) {
char value = 0;
cmd_str = g_strdup_printf("AT+SATR=\"%s\"", hexString);
req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ g_free(cmd_str);
+ g_free(hexString);
+ tcore_pending_free(pending);
+ return TCORE_RETURN_FAILURE;
+ }
+
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
tcore_hal_send_request(hal, pending);
g_free(cmd_str);
+ g_free(hexString);
dbg("Function Exit");
return TCORE_RETURN_SUCCESS;
}
static struct tcore_sat_operations sat_ops = {
- .envelope = s_envelope,
- .terminal_response = s_terminal_response,
+ .envelope = imc_envelope,
+ .terminal_response = imc_terminal_response,
};
-gboolean s_sat_init(TcorePlugin *p, TcoreHal *h)
+gboolean imc_sat_init(TcorePlugin *cp, CoreObject *co_sat)
{
- CoreObject *o = NULL;
-
dbg("Entry");
- o = tcore_sat_new(p, "sat", &sat_ops, h);
- if (!o) {
- dbg("CoreObject NULL !!");
- return FALSE;
- }
- tcore_object_add_callback(o, "+SATI", on_event_sat_proactive_command, NULL);
- tcore_object_add_callback(o, "+SATN", on_event_sat_proactive_command, NULL);
- tcore_object_add_callback(o, "+SATF", on_response_terminal_response_confirm, NULL);
+ /* Set operations */
+ tcore_sat_set_ops(co_sat, &sat_ops);
+
+ tcore_object_add_callback(co_sat, "+SATI", on_event_sat_proactive_command, NULL);
+ tcore_object_add_callback(co_sat, "+SATN", on_event_sat_proactive_command, NULL);
+ tcore_object_add_callback(co_sat, "+SATF", on_response_terminal_response_confirm, NULL);
dbg("Exit");
+
return TRUE;
}
-void s_sat_exit(TcorePlugin *p)
+void imc_sat_exit(TcorePlugin *cp, CoreObject *co_sat)
{
- CoreObject *o = NULL;
- o = tcore_plugin_ref_core_object(p, "sat");
- if (!o)
- return;
- tcore_sat_free(o);
+ dbg("Exit");
}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Ankit Jogi <ankit.jogi@samsung.com>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <tcore.h>
+#include <hal.h>
+#include <core_object.h>
+#include <plugin.h>
+#include <queue.h>
+#include <co_sim.h>
+#include <co_sms.h>
+#include <storage.h>
+#include <user_request.h>
+#include <server.h>
+#include <at.h>
+
+#include "imc_common.h"
+#include "imc_sms.h"
+#include "imc_sim.h"
+
+#define ID_RESERVED_AT 0x0229
+#define SIM_PIN_MAX_RETRY_COUNT 3
+
+#define SWAPBYTES16(x) \
+ { \
+ unsigned short int data = *(unsigned short int *)&(x); \
+ data = ((data & 0xff00) >> 8) | \
+ ((data & 0x00ff) << 8); \
+ *(unsigned short int *)&(x) = data; \
+ }
+
+enum imc_sim_file_type_e {
+ SIM_FTYPE_DEDICATED = 0x00, /**< Dedicated */
+ SIM_FTYPE_TRANSPARENT = 0x01, /**< Transparent -binary type*/
+ SIM_FTYPE_LINEAR_FIXED = 0x02, /**< Linear fixed - record type*/
+ SIM_FTYPE_CYCLIC = 0x04, /**< Cyclic - record type*/
+ SIM_FTYPE_INVALID_TYPE = 0xFF /**< Invalid type */
+};
+
+enum imc_sim_sec_op_e {
+ SEC_PIN1_VERIFY,
+ SEC_PIN2_VERIFY,
+ SEC_PUK1_VERIFY,
+ SEC_PUK2_VERIFY,
+ SEC_SIM_VERIFY,
+ SEC_ADM_VERIFY,
+ SEC_PIN1_CHANGE,
+ SEC_PIN2_CHANGE,
+ SEC_PIN1_ENABLE,
+ SEC_PIN1_DISABLE,
+ SEC_PIN2_ENABLE,
+ SEC_PIN2_DISABLE, // 10
+ SEC_SIM_ENABLE,
+ SEC_SIM_DISABLE,
+ SEC_NET_ENABLE,
+ SEC_NET_DISABLE,
+ SEC_NS_ENABLE,
+ SEC_NS_DISABLE,
+ SEC_SP_ENABLE,
+ SEC_SP_DISABLE,
+ SEC_CP_ENABLE,
+ SEC_CP_DISABLE, // 20
+ SEC_FDN_ENABLE,
+ SEC_FDN_DISABLE,
+ SEC_PIN1_STATUS,
+ SEC_PIN2_STATUS,
+ SEC_FDN_STATUS,
+ SEC_NET_STATUS,
+ SEC_NS_STATUS,
+ SEC_SP_STATUS,
+ SEC_CP_STATUS,
+ SEC_SIM_STATUS,
+ SEC_SIM_UNKNOWN = 0xff
+};
+
+struct imc_sim_property {
+ gboolean b_valid; /**< Valid or not */
+ enum tel_sim_file_id file_id; /**< File identifier */
+ enum imc_sim_file_type_e file_type; /**< File type and structure */
+ int rec_length; /**< Length of one record in file */
+ int rec_count; /**< Number of records in file */
+ int data_size; /**< File size */
+ int current_index; /**< current index to read */
+ enum imc_sim_sec_op_e current_sec_op; /**< current index to read */
+ int mb_count; /**< Number of MB records in file */
+ struct tel_sim_mbi_list mbi_list;
+// struct tel_sim_mb_number mb_list[SIM_MSP_CNT_MAX*5];
+ struct tel_sim_mailbox mb_data;
+ struct tresp_sim_read files;
+};
+
+void on_response_update_file (TcorePending *p, int data_len, const void *data, void *user_data);
+static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt);
+static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret);
+static gboolean _get_sim_type(CoreObject *o);
+static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef);
+static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length);
+static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length);
+static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status);
+extern gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
+
+static void sim_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
+{
+ TcoreATRequest *req = NULL;
+ TcoreHal *hal = NULL;
+ TcorePending *pending = NULL;
+ TReturn ret;
+
+
+ hal = tcore_object_get_hal(co);
+ dbg("hal: %p", hal);
+
+ pending = tcore_pending_new(co, 0);
+ if (!pending) {
+ dbg("Pending is NULL");
+ return;
+ }
+ req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ return;
+ }
+
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, callback, NULL);
+ tcore_pending_link_user_request(pending, NULL); // set user request to NULL - this is internal request
+ ret = tcore_hal_send_request(hal, pending);
+ if (ret != TCORE_RETURN_SUCCESS) {
+ err("error: [0x%x]", ret);
+ tcore_pending_free(pending);
+ tcore_at_request_free(req);
+ }
+ return;
+}
+
+
+static enum tcore_response_command _find_resp_command(UserRequest *ur)
+{
+ enum tcore_request_command command;
+
+ command = tcore_user_request_get_command(ur);
+ switch (command) {
+ case TREQ_SIM_VERIFY_PINS:
+ return TRESP_SIM_VERIFY_PINS;
+ break;
+
+ case TREQ_SIM_VERIFY_PUKS:
+ return TRESP_SIM_VERIFY_PUKS;
+ break;
+
+ case TREQ_SIM_CHANGE_PINS:
+ return TRESP_SIM_CHANGE_PINS;
+ break;
+
+ case TREQ_SIM_GET_FACILITY_STATUS:
+ return TRESP_SIM_GET_FACILITY_STATUS;
+ break;
+
+ case TREQ_SIM_DISABLE_FACILITY:
+ return TRESP_SIM_DISABLE_FACILITY;
+ break;
+
+ case TREQ_SIM_ENABLE_FACILITY:
+ return TRESP_SIM_ENABLE_FACILITY;
+ break;
+
+ case TREQ_SIM_GET_LOCK_INFO:
+ return TRESP_SIM_GET_LOCK_INFO;
+ break;
+
+ case TREQ_SIM_TRANSMIT_APDU:
+ return TRESP_SIM_TRANSMIT_APDU;
+ break;
+
+ case TREQ_SIM_GET_ATR:
+ return TRESP_SIM_GET_ATR;
+ break;
+
+ case TREQ_SIM_GET_ECC:
+ return TRESP_SIM_GET_ECC;
+ break;
+
+ case TREQ_SIM_GET_LANGUAGE:
+ return TRESP_SIM_GET_LANGUAGE;
+ break;
+
+ case TREQ_SIM_SET_LANGUAGE:
+ return TRESP_SIM_SET_LANGUAGE;
+ break;
+
+ case TREQ_SIM_GET_ICCID:
+ return TRESP_SIM_GET_ICCID;
+ break;
+
+ case TREQ_SIM_GET_MAILBOX:
+ return TRESP_SIM_GET_MAILBOX;
+ break;
+
+ case TREQ_SIM_SET_MAILBOX:
+ return TRESP_SIM_SET_MAILBOX;
+ break;
+
+ case TREQ_SIM_GET_CALLFORWARDING:
+ return TRESP_SIM_GET_CALLFORWARDING;
+ break;
+
+ case TREQ_SIM_SET_CALLFORWARDING:
+ return TRESP_SIM_SET_CALLFORWARDING;
+ break;
+
+ case TREQ_SIM_GET_MESSAGEWAITING:
+ return TRESP_SIM_GET_MESSAGEWAITING;
+ break;
+
+ case TREQ_SIM_SET_MESSAGEWAITING:
+ return TRESP_SIM_SET_MESSAGEWAITING;
+ break;
+
+ case TREQ_SIM_GET_CPHS_INFO:
+ return TRESP_SIM_GET_CPHS_INFO;
+ break;
+
+ case TREQ_SIM_GET_MSISDN:
+ return TRESP_SIM_GET_MSISDN;
+ break;
+
+ case TREQ_SIM_GET_SPN:
+ return TRESP_SIM_GET_SPN;
+ break;
+
+ case TREQ_SIM_GET_SPDI:
+ return TRESP_SIM_GET_SPDI;
+ break;
+
+ case TREQ_SIM_GET_OPL:
+ return TRESP_SIM_GET_OPL;
+ break;
+
+ case TREQ_SIM_GET_PNN:
+ return TRESP_SIM_GET_PNN;
+ break;
+
+ case TREQ_SIM_GET_CPHS_NETNAME:
+ return TRESP_SIM_GET_CPHS_NETNAME;
+ break;
+
+ case TREQ_SIM_GET_OPLMNWACT:
+ return TRESP_SIM_GET_OPLMNWACT;
+ break;
+
+ case TREQ_SIM_REQ_AUTHENTICATION:
+ return TRESP_SIM_REQ_AUTHENTICATION;
+ break;
+
+ case TREQ_SIM_GET_SERVICE_TABLE:
+ return TRESP_SIM_GET_SERVICE_TABLE;
+ break;
+
+ default:
+ break;
+ }
+ return TRESP_UNKNOWN;
+}
+
+static int _sim_get_current_pin_facility(enum imc_sim_sec_op_e op)
+{
+ int ret_type = 0;
+
+ dbg("current sec_op[%d]", op);
+
+ switch (op) {
+ case SEC_PIN1_VERIFY:
+ case SEC_PIN1_CHANGE:
+ ret_type = SIM_PTYPE_PIN1;
+ break;
+
+ case SEC_PIN2_VERIFY:
+ case SEC_PIN2_CHANGE:
+ ret_type = SIM_PTYPE_PIN2;
+ break;
+
+ case SEC_PUK1_VERIFY:
+ ret_type = SIM_PTYPE_PUK1;
+ break;
+
+ case SEC_PUK2_VERIFY:
+ ret_type = SIM_PTYPE_PUK2;
+ break;
+
+ case SEC_SIM_VERIFY:
+ ret_type = SIM_PTYPE_SIM;
+ break;
+
+ case SEC_ADM_VERIFY:
+ ret_type = SIM_PTYPE_ADM;
+ break;
+
+ case SEC_PIN1_ENABLE:
+ case SEC_PIN1_DISABLE:
+ case SEC_PIN1_STATUS:
+ ret_type = SIM_FACILITY_SC;
+ break;
+
+ case SEC_SIM_ENABLE:
+ case SEC_SIM_DISABLE:
+ case SEC_SIM_STATUS:
+ ret_type = SIM_FACILITY_PS;
+ break;
+
+ case SEC_NET_ENABLE:
+ case SEC_NET_DISABLE:
+ case SEC_NET_STATUS:
+ ret_type = SIM_FACILITY_PN;
+ break;
+
+ case SEC_NS_ENABLE:
+ case SEC_NS_DISABLE:
+ case SEC_NS_STATUS:
+ ret_type = SIM_FACILITY_PU;
+ break;
+
+ case SEC_SP_ENABLE:
+ case SEC_SP_DISABLE:
+ case SEC_SP_STATUS:
+ ret_type = SIM_FACILITY_PP;
+ break;
+
+ case SEC_CP_ENABLE:
+ case SEC_CP_DISABLE:
+ case SEC_CP_STATUS:
+ ret_type = SIM_FACILITY_PC;
+ break;
+
+ case SEC_FDN_ENABLE:
+ case SEC_FDN_DISABLE:
+ case SEC_FDN_STATUS:
+ ret_type = SIM_FACILITY_FD;
+ break;
+
+ default:
+ dbg("not handled current sec op[%d]", op);
+ break;
+ }
+ return ret_type;
+}
+
+static enum tel_sim_access_result _decode_status_word(unsigned short status_word1, unsigned short status_word2)
+{
+ enum tel_sim_access_result rst = SIM_ACCESS_FAILED;
+
+ if (status_word1 == 0x93 && status_word2 == 0x00) {
+ rst = SIM_ACCESS_FAILED;
+ /*Failed SIM request command*/
+ dbg("error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x94 && status_word2 == 0x00) {
+ rst = SIM_ACCESS_FAILED;
+ /*Failed SIM request command*/
+ dbg("error - No EF Selected [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x94 && status_word2 == 0x02) {
+ rst = SIM_ACCESS_FAILED;
+ /*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) {
+ rst = SIM_ACCESS_FILE_NOT_FOUND;
+ /*Failed SIM request command*/
+ dbg("error - File ID not found [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x94 && status_word2 == 0x08) {
+ rst = SIM_ACCESS_FAILED; /* MOdem not support */
+ /*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) {
+ rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
+ /*Failed SIM request command*/
+ dbg("error - CHV not initialized [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x98 && status_word2 == 0x04) {
+ rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
+ /*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) {
+ rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
+ /*Failed SIM request command*/
+ dbg("error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x98 && status_word2 == 0x10) {
+ rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
+ /*Failed SIM request command*/
+ dbg("error - Contradiction with invalidation status [%x][%x]",
+ status_word1, status_word2);
+ } else if (status_word1 == 0x98 && status_word2 == 0x40) {
+ rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
+ /*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) {
+ rst = SIM_ACCESS_FAILED;
+ dbg("error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x6B && status_word2 == 0x00) {
+ rst = SIM_ACCESS_FAILED;
+ dbg("error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x6D && status_word2 == 0x00) {
+ rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
+ dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x6E && status_word2 == 0x00) {
+ rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
+ dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x69 && status_word2 == 0x82) {
+ rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
+ dbg("error -Access denied [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x6A && status_word2 == 0x87) {
+ rst = SIM_ACCESS_FAILED;
+ dbg("error -Incorrect parameters [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x6A && status_word2 == 0x82) {
+ rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
+ dbg("error -File Not found [%x][%x]", status_word1, status_word2);
+ } else if (status_word1 == 0x6A && status_word2 == 0x83) {
+ rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
+ dbg("error -Record Not found [%x][%x]", status_word1, status_word2);
+ } else {
+ rst = SIM_ACCESS_CARD_ERROR;
+ dbg("error -Unknown state [%x][%x]", status_word1, status_word2);
+ }
+ return rst;
+}
+
+#if 0
+static gboolean _sim_check_identity(CoreObject *o, struct tel_sim_imsi *imsi)
+{
+ Server *s = NULL;
+ Storage *strg = NULL;
+ char *old_imsi = NULL;
+ char new_imsi[15 + 1] = {0, };
+
+ s = tcore_plugin_ref_server(tcore_object_ref_plugin(o));
+ if (!s) {
+ dbg("there is no valid server at this point");
+ return FALSE;
+ }
+ strg = (Storage *)tcore_server_find_storage(s, "vconf");
+ if (!strg) {
+ dbg("there is no valid storage plugin");
+ return FALSE;
+ }
+ memcpy(&new_imsi, imsi->plmn, strlen(imsi->plmn));
+ memcpy(&new_imsi[strlen(imsi->plmn)], imsi->msin, strlen(imsi->msin));
+ new_imsi[strlen(imsi->plmn) + strlen(imsi->msin)] = '\0';
+
+ old_imsi = tcore_storage_get_string(strg, STORAGE_KEY_TELEPHONY_IMSI);
+ dbg("old_imsi[%s],newImsi[%s]", old_imsi, new_imsi);
+
+ if (old_imsi != NULL) {
+ if (strncmp(old_imsi, new_imsi, 15) != 0) {
+ dbg("NEW SIM");
+ if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *)&new_imsi) == FALSE) {
+ dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
+ }
+ tcore_sim_set_identification(o, TRUE);
+ } else {
+ dbg("SAME SIM");
+ tcore_sim_set_identification(o, FALSE);
+ }
+ } else {
+ dbg("OLD SIM VALUE IS NULL. NEW SIM");
+ if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *)&new_imsi) == FALSE) {
+ dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
+ }
+ tcore_sim_set_identification(o, TRUE);
+ }
+ return 1;
+}
+#endif
+
+static TReturn __sim_update_file(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef,
+ char *encoded_data, unsigned int encoded_len, int rec_index)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ struct imc_sim_property *meta_info = NULL;
+ int p1 = 0;
+ int p2 = 0;
+ int p3 = 0;
+ int cmd = 0;
+
+ dbg("Entry");
+
+ hal = tcore_object_get_hal(o);
+ pending = tcore_pending_new(o, 0);
+ if (!pending) {
+ err("Pending is NULL");
+ return TCORE_RETURN_FAILURE;
+ }
+ meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
+
+ meta_info->file_id = ef;
+ dbg("File ID: [0x%x]", meta_info->file_id);
+
+ switch (ef)
+ {
+ case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
+ case SIM_EF_ELP:
+ case SIM_EF_LP:
+ case SIM_EF_CPHS_VOICE_MSG_WAITING:
+ p1 = 0;
+ p2 = 0;
+ p3 = encoded_len;
+ cmd = 214;
+ break;
+
+ case SIM_EF_USIM_CFIS:
+ case SIM_EF_USIM_MWIS:
+ case SIM_EF_CPHS_MAILBOX_NUMBERS:
+ case SIM_EF_MBDN:
+ case SIM_EF_USIM_MBI:
+ p1 = rec_index;
+ p2 = 0x04;
+ p3 = encoded_len;
+ cmd = 220;
+ break;
+ default:
+ err("Unhandled File ID[0x%04x]", ef);
+ tcore_pending_free(pending);
+ return TCORE_RETURN_EINVAL;
+ }
+
+ cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"", cmd, ef, p1, p2, p3, encoded_data);
+
+ req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
+ g_free(cmd_str);
+
+ dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_update_file, hal);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_hal_send_request(hal, pending);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+
+static TReturn __set_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
+{
+ struct imc_sim_property *meta_info = NULL;
+ TReturn ret_code = TCORE_RETURN_FAILURE;
+ int encoded_len = 0;
+ enum tcore_request_command command;
+ char *tmp = NULL;
+ char *encoded_data = NULL;
+ int rec_index = -1;
+
+ dbg("Entry");
+
+ if (!o || !ur) {
+ err("NULL data : CoreObject[%p] UR[%p]", o, ur);
+ return TCORE_RETURN_EINVAL;
+ }
+ command = tcore_user_request_get_command(ur);
+ meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
+
+ switch (command) {
+
+ case TREQ_SIM_SET_LANGUAGE:
+ {
+ const struct treq_sim_set_language *lang = NULL;
+ struct tel_sim_language language = {0,};
+
+ lang = tcore_user_request_ref_data(ur, NULL);
+ language.language_count = 1;
+ language.language[0] = lang->language;
+ if (tcore_sim_get_type(o) == SIM_TYPE_GSM && ef == SIM_EF_LP){
+ dbg("Encoding EF-LP, language[%d]", lang->language);
+ tmp = tcore_sim_encode_lp(&encoded_len, &language);
+ } else {
+ dbg("Encoding EF-ELP, language[%d]", lang->language);
+ tmp = tcore_sim_encode_li(&encoded_len, &language);
+ }
+ }
+ break;
+
+ case TREQ_SIM_SET_CALLFORWARDING:
+ {
+ const struct treq_sim_set_callforwarding *cf = NULL;
+
+ cf = tcore_user_request_ref_data(ur, NULL);
+ if(ef == SIM_EF_CPHS_CALL_FORWARD_FLAGS ) {
+ if (cf->b_cphs) {
+ tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf*)&cf->cphs_cf, meta_info->data_size);
+ } else {
+ /* Convert 3GPP data to CPHS data */
+ struct tel_sim_cphs_cf cphs_cf;
+
+ dbg("Convert 3GPP data to CPHS data");
+ memset(&cphs_cf, 0x00, sizeof(struct tel_sim_cphs_cf));
+ if (cf->cf.cfu_status & 0x01) {
+ cphs_cf.b_line1 = TRUE;
+ }
+ if (cf->cf.cfu_status & 0x02) {
+ cphs_cf.b_fax = TRUE;
+ }
+ if (cf->cf.cfu_status & 0x04) {
+ cphs_cf.b_data = TRUE;
+ }
+ tmp = tcore_sim_encode_cff((const struct tel_sim_cphs_cf*)&cphs_cf, meta_info->data_size);
+ }
+ if (tmp) {
+ encoded_len = strlen(tmp);
+ } else {
+ err("NULL Encoding Data[%p].. No Updating EF", tmp);
+ goto EXIT;
+ }
+ } else if (ef == SIM_EF_USIM_CFIS){
+ tmp = tcore_sim_encode_cfis(&encoded_len, (const struct tel_sim_cfis*)&cf->cf);
+ rec_index = cf->cf.rec_index;
+ } else {
+ err("Invalid File ID[0x%04x]", ef);
+ goto EXIT;
+ }
+ }
+ break;
+
+ case TREQ_SIM_SET_MESSAGEWAITING:
+ {
+ const struct treq_sim_set_messagewaiting *mw = NULL;
+
+ mw = tcore_user_request_ref_data(ur, NULL);
+ if(ef == SIM_EF_CPHS_VOICE_MSG_WAITING ) {
+ if (mw->b_cphs) {
+ tmp = tcore_sim_encode_vmwf(&encoded_len, (const struct tel_sim_cphs_mw*)&mw->cphs_mw, meta_info->data_size);
+ } else {
+ /* Convert 3GPP data to CPHS data */
+ struct tel_sim_cphs_mw cphs_mw;
+
+ dbg("Convert 3GPP data to CPHS data");
+ memset(&cphs_mw, 0x00, sizeof(struct tel_sim_cphs_mw));
+
+ if (mw->mw.indicator_status & 0x01) {
+ cphs_mw.b_voice1 = TRUE;
+ }
+ if (mw->mw.indicator_status & 0x02) {
+ cphs_mw.b_fax = TRUE;
+ }
+ if (mw->mw.indicator_status & 0x04) {
+ cphs_mw.b_data = TRUE;
+ }
+ tmp = tcore_sim_encode_vmwf(&encoded_len, (const struct tel_sim_cphs_mw*)&cphs_mw, meta_info->data_size);
+ }
+ } else if (ef == SIM_EF_USIM_MWIS){
+ tmp = tcore_sim_encode_mwis(&encoded_len, (const struct tel_sim_mw*)&mw->mw, meta_info->rec_length);
+ rec_index = mw->mw.rec_index;
+ if (tmp)
+ encoded_len = meta_info->rec_length;
+ } else {
+ err("Invalid File ID[0x%04x]", ef);
+ goto EXIT;
+ }
+ }
+ break;
+
+ case TREQ_SIM_SET_MAILBOX:
+ {
+ const struct treq_sim_set_mailbox *mb = NULL;
+
+ mb = tcore_user_request_ref_data(ur, NULL);
+ if (ef == SIM_EF_USIM_MBI){
+ gboolean mbi_changed = FALSE;
+ struct tel_sim_mbi mbi;
+
+ do {
+ meta_info->current_index++;
+ memcpy(&mbi, &meta_info->mbi_list.mbi[meta_info->current_index - 1], sizeof(struct tel_sim_mbi));
+
+ switch(mb->mb_info.mb_type) {
+ case SIM_MAILBOX_VOICE:
+ if (mbi.voice_index != mb->mb_info.rec_index) {
+ mbi_changed = TRUE;
+ mbi.voice_index = mb->mb_info.rec_index;
+ }
+ break;
+ case SIM_MAILBOX_FAX:
+ if (mbi.fax_index != mb->mb_info.rec_index) {
+ mbi_changed = TRUE;
+ mbi.fax_index = mb->mb_info.rec_index;
+ }
+ break;
+ case SIM_MAILBOX_EMAIL:
+ if (mbi.email_index != mb->mb_info.rec_index) {
+ mbi_changed = TRUE;
+ mbi.email_index = mb->mb_info.rec_index;
+ }
+ break;
+ case SIM_MAILBOX_OTHER:
+ if (mbi.other_index != mb->mb_info.rec_index) {
+ mbi_changed = TRUE;
+ mbi.other_index = mb->mb_info.rec_index;
+ }
+ break;
+ case SIM_MAILBOX_VIDEO:
+ if (mbi.video_index != mb->mb_info.rec_index) {
+ mbi_changed = TRUE;
+ mbi.video_index = mb->mb_info.rec_index;
+ }
+ break;
+ case SIM_MAILBOX_DATA:
+ default:
+ break;
+ }
+
+ dbg("mbi_changed[%d], profile_count[%d], index (voice[%d], fax[%d], email[%d], other[%d], video[%d])",
+ mbi_changed, meta_info->mbi_list.profile_count,
+ mbi.voice_index, mbi.fax_index, mbi.email_index, mbi.other_index, mbi.video_index);
+ } while (mbi_changed == FALSE && meta_info->current_index < meta_info->mbi_list.profile_count);
+
+ if (mbi_changed == TRUE) {
+ rec_index = meta_info->current_index;
+ tmp = tcore_sim_encode_mbi(&mbi, meta_info->rec_length);
+ if (tmp)
+ encoded_len = meta_info->rec_length;
+ }
+ } else if (ef == SIM_EF_CPHS_MAILBOX_NUMBERS) {
+ tmp = tcore_sim_encode_xdn(meta_info->rec_length, (struct tel_sim_dialing_number*)&mb->mb_info.number_info);
+ rec_index = mb->mb_info.rec_index;
+ if (tmp)
+ encoded_len = meta_info->rec_length;
+ } else if (ef == SIM_EF_MBDN){
+ tmp = tcore_sim_encode_xdn(meta_info->rec_length, (struct tel_sim_dialing_number*)&mb->mb_info.number_info);
+ rec_index = mb->mb_info.rec_index;
+ if (tmp)
+ encoded_len = meta_info->rec_length;
+ } else {
+ err("Invalid File ID[0x%04x]", ef);
+ goto EXIT;
+ }
+ }
+ break;
+
+ default:
+ err("Unhandled update REQUEST command[%d]", command);
+ ret_code = TCORE_RETURN_EINVAL;
+ goto EXIT;
+ }
+
+ if(tmp) {
+ encoded_data = (char *) g_malloc0(2 * (encoded_len) + 1);
+ if (encoded_data == NULL) {
+ err("Memory allocation failed!!");
+ free(tmp);
+ return ret_code;
+ }
+
+ memset(encoded_data, 0x00, (2 * encoded_len) + 1);
+ util_byte_to_hex(tmp, encoded_data, encoded_len);
+ free(tmp);
+ } else {
+ err("Failed to Encode data");
+ goto EXIT;
+ }
+
+ dbg("Encoded Data length =[%d]", encoded_len);
+ tcore_util_hex_dump("[Encoded Data] ", encoded_len, encoded_data);
+
+ switch (ef)
+ {
+ case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
+ case SIM_EF_ELP:
+ case SIM_EF_LP:
+ case SIM_EF_CPHS_VOICE_MSG_WAITING:
+ ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, 0);
+ break;
+
+ case SIM_EF_USIM_CFIS:
+ case SIM_EF_USIM_MWIS:
+ case SIM_EF_CPHS_MAILBOX_NUMBERS:
+ case SIM_EF_MBDN:
+ ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, rec_index);
+ break;
+ case SIM_EF_USIM_MBI:
+ if (rec_index > 0) {
+ ret_code = __sim_update_file(o, ur, ef, encoded_data, encoded_len, rec_index);
+ } else {
+ memset(meta_info, 0x00, sizeof(struct imc_sim_property));
+ }
+ break;
+ default:
+ err("Unhandled File ID[0x%04x]", ef);
+ ret_code = TCORE_RETURN_EINVAL;
+ break;
+ }
+EXIT:
+ if(encoded_data) {
+ free(encoded_data);
+ encoded_data = NULL;
+ }
+ return ret_code;
+}
+
+static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt)
+{
+ struct tresp_sim_read resp = {0, };
+ struct imc_sim_property *meta_info = NULL;
+ enum tcore_request_command command = TREQ_UNKNOWN;
+ enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
+
+ dbg("EF[0x%x] access Result[%d]", ef, rt);
+
+ resp.result = rt;
+ memset(&resp.data, 0x00, sizeof(resp.data));
+ meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
+ command = tcore_user_request_get_command(ur);
+ sim_type = tcore_sim_get_type(o);
+
+ if ((ef != SIM_EF_ELP && ef != SIM_EF_LP && ef != SIM_EF_USIM_PL && ef != SIM_EF_CPHS_CPHS_INFO)
+ && (rt != SIM_ACCESS_SUCCESS)) {
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &resp);
+ return;
+ }
+
+ switch (ef) {
+ case SIM_EF_ELP:
+ if (rt == SIM_ACCESS_SUCCESS) {
+ dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
+ if (command == TREQ_SIM_SET_LANGUAGE) {
+ __set_file_data(o, ur, ef);
+ } else {
+ _get_file_data(o, ur, ef, 0, meta_info->data_size);
+ }
+ } else {
+ if (sim_type == SIM_TYPE_GSM) {
+ 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 */
+ _get_file_info(o, ur, SIM_EF_LP);
+ } else if (sim_type == SIM_TYPE_USIM) {
+ dbg(
+ " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
+ /* EFELPand EFLI not present at this point. */
+ /* po->language.lang_cnt = 0;*/
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_read), &resp);
+ return;
+ }
+ }
+ break;
+
+ case SIM_EF_LP: // same with SIM_EF_USIM_LI
+ if (rt == SIM_ACCESS_SUCCESS) {
+ dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
+ if (command == TREQ_SIM_SET_LANGUAGE) {
+ __set_file_data(o, ur, ef);
+ } else {
+ _get_file_data(o, ur, ef, 0, meta_info->data_size);
+ }
+ } else {
+ dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
+ sim_type);
+ if (sim_type == SIM_TYPE_GSM) {
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_read), &resp);
+ return;
+ }
+ /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
+ else if (sim_type == SIM_TYPE_USIM) {
+ dbg("[SIM DATA] try USIM EFPL(0x2F05)");
+ _get_file_info(o, ur, SIM_EF_ELP);
+ }
+ }
+ break;
+
+ case SIM_EF_USIM_PL:
+ if (rt == SIM_ACCESS_SUCCESS) {
+ dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
+ if (command == TREQ_SIM_SET_LANGUAGE) {
+ __set_file_data(o, ur, ef);
+ } else {
+ _get_file_data(o, ur, SIM_EF_ELP, 0, meta_info->data_size);
+ }
+ } 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");
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_read), &resp);
+ return;
+ }
+ break;
+
+ case SIM_EF_ECC:
+ if (sim_type == SIM_TYPE_GSM) {
+ _get_file_data(o, ur, ef, 0, meta_info->data_size);
+ } else if (sim_type == SIM_TYPE_USIM) {
+ if (meta_info->rec_count > SIM_ECC_RECORD_CNT_MAX) {
+ meta_info->rec_count = SIM_ECC_RECORD_CNT_MAX;
+ }
+
+ meta_info->current_index++;
+ _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
+ }
+ break;
+
+ case SIM_EF_ICCID:
+ case SIM_EF_IMSI:
+ case SIM_EF_SST:
+ case SIM_EF_SPN:
+ case SIM_EF_SPDI:
+ case SIM_EF_CPHS_VOICE_MSG_WAITING:
+ case SIM_EF_CPHS_OPERATOR_NAME_STRING:
+ case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
+ case SIM_EF_CPHS_DYNAMICFLAGS:
+ case SIM_EF_CPHS_DYNAMIC2FLAG:
+ case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
+ case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
+ case SIM_EF_OPLMN_ACT:
+ _get_file_data(o, ur, ef, 0, meta_info->data_size);
+ break;
+
+ case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
+ if (command == TREQ_SIM_SET_CALLFORWARDING) {
+ __set_file_data(o, ur, ef);
+ } else {
+ _get_file_data(o, ur, ef, 0, meta_info->data_size);
+ }
+ break;
+
+ case SIM_EF_CPHS_CPHS_INFO:
+ if (rt == SIM_ACCESS_SUCCESS) {
+ tcore_sim_set_cphs_status(o, TRUE);
+ if (!tcore_user_request_ref_communicator(ur)) {
+ dbg("internal CPHS INFO request before sim status update");
+ _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
+ } else {
+ dbg("external CPHS INFO request");
+ _get_file_data(o, ur, ef, 0, meta_info->data_size);
+ }
+ } else {
+ tcore_sim_set_cphs_status(o, FALSE);
+ if (!tcore_user_request_ref_communicator(ur)) {
+ dbg("internal CPHS INFO request before sim status update");
+ _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
+ } else {
+ dbg("external CPHS INFO request");
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_read), &resp);
+ }
+ }
+ break;
+
+ case SIM_EF_USIM_CFIS:
+ if (command == TREQ_SIM_SET_CALLFORWARDING) {
+ __set_file_data(o, ur, ef);
+ } else {
+ if (meta_info->rec_count > SIM_CF_RECORD_CNT_MAX) {
+ meta_info->rec_count = SIM_CF_RECORD_CNT_MAX;
+ }
+ meta_info->current_index++;
+ _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
+ }
+ break;
+
+ case SIM_EF_USIM_MWIS:
+ if (command == TREQ_SIM_SET_MESSAGEWAITING) {
+ __set_file_data(o, ur, ef);
+ } else {
+ meta_info->current_index++;
+ _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
+ }
+ break;
+
+ case SIM_EF_USIM_MBI:
+ if (command == TREQ_SIM_SET_MAILBOX) {
+ __set_file_data(o, ur, ef);
+ } else {
+ meta_info->current_index++;
+ _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
+ }
+ break;
+
+ case SIM_EF_OPL:
+ case SIM_EF_PNN:
+ case SIM_EF_CPHS_INFORMATION_NUMBERS:
+ case SIM_EF_MSISDN:
+ meta_info->current_index++;
+ _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
+ break;
+
+ case SIM_EF_MBDN:
+ case SIM_EF_CPHS_MAILBOX_NUMBERS:
+ if (command == TREQ_SIM_SET_MAILBOX) {
+ /* If EF_CPHS_MAILBOX_NUMBERS's structure type is Cyclic then should not allow to update. */
+ if (meta_info->file_id == SIM_EF_CPHS_MAILBOX_NUMBERS && meta_info->file_type == SIM_FTYPE_CYCLIC) {
+ err("Cyclic File ID. No update & return error.");
+ meta_info->files.result = SIM_ACCESS_FAILED;
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_read), &meta_info->files);
+ break;
+ } else {
+ __set_file_data(o, ur, ef);
+ }
+ } else {
+ /* Read MailBox */
+ meta_info->mb_count = 0;
+ meta_info->current_index = meta_info->mb_data.mb[meta_info->mb_count].rec_index;
+ if (meta_info->current_index == 0) {
+ err("Invalid MBDN index");
+ memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_read), &meta_info->files);
+ } else {
+ ur = tcore_user_request_ref(ur);
+ _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
+ }
+ _get_file_record(o, ur, ef, meta_info->current_index, meta_info->rec_length);
+ }
+ break;
+
+ default:
+ dbg("error - File id for get file info [0x%x]", ef);
+ break;
+ }
+ return;
+}
+
+static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
+{
+ struct imc_sim_property *meta_info = NULL;
+
+ dbg("Entry");
+
+ meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
+ dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", meta_info->file_id, rt, decode_ret);
+ switch (meta_info->file_id) {
+ case SIM_EF_ELP:
+ case SIM_EF_USIM_PL:
+ case SIM_EF_LP:
+ case SIM_EF_USIM_LI:
+ if (decode_ret == TRUE) {
+ if (meta_info->file_id == SIM_EF_LP || meta_info->file_id == SIM_EF_USIM_LI) {
+/* po->language_file = SIM_EF_LP;*/
+ } else if (meta_info->file_id == SIM_EF_ELP || meta_info->file_id == SIM_EF_USIM_PL) {
+/* po->language_file = SIM_EF_ELP;*/
+ }
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
+ } else {
+ /* 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 (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
+ if (meta_info->file_id == SIM_EF_LP) {
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
+ } else {
+ _get_file_info(o, ur, SIM_EF_LP);
+ }
+ } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
+ if (meta_info->file_id == SIM_EF_LP || meta_info->file_id == SIM_EF_USIM_LI) {
+ _get_file_info(o, ur, SIM_EF_ELP);
+ } else {
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
+ }
+ }
+ }
+ break;
+
+ case SIM_EF_ECC:
+ if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
+ if (meta_info->current_index == meta_info->rec_count) {
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
+ } else {
+ meta_info->current_index++;
+ _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
+ }
+ } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
+ } else {
+ dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
+ }
+ break;
+
+ case SIM_EF_IMSI:
+ ur = tcore_user_request_new(NULL, NULL); // this is for using ur metainfo set/ref functionality.
+ _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
+ break;
+
+ case SIM_EF_MSISDN:
+ if (meta_info->current_index == meta_info->rec_count) {
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
+ } else {
+ meta_info->current_index++;
+ _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
+ }
+ break;
+
+ case SIM_EF_OPL:
+ if (meta_info->current_index == meta_info->rec_count) {
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
+ } else {
+ meta_info->current_index++;
+ _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
+ }
+ break;
+
+ case SIM_EF_PNN:
+ if (meta_info->current_index == meta_info->rec_count) {
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
+ } else {
+ meta_info->current_index++;
+ _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
+ }
+ break;
+
+ case SIM_EF_USIM_MBI:
+ if (meta_info->current_index == meta_info->rec_count) {
+ _get_file_info(0, ur, SIM_EF_MBDN);
+ } else {
+ meta_info->current_index++;
+ _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
+ }
+ break;
+
+ case SIM_EF_MBDN:
+ case SIM_EF_CPHS_MAILBOX_NUMBERS:
+ if (meta_info->mb_count == meta_info->mb_data.count) {
+ memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_read), &meta_info->files);
+ } else {
+ meta_info->current_index = meta_info->mb_data.mb[meta_info->mb_count].rec_index;
+ if (meta_info->current_index == 0) {
+ err("Invalid MBDN index");
+ memcpy(&meta_info->files.data.mb, &meta_info->mb_data, sizeof(struct tel_sim_mailbox));
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_read), &meta_info->files);
+ } else {
+ ur = tcore_user_request_ref(ur);
+ _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
+ }
+ }
+ break;
+
+ case SIM_EF_USIM_CFIS:
+ case SIM_EF_USIM_MWIS:
+ case SIM_EF_CPHS_INFORMATION_NUMBERS:
+ if (meta_info->current_index == meta_info->rec_count) {
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
+ } else {
+ meta_info->current_index++;
+ _get_file_record(o, ur, meta_info->file_id, meta_info->current_index, meta_info->rec_length);
+ }
+ break;
+
+ case SIM_EF_CPHS_OPERATOR_NAME_STRING:
+ meta_info->files.result = rt;
+ _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING);
+ break;
+
+ case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
+ if (rt == SIM_ACCESS_SUCCESS) {
+ meta_info->files.result = SIM_ACCESS_SUCCESS;
+ }
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
+ break;
+
+ case SIM_EF_ICCID:
+ case SIM_EF_SST:
+ case SIM_EF_SPN:
+ case SIM_EF_SPDI:
+ case SIM_EF_OPLMN_ACT:
+ case SIM_EF_CPHS_CPHS_INFO:
+ case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
+ case SIM_EF_CPHS_VOICE_MSG_WAITING:
+ case SIM_EF_CPHS_DYNAMICFLAGS:
+ case SIM_EF_CPHS_DYNAMIC2FLAG:
+ case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
+ case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &meta_info->files);
+ break;
+
+ default:
+ dbg("File id not handled [0x%x]", meta_info->file_id);
+ break;
+ }
+}
+
+static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
+{
+ struct tnoti_sim_status noti_data = {0, };
+
+ if (sim_status != tcore_sim_get_status(o)) {
+ dbg("Change in SIM State - Old State: [0x%02x] New State: [0x%02x]",
+ tcore_sim_get_status(o), sim_status);
+
+ /* Update SIM Status */
+ tcore_sim_set_status(o, sim_status);
+ noti_data.sim_status = sim_status;
+
+ /* Send notification */
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
+ o, TNOTI_SIM_STATUS, sizeof(noti_data), ¬i_data);
+ }
+}
+
+static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ CoreObject *o = NULL;
+ GSList *tokens = NULL;
+ enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
+ const char *line;
+ int state;
+
+ dbg("Entry");
+
+ o = tcore_pending_ref_core_object(p);
+ ur = tcore_pending_ref_user_request(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) != 1) {
+ msg("Invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+ state = atoi(g_slist_nth_data(tokens, 0));
+ dbg("SIM Type is %d", state);
+
+ if (state == 0) {
+ sim_type = SIM_TYPE_GSM;
+ } else if (state == 1) {
+ sim_type = SIM_TYPE_USIM;
+ } else {
+ sim_type = SIM_TYPE_UNKNOWN;
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ sim_type = SIM_TYPE_UNKNOWN;
+ }
+
+ tcore_sim_set_type(o, sim_type);
+
+ if (sim_type != SIM_TYPE_UNKNOWN) {
+ /* set user request for using ur metainfo set/ref functionality */
+ ur = tcore_user_request_new(NULL, NULL);
+ _get_file_info(o, ur, SIM_EF_IMSI);
+ }
+
+ tcore_at_tok_free(tokens);
+ dbg("Exit");
+}
+
+static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ CoreObject *o = NULL;
+ struct imc_sim_property *meta_info = NULL;
+ GSList *tokens = NULL;
+ enum tel_sim_access_result rt;
+ const char *line = NULL;
+ int sw1 = 0;
+ int sw2 = 0;
+
+ dbg("Entry");
+
+ o = tcore_pending_ref_core_object(p);
+ ur = tcore_pending_ref_user_request(p);
+ meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
+
+ 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; /* 1 or 2 bytes ??? */
+ 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;
+
+ /* handling only last 3 bits */
+ unsigned char file_type_tag = 0x07;
+ unsigned char *ptr_data;
+
+ char *hexData;
+ char *tmp;
+ char *recordData = NULL;
+ hexData = g_slist_nth_data(tokens, 2);
+ dbg("hexData: %s", hexData);
+ dbg("hexData: %s", hexData + 1);
+
+ tmp = util_removeQuotes(hexData);
+ recordData = util_hexStringToBytes(tmp);
+ if (!recordData) {
+ err("util_hexStringToBytes Failed!!");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+
+ util_hex_dump(" ", strlen(hexData) / 2, recordData);
+ g_free(tmp);
+
+ ptr_data = (unsigned char *)recordData;
+ if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
+ /*
+ 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++;
+ /* unsigned char file_desc_len = *ptr_data++;*/
+ /* dbg("file descriptor length: [%d]", file_desc_len);*/
+ /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
+ /* 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 = SIM_FTYPE_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 */
+ SWAPBYTES16(record_len);
+ ptr_data = ptr_data + 2;
+ num_of_records = *ptr_data++;
+ /* Data lossy conversation from enum (int) to unsigned char */
+ file_type = SIM_FTYPE_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 */
+ SWAPBYTES16(record_len);
+ ptr_data = ptr_data + 2;
+ num_of_records = *ptr_data++;
+ file_type = SIM_FTYPE_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(recordData);
+ return;
+ }
+
+ /*File identifier - file id?? */ // 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 */
+ SWAPBYTES16(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(recordData);
+ 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("<RX> operation state -deactivated");
+ ptr_data++;
+ break;
+
+ case 0x05:
+ case 0x07:
+ dbg("<RX> operation state -activated");
+ ptr_data++;
+ break;
+
+ default:
+ dbg("<RX> 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 */
+ SWAPBYTES16(arr_file_id);
+ ptr_data = ptr_data + 2;
+ ptr_data++; /*arr_file_id_rec_num = *ptr_data++; */
+ } 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(recordData);
+ 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 */
+ SWAPBYTES16(file_size);
+ ptr_data = ptr_data + 2;
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ tcore_at_tok_free(tokens);
+ g_free(recordData);
+ return;
+ }
+
+ /* total file size including structural info*/
+ if (*ptr_data == 0x81) {
+ /* int len; */
+ /* increment to next byte */
+ ptr_data++;
+ /* length */
+ /* len = *ptr_data; */
+ /* 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! */
+ /* return -1; */
+ }
+ /*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(recordData);
+ return;
+ }
+ } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
+ 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 */
+ SWAPBYTES16(file_size);
+ /* parsed file size */
+ ptr_data = ptr_data + 2;
+ /* file id */
+ memcpy(&file_id, ptr_data, 2);
+ SWAPBYTES16(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) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_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 = SIM_FTYPE_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 {
+ dbg("Card Type - UNKNOWN [%d]", tcore_sim_get_type(o));
+ }
+
+ dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
+ meta_info->file_id, file_id, file_size, file_type, num_of_records, record_len);
+
+ meta_info->file_type = file_type;
+ meta_info->data_size = file_size;
+ meta_info->rec_length = record_len;
+ meta_info->rec_count = num_of_records;
+ meta_info->current_index = 0; // reset for new record type EF
+ rt = SIM_ACCESS_SUCCESS;
+ g_free(recordData);
+ } else {
+ /*2. SIM access fail case*/
+ dbg("error to get ef[0x%x]", meta_info->file_id);
+ dbg("error to get ef[0x%x] (meta_info->file_id) ", meta_info->file_id);
+ rt = _decode_status_word(sw1, sw2);
+ }
+ ur = tcore_user_request_ref(ur);
+
+ dbg("Calling _next_from_get_file_info");
+ _next_from_get_file_info(o, ur, meta_info->file_id, rt);
+ tcore_at_tok_free(tokens);
+ } else {
+ dbg("RESPONSE NOK");
+ dbg("error to get ef[0x%x]", meta_info->file_id);
+ dbg("error to get ef[0x%x] (meta_info->file_id) ", meta_info->file_id);
+ rt = SIM_ACCESS_FAILED;
+
+ ur = tcore_user_request_ref(ur);
+ _next_from_get_file_info(o, ur, meta_info->file_id, rt);
+ }
+ dbg("Exit");
+}
+
+static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ CoreObject *o = NULL;
+ struct imc_sim_property *meta_info = NULL;
+ GSList *tokens = NULL;
+ enum tel_sim_access_result rt;
+ gboolean dr = FALSE;
+ const char *line = NULL;
+ char *res = NULL;
+ char *tmp = NULL;
+ int res_len;
+ int sw1 = 0;
+ int sw2 = 0;
+
+ dbg("Entry");
+
+ o = tcore_pending_ref_core_object(p);
+ ur = tcore_pending_ref_user_request(p);
+ meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
+
+ 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) != 3) {
+ 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 = util_removeQuotes(res);
+ if (!tmp)
+ return;
+
+ res = util_hexStringToBytes(tmp);
+ res_len = strlen(tmp) / 2;
+
+ dbg("Response: [%s] Response length: [%d]", res, res_len);
+
+ if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
+ rt = SIM_ACCESS_SUCCESS;
+ meta_info->files.result = rt;
+
+ dbg("File ID: [0x%x]", meta_info->file_id);
+ switch (meta_info->file_id) {
+ case SIM_EF_IMSI:
+ {
+ struct tel_sim_imsi *imsi = NULL;
+
+ dbg("Data: [%s]", res);
+ imsi = g_try_new0(struct tel_sim_imsi, 1);
+ dr = tcore_sim_decode_imsi(imsi, (unsigned char *)res, res_len);
+ if (dr == FALSE) {
+ err("IMSI decoding failed");
+ } else {
+ //_sim_check_identity(o, imsi);
+ tcore_sim_set_imsi(o, imsi);
+ }
+
+ /* Free memory */
+ g_free(imsi);
+ }
+ break;
+
+ case SIM_EF_ICCID:
+ dr = tcore_sim_decode_iccid(&meta_info->files.data.iccid, (unsigned char *)res, res_len);
+ break;
+
+ case SIM_EF_ELP: /* 2G EF - 2 bytes decoding */
+ case SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding */
+ case SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding */
+ case SIM_EF_LP: /* 1 byte encoding */
+ if ((tcore_sim_get_type(o) == SIM_TYPE_GSM)
+ && (meta_info->file_id == SIM_EF_LP)) {
+ /*
+ * 2G LP(0x6F05) has 1 byte for each language
+ */
+ dr = tcore_sim_decode_lp(&meta_info->files.data.language,
+ (unsigned char *)res, res_len);
+ } else {
+ /*
+ * 3G LI(0x6F05)/PL(0x2F05),
+ * 2G ELP(0x2F05) has 2 bytes for each language
+ */
+ dr = tcore_sim_decode_li(meta_info->file_id,
+ &meta_info->files.data.language,
+ (unsigned char *)res, res_len);
+ }
+ break;
+
+ case SIM_EF_SPN:
+ dr = tcore_sim_decode_spn(&meta_info->files.data.spn,
+ (unsigned char *)res, res_len);
+ break;
+
+ case SIM_EF_SPDI:
+ dr = tcore_sim_decode_spdi(&meta_info->files.data.spdi,
+ (unsigned char *)res, res_len);
+ break;
+
+ case SIM_EF_SST: //EF UST has same address
+ {
+ if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
+ dr = tcore_sim_decode_sst(&meta_info->files.data.svct.table.sst , (unsigned char *)res, res_len);
+ if(dr == FALSE){
+ dbg("SST decoding failed");
+ tcore_sim_set_service_table(o, NULL);
+ }else{
+ int i = 0, size = sizeof(struct tel_sim_sst);
+ char *temp = NULL;
+ meta_info->files.data.svct.sim_type = SIM_TYPE_GSM;
+ if ((temp=g_try_malloc0(size + 1)) != NULL ) {
+ memcpy(temp, &meta_info->files.data.svct.table.sst, size);
+ for(i=0; i<size; i++) {
+ if(temp[i] == 1)
+ temp[i] = '1';
+ else
+ temp[i] = '0';
+ }
+ dbg("svct.table.sst=[%s]", temp);
+ g_free(temp);
+ }
+ tcore_sim_set_service_table(o, &meta_info->files.data.svct);
+ }
+ } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
+ dr = tcore_sim_decode_ust(&meta_info->files.data.svct.table.ust , (unsigned char *)res, res_len);
+ if(dr == FALSE){
+ dbg("SST decoding failed");
+ tcore_sim_set_service_table(o, NULL);
+ }else{
+ int i = 0, size = sizeof(struct tel_sim_ust);
+ char *temp = NULL;
+ meta_info->files.data.svct.sim_type = SIM_TYPE_USIM;
+ if ((temp=g_try_malloc0(size + 1)) != NULL ) {
+ memcpy(temp, &meta_info->files.data.svct.table.ust, size);
+ for(i=0; i<size; i++) {
+ if(temp[i] == 1)
+ temp[i] = '1';
+ else
+ temp[i] = '0';
+ }
+ dbg("svct.table.ust=[%s]", temp);
+ g_free(temp);
+ }
+ tcore_sim_set_service_table(o, &meta_info->files.data.svct);
+ }
+ } else {
+ dbg("err not handled tcore_sim_get_type(o)[%d] in here",tcore_sim_get_type(o));
+ }
+ }
+ break;
+
+ case SIM_EF_ECC:
+ {
+ if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
+ dr = tcore_sim_decode_ecc(&meta_info->files.data.ecc, (unsigned char *)res, res_len);
+ } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
+ struct tel_sim_ecc *ecc = NULL;
+
+ ecc = g_try_new0(struct tel_sim_ecc, 1);
+ dbg("Index [%d]", meta_info->current_index);
+
+ dr = tcore_sim_decode_uecc(ecc, (unsigned char *)res, res_len);
+ if (dr == TRUE) {
+ memcpy(&meta_info->files.data.ecc.ecc[meta_info->files.data.ecc.ecc_count], ecc, sizeof(struct tel_sim_ecc));
+ meta_info->files.data.ecc.ecc_count++;
+ }
+
+ /* Free memory */
+ g_free(ecc);
+ } else {
+ dbg("Unknown/Unsupported SIM Type: [%d]", tcore_sim_get_type(o));
+ }
+ }
+ break;
+
+ case SIM_EF_MSISDN:
+ {
+ struct tel_sim_msisdn *msisdn = NULL;
+
+ dbg("Index [%d]", meta_info->current_index);
+ msisdn = g_try_new0(struct tel_sim_msisdn, 1);
+ dr = tcore_sim_decode_msisdn(msisdn, (unsigned char *)res, res_len);
+ if (dr == TRUE) {
+ memcpy(&meta_info->files.data.msisdn_list.msisdn[meta_info->files.data.msisdn_list.count],
+ msisdn, sizeof(struct tel_sim_msisdn));
+
+ meta_info->files.data.msisdn_list.count++;
+ }
+
+ /* Free memory */
+ g_free(msisdn);
+ }
+ break;
+
+ case SIM_EF_OPL:
+ {
+ struct tel_sim_opl *opl = NULL;
+
+ dbg("decode w/ index [%d]", meta_info->current_index);
+
+ opl = g_try_new0(struct tel_sim_opl, 1);
+ dr = tcore_sim_decode_opl(opl, (unsigned char *)res, res_len);
+ if (dr == TRUE) {
+ memcpy(&meta_info->files.data.opl.list[meta_info->files.data.opl.opl_count],
+ opl, sizeof(struct tel_sim_opl));
+ meta_info->files.data.opl.opl_count++;
+ }
+
+ /* Free memory */
+ g_free(opl);
+ }
+ break;
+
+ case SIM_EF_PNN:
+ {
+ struct tel_sim_pnn *pnn = NULL;
+
+ dbg("decode w/ index [%d]", meta_info->current_index);
+
+ pnn = g_try_new0(struct tel_sim_pnn, 1);
+ dr = tcore_sim_decode_pnn(pnn, (unsigned char *)res, res_len);
+ if (dr == TRUE) {
+ memcpy(&meta_info->files.data.pnn.list[meta_info->files.data.pnn.pnn_count],
+ pnn, sizeof(struct tel_sim_pnn));
+
+ meta_info->files.data.pnn.pnn_count++;
+ }
+
+ /* Free memory */
+ g_free(pnn);
+ }
+ break;
+
+ case SIM_EF_OPLMN_ACT:
+ dr = tcore_sim_decode_oplmnwact(&meta_info->files.data.opwa,
+ (unsigned char *)res, res_len);
+ break;
+
+ case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
+ /*dr = tcore_sim_decode_csp(&po->p_cphs->csp,
+ p_data->response, p_data->response_len);*/
+ break;
+
+ case SIM_EF_USIM_MBI: //linear type
+ {
+ struct tel_sim_mbi *mbi = NULL;
+
+ mbi = g_try_new0(struct tel_sim_mbi, 1);
+ dr = tcore_sim_decode_mbi(mbi, (unsigned char *)res, res_len);
+ if (dr == TRUE) {
+ memcpy(&meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count],
+ mbi, sizeof(struct tel_sim_mbi));
+ meta_info->mbi_list.profile_count++;
+
+ dbg("mbi count[%d]", meta_info->mbi_list.profile_count);
+ dbg("voice_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count -1].voice_index);
+ dbg("fax_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count -1].fax_index);
+ dbg("email_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count -1].email_index);
+ dbg("other_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count -1].other_index);
+ dbg("video_index[%d]", meta_info->mbi_list.mbi[meta_info->mbi_list.profile_count -1].video_index);
+ }
+
+ /* Free memory */
+ g_free(mbi);
+ }
+ break;
+
+ case SIM_EF_CPHS_MAILBOX_NUMBERS: // linear type
+ case SIM_EF_MBDN: //linear type
+ dr = tcore_sim_decode_xdn(&meta_info->mb_data.mb[meta_info->mb_count].number_info,
+ (unsigned char *)res, res_len);
+ meta_info->mb_count++;
+ break;
+
+ case SIM_EF_CPHS_VOICE_MSG_WAITING: // transparent type
+ dr = tcore_sim_decode_vmwf(&meta_info->files.data.mw.cphs_mw,
+ (unsigned char *)res, res_len);
+ break;
+
+ case SIM_EF_USIM_MWIS: //linear type
+ {
+ struct tel_sim_mw *mw = NULL;
+
+ mw = g_try_new0(struct tel_sim_mw, 1);
+
+ dr = tcore_sim_decode_mwis(mw, (unsigned char *)res, res_len);
+ if (dr == TRUE) {
+ memcpy(&meta_info->files.data.mw.mw_list.mw[meta_info->files.data.mw.mw_list.profile_count], mw, sizeof(struct tel_sim_mw));
+ meta_info->files.data.mw.mw_list.mw[meta_info->files.data.mw.mw_list.profile_count].rec_index = meta_info->current_index;
+ meta_info->files.data.mw.mw_list.profile_count++;
+ }
+
+ /* Free memory */
+ g_free(mw);
+ }
+ break;
+
+ case SIM_EF_CPHS_CALL_FORWARD_FLAGS: //transparent type
+ dr = tcore_sim_decode_cff(&meta_info->files.data.cf.cphs_cf,
+ (unsigned char *)res, res_len);
+ break;
+
+ case SIM_EF_USIM_CFIS: //linear type
+ {
+ struct tel_sim_cfis *cf = NULL;
+
+ cf = g_try_new0(struct tel_sim_cfis, 1);
+ dr = tcore_sim_decode_cfis(cf, (unsigned char *)res, res_len);
+ if (dr == TRUE) {
+ memcpy(&meta_info->files.data.cf.cf_list.cf[meta_info->files.data.cf.cf_list.profile_count],
+ cf, sizeof(struct tel_sim_cfis));
+
+ meta_info->files.data.cf.cf_list.cf[meta_info->files.data.cf.cf_list.profile_count].rec_index = meta_info->current_index;
+ meta_info->files.data.cf.cf_list.profile_count++;
+ }
+
+ /* Free memory */
+ g_free(cf);
+ }
+ break;
+
+ case SIM_EF_CPHS_SERVICE_STRING_TABLE:
+ dbg("not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
+ break;
+
+ case SIM_EF_CPHS_OPERATOR_NAME_STRING:
+ dr = tcore_sim_decode_ons((unsigned char*)&meta_info->files.data.cphs_net.full_name,
+ (unsigned char *)res, res_len);
+ dbg("meta_info->files.result[%d],meta_info->files.data.cphs_net.full_name[%s]",
+ meta_info->files.result, meta_info->files.data.cphs_net.full_name);
+ break;
+
+ case SIM_EF_CPHS_DYNAMICFLAGS:
+ /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
+ p_data->response, p_data->response_len);*/
+ break;
+
+ case SIM_EF_CPHS_DYNAMIC2FLAG:
+ /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response,
+ p_data->response_len);*/
+ break;
+
+ case SIM_EF_CPHS_CPHS_INFO:
+ dr = tcore_sim_decode_cphs_info(&meta_info->files.data.cphs,
+ (unsigned char *)res, res_len);
+ break;
+
+ case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
+ dr = tcore_sim_decode_short_ons((unsigned char*)&meta_info->files.data.cphs_net.short_name,
+ (unsigned char *)res, res_len);
+ break;
+
+ case 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]", meta_info->file_id);
+ dr = 0;
+ break;
+ }
+ } else {
+ rt = _decode_status_word(sw1, sw2);
+ meta_info->files.result = rt;
+ }
+
+ /* 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]", meta_info->file_id);
+ rt = SIM_ACCESS_FAILED;
+ }
+
+ /* Reference User Request */
+ ur = tcore_user_request_ref(ur);
+
+ /* Get File data */
+ _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
+
+ dbg("Exit");
+}
+
+static void _on_response_get_retry_count(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ CoreObject *o = NULL;
+ struct imc_sim_property *sp = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ int lock_type = 0;
+ int attempts_left = 0;
+ int time_penalty = 0;
+
+ dbg("Entry");
+
+ o = tcore_pending_ref_core_object(p);
+ sp = tcore_sim_ref_userdata(o);
+ if(!sp) {
+ err("user data is null");
+ return;
+ }
+ ur = tcore_pending_ref_user_request(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) < 3) {
+ msg("Invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+ lock_type = atoi(g_slist_nth_data(tokens, 0));
+ attempts_left = atoi(g_slist_nth_data(tokens, 1));
+ time_penalty = atoi(g_slist_nth_data(tokens, 2));
+
+ dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
+ lock_type, attempts_left, time_penalty);
+
+ switch (sp->current_sec_op) {
+ case SEC_PIN1_VERIFY:
+ case SEC_PIN2_VERIFY:
+ case SEC_SIM_VERIFY:
+ case SEC_ADM_VERIFY:
+ {
+ struct tresp_sim_verify_pins v_pin = {0, };
+
+ v_pin.result = SIM_INCORRECT_PASSWORD;
+ v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
+ v_pin.retry_count = attempts_left;
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_verify_pins), &v_pin);
+ }
+ break;
+
+ case SEC_PUK1_VERIFY:
+ case SEC_PUK2_VERIFY:
+ {
+ struct tresp_sim_verify_puks v_puk = {0, };
+
+ v_puk.result = SIM_INCORRECT_PASSWORD;
+ v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
+ v_puk.retry_count = attempts_left;
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_verify_puks), &v_puk);
+ }
+ break;
+
+ case SEC_PIN1_CHANGE:
+ case SEC_PIN2_CHANGE:
+ {
+ struct tresp_sim_change_pins change_pin = {0, };
+
+ change_pin.result = SIM_INCORRECT_PASSWORD;
+ change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
+ change_pin.retry_count = attempts_left;
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_change_pins), &change_pin);
+ }
+ break;
+
+ case SEC_PIN1_DISABLE:
+ case SEC_PIN2_DISABLE:
+ case SEC_FDN_DISABLE:
+ case SEC_SIM_DISABLE:
+ case SEC_NET_DISABLE:
+ case SEC_NS_DISABLE:
+ case SEC_SP_DISABLE:
+ case SEC_CP_DISABLE:
+ {
+ struct tresp_sim_disable_facility dis_facility = {0, };
+
+ dis_facility.result = SIM_INCORRECT_PASSWORD;
+ dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
+ dis_facility.retry_count = attempts_left;
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_disable_facility), &dis_facility);
+ }
+ break;
+
+ case SEC_PIN1_ENABLE:
+ case SEC_PIN2_ENABLE:
+ case SEC_FDN_ENABLE:
+ case SEC_SIM_ENABLE:
+ case SEC_NET_ENABLE:
+ case SEC_NS_ENABLE:
+ case SEC_SP_ENABLE:
+ case SEC_CP_ENABLE:
+ {
+ struct tresp_sim_enable_facility en_facility = {0, };
+
+ en_facility.result = SIM_INCORRECT_PASSWORD;
+ en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
+ en_facility.retry_count = attempts_left;
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_enable_facility), &en_facility);
+ }
+ break;
+
+ default:
+ dbg("not handled sec op[%d]", sp->current_sec_op);
+ break;
+ }
+
+ /* Free tokens */
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("Exit");
+}
+
+static gboolean _get_sim_type(CoreObject *o)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ UserRequest *ur = NULL;
+ char *cmd_str = NULL;
+
+ dbg("Entry");
+
+ hal = tcore_object_get_hal(o);
+ pending = tcore_pending_new(o, 0);
+ if (!pending) {
+ err("Pending is NULL");
+ return FALSE;
+ }
+ cmd_str = g_strdup_printf("AT+XUICC?");
+ req = tcore_at_request_new(cmd_str, "+XUICC:", TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return FALSE;
+ }
+ g_free(cmd_str);
+
+ dbg("Command: [%s] Prefix(if any): [%s] Command length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, _response_get_sim_type, hal);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_hal_send_request(hal, pending);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
+{
+ TcoreHal *hal = NULL;
+ TcorePending *pending = NULL;
+ struct imc_sim_property meta_info = {0, };
+ char *cmd_str = NULL;
+ TReturn ret = TCORE_RETURN_FAILURE;
+ int trt = 0;
+
+ dbg("Entry");
+
+ meta_info.file_id = ef;
+ dbg("meta_info.file_id: [0x%02x]", meta_info.file_id);
+ hal = tcore_object_get_hal(o);
+ dbg("hal: %x", hal);
+
+ trt = tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
+ dbg("trt[%d]", trt);
+ cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef); /*command - 192 : GET RESPONSE*/
+ dbg("Command: [%s] Command length: [%d]", cmd_str, strlen(cmd_str));
+
+ pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ ret = tcore_hal_send_request(hal, pending);
+ if (TCORE_RETURN_SUCCESS != ret) {
+ tcore_user_request_free(ur);
+ }
+
+ g_free(cmd_str);
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ int p1 = 0;
+ int p2 = 0;
+ int p3 = 0;
+
+ dbg("Entry");
+ hal = tcore_object_get_hal(o);
+ pending = tcore_pending_new(o, 0);
+ if (!pending) {
+ err("Pending is NULL");
+ return FALSE;
+ }
+
+ dbg("file_id: %x", ef);
+
+ p1 = (unsigned char) (offset & 0xFF00) >> 8;
+ p2 = (unsigned char) offset & 0x00FF; // offset low
+ p3 = (unsigned char) length;
+
+ cmd_str = g_strdup_printf("AT+CRSM=176, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 176 : READ BINARY*/
+
+ req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return FALSE;
+ }
+ g_free(cmd_str);
+
+ dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_hal_send_request(hal, pending);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ int p1 = 0;
+ int p2 = 0;
+ int p3 = 0;
+
+ dbg("Entry");
+
+ hal = tcore_object_get_hal(o);
+ pending = tcore_pending_new(o, 0);
+ if (!pending) {
+ err("Pending is NULL");
+ return FALSE;
+ }
+
+ p1 = (unsigned char) index;
+ p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
+ p3 = (unsigned char) length;
+
+ cmd_str = g_strdup_printf("AT+CRSM=178, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 178 : READ RECORD*/
+
+ req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return FALSE;
+ }
+ g_free(cmd_str);
+
+ dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_hal_send_request(hal, pending);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+static TReturn _get_retry_count(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ int lock_type = 0;
+ struct imc_sim_property *sp = NULL;
+
+ dbg("Entry");
+
+ hal = tcore_object_get_hal(o);
+ pending = tcore_pending_new(o, 0);
+ if (!pending) {
+ err("Pending is NULL");
+ return TCORE_RETURN_FAILURE;
+ }
+ sp = tcore_sim_ref_userdata(o);
+ if(!sp) {
+ err("user data is null");
+ tcore_pending_free(pending);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ switch (sp->current_sec_op) {
+ case SEC_PIN1_VERIFY:
+ case SEC_PIN1_CHANGE:
+ case SEC_PIN1_ENABLE:
+ case SEC_PIN1_DISABLE:
+ lock_type = 1;
+ break;
+
+ case SEC_PIN2_VERIFY:
+ case SEC_PIN2_CHANGE:
+ case SEC_PIN2_ENABLE:
+ case SEC_PIN2_DISABLE:
+ case SEC_FDN_ENABLE:
+ case SEC_FDN_DISABLE:
+ lock_type = 2;
+ break;
+
+ case SEC_PUK1_VERIFY:
+ lock_type = 3;
+ break;
+
+ case SEC_PUK2_VERIFY:
+ lock_type = 4;
+ break;
+
+ case SEC_NET_ENABLE:
+ case SEC_NET_DISABLE:
+ lock_type = 5;
+ break;
+
+ case SEC_NS_ENABLE:
+ case SEC_NS_DISABLE:
+ lock_type = 6;
+ break;
+
+ case SEC_SP_ENABLE:
+ case SEC_SP_DISABLE:
+ lock_type = 7;
+ break;
+
+ case SEC_CP_ENABLE:
+ case SEC_CP_DISABLE:
+ lock_type = 8;
+ break;
+
+ case SEC_ADM_VERIFY:
+ lock_type = 9;
+ break;
+
+ default:
+ break;
+ }
+
+ cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
+ req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
+ g_free(cmd_str);
+
+ dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, _on_response_get_retry_count, hal);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_hal_send_request(hal, pending);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
+{
+ char *line = NULL;
+ GSList *tokens = NULL;
+ GSList *lines = NULL;
+
+ dbg("Function entry");
+
+ lines = (GSList *)event_info;
+ if (1 != g_slist_length(lines)) {
+ dbg("unsolicited msg but multiple line");
+ goto OUT;
+ }
+ line = (char *)(lines->data);
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) != 1) {
+ msg("Invalid message");
+ tcore_at_tok_free(tokens);
+ return TRUE;
+ }
+
+OUT:
+ dbg("Exit");
+ if (NULL != tokens)
+ tcore_at_tok_free(tokens);
+ return TRUE;
+}
+
+static void notify_sms_state(TcorePlugin *plugin, CoreObject *o,
+ gboolean sms_ready)
+{
+ Server *server = tcore_plugin_ref_server(plugin);
+ struct tnoti_sms_ready_status sms_ready_noti;
+ CoreObject *co_sms;
+
+ dbg("Entry");
+
+ co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
+ if (co_sms == NULL) {
+ err("Can't find SMS core object");
+ return;
+ }
+
+ if (tcore_sms_get_ready_status(co_sms) == sms_ready)
+ return;
+
+ tcore_sms_set_ready_status(co_sms, sms_ready);
+
+ if (tcore_sim_get_status(o) == SIM_STATUS_INIT_COMPLETED) {
+ sms_ready_noti.status = sms_ready;
+ tcore_server_send_notification(server, co_sms,
+ TNOTI_SMS_DEVICE_READY,
+ sizeof(sms_ready_noti),
+ &sms_ready_noti);
+ }
+
+ dbg("Exit");
+}
+
+static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
+{
+ TcorePlugin *plugin = tcore_object_ref_plugin(o);
+ enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
+ GSList *tokens = NULL;
+ GSList *lines;
+ const char *line;
+ int sim_state = 0;
+ int sms_state = 0;
+
+ dbg("Entry");
+
+ lines = (GSList *)event_info;
+ if (g_slist_length(lines) != 1) {
+ err("Unsolicited message BUT multiple lines");
+ goto out;
+ }
+
+ line = lines->data;
+
+ /* Create 'tokens' */
+ tokens = tcore_at_tok_new(line);
+
+ /* SIM State */
+ if (g_slist_length(tokens) == 4) {
+ sim_state = atoi(g_slist_nth_data(tokens, 1));
+ sms_state = atoi(g_slist_nth_data(tokens, 3));
+ notify_sms_state(plugin, o, (sms_state > 0));
+ } else if (g_slist_length(tokens) == 1) {
+ sim_state = atoi(g_slist_nth_data(tokens, 0));
+ } else {
+ err("Invalid message");
+ goto out;
+ }
+
+ switch (sim_state) {
+ case 0:
+ sim_status = SIM_STATUS_CARD_NOT_PRESENT;
+ dbg("NO SIM");
+ break;
+
+ case 1:
+ sim_status = SIM_STATUS_PIN_REQUIRED;
+ dbg("PIN REQUIRED");
+ break;
+
+ case 2:
+ sim_status = SIM_STATUS_INITIALIZING;
+ dbg("PIN DISABLED AT BOOT UP");
+ break;
+
+ case 3:
+ sim_status = SIM_STATUS_INITIALIZING;
+ dbg("PIN VERIFIED");
+ break;
+
+ case 4:
+ sim_status = SIM_STATUS_PUK_REQUIRED;
+ dbg("PUK REQUIRED");
+ break;
+
+ case 5:
+ sim_status = SIM_STATUS_CARD_BLOCKED;
+ dbg("CARD PERMANENTLY BLOCKED");
+ break;
+
+ case 6:
+ sim_status = SIM_STATUS_CARD_ERROR;
+ dbg("SIM CARD ERROR");
+ break;
+
+ case 7:
+ sim_status = SIM_STATUS_INIT_COMPLETED;
+ dbg("SIM INIT COMPLETED");
+ break;
+
+ case 8:
+ sim_status = SIM_STATUS_CARD_ERROR;
+ dbg("SIM CARD ERROR");
+ break;
+
+ case 9:
+ sim_status = SIM_STATUS_CARD_REMOVED;
+ dbg("SIM REMOVED");
+ break;
+
+ case 12:
+ dbg("SIM SMS Ready");
+ notify_sms_state(plugin, o, TRUE);
+ goto out;
+
+ case 99:
+ sim_status = SIM_STATUS_UNKNOWN;
+ dbg("SIM STATE UNKNOWN");
+ break;
+
+ default:
+ err("Unknown/Unsupported SIM state: [%d]", sim_state);
+ goto out;
+ }
+
+ switch (sim_status) {
+ case SIM_STATUS_INIT_COMPLETED:
+ dbg("[SIM] SIM INIT COMPLETED");
+ if (tcore_sim_get_type(o) == SIM_TYPE_UNKNOWN) {
+ _get_sim_type(o);
+ goto out;
+ }
+
+ break;
+
+ case SIM_STATUS_CARD_REMOVED:
+ dbg("[SIM] SIM CARD REMOVED");
+ tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
+ break;
+
+ case SIM_STATUS_CARD_NOT_PRESENT:
+ dbg("[SIM] SIM CARD NOT PRESENT");
+ tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
+ break;
+
+ case SIM_STATUS_CARD_ERROR:
+ dbg("[SIM] SIM CARD ERROR");
+ tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
+ break;
+
+ default:
+ dbg("SIM Status: [0x%02x]", sim_status);
+ break;
+ }
+
+ _sim_status_update(o, sim_status);
+
+out:
+ tcore_at_tok_free(tokens);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+static void on_response_get_sim_status(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ CoreObject *o = NULL;
+
+ dbg("Entry");
+
+ o = tcore_pending_ref_core_object(p);
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ if (resp->lines)
+ on_event_pin_status(o, resp->lines, NULL);
+ } else {
+ dbg("RESPONSE NOK");
+ }
+
+ dbg("Exit");
+}
+
+static enum tcore_hook_return on_hook_modem_power(Server *s, CoreObject *source, enum tcore_notification_command command,
+ unsigned int data_len, void *data, void *user_data)
+{
+ TcorePlugin *plugin = tcore_object_ref_plugin(source);
+ CoreObject *o = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
+
+ if (o == NULL)
+ return TCORE_HOOK_RETURN_CONTINUE;
+
+ dbg("Get SIM status");
+
+ sim_prepare_and_send_pending_request(o, "AT+XSIMSTATE?", "+XSIMSTATE:", TCORE_AT_SINGLELINE, on_response_get_sim_status);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ CoreObject *co_sim = NULL;
+ struct imc_sim_property *sp = NULL;
+ GSList *tokens = NULL;
+ struct tresp_sim_verify_pins res;
+ const char *line;
+ int err;
+
+ dbg("Entry");
+
+ co_sim = tcore_pending_ref_core_object(p);
+ sp = tcore_sim_ref_userdata(co_sim);
+ if(!sp) {
+ err("user data is null");
+ return;
+ }
+
+ ur = tcore_pending_ref_user_request(p);
+
+ memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ res.result = SIM_PIN_OPERATION_SUCCESS;
+
+ /* Get PIN facility */
+ res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
+ if ((res.pin_type == SIM_PTYPE_PIN1)
+ || (res.pin_type == SIM_PTYPE_SIM)) {
+ if (tcore_sim_get_status(co_sim) != SIM_STATUS_INIT_COMPLETED) {
+ /* Update SIM Status */
+ _sim_status_update(co_sim, SIM_STATUS_INITIALIZING);
+ }
+ }
+
+ /* Send Response */
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_verify_pins), &res);
+ } else {
+ dbg("RESPONSE NOK");
+ line = (const char *)resp->final_response;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ dbg("Unkown Error OR String corrupted");
+ res.result = TCORE_RETURN_3GPP_ERROR;
+
+ /* Send Response */
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_verify_pins), &res);
+ } else {
+ err = atoi(g_slist_nth_data(tokens, 0));
+ dbg("Error: [%d]", err);
+
+ ur = tcore_user_request_ref(ur);
+
+ /* Get retry count */
+ _get_retry_count(co_sim, ur);
+ }
+
+ /* Free tokens */
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("Exit");
+}
+
+static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ CoreObject *co_sim = NULL;
+ struct imc_sim_property *sp = NULL;
+ GSList *tokens = NULL;
+ struct tresp_sim_verify_puks res;
+ const char *line;
+ int err;
+
+ dbg("Entry");
+
+ co_sim = tcore_pending_ref_core_object(p);
+ sp = tcore_sim_ref_userdata(co_sim);
+ if(!sp) {
+ err("user data is null");
+ return;
+ }
+
+ ur = tcore_pending_ref_user_request(p);
+
+ memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ res.result = SIM_PIN_OPERATION_SUCCESS;
+ res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
+
+ /* Send Response */
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_verify_pins), &res);
+ } else {
+ dbg("RESPONSE NOK");
+ line = (const char *)resp->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ dbg("Unkown Error OR String corrupted");
+ res.result = TCORE_RETURN_3GPP_ERROR;
+
+ /* Send Response */
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_verify_pins), &res);
+ } else {
+ err = atoi(g_slist_nth_data(tokens, 0));
+ dbg("Error: [%d]", err);
+ ur = tcore_user_request_ref(ur);
+ _get_retry_count(co_sim, ur);
+ }
+ tcore_at_tok_free(tokens);
+ }
+ dbg("Exit");
+}
+
+static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ CoreObject *co_sim = NULL;
+ struct imc_sim_property *sp = NULL;
+ GSList *tokens = NULL;
+ struct tresp_sim_change_pins res;
+ const char *line;
+ int err;
+
+ dbg("Entry");
+
+ co_sim = tcore_pending_ref_core_object(p);
+ sp = tcore_sim_ref_userdata(co_sim);
+ if(!sp) {
+ err("user data is null");
+ return;
+ }
+
+ ur = tcore_pending_ref_user_request(p);
+
+ memset(&res, 0, sizeof(struct tresp_sim_change_pins));
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ res.result = SIM_PIN_OPERATION_SUCCESS;
+ res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
+
+ /* Send Response */
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_change_pins), &res);
+ } else {
+ dbg("RESPONSE NOK");
+ line = (const char *)resp->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ dbg("Unkown Error OR String corrupted");
+ res.result = TCORE_RETURN_3GPP_ERROR;
+
+ /* Send Response */
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_change_pins), &res);
+ } else {
+ err = atoi(g_slist_nth_data(tokens, 0));
+ dbg("Error: [%d]", err);
+ ur = tcore_user_request_ref(ur);
+ _get_retry_count(co_sim, ur);
+ }
+
+ /* Free tokens */
+ tcore_at_tok_free(tokens);
+ }
+ dbg("Exit");
+}
+
+static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ struct tresp_sim_get_facility_status *res = user_data;
+ const char *line;
+
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+
+ res->result = SIM_PIN_OPERATION_SUCCESS;
+
+ 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) != 1) {
+ msg("Invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+ res->b_enable = atoi(g_slist_nth_data(tokens, 0));
+ } else {
+ dbg("RESPONSE NOK");
+ res->result = SIM_INCOMPATIBLE_PIN_OPERATION;
+ }
+
+ /* Send Response */
+ if (ur) {
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_get_facility_status), res);
+ }
+ tcore_at_tok_free(tokens);
+ g_free(res);
+ dbg("Exit");
+}
+
+static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ CoreObject *co_sim = NULL;
+ struct imc_sim_property *sp = NULL;
+ GSList *tokens = NULL;
+ struct tresp_sim_enable_facility res;
+ const char *line;
+
+ dbg("Entry");
+
+ co_sim = tcore_pending_ref_core_object(p);
+ sp = tcore_sim_ref_userdata(co_sim);
+ if(!sp) {
+ err("user data is null");
+ return;
+ }
+
+ ur = tcore_pending_ref_user_request(p);
+
+ memset(&res, 0, sizeof(struct tresp_sim_enable_facility));
+
+ res.result = SIM_CARD_ERROR;
+ res.type = _sim_get_current_pin_facility(sp->current_sec_op);
+
+ 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) != 1) {
+ msg("Invalid message");
+
+ /* Send Response */
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_enable_facility), &res);
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+
+ res.result = SIM_PIN_OPERATION_SUCCESS;
+
+ /* Send Response */
+ if (ur) {
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_enable_facility), &res);
+ }
+
+ /* Free tokens */
+ tcore_at_tok_free(tokens);
+ } else {
+ dbg("RESPONSE NOK");
+ ur = tcore_user_request_ref(ur);
+ _get_retry_count(co_sim, ur);
+ }
+ dbg("Exit");
+}
+
+static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ CoreObject *co_sim = NULL;
+ struct imc_sim_property *sp = NULL;
+ GSList *tokens = NULL;
+ struct tresp_sim_disable_facility res;
+ const char *line;
+
+ dbg("Entry");
+
+ co_sim = tcore_pending_ref_core_object(p);
+ sp = tcore_sim_ref_userdata(co_sim);
+ if(!sp) {
+ err("user data is null");
+ return;
+ }
+
+ ur = tcore_pending_ref_user_request(p);
+
+ memset(&res, 0, sizeof(struct tresp_sim_disable_facility));
+
+ res.result = SIM_CARD_ERROR;
+ res.type = _sim_get_current_pin_facility(sp->current_sec_op);
+
+ 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) != 1) {
+ msg("Invalid message");
+
+ /* Send Response */
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_disable_facility), &res);
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+
+ res.result = SIM_PIN_OPERATION_SUCCESS;
+ /* Send Response */
+ if (ur) {
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_disable_facility), &res);
+ }
+
+ /* Free tokens */
+ tcore_at_tok_free(tokens);
+ } else {
+ dbg("RESPONSE NOK");
+ ur = tcore_user_request_ref(ur);
+ _get_retry_count(co_sim, ur);
+ }
+ dbg("Exit");
+}
+
+static void on_response_get_lock_info(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *response = (TcoreATResponse *)data;
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ struct treq_sim_get_lock_info *req_data = NULL;
+ struct tresp_sim_get_lock_info resp;
+ const char *line;
+ int pin1_attempts_left = 0;
+ int puk1_attempts_left = 0;
+ int pin2_attempts_left = 0;
+ int puk2_attempts_left = 0;
+ int length_tokens = 0;
+
+ dbg("Entry");
+
+ memset(&resp, 0x00, sizeof(struct tresp_sim_get_lock_info));
+
+ ur = tcore_pending_ref_user_request(p);
+
+ if (!ur || !response) {
+ err("NULL data : ur[%p], response[%p]", ur, response);
+ resp.result = SIM_CARD_ERROR;
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_get_lock_info), &resp);
+ return;
+ }
+
+ req_data = (struct treq_sim_get_lock_info *) tcore_user_request_ref_data(ur, 0);
+
+ resp.result = SIM_PIN_OPERATION_SUCCESS;
+ resp.type = req_data->type;
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ if (response->lines) {
+ line = (const char *)response->lines->data;
+ tokens = tcore_at_tok_new(line);
+ length_tokens = g_slist_length(tokens);
+ dbg("No of Tokens [%d]",length_tokens);
+ switch (length_tokens) {
+ case 4:
+ puk2_attempts_left = atoi(g_slist_nth_data(tokens, 3));
+ case 3:
+ puk1_attempts_left = atoi(g_slist_nth_data(tokens, 2));
+ case 2:
+ pin2_attempts_left = atoi(g_slist_nth_data(tokens, 1));
+ case 1:
+ pin1_attempts_left = atoi(g_slist_nth_data(tokens, 0));
+ break;
+ default :
+ err("Invalid response");
+ tcore_at_tok_free(tokens);
+ resp.result = SIM_CARD_ERROR;
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_get_lock_info), &resp);
+ return;
+ }
+
+
+ dbg("PIN1 attempts = %d, PUK1 attempts = %d",
+ pin1_attempts_left, puk1_attempts_left);
+ dbg("PIN2 attempts = %d, PUK2 attempts = %d",
+ pin2_attempts_left, puk2_attempts_left);
+
+ resp.lock_status = SIM_LOCK_STATUS_UNLOCKED;
+
+ switch(resp.type)
+ {
+ case SIM_FACILITY_SC :
+ resp.retry_count = pin1_attempts_left;
+ if (pin1_attempts_left > 0 && pin1_attempts_left < SIM_PIN_MAX_RETRY_COUNT) {
+ resp.lock_status = SIM_LOCK_STATUS_PIN;
+ } else if (pin1_attempts_left == 0){
+ if (puk1_attempts_left) {
+ resp.lock_status = SIM_LOCK_STATUS_PUK;
+ resp.retry_count = puk1_attempts_left;
+ }
+ else {
+ resp.lock_status = SIM_LOCK_STATUS_PERM_BLOCKED;
+ }
+ }
+ break;
+ case SIM_FACILITY_FD :
+ resp.retry_count = pin2_attempts_left;
+ if (pin2_attempts_left > 0 && pin2_attempts_left < SIM_PIN_MAX_RETRY_COUNT) {
+ resp.lock_status = SIM_LOCK_STATUS_PIN2;
+ } else if (pin2_attempts_left == 0){
+ if (puk2_attempts_left) {
+ resp.lock_status = SIM_LOCK_STATUS_PUK2;
+ resp.retry_count = puk2_attempts_left;
+ }
+ else {
+ resp.lock_status = SIM_LOCK_STATUS_PERM_BLOCKED;
+ }
+ }
+ break;
+ default :
+ err("Unhandled facility type : [%d]", resp.type);
+ }
+ dbg("Lock type : [%d], Lock status : [%d]", resp.type, resp.lock_status);
+ tcore_at_tok_free(tokens);
+ }
+ } else {
+ err("RESPONSE NOK");
+ resp.result = SIM_INCOMPATIBLE_PIN_OPERATION;
+ }
+
+ /* Send Response */
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_get_lock_info), &resp);
+}
+
+void on_response_update_file (TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = (TcoreATResponse *)data;
+ CoreObject *co_sim = NULL;
+ struct imc_sim_property *meta_info = NULL;
+ struct tresp_sim_set_data resp;
+ int sw1 = 0;
+ int sw2 = 0;
+ gboolean cphs_sim = FALSE;
+ enum tcore_request_command command;
+ dbg("Entry");
+
+ memset(&resp, 0x00, sizeof(struct tresp_sim_set_data));
+
+ ur = tcore_pending_ref_user_request(p);
+ command = tcore_user_request_get_command(ur);
+ co_sim = tcore_pending_ref_core_object(p);
+ cphs_sim = tcore_sim_get_cphs_status(co_sim);
+ meta_info = (struct imc_sim_property *)tcore_user_request_ref_metainfo(ur, NULL);
+
+ if (!ur || !co_sim || !meta_info || !response) {
+ err("NULL data : ur[%p], cp_sim[%p], sp[%p], response[%p]", ur, co_sim, meta_info, response);
+ resp.result = SIM_CARD_ERROR;
+ goto EXIT;
+ } else {
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ if (response->lines) {
+ line = (const char *)response->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 2) {
+ err("Invalid response");
+ resp.result = SIM_CARD_ERROR;
+ } else {
+ sw1 = atoi(g_slist_nth_data(tokens, 0));
+ sw2 = atoi(g_slist_nth_data(tokens, 1));
+
+ if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
+ resp.result = SIM_ACCESS_SUCCESS;
+ } else {
+ resp.result = _decode_status_word(sw1, sw2);
+ }
+ }
+ tcore_at_tok_free(tokens);
+ }
+ } else {
+ err("RESPONSE NOK");
+ resp.result = SIM_ACCESS_FAILED;
+ }
+ }
+
+ if (cphs_sim == FALSE){
+ switch (command) {
+ case TREQ_SIM_SET_MAILBOX:
+ if (meta_info->file_id == SIM_EF_USIM_MBI) {
+ if (resp.result == SIM_ACCESS_SUCCESS) {
+ ur = tcore_user_request_ref(ur);
+ _get_file_info(co_sim, ur, SIM_EF_MBDN);
+ } else {
+ dbg("EF-MBI update failed. but try to update EF-MBDN continuously.");
+ memset(meta_info, 0x00, sizeof(struct imc_sim_property));
+ ur = tcore_user_request_ref(ur);
+ _get_file_info(co_sim, ur, SIM_EF_MBDN);
+ }
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (command) {
+ case TREQ_SIM_SET_MAILBOX:
+ {
+ if (meta_info->file_id != SIM_EF_CPHS_MAILBOX_NUMBERS) {
+ _get_file_info(co_sim, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
+ return;
+ }
+ }
+ break;
+ case TREQ_SIM_SET_CALLFORWARDING:
+ {
+ if (meta_info->file_id != SIM_EF_CPHS_CALL_FORWARD_FLAGS) {
+ _get_file_info(co_sim, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
+ return;
+ }
+ }
+ break;
+ case TREQ_SIM_SET_MESSAGEWAITING:
+ {
+ if (meta_info->file_id != SIM_EF_CPHS_VOICE_MSG_WAITING) {
+ _get_file_info(co_sim, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
+ return;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+EXIT:
+ /* Send Response */
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_set_data), &resp);
+}
+
+static void on_response_transmit_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ struct tresp_sim_transmit_apdu res;
+ const char *line;
+
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+
+ memset(&res, 0, sizeof(struct tresp_sim_transmit_apdu));
+ res.result = SIM_ACCESS_FAILED;
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ if (resp->lines) {
+ GSList *tokens = NULL;
+ char *tmp = NULL;
+ char *decoded_data = NULL;
+ 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);
+ res.result = SIM_CARD_ERROR;
+ goto OUT;
+ }
+
+ tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 1));
+ if (tmp) {
+ decoded_data = util_hexStringToBytes(tmp);
+ if (decoded_data) {
+ res.apdu_resp_length = strlen(tmp) / 2;
+ res.apdu_resp = g_malloc0(res.apdu_resp_length + 1);
+ if (res.apdu_resp == NULL) {
+ err("Memory allocation failed!!");
+ tcore_at_tok_free(tokens);
+ g_free(tmp);
+ g_free(decoded_data);
+ goto OUT;
+ }
+ memcpy((char *)res.apdu_resp, decoded_data, res.apdu_resp_length);
+ g_free(tmp);
+ g_free(decoded_data);
+ res.result = SIM_ACCESS_SUCCESS;
+ tcore_at_tok_free(tokens);
+ } else {
+ err("util_hexStringToBytes Failed!!");
+ g_free(tmp);
+ }
+ }
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ }
+
+OUT:
+ /* Send Response */
+ if (ur) {
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_transmit_apdu), &res);
+ }
+ dbg("Exit");
+}
+
+static void on_response_get_atr(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ struct tresp_sim_get_atr res;
+ const char *line;
+
+ dbg("Entry");
+
+ memset(&res, 0, sizeof(struct tresp_sim_get_atr));
+ ur = tcore_pending_ref_user_request(p);
+
+ res.result = SIM_ACCESS_FAILED;
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ if (resp->lines) {
+ char *tmp = NULL;
+ char *decoded_data = NULL;
+ line = (const char *)resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ msg("Invalid message");
+ goto OUT;
+ }
+
+ tmp = util_removeQuotes(g_slist_nth_data(tokens, 0));
+ if (tmp) {
+ decoded_data = util_hexStringToBytes(tmp);
+ if (!decoded_data) {
+ err("util_hexStringToBytes Failed!!");
+ goto OUT;
+ }
+
+ res.atr_length = strlen(tmp) / 2;
+ memcpy((char *)res.atr, decoded_data, res.atr_length);
+ g_free(tmp);
+ g_free(decoded_data);
+ res.result = SIM_ACCESS_SUCCESS;
+ }
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ }
+
+OUT:
+ /* Send Response */
+ if (ur) {
+ tcore_user_request_send_response(ur, _find_resp_command(ur),
+ sizeof(struct tresp_sim_get_atr), &res);
+ }
+ tcore_at_tok_free(tokens);
+ dbg("Exit");
+}
+
+static void on_response_req_authentication(TcorePending *p, int data_len,
+ const void *data, void *user_data)
+{
+ const TcoreATResponse *at_resp = data;
+ GSList *tokens = NULL;
+ struct tresp_sim_req_authentication resp_auth;
+ const struct treq_sim_req_authentication *req_data;
+ UserRequest *ur = tcore_pending_ref_user_request(p);
+
+ dbg("Entry");
+
+ memset(&resp_auth, 0, sizeof(struct tresp_sim_req_authentication));
+
+ if (at_resp == NULL) {
+ err("at_resp is NULL");
+ resp_auth.result = SIM_ACCESS_FAILED;
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+ if (req_data == NULL) {
+ err("req_data is NULL");
+ resp_auth.result = SIM_ACCESS_FAILED;
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+ resp_auth.auth_type = req_data->auth_type;
+
+ if (at_resp->success == TRUE) {
+ const char *line;
+ int status;
+
+ dbg("RESPONSE OK");
+ if (at_resp->lines != NULL) {
+ line = at_resp->lines->data;
+ dbg("Received data: [%s]", line);
+ } else {
+ err("at_resp->lines is NULL");
+ resp_auth.result = SIM_ACCESS_FAILED;
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ tokens = tcore_at_tok_new(line);
+ if (tokens == NULL) {
+ err("tokens is NULL");
+ resp_auth.result = SIM_ACCESS_FAILED;
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ status = atoi(g_slist_nth_data(tokens, 0));
+ switch (status) {
+ case 0:
+ dbg("Authentications successful");
+ resp_auth.auth_result = SIM_AUTH_NO_ERROR;
+ break;
+ case 1:
+ err("Synchronize fail");
+ resp_auth.auth_result = SIM_AUTH_SYNCH_FAILURE;
+ goto out;
+ case 2:
+ err("MAC wrong");
+ resp_auth.auth_result = SIM_AUTH_MAK_CODE_FAILURE;
+ goto out;
+ case 3:
+ err("Does not support security context");
+ resp_auth.auth_result = SIM_AUTH_UNSUPPORTED_CONTEXT;
+ goto out;
+ default:
+ err("Other failure");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ goto out;
+ }
+
+ if (resp_auth.auth_type == SIM_AUTH_TYPE_GSM) {
+ char *kc, *sres;
+ char *convert_kc, *convert_sres;
+
+ kc = g_slist_nth_data(tokens, 1);
+ if (kc != NULL) {
+ kc = tcore_at_tok_extract(kc);
+ dbg("Kc: [%s]", kc);
+ convert_kc = util_hexStringToBytes(kc);
+ if (convert_kc && strlen(convert_kc) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
+ resp_auth.authentication_key_length = strlen(convert_kc);
+ memcpy(&resp_auth.authentication_key, convert_kc, strlen(convert_kc));
+ } else {
+ err("Invalid Kc");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ }
+ g_free(kc);
+ g_free(convert_kc);
+ }
+
+ sres = g_slist_nth_data(tokens, 2);
+ if (sres != NULL) {
+ sres = tcore_at_tok_extract(sres);
+ dbg("SRES: [%s]", sres);
+ convert_sres = util_hexStringToBytes(sres);
+ if (convert_sres && strlen(sres) <= SIM_AUTH_RESP_DATA_LEN_MAX) {
+ resp_auth.resp_length = strlen(convert_sres);
+ memcpy(&resp_auth.resp_data, convert_sres, strlen(convert_sres));
+ } else {
+ err("Invalid SRES");
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ }
+ g_free(sres);
+ g_free(convert_sres);
+ }
+ } else if (resp_auth.auth_type == SIM_AUTH_TYPE_3G
+ || resp_auth.auth_type == SIM_AUTH_TYPE_IMS) {
+ /* TODO */
+ }
+ } else {
+ err("RESPONSE NOK");
+ resp_auth.result = SIM_ACCESS_FAILED;
+ resp_auth.auth_result = SIM_AUTH_CANNOT_PERFORM;
+ }
+
+out:
+ tcore_user_request_send_response(ur, TRESP_SIM_REQ_AUTHENTICATION,
+ sizeof(struct tresp_sim_req_authentication), &resp_auth);
+
+ tcore_at_tok_free(tokens);
+}
+
+static TReturn imc_verify_pins(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_sim_verify_pins *req_data = NULL;
+ struct imc_sim_property *sp = NULL;
+ TReturn ret = TCORE_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ if ((o == NULL )|| (ur == NULL))
+ return TCORE_RETURN_EINVAL;
+
+ hal = tcore_object_get_hal(o);
+ if (FALSE == tcore_hal_get_power_state(hal)) {
+ err("CP NOT READY");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ sp = tcore_sim_ref_userdata(o);
+ if(!sp) {
+ err("user data is null");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ pending = tcore_pending_new(o, 0);
+ if (!pending) {
+ err("Pending is NULL");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ if (req_data->pin_type == SIM_PTYPE_PIN1) {
+ sp->current_sec_op = SEC_PIN1_VERIFY;
+ cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
+ } else if (req_data->pin_type == SIM_PTYPE_PIN2) {
+ sp->current_sec_op = SEC_PIN2_VERIFY;
+ cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", req_data->pin);
+ } else if (req_data->pin_type == SIM_PTYPE_SIM) {
+ sp->current_sec_op = SEC_SIM_VERIFY;
+ cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
+ } else if (req_data->pin_type == SIM_PTYPE_ADM) {
+ sp->current_sec_op = SEC_ADM_VERIFY;
+ cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
+ } else {
+ tcore_pending_free(pending);
+ return TCORE_RETURN_EINVAL;
+ }
+
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
+ g_free(cmd_str);
+
+ dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_verify_pins, hal);
+ tcore_pending_link_user_request(pending, ur);
+ ret = tcore_hal_send_request(hal, pending);
+
+ dbg("Exit");
+ return ret;
+}
+
+static TReturn imc_verify_puks(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_sim_verify_puks *req_data;
+ struct imc_sim_property *sp = NULL;
+ TReturn ret = TCORE_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ if ((o == NULL )|| (ur == NULL))
+ return TCORE_RETURN_EINVAL;
+
+ hal = tcore_object_get_hal(o);
+ if (FALSE == tcore_hal_get_power_state(hal)) {
+ err("CP NOT READY");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ sp = tcore_sim_ref_userdata(o);
+ if(!sp) {
+ err("user data is null");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ pending = tcore_pending_new(o, 0);
+ if (!pending) {
+ err("Pending is NULL");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ if (req_data->puk_type == SIM_PTYPE_PUK1) {
+ sp->current_sec_op = SEC_PUK1_VERIFY;
+ cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", req_data->puk, req_data->pin);
+ } else if (req_data->puk_type == SIM_PTYPE_PUK2) {
+ sp->current_sec_op = SEC_PUK2_VERIFY;
+ cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"", req_data->puk, req_data->pin);
+ } else {
+ tcore_pending_free(pending);
+ return TCORE_RETURN_EINVAL;
+ }
+
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
+ g_free(cmd_str);
+
+ dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_verify_puks, hal);
+ tcore_pending_link_user_request(pending, ur);
+ ret = tcore_hal_send_request(hal, pending);
+
+ dbg("Exit");
+ return ret;
+}
+
+static TReturn imc_change_pins(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_sim_change_pins *req_data;
+ struct imc_sim_property *sp = NULL;
+ char *pin1 = "SC";
+ char *pin2 = "P2";
+ TReturn ret = TCORE_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ if ((o == NULL )|| (ur == NULL))
+ return TCORE_RETURN_EINVAL;
+
+ hal = tcore_object_get_hal(o);
+ if (FALSE == tcore_hal_get_power_state(hal)) {
+ err("CP NOT READY");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ sp = tcore_sim_ref_userdata(o);
+ if(!sp) {
+ err("user data is null");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ pending = tcore_pending_new(o, 0);
+ if (!pending) {
+ err("Pending is NULL");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ if (req_data->type == SIM_PTYPE_PIN1) {
+ sp->current_sec_op = SEC_PIN1_CHANGE;
+ cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin1, req_data->old_pin, req_data->new_pin);
+ } else if (req_data->type == SIM_PTYPE_PIN2) {
+ sp->current_sec_op = SEC_PIN2_CHANGE;
+ cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin2, req_data->old_pin, req_data->new_pin);
+ } else {
+ tcore_pending_free(pending);
+ return TCORE_RETURN_EINVAL;
+ }
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
+ g_free(cmd_str);
+
+ dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_change_pins, hal);
+ tcore_pending_link_user_request(pending, ur);
+ ret = tcore_hal_send_request(hal, pending);
+
+ dbg("Exit");
+ return ret;
+}
+
+static TReturn imc_get_facility_status(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_sim_get_facility_status *req_data;
+ struct tresp_sim_get_facility_status *res;
+ char *fac = "SC";
+ int mode = 2; /* 0:unlock, 1:lock, 2:query*/
+ TReturn ret = TCORE_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ if ((o == NULL )|| (ur == NULL))
+ return TCORE_RETURN_EINVAL;
+
+ hal = tcore_object_get_hal(o);
+ if (FALSE == tcore_hal_get_power_state(hal)) {
+ err("CP NOT READY");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ pending = tcore_pending_new(o, 0);
+ if (!pending) {
+ err("Pending is NULL");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ res = g_try_new0(struct tresp_sim_get_facility_status, 1);
+ if (!res) {
+ tcore_pending_free(pending);
+ return TCORE_RETURN_ENOMEM;
+ }
+
+ res->type = req_data->type;
+
+ if (req_data->type == SIM_FACILITY_PS) {
+ fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
+ } else if (req_data->type == SIM_FACILITY_SC) {
+ fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
+ } else if (req_data->type == SIM_FACILITY_FD) {
+ fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
+ } else if (req_data->type == SIM_FACILITY_PN) {
+ fac = "PN"; /*Network Personalization*/
+ } else if (req_data->type == SIM_FACILITY_PU) {
+ fac = "PU"; /*network sUbset Personalization*/
+ } else if (req_data->type == SIM_FACILITY_PP) {
+ fac = "PP"; /*service Provider Personalization*/
+ } else if (req_data->type == SIM_FACILITY_PC) {
+ fac = "PC"; /*Corporate Personalization*/
+ } else {
+ return TCORE_RETURN_EINVAL;
+ }
+ cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
+ req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
+ g_free(cmd_str);
+
+ dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_get_facility_status, res);
+ tcore_pending_link_user_request(pending, ur);
+ ret = tcore_hal_send_request(hal, pending);
+
+ dbg("Exit");
+ return ret;
+}
+
+static TReturn imc_enable_facility(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_sim_enable_facility *req_data;
+ struct imc_sim_property *sp = NULL;
+ char *fac = "SC";
+ int mode = 1; /* 0:unlock, 1:lock, 2:query*/
+ TReturn ret = TCORE_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ if ((o == NULL )|| (ur == NULL))
+ return TCORE_RETURN_EINVAL;
+
+ hal = tcore_object_get_hal(o);
+ if (FALSE == tcore_hal_get_power_state(hal)) {
+ err("CP NOT READY");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ sp = tcore_sim_ref_userdata(o);
+ if(!sp) {
+ err("user data is null");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ pending = tcore_pending_new(o, 0);
+ if (!pending) {
+ err("Pending is NULL");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ if (req_data->type == SIM_FACILITY_PS) {
+ fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
+ sp->current_sec_op = SEC_SIM_ENABLE;
+ } else if (req_data->type == SIM_FACILITY_SC) {
+ fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
+ sp->current_sec_op = SEC_PIN1_ENABLE;
+ } else if (req_data->type == SIM_FACILITY_FD) {
+ fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
+ sp->current_sec_op = SEC_FDN_ENABLE;
+ } else if (req_data->type == SIM_FACILITY_PN) {
+ fac = "PN"; /*Network Personalization*/
+ sp->current_sec_op = SEC_NET_ENABLE;
+ } else if (req_data->type == SIM_FACILITY_PU) {
+ fac = "PU"; /*network sUbset Personalization*/
+ sp->current_sec_op = SEC_NS_ENABLE;
+ } else if (req_data->type == SIM_FACILITY_PP) {
+ fac = "PP"; /*service Provider Personalization*/
+ sp->current_sec_op = SEC_SP_ENABLE;
+ } else if (req_data->type == SIM_FACILITY_PC) {
+ fac = "PC"; /*Corporate Personalization*/
+ sp->current_sec_op = SEC_CP_ENABLE;
+ } else {
+ return TCORE_RETURN_EINVAL;
+ }
+ cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
+ req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
+ g_free(cmd_str);
+
+ dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_enable_facility, hal);
+ tcore_pending_link_user_request(pending, ur);
+ ret = tcore_hal_send_request(hal, pending);
+
+ dbg("Exit");
+ return ret;
+}
+
+static TReturn imc_disable_facility(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal;
+ TcoreATRequest *req;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_sim_enable_facility *req_data;
+ struct imc_sim_property *sp = NULL;
+ char *fac = "SC";
+ int mode = 0; /* 0:unlock, 1:lock, 2:query*/
+ TReturn ret = TCORE_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ if ((o == NULL )|| (ur == NULL))
+ return TCORE_RETURN_EINVAL;
+
+ hal = tcore_object_get_hal(o);
+ if (FALSE == tcore_hal_get_power_state(hal)) {
+ err("CP NOT READY");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ sp = tcore_sim_ref_userdata(o);
+ if(!sp) {
+ err("user data is null");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ pending = tcore_pending_new(o, 0);
+ if (!pending) {
+ err("Pending is NULL");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ if (req_data->type == SIM_FACILITY_PS) {
+ fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
+ sp->current_sec_op = SEC_SIM_DISABLE;
+ } else if (req_data->type == SIM_FACILITY_SC) {
+ fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
+ sp->current_sec_op = SEC_PIN1_DISABLE;
+ } else if (req_data->type == SIM_FACILITY_FD) {
+ fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
+ sp->current_sec_op = SEC_FDN_DISABLE;
+ } else if (req_data->type == SIM_FACILITY_PN) {
+ fac = "PN"; /*Network Personalization*/
+ sp->current_sec_op = SEC_NET_DISABLE;
+ } else if (req_data->type == SIM_FACILITY_PU) {
+ fac = "PU"; /*network sUbset Personalization*/
+ sp->current_sec_op = SEC_NS_DISABLE;
+ } else if (req_data->type == SIM_FACILITY_PP) {
+ fac = "PP"; /*service Provider Personalization*/
+ sp->current_sec_op = SEC_SP_DISABLE;
+ } else if (req_data->type == SIM_FACILITY_PC) {
+ fac = "PC"; /*Corporate Personalization*/
+ sp->current_sec_op = SEC_CP_DISABLE;
+ } else {
+ return TCORE_RETURN_EINVAL;
+ }
+ cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
+ req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
+ g_free(cmd_str);
+
+ dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_disable_facility, hal);
+ tcore_pending_link_user_request(pending, ur);
+ ret = tcore_hal_send_request(hal, pending);
+
+ dbg("Exit");
+ return ret;
+}
+
+static TReturn imc_get_lock_info(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+
+ dbg("Entry");
+
+ hal = tcore_object_get_hal(o);
+ pending = tcore_pending_new(o, 0);
+ if (!pending) {
+ err("Pending is NULL");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ if ((o == NULL )|| (ur == NULL)) {
+ tcore_pending_free(pending);
+ return TCORE_RETURN_EINVAL;
+ }
+ req = tcore_at_request_new("AT+XPINCNT", "+XPINCNT:", TCORE_AT_SINGLELINE);
+
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("Command: [%s] Prefix(if any): [%s], Command length: [%d]",
+ req->cmd, req->prefix, strlen(req->cmd));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_hal_send_request(hal, pending);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn imc_read_file(CoreObject *o, UserRequest *ur)
+{
+ TReturn api_ret = TCORE_RETURN_SUCCESS;
+ enum tcore_request_command command;
+
+ dbg("Entry");
+
+ if ((o == NULL )|| (ur == NULL))
+ return TCORE_RETURN_EINVAL;
+
+ command = tcore_user_request_get_command(ur);
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ err("CP NOT READY");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ switch (command) {
+ case TREQ_SIM_GET_ECC:
+ api_ret = _get_file_info(o, ur, SIM_EF_ECC);
+ break;
+
+ case TREQ_SIM_GET_LANGUAGE:
+ if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
+ api_ret = _get_file_info(o, ur, SIM_EF_ELP);
+ else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
+ api_ret = _get_file_info(o, ur, SIM_EF_LP);
+ else
+ api_ret = TCORE_RETURN_ENOSYS;
+ break;
+
+ case TREQ_SIM_GET_ICCID:
+ api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
+ break;
+
+ case TREQ_SIM_GET_MAILBOX:
+ if (tcore_sim_get_cphs_status(o))
+ api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
+ else
+ api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
+ break;
+
+ case TREQ_SIM_GET_CALLFORWARDING:
+ if (tcore_sim_get_cphs_status(o))
+ api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
+ else
+ api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
+ break;
+
+ case TREQ_SIM_GET_MESSAGEWAITING:
+ if (tcore_sim_get_cphs_status(o))
+ api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
+ else
+ api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
+ break;
+
+ case TREQ_SIM_GET_CPHS_INFO:
+ api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
+ break;
+
+ case TREQ_SIM_GET_MSISDN:
+ api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
+ break;
+
+ case TREQ_SIM_GET_SPN:
+ dbg("enter case SPN");
+ api_ret = _get_file_info(o, ur, SIM_EF_SPN);
+ break;
+
+ case TREQ_SIM_GET_SPDI:
+ api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
+ break;
+
+ case TREQ_SIM_GET_OPL:
+ api_ret = _get_file_info(o, ur, SIM_EF_OPL);
+ break;
+
+ case TREQ_SIM_GET_PNN:
+ api_ret = _get_file_info(o, ur, SIM_EF_PNN);
+ break;
+
+ case TREQ_SIM_GET_CPHS_NETNAME:
+ api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
+ break;
+
+ case TREQ_SIM_GET_OPLMNWACT:
+ api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
+ break;
+
+ case TREQ_SIM_GET_SERVICE_TABLE:
+ api_ret = _get_file_info(o, ur, SIM_EF_SST);
+ break;
+
+ default:
+ dbg("error - not handled read treq command[%d]", command);
+ api_ret = TCORE_RETURN_EINVAL;
+ break;
+ }
+ dbg("Exit");
+ return api_ret;
+}
+
+
+static TReturn imc_update_file(CoreObject *co_sim, UserRequest *ur)
+{
+ TReturn ret_code = TCORE_RETURN_SUCCESS;
+ enum tcore_request_command command;
+ enum tel_sim_file_id ef = SIM_EF_INVALID;
+ struct imc_sim_property meta_info = {0, };
+ enum tel_sim_type sim_type;
+ gboolean cphs_sim = FALSE;
+ dbg("Entry");
+
+ command = tcore_user_request_get_command(ur);
+ cphs_sim = tcore_sim_get_cphs_status(co_sim);
+ sim_type = tcore_sim_get_type(co_sim);
+
+ if ((co_sim == NULL )|| (ur == NULL)) {
+ return TCORE_RETURN_EINVAL;
+ }
+
+ switch (command) {
+ case TREQ_SIM_SET_LANGUAGE:
+ if (sim_type == SIM_TYPE_GSM)
+ ret_code = _get_file_info(co_sim, ur, SIM_EF_ELP);
+ else if (sim_type == SIM_TYPE_USIM)
+ ret_code = _get_file_info(co_sim, ur, SIM_EF_LP);
+ else
+ ret_code = TCORE_RETURN_ENOSYS;
+ break;
+
+ case TREQ_SIM_SET_MAILBOX:
+ {
+ if (cphs_sim) {
+ struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
+
+ if(!svct)
+ break;
+ if ((sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_MBDN]) || (sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_MBDN])) {
+ tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
+ ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MBI);
+ } else {
+ dbg("Service not available in SST/UST - Updating CPHS file : Fild ID[0x%x]", SIM_EF_CPHS_MAILBOX_NUMBERS);
+ ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
+ }
+ free(svct);
+ } else {
+ ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MBI);
+ }
+ }
+ break;
+
+ case TREQ_SIM_SET_CALLFORWARDING:
+ {
+ const struct treq_sim_set_callforwarding *cf = NULL;
+ cf = (struct treq_sim_set_callforwarding *) tcore_user_request_ref_data(ur, NULL);
+
+ if (cf){
+ if (cphs_sim) {
+ struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
+ if(!svct)
+ break;
+ if ((sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_CFIS]) || (sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_CFIS])) {
+ if (cf->b_cphs == FALSE) {
+ ef = SIM_EF_USIM_CFIS;
+ } else {
+ ef = SIM_EF_CPHS_CALL_FORWARD_FLAGS;
+ }
+ tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
+ ret_code = _get_file_info(co_sim, ur, ef);
+ } else {
+ dbg("Service not available in SST/UST - Updating CPHS file : File ID[0x%x]", SIM_EF_CPHS_CALL_FORWARD_FLAGS);
+ ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
+ }
+ free(svct);
+ } else {
+ ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_CFIS);
+ }
+ } else {
+ ret_code = TCORE_RETURN_EINVAL;
+ }
+ }
+ break;
+
+ case TREQ_SIM_SET_MESSAGEWAITING:
+ {
+ const struct treq_sim_set_messagewaiting *mw = NULL;
+ mw = (struct treq_sim_set_messagewaiting *) tcore_user_request_ref_data(ur, NULL);
+ if (mw) {
+ if(cphs_sim) {
+ struct tel_sim_service_table *svct = tcore_sim_get_service_table(co_sim);
+ if(!svct)
+ break;
+ if (( sim_type == SIM_TYPE_GSM && svct->table.sst.service[SIM_SST_MWIS] ) || ( sim_type == SIM_TYPE_USIM && svct->table.ust.service[SIM_UST_MWIS] )) {
+ if (mw->b_cphs == FALSE) {
+ ef = SIM_EF_USIM_MWIS;
+ } else {
+ ef = SIM_EF_CPHS_VOICE_MSG_WAITING;
+ }
+ tcore_user_request_set_metainfo(ur, sizeof(struct imc_sim_property), &meta_info);
+ ret_code = _get_file_info(co_sim, ur, ef);
+ } else {
+ dbg("Service not available in SST/UST - Updating CPHS file : File ID[0x%x]", SIM_EF_CPHS_VOICE_MSG_WAITING);
+ ret_code = _get_file_info(co_sim, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
+ }
+ free(svct);
+ } else {
+ ret_code = _get_file_info(co_sim, ur, SIM_EF_USIM_MWIS);
+ }
+ } else{
+ ret_code = TCORE_RETURN_EINVAL;
+ }
+ }
+ break;
+
+ default:
+ {
+ err("Unhandled UPDATE command[%d]", command);
+ return TCORE_RETURN_EINVAL;
+ }
+ }
+
+ return ret_code;
+}
+
+static TReturn imc_transmit_apdu(CoreObject *o, UserRequest *ur)
+{
+ const struct treq_sim_transmit_apdu *req_data;
+ TcoreHal *hal = NULL;
+ char *cmd_str = NULL;
+ char *apdu = NULL;
+ int result = 0;
+ TReturn ret = TCORE_RETURN_FAILURE;
+
+ dbg("Entry");
+
+ if ((o == NULL )|| (ur == NULL))
+ return TCORE_RETURN_EINVAL;
+
+ hal = tcore_object_get_hal(o);
+ if (FALSE == tcore_hal_get_power_state(hal)) {
+ err("CP NOT READY");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ apdu = (char *)g_try_malloc0((2 * req_data->apdu_length) + 1);
+ if (apdu == NULL) {
+ err("Memory allocation failed!!");
+ return TCORE_RETURN_ENOMEM;
+ }
+ result = util_byte_to_hex((const char *)req_data->apdu, apdu, req_data->apdu_length);
+ dbg("result %d", result);
+
+ cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", strlen(apdu), apdu);
+
+ ret = tcore_prepare_and_send_at_request(o, cmd_str, "+CSIM:",
+ TCORE_AT_SINGLELINE, ur,
+ on_response_transmit_apdu, hal,
+ NULL, NULL, 0, NULL, NULL);
+ g_free(cmd_str);
+ g_free(apdu);
+
+ dbg("Exit");
+ return ret;
+}
+
+static TReturn imc_get_atr(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal = NULL;
+
+ dbg("Entry");
+
+ if ((o == NULL )|| (ur == NULL)) {
+ err("Invalid parameters");
+ return TCORE_RETURN_EINVAL;
+ }
+
+ hal = tcore_object_get_hal(o);
+ if (FALSE == tcore_hal_get_power_state(hal)) {
+ err("CP NOT READY");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ return tcore_prepare_and_send_at_request(o, "AT+XGATR", "+XGATR:",
+ TCORE_AT_SINGLELINE, ur,
+ on_response_get_atr, hal,
+ NULL, NULL, 0, NULL, NULL);
+}
+
+static TReturn imc_req_authentication(CoreObject *co, UserRequest *ur)
+{
+ const struct treq_sim_req_authentication *req_data;
+ char *cmd_str = NULL;
+ enum tel_sim_type sim_type;
+ int session_id;
+ int context_type;
+ TReturn ret = TCORE_RETURN_FAILURE;
+ char *convert_rand = NULL;
+ char *convert_autn = NULL;
+
+ dbg("Entry");
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+ if (req_data == NULL) {
+ err("req_data is NULL");
+ return ret;
+ }
+
+ convert_rand = util_hex_to_string(req_data->rand_data, strlen(req_data->rand_data));
+ dbg("Convert RAND hex to string: [%s]", convert_rand);
+
+ sim_type = tcore_sim_get_type(co);
+ switch (sim_type) {
+ case SIM_TYPE_GSM:
+ case SIM_TYPE_USIM:
+ session_id = 0;
+ break;
+ default:
+ err("Not supported");
+ ret = TCORE_RETURN_ENOSYS;
+ goto out;
+ }
+
+ switch (req_data->auth_type) {
+ case SIM_AUTH_TYPE_GSM:
+ context_type = 2;
+ cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\"", session_id,
+ context_type, convert_rand);
+ break;
+ case SIM_AUTH_TYPE_3G:
+ context_type = 1;
+ convert_autn = util_hex_to_string(req_data->autn_data, strlen(req_data->autn_data));
+ dbg("Convert AUTN hex to string: [%s]", convert_autn);
+
+ cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\",\"%s\"",
+ session_id, context_type,
+ convert_rand, convert_autn);
+ break;
+ default:
+ err("Not supported");
+ ret = TCORE_RETURN_ENOSYS;
+ goto out;
+ }
+
+ ret = tcore_prepare_and_send_at_request(co, cmd_str, "+XAUTH",
+ TCORE_AT_SINGLELINE, ur,
+ on_response_req_authentication, NULL, NULL, NULL, 0, NULL, NULL);
+
+out:
+ g_free(cmd_str);
+ g_free(convert_rand);
+ g_free(convert_autn);
+
+ return ret;
+}
+
+/* SIM Operations */
+static struct tcore_sim_operations sim_ops = {
+ .verify_pins = imc_verify_pins,
+ .verify_puks = imc_verify_puks,
+ .change_pins = imc_change_pins,
+ .get_facility_status = imc_get_facility_status,
+ .enable_facility = imc_enable_facility,
+ .disable_facility = imc_disable_facility,
+ .get_lock_info = imc_get_lock_info,
+ .read_file = imc_read_file,
+ .update_file = imc_update_file,
+ .transmit_apdu = imc_transmit_apdu,
+ .get_atr = imc_get_atr,
+ .req_authentication = imc_req_authentication,
+ .set_powerstate = NULL,
+};
+
+gboolean imc_sim_init(TcorePlugin *cp, CoreObject *co_sim)
+{
+ struct imc_sim_property *meta_info;
+
+ dbg("Entry");
+
+ /* Set operations */
+ tcore_sim_set_ops(co_sim, &sim_ops);
+
+ meta_info = g_try_new0(struct imc_sim_property, 1);
+ if (meta_info == NULL)
+ return FALSE;
+
+ tcore_sim_link_userdata(co_sim, meta_info);
+
+ tcore_object_add_callback(co_sim, "+XLOCK:",
+ on_event_facility_lock_status, NULL);
+ tcore_object_add_callback(co_sim, "+XSIM:",
+ on_event_pin_status, NULL);
+
+ tcore_server_add_notification_hook(tcore_plugin_ref_server(cp),
+ TNOTI_MODEM_POWER, on_hook_modem_power, co_sim);
+
+ dbg("Exit");
+
+ return TRUE;
+}
+
+void imc_sim_exit(TcorePlugin *cp, CoreObject *co_sim)
+{
+ struct imc_sim_property *meta_info;
+
+ meta_info = tcore_sim_ref_userdata(co_sim);
+ g_free(meta_info);
+
+ dbg("Exit");
+}
#include <at.h>
#include <plugin.h>
-#include "common/TelErr.h"
-#include "s_common.h"
-#include "s_sms.h"
+#include <util.h>
+
+#include "common/imc_tel_err.h"
+#include "imc_common.h"
+#include "imc_sms.h"
/*=============================================================
- GSM-SMS Size
+ GSM-SMS Size
==============================================================*/
-#define MAX_GSM_SMS_TPDU_SIZE 244
-#define MAX_GSM_SMS_MSG_NUM 255
-#define MAX_GSM_SMS_SERVICE_CENTER_ADDR 12 /* Maximum number of bytes of service center address */
-#define MAX_GSM_SMS_CBMI_LIST_SIZE 100 /* Maximum number of CBMI list size for CBS 30*2=60 */
-#define MAX_GSM_SMS_PARAM_RECORD_SIZE 156 /* Maximum number of bytes SMSP Record size (Y + 28), y : 0 ~ 128 */
-#define MAX_GSM_SMS_STATUS_FILE_SIZE 2 /* Last Used TP-MR + SMS "Memory Cap. Exceeded" Noti Flag */
-#define TAPI_SIM_SMSP_ADDRESS_LEN 20
+#define MAX_GSM_SMS_TPDU_SIZE 244
+#define MAX_GSM_SMS_MSG_NUM 255
+#define MAX_GSM_SMS_SERVICE_CENTER_ADDR 12 /* Maximum number of bytes of service center address */
+#define MAX_GSM_SMS_CBMI_LIST_SIZE 100 /* Maximum number of CBMI list size for CBS 30*2=60 */
+#define MAX_GSM_SMS_PARAM_RECORD_SIZE 156 /* Maximum number of bytes SMSP Record size (Y + 28), y : 0 ~ 128 */
+#define MAX_GSM_SMS_STATUS_FILE_SIZE 2 /* Last Used TP-MR + SMS "Memory Cap. Exceeded" Noti Flag */
+#define TAPI_SIM_SMSP_ADDRESS_LEN 20
/*=============================================================
- Device Ready
+ Device Ready
==============================================================*/
-#define AT_SMS_DEVICE_READY 12 /* AT device ready */
-#define SMS_DEVICE_READY 1 /* Telephony device ready */
-#define SMS_DEVICE_NOT_READY 0 /* Telephony device not ready */
+#define SMS_DEVICE_READY 1 /* Telephony device ready */
+#define SMS_DEVICE_NOT_READY 0 /* Telephony device not ready */
/*=============================================================
- CBMI Selection
+ CBMI Selection
==============================================================*/
-#define SMS_CBMI_SELECTED_SOME 0x02 /* Some CBMIs are selected */
-#define SMS_CBMI_SELECTED_ALL 0x01 /* All CBMIs are selected */
+#define SMS_CBMI_SELECTED_SOME 0x02 /* Some CBMIs are selected */
+#define SMS_CBMI_SELECTED_ALL 0x01 /* All CBMIs are selected */
/*=============================================================
- Message Status
+ Message Status
==============================================================*/
-#define AT_REC_UNREAD 0 /* Received and Unread */
-#define AT_REC_READ 1 /* Received and Read */
-#define AT_STO_UNSENT 2 /* Unsent */
-#define AT_STO_SENT 3 /* Sent */
-#define AT_ALL 4 /* Unknown */
+#define AT_REC_UNREAD 0 /* Received and Unread */
+#define AT_REC_READ 1 /* Received and Read */
+#define AT_STO_UNSENT 2 /* Unsent */
+#define AT_STO_SENT 3 /* Sent */
+#define AT_ALL 4 /* Unknown */
/*=============================================================
- Memory Status
+ Memory Status
==============================================================*/
-#define AT_MEMORY_AVAILABLE 0 /* Memory Available */
-#define AT_MEMORY_FULL 1 /* Memory Full */
+#define AT_MEMORY_AVAILABLE 0 /* Memory Available */
+#define AT_MEMORY_FULL 1 /* Memory Full */
/*=============================================================
- SIM CRSM SW1 and Sw2 Error definitions */
-
-#define AT_SW1_SUCCESS 0x90
-#define AT_SW2_SUCCESS 0
-#define AT_SW1_LEN_RESP 0x9F
-
-#define AT_MAX_RECORD_LEN 256
-#define AT_EF_SMS_RECORD_LEN 176
+ SIM CRSM SW1 and Sw2 Error definitions */
-/*=============================================================*/
+#define AT_SW1_SUCCESS 0x90
+#define AT_SW2_SUCCESS 0
+#define AT_SW1_LEN_RESP 0x9F
-
-/*=========================================================
- Security
-==============================================================*/
-#define MAX_SEC_PIN_LEN 8
-#define MAX_SEC_PUK_LEN 8
-#define MAX_SEC_PHONE_LOCK_PW_LEN 39 /* Maximum Phone Locking Password Length */
-#define MAX_SEC_SIM_DATA_STRING 256 /* Maximum Length of the DATA or RESPONSE. Restricted SIM Access, Generic SIM Access Message */
-#define MAX_SEC_NUM_LOCK_TYPE 8 /* Maximum number of Lock Type used in Lock Information Message */
-#define MAX_SEC_IMS_AUTH_LEN 512 /* Maximum Length of IMS Authentication Message */
+#define AT_MAX_RECORD_LEN 256
+ /* 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)
/*=============================================================
- String Preprocessor
+ String Preprocessor
==============================================================*/
-#define CR '\r' /* Carriage Return */
+#define CR '\r' /* Carriage Return */
/*=============================================================
- Developer
+ Developer
==============================================================*/
-#define SMS_SWAPBYTES16(x) (((x) & 0xffff0000) | (((x) & 0x0000ff00) >> 8) | (((x) & 0x000000ff) << 8))
+#define SMS_SWAPBYTES16(x) ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8))
+#define SMS_ENCODED_SCA_LEN_MAX 12
+#define CONVERT_TO_HEX(in, out) (in <= 9) ? \
+ (out = '0' + in) : (out = 'A' + in - 10)
void print_glib_list_elem(gpointer data, gpointer user_data);
gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
-/* gaurav.kalra: For test */
void print_glib_list_elem(gpointer data, gpointer user_data)
{
- char *item = (char *) data;
+ char *item = (char *)data;
dbg("item: [%s]", item);
}
/*=============================================================
- Send Callback
+ Send Callback
==============================================================*/
static void on_confirmation_sms_message_send(TcorePending *p, gboolean result, void *user_data)
{
}
/*=============================================================
- Utilities
+ Utilities
==============================================================*/
static void util_sms_free_memory(void *sms_ptr)
{
}
+static guint __util_sms_encode_pdu(const guchar *sca,
+ const guchar *tpdu, guint tpdu_len, gchar *pdu)
+{
+ guint sca_len = 0;
+ unsigned char converted_sca[SMS_ENCODED_SCA_LEN_MAX];
+
+ if (sca[0] == 0) {
+ converted_sca[0] = 0;
+ sca_len = 0;
+ }
+ else {
+ unsigned int i;
+ /*
+ * For PDU, the SC Address length is the number of packed BCD bytes
+ * + 1 byte for SC Address type whereas the length given in
+ * 3GPP 23.040 Address encoding is the number of digits without 1 byte
+ * for address type.
+ */
+ sca_len = ((sca[0] + 1) / 2) + 1;
+
+ converted_sca[0] = (unsigned char)sca_len;
+
+ for (i = 1; i <= sca_len; i++)
+ converted_sca[i] = sca[i];
+ }
+
+ memcpy(pdu, converted_sca, sca_len + 1);
+ memcpy(pdu + sca_len + 1, tpdu, tpdu_len);
+
+ return sca_len + 1 + tpdu_len;
+
+}
+
+static long __util_sms_encode_hex(const guchar *src, long num_bytes, gchar *buf)
+{
+ long i, j;
+
+ if (num_bytes <= 0)
+ return -1;
+
+ for (i = 0, j = 0; i < num_bytes; i++, j++) {
+ CONVERT_TO_HEX(((src[i] >> 4) & 0xf), buf[j++]);
+ CONVERT_TO_HEX((src[i] & 0xf), buf[j]);
+ }
+
+ buf[j] = '\0';
+
+ return j;
+}
+
static int util_sms_decode_smsParameters(unsigned char *incoming, unsigned int length, struct telephony_sms_Params *params)
{
int alpha_id_len = 0;
dbg(" RecordLen = %d", length);
- if (incoming == NULL || params == NULL)
+ if(incoming == NULL || params == NULL)
return FALSE;
- alpha_id_len = length - SMS_SMSP_PARAMS_MAX_LEN;
+ alpha_id_len = length -SMS_SMSP_PARAMS_MAX_LEN;
if (alpha_id_len > 0) {
if (alpha_id_len > SMS_SMSP_ALPHA_ID_LEN_MAX) {
dbg(" Alpha id length is zero");
}
- // dongil01.park - start parse from here.
params->paramIndicator = incoming[alpha_id_len];
dbg(" Param Indicator = %02x", params->paramIndicator);
- // dongil01.park(2008/12/26) - DestAddr
if ((params->paramIndicator & SMSPValidDestAddr) == 0) {
nOffset = nDestAddrOffset;
params->tpDestAddr.dialNumLen = 0;
}
- // dongil01.park(2008/12/26) - SvcAddr
if ((params->paramIndicator & SMSPValidSvcAddr) == 0) {
nOffset = nSCAAddrOffset;
}
}
} else {
- params->tpSvcCntrAddr.dialNumLen = 0;
+ params->tpSvcCntrAddr.dialNumLen = 0;
}
if ((params->paramIndicator & SMSPValidPID) == 0 && (alpha_id_len + nPIDOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
for (i = 0; i < (int) params->alphaIdLen; i++) {
dbg(" Alpha Id = [%d] [%c]", i, params->szAlphaId[i]);
}
- dbg(" PID = %d", params->tpProtocolId);
- dbg(" DCS = %d", params->tpDataCodingScheme);
- dbg(" VP = %d", params->tpValidityPeriod);
+ dbg(" PID = %d",params->tpProtocolId);
+ dbg(" DCS = %d",params->tpDataCodingScheme);
+ dbg(" VP = %d",params->tpValidityPeriod);
return TRUE;
}
-
/*=============================================================
- Notifications
+ Notifications
==============================================================*/
-static gboolean on_event_sms_ready_status(CoreObject *o, const void *event_info, void *user_data)
+static gboolean on_event_class2_sms_incom_msg(CoreObject *obj,
+ const void *event_info, void *user_data)
{
- struct tnoti_sms_ready_status readyStatusInfo = {0, };
- char *line = NULL;
- GSList *tokens = NULL;
- GSList *lines = NULL;
- char *pResp = NULL;
- // CoreObject *o = NULL;
+ //+CMTI: <mem>,<index>
- int rtn = -1, status = 0;
-
- dbg(" Func Entrance");
-
- lines = (GSList *) event_info;
- if (1 != g_slist_length(lines)) {
- dbg("unsolicited msg but multiple line");
- goto OUT;
- }
- line = (char *) (lines->data);
-
- dbg(" Func Entrance");
-
- if (line != NULL) {
- dbg("Response OK");
- dbg("noti line is %s", line);
- tokens = tcore_at_tok_new(line);
- pResp = g_slist_nth_data(tokens, 0);
- if (pResp != NULL)
- status = atoi(pResp);
- } else {
- dbg("Response NOK");
- }
-
- if (status == AT_SMS_DEVICE_READY) {
- readyStatusInfo.status = SMS_DEVICE_READY;
- tcore_sms_set_ready_status(o, readyStatusInfo.status);
- dbg("SMS Ready status = [%s]", readyStatusInfo.status ? "TRUE" : "FALSE");
- rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_DEVICE_READY, sizeof(struct tnoti_sms_ready_status), &readyStatusInfo);
- dbg(" Return value [%d]", rtn);
- } else {
- readyStatusInfo.status = SMS_DEVICE_NOT_READY;
- }
-
-OUT:
- if (NULL != tokens)
- tcore_at_tok_free(tokens);
- return TRUE;
-}
-
-static gboolean on_event_class2_sms_incom_msg(CoreObject *obj, const void *event_info, void *user_data)
-{
- // +CMTI: <mem>,<index>
-
- GSList *tokens = NULL, *lines = NULL;
+ GSList *tokens = NULL , *lines = NULL;
char *line = NULL, *cmd_str = NULL;
int index = 0, mem_type = 0;
TcoreHal *hal = NULL;
dbg("Entered Function");
- lines = (GSList *) event_info;
- line = (char *) g_slist_nth_data(lines, 0); /* Fetch Line 1 */
+ lines = (GSList *)event_info;
+ line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
dbg("Line 1: [%s]", line);
tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
mem_type = atoi(g_slist_nth_data(tokens, 0)); // Type of Memory stored
+ if (mem_type == 0)
+ err("Token 0 not present");
+
index = atoi((char *) g_slist_nth_data(tokens, 1));
hal = tcore_object_get_hal(obj);
dbg("index: [%d]", index);
cmd_str = g_strdup_printf("AT+CMGR=%d", index);
- atreq = tcore_at_request_new((const char *) cmd_str, "+CMGR", TCORE_AT_PDU);
+ atreq = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
pending = tcore_pending_new(obj, 0);
if (NULL == cmd_str || NULL == atreq || NULL == pending) {
err("Out of memory. Unable to proceed");
dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
- // free memory we own
+ //free memory we own
g_free(cmd_str);
util_sms_free_memory(atreq);
util_sms_free_memory(pending);
return TCORE_RETURN_ENOMEM;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_class2_read_msg, (void *) (uintptr_t) index); // storing index as user data for response
+ tcore_pending_set_response_callback(pending, on_response_class2_read_msg, (void *)(uintptr_t)index); //storing index as user data for response
tcore_pending_link_user_request(pending, NULL);
tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
tcore_hal_send_request(hal, pending);
g_free(cmd_str);
- if (tokens)
+ if(tokens)
tcore_at_tok_free(tokens);
return TRUE;
static gboolean on_event_sms_incom_msg(CoreObject *o, const void *event_info, void *user_data)
{
- // +CMT: [<alpha>],<length><CR><LF><pdu> (PDU mode enabled);
+ //+CMT: [<alpha>],<length><CR><LF><pdu> (PDU mode enabled);
- int rtn = -1;
+ TReturn ret;
GSList *tokens = NULL;
GSList *lines = NULL;
char *line = NULL;
dbg("Entered Function");
- lines = (GSList *) event_info;
+ lines = (GSList *)event_info;
memset(&gsmMsgInfo, 0x00, sizeof(struct tnoti_sms_umts_msg));
if (2 != g_slist_length(lines)) {
return FALSE;
}
- line = (char *) g_slist_nth_data(lines, 0); /* Fetch Line 1 */
+ line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
dbg("Line 1: [%s]", line);
if (no_of_tokens == 2) { // in case of incoming SMS +CMT
dbg("Alpha ID: [%02x]", g_slist_nth_data(tokens, 0)); /* 0: Alpha ID */
- pdu_len = atoi((char *) g_slist_nth_data(tokens, 1));
- dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
+ pdu_len = atoi((char *)g_slist_nth_data(tokens, 1));
+ dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
} else if (no_of_tokens == 1) { // in case of incoming status report +CDS
- pdu_len = atoi((char *) g_slist_nth_data(tokens, 0));
- dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
+ pdu_len = atoi((char *)g_slist_nth_data(tokens, 0));
+ dbg("pdu_len: [%d]", pdu_len); /* 1: PDU Length */
}
- line = (char *) g_slist_nth_data(lines, 1); /* Fetch Line 2 */
+ line = (char *)g_slist_nth_data(lines, 1); /* Fetch Line 2 */
dbg("Line 2: [%s]", line);
}
/* Convert to Bytes */
- bytePDU = (unsigned char *) util_hexStringToBytes(line);
-
+ bytePDU = (unsigned char *)util_hexStringToBytes(line);
+ if (!bytePDU) {
+ err("NULL data received[%p]", bytePDU);
+ tcore_at_tok_free(tokens);
+ return FALSE;
+ }
sca_length = bytePDU[0];
dbg("SCA length = %d", sca_length);
- gsmMsgInfo.msgInfo.msgLength = pdu_len - (sca_length + 1);
+ gsmMsgInfo.msgInfo.msgLength = pdu_len;
if (sca_length == 0) {
memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
} else {
- memcpy(gsmMsgInfo.msgInfo.sca, &bytePDU[1], sca_length);
- memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length + 1], gsmMsgInfo.msgInfo.msgLength);
+ gsmMsgInfo.msgInfo.sca[0] = sca_length;
+ memcpy(&(gsmMsgInfo.msgInfo.sca[1]), &bytePDU[1], sca_length);
+ memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length+1], gsmMsgInfo.msgInfo.msgLength);
}
- util_hex_dump(" ", strlen(line) / 2, bytePDU);
+ util_hex_dump(" ", strlen(line)/2, bytePDU);
util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
- util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength, gsmMsgInfo.msgInfo.tpduData);
+ util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength,gsmMsgInfo.msgInfo.tpduData);
- rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_INCOM_MSG, sizeof(struct tnoti_sms_umts_msg), &gsmMsgInfo);
+ ret = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_INCOM_MSG, sizeof(struct tnoti_sms_umts_msg), &gsmMsgInfo);
+ dbg("ret: %x", ret);
- if (tokens)
+ if(tokens)
tcore_at_tok_free(tokens);
- free(bytePDU);
+ g_free(bytePDU);
return TRUE;
}
static gboolean on_event_sms_memory_status(CoreObject *o, const void *event_info, void *user_data)
{
- struct tnoti_sms_memory_status memStatusInfo = {0, };
+ struct tnoti_sms_memory_status memStatusInfo = {0,};
- int rtn = -1, memoryStatus = -1;
- GSList *tokens = NULL;
- GSList *lines = NULL;
- char *line = NULL, *pResp = NULL;
+ int memoryStatus = -1;
+ GSList *tokens=NULL;
+ GSList *lines=NULL;
+ char *line = NULL , *pResp = NULL;
+ TReturn ret;
dbg(" Entry");
- lines = (GSList *) event_info;
+ lines = (GSList *)event_info;
if (1 != g_slist_length(lines)) {
- dbg("unsolicited msg but multiple line");
- }
+ dbg("unsolicited msg but multiple line");
+ }
- line = (char *) (lines->data);
+ line = (char*)(lines->data);
if (line) {
dbg("Response OK");
if (pResp) {
memoryStatus = atoi(pResp);
- dbg("memoryStatus is %d", memoryStatus);
- if (memoryStatus == 0) { // SIM Full condition
+ dbg("memoryStatus is %d",memoryStatus);
+ if (memoryStatus == 0) {//SIM Full condition
memStatusInfo.status = SMS_PHONE_MEMORY_STATUS_FULL;
}
- rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_MEMORY_STATUS, sizeof(struct tnoti_sms_memory_status), &memStatusInfo);
+ ret = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_MEMORY_STATUS, sizeof(struct tnoti_sms_memory_status), &memStatusInfo);
+ dbg("ret: %x", ret);
}
tcore_at_tok_free(tokens);
- } else {
+ }else {
dbg("Response NOK");
}
static gboolean on_event_sms_cb_incom_msg(CoreObject *o, const void *event_info, void *user_data)
{
- // +CBM: <length><CR><LF><pdu>
+ //+CBM: <length><CR><LF><pdu>
struct tnoti_sms_cellBroadcast_msg cbMsgInfo;
- int rtn = -1, length = 0;
- char *line = NULL, *pdu = NULL, *pResp = NULL;
+ int rtn = -1 , length = 0;
+ char * line = NULL, *pdu = NULL, *pResp = NULL;
GSList *tokens = NULL;
GSList *lines = NULL;
dbg(" Func Entrance");
- lines = (GSList *) event_info;
+ lines = (GSList *)event_info;
memset(&cbMsgInfo, 0, sizeof(struct tnoti_sms_cellBroadcast_msg));
- line = (char *) (lines->data);
+ line = (char *)(lines->data);
if (line != NULL) {
dbg("Response OK");
- dbg("Noti line is %s", line);
+ dbg("Noti line is %s",line);
tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
pResp = g_slist_nth_data(tokens, 0);
pdu = g_slist_nth_data(lines, 1);
if (pdu != NULL) {
cbMsgInfo.cbMsg.length = length;
- cbMsgInfo.cbMsg.cbMsgType = SMS_CB_MSG_CBS;
+ cbMsgInfo.cbMsg.cbMsgType = SMS_CB_MSG_GSM;
dbg("CB Msg LENGTH [%2x]", length);
- if ((cbMsgInfo.cbMsg.length > 0) && (SMS_CB_SIZE_MAX >= cbMsgInfo.cbMsg.length)) {
+ if ((cbMsgInfo.cbMsg.length >0) && (SMS_CB_SIZE_MAX >= cbMsgInfo.cbMsg.length)) {
unsigned char *byte_pdu = NULL;
- byte_pdu = (unsigned char *) util_hexStringToBytes(pdu);
-
- memcpy(cbMsgInfo.cbMsg.msgData, (char *) byte_pdu, cbMsgInfo.cbMsg.length);
- rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_CB_INCOM_MSG, sizeof(struct tnoti_sms_cellBroadcast_msg), &cbMsgInfo);
- free(byte_pdu);
+ byte_pdu = (unsigned char *)util_hexStringToBytes(pdu);
+ if (byte_pdu) {
+ memcpy(cbMsgInfo.cbMsg.msgData, (char*)byte_pdu, cbMsgInfo.cbMsg.length);
+ rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SMS_CB_INCOM_MSG, sizeof(struct tnoti_sms_cellBroadcast_msg), &cbMsgInfo);
+ g_free(byte_pdu);
+ } else {
+ err("util_hexStringToBytes Failed!!");
+ }
} else {
dbg("Invalid Message Length");
}
dbg("Response NOK");
}
- dbg(" Return value [%d]", rtn);
+ dbg(" Return value [%d]",rtn);
- if (tokens)
+ if(tokens)
tcore_at_tok_free(tokens);
return TRUE;
/*=============================================================
- Responses
+ Responses
==============================================================*/
static void on_response_sms_delete_msg(TcorePending *p, int data_len, const void *data, void *user_data)
{
- struct tresp_sms_delete_msg delMsgInfo = {0, };
+ struct tresp_sms_delete_msg delMsgInfo = {0,};
UserRequest *ur = NULL;
const TcoreATResponse *atResp = data;
-
- int rtn = -1;
int index = (int) user_data;
dbg(" Func Entrance");
delMsgInfo.result = SMS_DEVICE_FAILURE;
}
- rtn = tcore_user_request_send_response(ur, TRESP_SMS_DELETE_MSG, sizeof(struct tresp_sms_delete_msg), &delMsgInfo);
+ tcore_user_request_send_response(ur, TRESP_SMS_DELETE_MSG, sizeof(struct tresp_sms_delete_msg), &delMsgInfo);
return;
}
static void on_response_sms_save_msg(TcorePending *p, int data_len, const void *data, void *user_data)
{
- struct tresp_sms_save_msg saveMsgInfo = {0, };
+ struct tresp_sms_save_msg saveMsgInfo = {0,};
UserRequest *ur = NULL;
const TcoreATResponse *atResp = data;
GSList *tokens = NULL;
if (atResp->success) {
dbg("Response OK");
if (atResp->lines) {
- line = (char *) atResp->lines->data;
+ line = (char *)atResp->lines->data;
tokens = tcore_at_tok_new(line);
pResp = g_slist_nth_data(tokens, 0);
if (pResp) {
dbg("0: %s", pResp);
- saveMsgInfo.index = (atoi(pResp) - 1); /* IMC index starts from 1 */
+ saveMsgInfo.index = (atoi(pResp) - 1); /* IMC index starts from 1 */
saveMsgInfo.result = SMS_SENDSMS_SUCCESS;
} else {
dbg("No Tokens");
memset(&resp_umts, 0x00, sizeof(resp_umts));
resp_umts.result = SMS_DEVICE_FAILURE;
- if (at_response->success > 0) { // success
+ if (at_response->success > 0) { /* SUCCESS */
dbg("Response OK");
if (at_response->lines) { // lines present in at_response
- gslist_line = (char *) at_response->lines->data;
+ gslist_line = (char *)at_response->lines->data;
dbg("gslist_line: [%s]", gslist_line);
- tokens = tcore_at_tok_new(gslist_line); // extract tokens
+ tokens = tcore_at_tok_new(gslist_line); //extract tokens
line_token = g_slist_nth_data(tokens, 0);
if (line_token != NULL) {
static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
{
const TcoreATResponse *at_response = data;
- GSList *tokens = NULL;
+ GSList *tokens=NULL;
char *gslist_line = NULL, *line_token = NULL, *hex_pdu = NULL;
- int pdu_len = 0, rtn = 0;
+ int pdu_len = 0, rtn = 0;
unsigned char *bytePDU = NULL;
struct tnoti_sms_umts_msg gsmMsgInfo;
- int sca_length = 0;
+ int sca_length= 0;
dbg("Entry");
dbg("lines: [%p]", at_response->lines);
- g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); // for debug log
+ g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
if (at_response->success > 0) {
dbg("Response OK");
if (at_response->lines) {
- // fetch first line
- gslist_line = (char *) at_response->lines->data;
+ //fetch first line
+ gslist_line = (char *)at_response->lines->data;
dbg("gslist_line: [%s]", gslist_line);
tokens = tcore_at_tok_new(gslist_line);
dbg("Number of tokens: [%d]", g_slist_length(tokens));
- g_slist_foreach(tokens, print_glib_list_elem, NULL); // for debug log
+ g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
- line_token = g_slist_nth_data(tokens, 2); // Third Token: Length
+ line_token = g_slist_nth_data(tokens, 2); //Third Token: Length
if (line_token != NULL) {
pdu_len = atoi(line_token);
dbg("Length: [%d]", pdu_len);
}
- // fetch second line
- gslist_line = (char *) at_response->lines->next->data;
+ //fetch second line
+ gslist_line = (char *)at_response->lines->next->data;
dbg("gslist_line: [%s]", gslist_line);
- // free the consumed token
+ //free the consumed token
tcore_at_tok_free(tokens);
tokens = tcore_at_tok_new(gslist_line);
dbg("Number of tokens: [%d]", g_slist_length(tokens));
- g_slist_foreach(tokens, print_glib_list_elem, NULL); // for debug log
+ g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
- hex_pdu = g_slist_nth_data(tokens, 0); // Fetch SMS PDU
+ hex_pdu = g_slist_nth_data(tokens, 0); //Fetch SMS PDU
- // free the consumed token
+ //free the consumed token
tcore_at_tok_free(tokens);
} else {
dbg("No lines");
}
/* Convert to Bytes */
- bytePDU = (unsigned char *) util_hexStringToBytes(hex_pdu);
-
+ bytePDU = (unsigned char *)util_hexStringToBytes(hex_pdu);
+ if (!bytePDU) {
+ err("util_hexStringToBytes Failed!!");
+ return;
+ }
sca_length = bytePDU[0];
dbg("SCA length = %d", sca_length);
- gsmMsgInfo.msgInfo.msgLength = pdu_len - (sca_length + 1);
+ gsmMsgInfo.msgInfo.msgLength = pdu_len;
if (sca_length == 0) {
memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[1], gsmMsgInfo.msgInfo.msgLength);
} else {
memcpy(gsmMsgInfo.msgInfo.sca, bytePDU, sca_length);
- memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length + 1], gsmMsgInfo.msgInfo.msgLength);
+ memcpy(gsmMsgInfo.msgInfo.tpduData, &bytePDU[sca_length+1], gsmMsgInfo.msgInfo.msgLength);
}
- util_hex_dump(" ", strlen(hex_pdu) / 2, bytePDU);
+ util_hex_dump(" ", strlen(hex_pdu)/2, bytePDU);
util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
- util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength, gsmMsgInfo.msgInfo.tpduData);
+ util_hex_dump(" ", gsmMsgInfo.msgInfo.msgLength,gsmMsgInfo.msgInfo.tpduData);
- rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(tcore_pending_ref_core_object(pending))), tcore_pending_ref_core_object(pending), TNOTI_SMS_INCOM_MSG, sizeof(struct tnoti_sms_umts_msg), &gsmMsgInfo);
+ rtn = tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(tcore_pending_ref_core_object(pending))),
+ tcore_pending_ref_core_object(pending), TNOTI_SMS_INCOM_MSG, sizeof(struct tnoti_sms_umts_msg), &gsmMsgInfo);
+ dbg("rtn: [%d]", rtn);
- free(bytePDU);
+ g_free(bytePDU);
dbg("Exit");
return;
struct tresp_sms_read_msg resp_read_msg;
UserRequest *user_req = NULL;
- GSList *tokens = NULL;
+ GSList *tokens=NULL;
char *gslist_line = NULL, *line_token = NULL, *byte_pdu = NULL, *hex_pdu = NULL;
int sca_length = 0;
int msg_status = 0, alpha_id = 0, pdu_len = 0;
- int index = (int) (uintptr_t) user_data;
+ int index = (int)(uintptr_t)user_data;
dbg("Entry");
dbg("index: [%d]", index);
- g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); // for debug log
+ g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
user_req = tcore_pending_ref_user_request(pending);
if (NULL == user_req) {
if (at_response->success > 0) {
dbg("Response OK");
if (at_response->lines) {
- // fetch first line
- gslist_line = (char *) at_response->lines->data;
+ if (g_slist_length(at_response->lines) != 2) {
+ err("2 lines are required");
+ goto OUT;
+ }
+ //fetch first line
+ gslist_line = (char *)at_response->lines->data;
dbg("gslist_line: [%s]", gslist_line);
tokens = tcore_at_tok_new(gslist_line);
dbg("Number of tokens: [%d]", g_slist_length(tokens));
- g_slist_foreach(tokens, print_glib_list_elem, NULL); // for debug log
+ g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
- line_token = g_slist_nth_data(tokens, 0); // First Token: Message Status
+ line_token = g_slist_nth_data(tokens, 0); //First Token: Message Status
if (line_token != NULL) {
msg_status = atoi(line_token);
- dbg("msg_status is %d", msg_status);
+ dbg("msg_status is %d",msg_status);
switch (msg_status) {
- case AT_REC_UNREAD:
- resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNREAD;
- break;
-
- case AT_REC_READ:
- resp_read_msg.dataInfo.msgStatus = SMS_STATUS_READ;
- break;
-
- case AT_STO_UNSENT:
- resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNSENT;
- break;
-
- case AT_STO_SENT:
- resp_read_msg.dataInfo.msgStatus = SMS_STATUS_SENT;
- break;
-
- case AT_ALL: // Fall Through
- default: // Fall Through
- resp_read_msg.dataInfo.msgStatus = SMS_STATUS_RESERVED;
- break;
+ case AT_REC_UNREAD:
+ resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNREAD;
+ break;
+
+ case AT_REC_READ:
+ resp_read_msg.dataInfo.msgStatus = SMS_STATUS_READ;
+ break;
+
+ case AT_STO_UNSENT:
+ resp_read_msg.dataInfo.msgStatus = SMS_STATUS_UNSENT;
+ break;
+
+ case AT_STO_SENT:
+ resp_read_msg.dataInfo.msgStatus = SMS_STATUS_SENT;
+ break;
+
+ case AT_ALL: //Fall Through
+ default: //Fall Through
+ resp_read_msg.dataInfo.msgStatus = SMS_STATUS_RESERVED;
+ break;
}
}
- line_token = g_slist_nth_data(tokens, 1); // Second Token: AlphaID
+ line_token = g_slist_nth_data(tokens, 1); //Second Token: AlphaID
if (line_token != NULL) {
alpha_id = atoi(line_token);
dbg("AlphaID: [%d]", alpha_id);
}
- line_token = g_slist_nth_data(tokens, 2); // Third Token: Length
+ line_token = g_slist_nth_data(tokens, 2); //Third Token: Length
if (line_token != NULL) {
pdu_len = atoi(line_token);
dbg("Length: [%d]", pdu_len);
}
- // fetch second line
+ //fetch second line
hex_pdu = (char *) at_response->lines->next->data;
dbg("EF-SMS PDU: [%s]", hex_pdu);
- // free the consumed token
+ //free the consumed token
tcore_at_tok_free(tokens);
if (NULL != hex_pdu) {
- util_hex_dump(" ", sizeof(hex_pdu), (void *) hex_pdu);
+ util_hex_dump(" ", strlen(hex_pdu), (void *)hex_pdu);
byte_pdu = util_hexStringToBytes(hex_pdu);
+ if (!byte_pdu) {
+ err("util_hexStringToBytes Failed!!");
+ goto OUT;
+ }
+ sca_length = (int)byte_pdu[0];
- sca_length = (int) byte_pdu[0];
-
- resp_read_msg.dataInfo.simIndex = index; // Retrieving index stored as user_data
+ resp_read_msg.dataInfo.simIndex = index; //Retrieving index stored as user_data
dbg("SCA Length : %d", sca_length);
resp_read_msg.dataInfo.smsData.msgLength = pdu_len;
dbg("msgLength: [%d]", resp_read_msg.dataInfo.smsData.msgLength);
- if (0 == sca_length) {
+ if(0 == sca_length) {
if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
- && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
+ && (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
memset(resp_read_msg.dataInfo.smsData.sca, 0, TAPI_SIM_SMSP_ADDRESS_LEN);
memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[1], resp_read_msg.dataInfo.smsData.msgLength);
dbg("Invalid Message Length");
resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
}
+ } else if (sca_length > SMS_ENCODED_SCA_LEN_MAX) {
+ dbg("Invalid Message Length");
+ resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
} else {
if ((resp_read_msg.dataInfo.smsData.msgLength > 0)
&& (resp_read_msg.dataInfo.smsData.msgLength <= SMS_SMDATA_SIZE_MAX)) {
- memcpy(resp_read_msg.dataInfo.smsData.sca, (char *) byte_pdu, (sca_length + 1));
- memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[sca_length + 1], resp_read_msg.dataInfo.smsData.msgLength);
+ memcpy(resp_read_msg.dataInfo.smsData.sca, (char *)byte_pdu, (sca_length+1));
+ memcpy(resp_read_msg.dataInfo.smsData.tpduData, &byte_pdu[sca_length+1], resp_read_msg.dataInfo.smsData.msgLength);
- util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *) resp_read_msg.dataInfo.smsData.sca);
- util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX + 1), (void *) resp_read_msg.dataInfo.smsData.tpduData);
- util_hex_dump(" ", sizeof(byte_pdu), (void *) byte_pdu);
+ util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)resp_read_msg.dataInfo.smsData.sca);
+ util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX + 1), (void *)resp_read_msg.dataInfo.smsData.tpduData);
+ util_hex_dump(" ", strlen(hex_pdu) / 2 + 1, (void *)byte_pdu);
resp_read_msg.result = SMS_SUCCESS;
} else {
resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
}
}
- free(byte_pdu);
- } else {
+ g_free(byte_pdu);
+ }else {
dbg("NULL PDU");
}
- } else {
+ }else {
dbg("No lines");
}
} else {
err("Response NOK");
}
+OUT:
tcore_user_request_send_response(user_req, TRESP_SMS_READ_MSG, sizeof(resp_read_msg), &resp_read_msg);
dbg("Exit");
dbg("Entry");
- resp_stored_msg_cnt_prev = (struct tresp_sms_get_storedMsgCnt *) user_data;
+ resp_stored_msg_cnt_prev = (struct tresp_sms_get_storedMsgCnt *)user_data;
user_req = tcore_pending_ref_user_request(pending);
memset(&resp_stored_msg_cnt, 0x00, sizeof(resp_stored_msg_cnt));
gslist_line_count = SMS_GSM_SMS_MSG_NUM_MAX;
dbg("Number of lines: [%d]", gslist_line_count);
- g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); // for debug log
+ g_slist_foreach(at_response->lines, print_glib_list_elem, NULL); //for debug log
for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
- gslist_line = (char *) g_slist_nth_data(at_response->lines, ctr_loop); /* Fetch Line i */
+ gslist_line = (char *)g_slist_nth_data(at_response->lines, ctr_loop); /* Fetch Line i */
dbg("gslist_line [%d] is [%s]", ctr_loop, gslist_line);
if (NULL != gslist_line) {
tokens = tcore_at_tok_new(gslist_line);
- g_slist_foreach(tokens, print_glib_list_elem, NULL); // for debug log
+ g_slist_foreach(tokens, print_glib_list_elem, NULL); //for debug log
line_token = g_slist_nth_data(tokens, 0);
if (NULL != line_token) {
dbg("gslist_line [%d] is NULL", ctr_loop);
continue;
}
- }
+ }
} else {
dbg("No lines.");
if (resp_stored_msg_cnt_prev->storedMsgCnt.usedCount == 0) { // Check if used count is zero
UserRequest *ur = NULL, *ur_dup = NULL;
struct tresp_sms_get_storedMsgCnt *respStoredMsgCnt = NULL;
const TcoreATResponse *atResp = data;
- GSList *tokens = NULL;
- char *line = NULL, *pResp = NULL, *cmd_str = NULL;
+ GSList *tokens=NULL;
+ char *line = NULL , *pResp = NULL , *cmd_str = NULL;
TcoreATRequest *atReq = NULL;
int usedCnt = 0, totalCnt = 0, result = 0;
dbg("Entered");
respStoredMsgCnt = malloc(sizeof(struct tresp_sms_get_storedMsgCnt));
+ if (!respStoredMsgCnt)
+ return;
+
result = SMS_DEVICE_FAILURE;
ur = tcore_pending_ref_user_request(pending);
if (atResp->success > 0) {
dbg("Response OK");
if (NULL != atResp->lines) {
- line = (char *) atResp->lines->data;
- dbg("line is %s", line);
+ line = (char *)atResp->lines->data;
+ dbg("line is %s",line);
tokens = tcore_at_tok_new(line);
pResp = g_slist_nth_data(tokens, 0);
if (pResp) {
- usedCnt = atoi(pResp);
- dbg("used cnt is %d", usedCnt);
+ usedCnt =atoi(pResp);
+ dbg("used cnt is %d",usedCnt);
}
pResp = g_slist_nth_data(tokens, 1);
if (pResp) {
- totalCnt = atoi(pResp);
+ totalCnt =atoi(pResp);
result = SMS_SENDSMS_SUCCESS;
respStoredMsgCnt->storedMsgCnt.usedCount = usedCnt;
respStoredMsgCnt->storedMsgCnt.totalCount = totalCnt;
respStoredMsgCnt->result = result;
- dbg("used %d, total %d, result %d", usedCnt, totalCnt, result);
+ dbg("used %d, total %d, result %d",usedCnt, totalCnt,result);
pending_new = tcore_pending_new(o, 0);
- // Get all messages information
+ //Get all messages information
cmd_str = g_strdup_printf("AT+CMGL=4");
- atReq = tcore_at_request_new((const char *) cmd_str, "+CMGL", TCORE_AT_MULTILINE);
+ atReq = tcore_at_request_new((const char *)cmd_str, "+CMGL", TCORE_AT_MULTILINE);
- dbg("cmd str is %s", cmd_str);
+ dbg("cmd str is %s",cmd_str);
- tcore_pending_set_request_data(pending_new, 0, atReq);
- tcore_pending_set_response_callback(pending_new, on_response_get_msg_indices, (void *) respStoredMsgCnt);
+ tcore_pending_set_request_data(pending_new, 0,atReq);
+ tcore_pending_set_response_callback(pending_new, on_response_get_msg_indices, (void *)respStoredMsgCnt);
tcore_pending_link_user_request(pending_new, ur_dup);
tcore_pending_set_send_callback(pending_new, on_confirmation_sms_message_send, NULL);
tcore_hal_send_request(tcore_object_get_hal(o), pending_new);
- // free the consumed token
+ //free the consumed token
tcore_at_tok_free(tokens);
g_free(cmd_str);
dbg("Exit");
return;
}
- // free the consumed token
+ //free the consumed token
if (tokens)
- tcore_at_tok_free(tokens);
+ tcore_at_tok_free(tokens);
} else {
dbg("No data");
}
UserRequest *user_req = NULL;
GSList *tokens = NULL;
+ const char *sca_tok_addr;
char *gslist_line = NULL, *sca_addr = NULL, *sca_toa = NULL;
dbg("Entry");
if (at_response->success) {
dbg("Response OK");
if (at_response->lines) {
- gslist_line = (char *) at_response->lines->data;
+ gslist_line = (char *)at_response->lines->data;
tokens = tcore_at_tok_new(gslist_line);
- sca_addr = g_slist_nth_data(tokens, 0);
+ 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);
if ((NULL != sca_addr)
&& (NULL != sca_toa)) {
dbg("sca_addr: [%s]. sca_toa: [%s]", sca_addr, sca_toa);
tcore_user_request_send_response(user_req, TRESP_SMS_GET_SCA, sizeof(respGetSca), &respGetSca);
- if (tokens)
- tcore_at_tok_free(tokens);
+ tcore_at_tok_free(tokens);
+ g_free(sca_addr);
dbg("Exit");
return;
/*
Response is expected in this format
OK
- or
+ or
+CMS ERROR: <err>
*/
-
- // CoreObject *obj = user_data;
UserRequest *ur;
- // copies the AT response data to resp
+ //copies the AT response data to resp
const TcoreATResponse *atResp = data;
struct tresp_sms_set_sca respSetSca;
UserRequest *ur;
struct tresp_sms_get_cb_config respGetCbConfig;
const TcoreATResponse *atResp = data;
- GSList *tokens = NULL;
- int i = 0, mode = 0, h_flag = FALSE;
- char *mid = NULL, *mid1 = NULL, *pResp = NULL, *line = NULL;
- char delim[] = ",", delim1[] = "-";
+ GSList *tokens=NULL;
+ int i = 0, mode =0;
+ char *pResp = NULL, *line = NULL;
memset(&respGetCbConfig, 0, sizeof(struct tresp_sms_get_cb_config));
respGetCbConfig.result = SMS_DEVICE_FAILURE;
if (atResp->success) {
dbg("Response OK");
if (atResp->lines) {
- line = (char *) atResp->lines->data;
+ line = (char*)atResp->lines->data;
if (line != NULL) {
- dbg("line is %s", line);
+ dbg("line is %s",line);
tokens = tcore_at_tok_new(line);
pResp = g_slist_nth_data(tokens, 0);
if (pResp) {
pResp = g_slist_nth_data(tokens, 1);
if (pResp) {
- mid = strtok(pResp, delim); // check for multiple msg ids seperated by comma delimiter
- while (mid != NULL) {
- mid1 = strtok(mid, delim1); // check for msg id ranges where delim is hyphen. Ex 0 -21
- while (mid1 != NULL) {
- respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(mid1);
- mid1 = strtok(NULL, delim1);
- if (mid1 != NULL) {
- respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(mid1);
- }
- respGetCbConfig.cbConfig.msgIDs[i].net3gpp.selected = TRUE;
- respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
- i++;
- h_flag = TRUE;
- }
- if ((h_flag == FALSE) && (mid != NULL) && (strlen(mid) > 0)) {
- respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(mid);
- respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(mid);
- respGetCbConfig.cbConfig.msgIDs[i].net3gpp.selected = TRUE;
- i++;
+ GSList *cb_tokens = NULL;
+ char *cb_mid_str = NULL;
+ int num_cb_tokens = 0;
+ char *mid_tok = NULL;
+ char *first_tok = NULL, *second_tok = NULL;
+ char *ptr = NULL;
+
+ // 0,1,5,320-478,922
+ cb_mid_str = util_removeQuotes(pResp);
+ cb_tokens = tcore_at_tok_new((const char *) cb_mid_str);
+
+ g_free(cb_mid_str);
+
+ num_cb_tokens = g_slist_length(cb_tokens);
+ dbg("num_cb_tokens = %d", num_cb_tokens);
+
+ if (num_cb_tokens == 0) {
+ if (mode == 1) { // Enable all CBs
+ respGetCbConfig.cbConfig.msgIdRangeCount = 1;
+ respGetCbConfig.cbConfig.msgIDs[0].net3gpp.fromMsgId = 0x0000;
+ respGetCbConfig.cbConfig.msgIDs[0].net3gpp.toMsgId = SMS_GSM_SMS_CBMI_LIST_SIZE_MAX + 1;
+ respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = TRUE;
+ respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
+ } else { // all CBs disabled
+ respGetCbConfig.cbConfig.msgIdRangeCount = 0;
+ respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
}
- dbg("mid is %s\n", mid);
- mid = strtok(NULL, delim);
- }
-
- respGetCbConfig.cbConfig.msgIdRangeCount = i;
- } else {
- if (mode == 1) {
- respGetCbConfig.cbConfig.msgIdRangeCount = 1;
- respGetCbConfig.cbConfig.msgIDs[0].net3gpp.fromMsgId = 0x0000;
- respGetCbConfig.cbConfig.msgIDs[0].net3gpp.toMsgId = 0xFFFF;
- respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = TRUE;
- respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
} else {
respGetCbConfig.cbConfig.msgIdRangeCount = 0;
respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
}
+
+ for (i = 0; i < num_cb_tokens; i++) {
+ respGetCbConfig.cbConfig.msgIDs[i].net3gpp.selected = TRUE;
+ respGetCbConfig.cbConfig.msgIdRangeCount++;
+
+ mid_tok = tcore_at_tok_nth(cb_tokens, i);
+ first_tok = strtok_r(mid_tok, "-", &ptr);
+ second_tok = strtok_r(NULL, "-", &ptr);
+
+ if ((first_tok != NULL) && (second_tok != NULL)) { // mids in range (320-478)
+ dbg("inside if mid_range");
+ respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(first_tok);
+ respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(second_tok);
+ } // single mid value (0,1,5, 922)
+ else {
+ respGetCbConfig.cbConfig.msgIDs[i].net3gpp.fromMsgId = atoi(mid_tok);
+ respGetCbConfig.cbConfig.msgIDs[i].net3gpp.toMsgId = atoi(mid_tok);
+ }
+ }
}
}
- } else {
+ }else {
dbg("line is NULL");
}
- } else {
+ }else {
dbg("atresp->lines is NULL");
}
- } else {
+ }else {
dbg("RESPONSE NOK");
}
tcore_user_request_send_response(ur, TRESP_SMS_GET_CB_CONFIG, sizeof(struct tresp_sms_get_cb_config), &respGetCbConfig);
- if (tokens)
+ if(tokens)
tcore_at_tok_free(tokens);
return;
/*
Response is expected in this format
OK
- or
+ or
+CMS ERROR: <err>
*/
const TcoreATResponse *resp = data;
int response = 0;
const char *line = NULL;
- GSList *tokens = NULL;
+ GSList *tokens=NULL;
- struct tresp_sms_set_cb_config respSetCbConfig = {0, };
+ struct tresp_sms_set_cb_config respSetCbConfig = {0,};
memset(&respSetCbConfig, 0, sizeof(struct tresp_sms_set_cb_config));
dbg("RESPONSE OK");
} else {
dbg("RESPONSE NOK");
- line = (const char *) resp->final_response;
+ line = (const char*)resp->final_response;
tokens = tcore_at_tok_new(line);
if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- respSetCbConfig.result = SMS_DEVICE_FAILURE;
+ dbg("err cause not specified or string corrupted");
+ respSetCbConfig.result = SMS_DEVICE_FAILURE;
} else {
response = atoi(g_slist_nth_data(tokens, 0));
+ dbg("response is %d", response);
/* TODO: CMEE error mapping is required. */
- respSetCbConfig.result = SMS_DEVICE_FAILURE;
+ respSetCbConfig.result = SMS_DEVICE_FAILURE;
}
}
if (!ur) {
tcore_user_request_send_response(ur, TRESP_SMS_SET_CB_CONFIG, sizeof(struct tresp_sms_set_cb_config), &respSetCbConfig);
- if (tokens)
+ if(tokens)
tcore_at_tok_free(tokens);
return;
static void on_response_set_mem_status(TcorePending *p, int data_len, const void *data, void *user_data)
{
UserRequest *ur;
- struct tresp_sms_set_mem_status respSetMemStatus = {0, };
+ struct tresp_sms_set_mem_status respSetMemStatus = {0,};
const TcoreATResponse *resp = data;
memset(&respSetMemStatus, 0, sizeof(struct tresp_sms_set_mem_status));
if (pResp != NULL) {
response = atoi(pResp);
- dbg("response is %s", response);
+ dbg("response is %d", response);
}
} else {
dbg("No lines");
dbg("RESPONSE NOK");
}
- tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS, sizeof(struct tresp_sms_set_msg_status), &respMsgStatus);
+ tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &respMsgStatus);
- if (tokens)
+ if(tokens)
tcore_at_tok_free(tokens);
dbg("Exit");
static void on_response_get_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
{
UserRequest *ur;
- struct tresp_sms_get_params respGetParams;
+ struct tresp_sms_get_params respGetParams ;
const TcoreATResponse *atResp = data;
int sw1 = 0, sw2 = 0;
const char *line = NULL;
char *pResp = NULL;
- GSList *tokens = NULL;
- char *hexData = NULL;
- char *recordData = NULL;
- int i = 0;
+ GSList *tokens=NULL;
+ char *hexData = NULL;
+ char *recordData = NULL;
+ int i = 0;
memset(&respGetParams, 0, sizeof(struct tresp_sms_get_params));
respGetParams.result = SMS_DEVICE_FAILURE;
pResp = g_slist_nth_data(tokens, 2);
if (pResp != NULL) {
hexData = util_removeQuotes(pResp);
+ if (hexData) {
+ recordData = util_hexStringToBytes(hexData);
+ util_hex_dump(" ", strlen(hexData) / 2, recordData);
- recordData = util_hexStringToBytes(hexData);
- util_hex_dump(" ", strlen(hexData) / 2, recordData);
-
- respGetParams.paramsInfo.recordLen = strlen(hexData) / 2;
+ respGetParams.paramsInfo.recordLen = strlen(hexData) / 2;
- util_sms_decode_smsParameters((unsigned char *) recordData, strlen(hexData) / 2, &(respGetParams.paramsInfo));
- respGetParams.result = SMS_SENDSMS_SUCCESS;
+ util_sms_decode_smsParameters((unsigned char *) recordData, strlen(hexData) / 2, &(respGetParams.paramsInfo));
+ respGetParams.result = SMS_SENDSMS_SUCCESS;
- for (i = 0; i < (int) respGetParams.paramsInfo.tpSvcCntrAddr.dialNumLen; i++)
- dbg("SCAddr = %d [%02x]", i, respGetParams.paramsInfo.tpSvcCntrAddr.diallingNum[i]);
+ for (i = 0; i < (int) respGetParams.paramsInfo.tpSvcCntrAddr.dialNumLen; i++)
+ dbg("SCAddr = %d [%02x]", i, respGetParams.paramsInfo.tpSvcCntrAddr.diallingNum[i]);
- free(recordData);
- free(hexData);
+ g_free(recordData);
+ g_free(hexData);
+ }
} else {
dbg("No response");
}
UserRequest *ur;
struct tresp_sms_set_params respSetParams = {0, };
const TcoreATResponse *atResp = data;
- int sw1 = 0, sw2 = 0;
+ int sw1 =0 , sw2 = 0;
const char *line = NULL;
char *pResp = NULL;
- GSList *tokens = NULL;
+ GSList *tokens=NULL;
memset(&respSetParams, 0, sizeof(struct tresp_sms_set_params));
dbg("RESPONSE NOK");
}
- tcore_user_request_send_response(ur, TRESP_SMS_SET_PARAMS, sizeof(struct tresp_sms_set_params), &respSetParams);
+ tcore_user_request_send_response(ur, TRESP_SMS_SET_PARAMS , sizeof(struct tresp_sms_set_params), &respSetParams);
- if (tokens)
+ if(tokens)
tcore_at_tok_free(tokens);
dbg("Exit");
UserRequest *ur = NULL;
struct tresp_sms_get_paramcnt respGetParamCnt = {0, };
const TcoreATResponse *atResp = data;
- char *line = NULL, *pResp = NULL;
- int sw1 = 0, sw2 = 0, *smsp_record_len = NULL;
+ char *line = NULL , *pResp = NULL;
+ int sw1 = 0 , sw2 = 0, *smsp_record_len = NULL;
int sim_type = 0;
- GSList *tokens = NULL;
- CoreObject *co_sim = NULL; // need this to get the sim type GSM/USIM
+ GSList *tokens=NULL;
+ CoreObject *co_sim = NULL; //need this to get the sim type GSM/USIM
TcorePlugin *plugin = NULL;
dbg("Entry");
unsigned char *ptr_data;
recordData = util_hexStringToBytes(hexData);
- util_hex_dump(" ", strlen(hexData) / 2, recordData);
+ if (!recordData) {
+ err("util_hexStringToBytes Failed!!");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+
+ util_hex_dump(" ", strlen(hexData)/2, recordData);
- ptr_data = (unsigned char *) recordData;
+ ptr_data = (unsigned char *)recordData;
- co_sim = tcore_plugin_ref_core_object(tcore_pending_ref_plugin(p), "sim");
+ co_sim = tcore_plugin_ref_core_object(tcore_pending_ref_plugin(p), CORE_OBJECT_TYPE_SIM);
sim_type = tcore_sim_get_type(co_sim);
- dbg("sim type is %d", sim_type);
+ dbg("sim type is %d",sim_type);
- if (sim_type == SIM_TYPE_USIM) {
+ if (sim_type == SIM_TYPE_USIM) {
/*
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)
- */
+ - 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 */
/* increment to next byte */
ptr_data++;
tag_len = *ptr_data++;
+ dbg("tag_len: [%d]", 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++;
- /* unsigned char file_desc_len = *ptr_data++;*/
- /* dbg("file descriptor length: [%d]", file_desc_len);*/
- /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
- /* consider only last 3 bits*/
- file_type_tag = file_type_tag & (*ptr_data);
-
- switch (file_type_tag) {
/* increment to next byte */
ptr_data++;
+ /*2 or 5 value*/
+ ptr_data++;
+ /* unsigned char file_desc_len = *ptr_data++;*/
+ /* dbg("file descriptor length: [%d]", file_desc_len);*/
+ /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
+ /* consider only last 3 bits*/
+ file_type_tag = file_type_tag & (*ptr_data);
+
+ switch (file_type_tag) {
+ /* increment to next byte */
+ ptr_data++;
case 0x1:
dbg("Getting FileType: [Transparent file type]");
/* increment to next byte */
ptr_data++;
- file_type = 0x01; // SIM_FTYPE_TRANSPARENT
+ file_type = 0x01; //SIM_FTYPE_TRANSPARENT
/* data coding byte - value 21 */
ptr_data++;
break;
ptr_data = ptr_data + 2;
num_of_records = *ptr_data++;
/* Data lossy conversation from enum (int) to unsigned char */
- file_type = 0x02; // SIM_FTYPE_LINEAR_FIXED
+ file_type = 0x02; // SIM_FTYPE_LINEAR_FIXED
break;
case 0x6:
record_len = SMS_SWAPBYTES16(record_len);
ptr_data = ptr_data + 2;
num_of_records = *ptr_data++;
- file_type = 0x04; // SIM_FTYPE_CYCLIC
+ file_type = 0x04; //SIM_FTYPE_CYCLIC
break;
default:
}
} else {
dbg("INVALID FCP received - DEbug!");
+ g_free(hexData);
+ g_free(recordData);
tcore_at_tok_free(tokens);
return;
}
dbg("Getting FileID=[0x%x]", file_id);
} else {
dbg("INVALID FCP received - DEbug!");
- free(hexData);
- free(recordData);
+ g_free(hexData);
+ g_free(recordData);
tcore_at_tok_free(tokens);
return;
}
ptr_data++;
switch (*ptr_data) {
- case 0x04:
- case 0x06:
- dbg("<IPC_RX> operation state -deactivated");
- ptr_data++;
- break;
-
- case 0x05:
- case 0x07:
- dbg("<IPC_RX> operation state -activated");
- ptr_data++;
- break;
-
- default:
- dbg("<IPC_RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
- ptr_data++;
- break;
+ case 0x04:
+ case 0x06:
+ dbg("[RX] Operation State: DEACTIVATED");
+ ptr_data++;
+ break;
+
+ case 0x05:
+ case 0x07:
+ dbg("[RX] Operation State: ACTIVATED");
+ ptr_data++;
+ break;
+
+ default:
+ dbg("[RX] DEBUG! LIFE CYCLE STATUS: [0x%x]",*ptr_data);
+ ptr_data++;
+ break;
}
}
arr_file_id = SMS_SWAPBYTES16(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;
+ // 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);
- free(hexData);
- free(recordData);
+ g_free(hexData);
+ g_free(recordData);
tcore_at_tok_free(tokens);
return;
}
ptr_data = ptr_data + 2;
} else {
dbg("INVALID FCP received - DEbug!");
- free(hexData);
- free(recordData);
+ g_free(hexData);
+ g_free(recordData);
tcore_at_tok_free(tokens);
return;
}
ptr_data++;
/* length */
len = *ptr_data;
+ dbg("len: [%d]", len);
/* ignored bytes */
ptr_data = ptr_data + 3;
} else {
}
} else {
dbg("INVALID FCP received - DEbug!");
- free(hexData);
- free(recordData);
+ g_free(hexData);
+ g_free(recordData);
tcore_at_tok_free(tokens);
return;
}
ptr_data++;
ptr_data++;
/* file size */
- // file_size = p_info->response_len;
+ //file_size = p_info->response_len;
memcpy(&file_size, ptr_data, 2);
/* swap bytes */
file_size = SMS_SWAPBYTES16(file_size);
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++;
+ 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 */
+ 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) ? 0x01 : 0x02; // SIM_FTYPE_TRANSPARENT:SIM_FTYPE_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 = 0x04; // SIM_FTYPE_CYCLIC;
+ }
+ /* bytes 9 to 11 give SIM file access conditions */
ptr_data++;
- file_type =
- (file_type_tag == 0x00) ? 0x01 : 0x02; // SIM_FTYPE_TRANSPARENT:SIM_FTYPE_LINEAR_FIXED;
- } else {
- /* increment to next byte */
+ /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
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 = 0x04; // SIM_FTYPE_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;
- 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);
+ /* 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);
+ if (record_len != 0)
+ num_of_records = (file_size / record_len);
- dbg("Number of records [%d]", num_of_records);
- break;
+ dbg("Number of records [%d]", num_of_records);
+ break;
- default:
- dbg(" not handled file type");
- break;
+ default:
+ dbg(" not handled file type");
+ break;
}
} else {
dbg(" Card Type - UNKNOWN [%d]", sim_type);
respGetParamCnt.recordCount = num_of_records;
respGetParamCnt.result = SMS_SUCCESS;
- // TO Store smsp record length in the property
+ //TO Store smsp record length in the property
plugin = tcore_pending_ref_plugin(p);
smsp_record_len = tcore_plugin_ref_property(plugin, "SMSPRECORDLEN");
memcpy(smsp_record_len, &record_len, sizeof(int));
- free(recordData);
- free(hexData);
+ g_free(recordData);
+ g_free(hexData);
} else {
/*2. SIM access fail case*/
dbg("SIM access fail");
tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMCNT, sizeof(struct tresp_sms_get_paramcnt), &respGetParamCnt);
- if (tokens)
+ if(tokens)
tcore_at_tok_free(tokens);
dbg("Exit");
{
UserRequest *ur = NULL;
UserRequest *dup_ur = NULL;
- struct tresp_sms_set_msg_status resp_msg_status = {0, };
- const struct treq_sms_set_msg_status *req_msg_status = NULL;
+ struct tresp_sms_set_msg_status resp_msg_status = {0,};
+ const struct treq_sms_set_msg_status *req_msg_status = NULL ;
const TcoreATResponse *resp = data;
char *encoded_data = NULL;
char msg_status = 0;
char *pResp = NULL;
- GSList *tokens = NULL;
+ GSList *tokens=NULL;
const char *line = NULL;
int sw1 = 0;
int sw2 = 0;
if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
switch (req_msg_status->msgStatus) {
- case SMS_STATUS_READ:
- msg_status = 0x01;
- break;
+ case SMS_STATUS_READ:
+ msg_status = 0x01;
+ break;
- case SMS_STATUS_UNREAD:
- msg_status = 0x03;
- break;
+ case SMS_STATUS_UNREAD:
+ msg_status = 0x03;
+ break;
- case SMS_STATUS_UNSENT:
- msg_status = 0x07;
- break;
+ case SMS_STATUS_UNSENT:
+ msg_status = 0x07;
+ break;
- case SMS_STATUS_SENT:
- msg_status = 0x05;
- break;
+ case SMS_STATUS_SENT:
+ msg_status = 0x05;
+ break;
- case SMS_STATUS_DELIVERED:
- msg_status = 0x1D;
- break;
+ case SMS_STATUS_DELIVERED:
+ msg_status = 0x1D;
+ break;
- case SMS_STATUS_DELIVERY_UNCONFIRMED:
- msg_status = 0xD;
- break;
+ case SMS_STATUS_DELIVERY_UNCONFIRMED:
+ msg_status = 0xD;
+ break;
- case SMS_STATUS_MESSAGE_REPLACED:
- case SMS_STATUS_RESERVED:
- default:
- msg_status = 0x03;
- break;
+ case SMS_STATUS_MESSAGE_REPLACED:
+ case SMS_STATUS_RESERVED:
+ default:
+ msg_status = 0x03;
+ break;
}
encoded_data = util_removeQuotes(pResp);
+ if (!encoded_data) {
+ err("Encoded data is NULL");
+ goto OUT;
+ }
- // overwrite Status byte information
- util_byte_to_hex((const char *) &msg_status, (char *) encoded_data, 1);
+ //overwrite Status byte information
+ util_byte_to_hex((const char *)&msg_status, (char *)encoded_data, 1);
- // Update EF-SMS with just status byte overwritten, rest 175 bytes are same as received in read information
- cmd_str = g_strdup_printf("AT+CRSM=220,28476,%d, 4, %d, \"%s\"", (req_msg_status->index + 1), AT_EF_SMS_RECORD_LEN, encoded_data);
- atreq = tcore_at_request_new((const char *) cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
+ //Update EF-SMS with just status byte overwritten, rest 175 bytes are same as received in read information
+ cmd_str = g_strdup_printf("AT+CRSM=220,28476,%d, 4, %d, \"%s\"", (req_msg_status->index+1), PDU_LEN_MAX, encoded_data);
+ atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
pending = tcore_pending_new(tcore_pending_ref_core_object(pending), 0);
if (NULL == cmd_str || NULL == atreq || NULL == pending) {
err("Out of memory. Unable to proceed");
dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
- // free memory we own
+ //free memory we own
g_free(cmd_str);
- free(encoded_data);
+ g_free(encoded_data);
util_sms_free_memory(atreq);
util_sms_free_memory(pending);
goto OUT;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
dup_ur = tcore_user_request_ref(ur);
tcore_hal_send_request(hal, pending);
g_free(cmd_str);
- free(encoded_data);
+ g_free(encoded_data);
+
+ resp_msg_status.result = SMS_SENDSMS_SUCCESS;
}
}
OUT:
- if (tokens)
+ if(tokens)
tcore_at_tok_free(tokens);
- tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS, sizeof(struct tresp_sms_set_msg_status), &msg_status);
+ tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &resp_msg_status);
dbg("Exit");
}
/*=============================================================
- Requests
+ Requests
==============================================================*/
-static TReturn send_umts_msg(CoreObject *obj, UserRequest *ur)
+static TReturn send_umts_msg(CoreObject *co_sms, UserRequest *ur)
{
- gchar *cmd_str = NULL;
- TcoreHal *hal = NULL;
- TcoreATRequest *atreq = NULL;
- TcorePending *pending = NULL;
- const struct treq_sms_send_umts_msg *sendUmtsMsg = NULL;
- char buf[2 * (SMS_SMSP_ADDRESS_LEN + SMS_SMDATA_SIZE_MAX) + 1] = {0};
- int ScLength = 0;
- int pdu_len = 0;
+ const struct treq_sms_send_umts_msg *send_msg;
+ const unsigned char *tpdu_byte_data;
+ const unsigned char *sca_byte_data;
+ int tpdu_byte_len;
+ int pdu_byte_len;
+ int pdu_hex_len = 0;
+ char buf[HEX_PDU_LEN_MAX];
+ char pdu[PDU_LEN_MAX];
+ char *cmd_str;
+ int mms = 0;
+ TReturn ret;
- dbg("Entry");
+ dbg("Enter");
- sendUmtsMsg = tcore_user_request_ref_data(ur, NULL);
- hal = tcore_object_get_hal(obj);
- if (NULL == sendUmtsMsg || NULL == hal) {
- err("NULL input. Unable to proceed");
- dbg("sendUmtsMsg: [%p], hal: [%p]", sendUmtsMsg, hal);
+ send_msg = tcore_user_request_ref_data(ur, NULL);
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
- }
+ tpdu_byte_data = send_msg->msgDataPackage.tpduData;
+ sca_byte_data = send_msg->msgDataPackage.sca;
- dbg("msgLength: [%d]", sendUmtsMsg->msgDataPackage.msgLength);
- util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX + 1), (void *) sendUmtsMsg->msgDataPackage.tpduData);
- util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *) sendUmtsMsg->msgDataPackage.sca);
- ScLength = (int) sendUmtsMsg->msgDataPackage.sca[0];
+ /* TPDU length is in byte */
+ tpdu_byte_len = send_msg->msgDataPackage.msgLength;
+ dbg("TDPU length: [%d]", tpdu_byte_len);
+ dbg("SCA semi-octet length: [%d]", sca_byte_data[0]);
- dbg("ScLength: [%d]", ScLength);
+ /* Use same Radio Resource Channel */
+ mms = send_msg->more;
- if ((sendUmtsMsg->msgDataPackage.msgLength > 0)
- && (sendUmtsMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX)
- && (ScLength <= SMS_MAX_SMS_SERVICE_CENTER_ADDR)) {
- if (ScLength == 0) { // ScAddress not specified
- buf[0] = '0';
- buf[1] = '0';
- pdu_len = 2;
- } else {
- dbg("Specifying SCA in TPDU is currently not supported");
-
- buf[0] = '0';
- buf[1] = '0';
- pdu_len = 2;
- }
+ /* Prepare PDU for hex encoding */
+ pdu_byte_len = __util_sms_encode_pdu(sca_byte_data, tpdu_byte_data,
+ tpdu_byte_len, pdu);
- util_byte_to_hex((const char *) sendUmtsMsg->msgDataPackage.tpduData, (char *) &buf[pdu_len], sendUmtsMsg->msgDataPackage.msgLength);
+ pdu_hex_len = (int) __util_sms_encode_hex((unsigned char *) pdu,
+ pdu_byte_len, buf);
- pdu_len = pdu_len + 2 * sendUmtsMsg->msgDataPackage.msgLength;
+ dbg("PDU hexadecimal length: [%d]", pdu_hex_len);
- buf[pdu_len] = '\0'; // Ensure termination
+ if (mms > 0) {
+ cmd_str = g_strdup_printf("AT+CMMS=%d", mms);
- dbg("pdu_len: [%d]", pdu_len);
- util_hex_dump(" ", sizeof(buf), (void *) buf);
-
- // AT+CMGS=<length><CR>PDU is given<ctrl-Z/ESC>
- cmd_str = g_strdup_printf("AT+CMGS=%d%s%s\x1A", sendUmtsMsg->msgDataPackage.msgLength, "\r", buf);
- atreq = tcore_at_request_new((const char *) cmd_str, "+CMGS", TCORE_AT_SINGLELINE);
- pending = tcore_pending_new(obj, 0);
-
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
- err("Out of memory. Unable to proceed");
- dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
-
- // free memory we own
- g_free(cmd_str);
- util_sms_free_memory(atreq);
- util_sms_free_memory(pending);
-
- dbg("Exit");
- return TCORE_RETURN_ENOMEM;
+ ret = tcore_prepare_and_send_at_request(co_sms, cmd_str, NULL,
+ TCORE_AT_NO_RESULT, NULL, NULL, NULL,
+ on_confirmation_sms_message_send,
+ NULL, 0, NULL, NULL);
+ if (ret != TCORE_RETURN_SUCCESS) {
+ err("Failed to prepare and send AT request");
+ goto error;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ g_free(cmd_str);
+ }
- tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_send_umts_msg, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
- tcore_hal_send_request(hal, pending);
+ cmd_str = g_strdup_printf("AT+CMGS=%d\r%s\x1A", tpdu_byte_len, buf);
- g_free(cmd_str);
+ ret = tcore_prepare_and_send_at_request(co_sms, cmd_str, "+CMGS:",
+ TCORE_AT_SINGLELINE, ur,
+ on_response_send_umts_msg, NULL,
+ on_confirmation_sms_message_send, NULL,
+ 0, NULL, NULL);
+ if (ret != TCORE_RETURN_SUCCESS)
+ err("Failed to prepare and send AT request");
- dbg("Exit");
- return TCORE_RETURN_SUCCESS;
- }
+error:
+ g_free(cmd_str);
- err("Invalid Data len");
dbg("Exit");
- return TCORE_RETURN_SMS_INVALID_DATA_LEN;
+
+ return ret;
}
static TReturn read_msg(CoreObject *obj, UserRequest *ur)
return TCORE_RETURN_EINVAL;
}
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
dbg("index: [%d]", readMsg->index);
- cmd_str = g_strdup_printf("AT+CMGR=%d", (readMsg->index + 1)); // IMC index is one ahead of TAPI
- atreq = tcore_at_request_new((const char *) cmd_str, "+CMGR", TCORE_AT_PDU);
+ cmd_str = g_strdup_printf("AT+CMGR=%d", readMsg->index); //IMC index is one ahead of TAPI
+ atreq = tcore_at_request_new((const char *)cmd_str, "+CMGR", TCORE_AT_PDU);
pending = tcore_pending_new(obj, 0);
if (NULL == cmd_str || NULL == atreq || NULL == pending) {
err("Out of memory. Unable to proceed");
dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
- // free memory we own
+ //free memory we own
g_free(cmd_str);
util_sms_free_memory(atreq);
util_sms_free_memory(pending);
return TCORE_RETURN_ENOMEM;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
tcore_pending_set_request_data(pending, 0, atreq);
- tcore_pending_set_response_callback(pending, on_response_read_msg, (void *) (uintptr_t) (readMsg->index)); // storing index as user data for response
+ tcore_pending_set_response_callback(pending, on_response_read_msg, (void *)(uintptr_t)(readMsg->index)); //storing index as user data for response
tcore_pending_link_user_request(pending, ur);
tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
tcore_hal_send_request(hal, pending);
TcorePending *pending = NULL;
const struct treq_sms_save_msg *saveMsg = NULL;
int ScLength = 0, pdu_len = 0, stat = 0;
- char buf[2 * (SMS_SMSP_ADDRESS_LEN + SMS_SMDATA_SIZE_MAX) + 1] = {0};
+ char buf[2*(SMS_SMSP_ADDRESS_LEN+SMS_SMDATA_SIZE_MAX)+1] = {0};
char *hex_pdu = NULL;
dbg("Entry");
dbg("Exit");
return TCORE_RETURN_EINVAL;
}
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
dbg("msgStatus: %x, msgLength: [%d]", saveMsg->msgStatus, saveMsg->msgDataPackage.msgLength);
- util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX + 1), (void *) saveMsg->msgDataPackage.tpduData);
- util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *) saveMsg->msgDataPackage.sca);
+ util_hex_dump(" ", (SMS_SMDATA_SIZE_MAX+1), (void *)saveMsg->msgDataPackage.tpduData);
+ util_hex_dump(" ", SMS_SMSP_ADDRESS_LEN, (void *)saveMsg->msgDataPackage.sca);
switch (saveMsg->msgStatus) {
- case SMS_STATUS_READ:
- stat = AT_REC_READ;
- break;
+ case SMS_STATUS_READ:
+ stat = AT_REC_READ;
+ break;
- case SMS_STATUS_UNREAD:
- stat = AT_REC_UNREAD;
- break;
+ case SMS_STATUS_UNREAD:
+ stat = AT_REC_UNREAD;
+ break;
- case SMS_STATUS_SENT:
- stat = AT_STO_SENT;
- break;
+ case SMS_STATUS_SENT:
+ stat = AT_STO_SENT;
+ break;
- case SMS_STATUS_UNSENT:
- stat = AT_STO_UNSENT;
- break;
+ case SMS_STATUS_UNSENT:
+ stat = AT_STO_UNSENT;
+ break;
- default:
- err("Invalid msgStatus");
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
+ default:
+ err("Invalid msgStatus");
+ dbg("Exit");
+ return TCORE_RETURN_EINVAL;
}
if ((saveMsg->msgDataPackage.msgLength > 0)
&& (saveMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX)) {
- ScLength = (int) saveMsg->msgDataPackage.sca[0];
+ ScLength = (int)saveMsg->msgDataPackage.sca[0];
buf[0] = ScLength;
dbg("ScLength = %d", ScLength);
- if (ScLength == 0) {
+ if(ScLength == 0) {
buf[0] = 0;
} else {
- memcpy(&buf[1], saveMsg->msgDataPackage.sca, ScLength);
+ memcpy(&buf[1], saveMsg->msgDataPackage.sca, ScLength);
}
- memcpy(&buf[ScLength + 1], saveMsg->msgDataPackage.tpduData, saveMsg->msgDataPackage.msgLength);
+ memcpy(&buf[ScLength+1], saveMsg->msgDataPackage.tpduData, saveMsg->msgDataPackage.msgLength);
- pdu_len = saveMsg->msgDataPackage.msgLength + ScLength + 1;
+ pdu_len= saveMsg->msgDataPackage.msgLength + ScLength + 1;
dbg("pdu_len: [%d]", pdu_len);
- hex_pdu = malloc(pdu_len * 2 + 1);
- util_hex_dump(" ", sizeof(buf), (void *) buf);
+ hex_pdu = g_malloc0(pdu_len * 2 + 1);
+ util_hex_dump(" ", sizeof(buf), (void *)buf);
- memset(hex_pdu, 0x00, pdu_len * 2 + 1);
+ memset (hex_pdu, 0x00, pdu_len * 2 + 1);
- util_byte_to_hex((const char *) buf, (char *) hex_pdu, pdu_len);
+ util_byte_to_hex((const char *)buf, (char *)hex_pdu, pdu_len);
- // AT+CMGW=<length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
+ //AT+CMGW=<length>[,<stat>]<CR>PDU is given<ctrl-Z/ESC>
cmd_str = g_strdup_printf("AT+CMGW=%d,%d%s%s\x1A", saveMsg->msgDataPackage.msgLength, stat, "\r", hex_pdu);
pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *) cmd_str, "+CMGW", TCORE_AT_SINGLELINE);
+ atreq = tcore_at_request_new((const char *)cmd_str, "+CMGW", TCORE_AT_SINGLELINE);
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
+ if(NULL == cmd_str || NULL == atreq || NULL == pending) {
err("Out of memory. Unable to proceed");
dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
- // free memory we own
+ //free memory we own
g_free(cmd_str);
util_sms_free_memory(atreq);
util_sms_free_memory(pending);
return TCORE_RETURN_ENOMEM;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
tcore_pending_set_request_data(pending, 0, atreq);
tcore_pending_set_response_callback(pending, on_response_sms_save_msg, NULL);
return TCORE_RETURN_EINVAL;
}
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
dbg("index: %d", delete_msg->index);
if (delete_msg->index == -1) {
}
pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *) cmd_str, NULL, TCORE_AT_NO_RESULT);
+ atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
if (NULL == cmd_str || NULL == atreq || NULL == pending) {
err("Out of memory. Unable to proceed");
dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
- // free memory we own
+ //free memory we own
g_free(cmd_str);
util_sms_free_memory(atreq);
util_sms_free_memory(pending);
return TCORE_RETURN_ENOMEM;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
tcore_pending_set_request_data(pending, 0, atreq);
tcore_pending_set_response_callback(pending, on_response_sms_delete_msg, (void *) (uintptr_t) (delete_msg->index)); // storing index as user data for response
return TCORE_RETURN_SUCCESS;
}
-static TReturn get_storedMsgCnt(CoreObject *obj, UserRequest *ur)
+static TReturn get_stored_msg_cnt(CoreObject *obj, UserRequest *ur)
{
gchar *cmd_str = NULL;
TcoreHal *hal = NULL;
return TCORE_RETURN_EINVAL;
}
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
cmd_str = g_strdup_printf("AT+CPMS=\"SM\"");
pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *) cmd_str, "+CPMS", TCORE_AT_SINGLELINE);
+ atreq = tcore_at_request_new((const char *)cmd_str, "+CPMS", TCORE_AT_SINGLELINE);
if (NULL == cmd_str || NULL == atreq || NULL == pending) {
err("Out of memory. Unable to proceed");
dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
- // free memory we own
+ //free memory we own
g_free(cmd_str);
util_sms_free_memory(atreq);
util_sms_free_memory(pending);
return TCORE_RETURN_ENOMEM;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
tcore_pending_set_request_data(pending, 0, atreq);
tcore_pending_set_response_callback(pending, on_response_get_stored_msg_cnt, NULL);
static TReturn get_sca(CoreObject *obj, UserRequest *ur)
{
- gchar *cmd_str = NULL;
+ gchar * cmd_str = NULL;
TcoreHal *hal = NULL;
TcoreATRequest *atreq = NULL;
TcorePending *pending = NULL;
dbg("Exit");
return TCORE_RETURN_EINVAL;
}
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
cmd_str = g_strdup_printf("AT+CSCA?");
pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *) cmd_str, "+CSCA", TCORE_AT_SINGLELINE);
+ atreq = tcore_at_request_new((const char *)cmd_str, "+CSCA", TCORE_AT_SINGLELINE);
if (NULL == cmd_str || NULL == atreq || NULL == pending) {
err("Out of memory. Unable to proceed");
dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
- // free memory we own
+ //free memory we own
g_free(cmd_str);
util_sms_free_memory(atreq);
util_sms_free_memory(pending);
return TCORE_RETURN_ENOMEM;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
tcore_pending_set_request_data(pending, 0, atreq);
tcore_pending_set_response_callback(pending, on_response_get_sca, NULL);
dbg("Exit");
return TCORE_RETURN_EINVAL;
}
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
dbg("dialNumLen: %u, typeOfNum: %d, numPlanId: %d, ", setSca->scaInfo.dialNumLen, setSca->scaInfo.typeOfNum, setSca->scaInfo.numPlanId);
- util_hex_dump(" ", (SMS_SMSP_ADDRESS_LEN + 1), (void *) setSca->scaInfo.diallingNum);
+ util_hex_dump(" ", (SMS_SMSP_ADDRESS_LEN+1), (void *)setSca->scaInfo.diallingNum);
addrType = ((setSca->scaInfo.typeOfNum << 4) | setSca->scaInfo.numPlanId) | 0x80;
cmd_str = g_strdup_printf("AT+CSCA=\"%s\",%d", setSca->scaInfo.diallingNum, addrType);
pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *) cmd_str, NULL, TCORE_AT_NO_RESULT);
+ atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
if (NULL == cmd_str || NULL == atreq || NULL == pending) {
err("Out of memory. Unable to proceed");
dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
- // free memory we own
+ //free memory we own
g_free(cmd_str);
util_sms_free_memory(atreq);
util_sms_free_memory(pending);
return TCORE_RETURN_ENOMEM;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
tcore_pending_set_request_data(pending, 0, atreq);
tcore_pending_set_response_callback(pending, on_response_set_sca, NULL);
dbg("Exit");
return TCORE_RETURN_EINVAL;
}
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
cmd_str = g_strdup_printf("AT+CSCB?");
pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *) cmd_str, "+CSCB", TCORE_AT_SINGLELINE);
+ atreq = tcore_at_request_new((const char *)cmd_str, "+CSCB", TCORE_AT_SINGLELINE);
if (NULL == cmd_str || NULL == atreq || NULL == pending) {
err("Out of memory. Unable to proceed");
dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
- // free memory we own
+ //free memory we own
g_free(cmd_str);
util_sms_free_memory(atreq);
util_sms_free_memory(pending);
return TCORE_RETURN_ENOMEM;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
tcore_pending_set_request_data(pending, 0, atreq);
tcore_pending_set_response_callback(pending, on_response_get_cb_config, NULL);
TcoreATRequest *atreq = NULL;
TcorePending *pending = NULL;
const struct treq_sms_set_cb_config *setCbConfig = NULL;
- int ctr1 = 0, ctr2 = 0;
+ int ctr1= 0, ctr2 =0;
unsigned short appendMsgId = 0;
dbg("Entry");
dbg("Exit");
return TCORE_RETURN_EINVAL;
}
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
- dbg("bCBEnabled: %d, msgIdMaxCount: %x, msgIdCount: %d", setCbConfig->cbEnabled, setCbConfig->msgIdMaxCount, setCbConfig->msgIdRangeCount);
- // util_hex_dump(" ", SMS_GSM_SMS_CBMI_LIST_SIZE_MAX, (void *)setCbConfig->msgIDs);
+ dbg("bCBEnabled: %d, msgIdCount: %d", setCbConfig->cbEnabled, setCbConfig->msgIdRangeCount);
- if (setCbConfig->cbEnabled == 2) { // Enable all CBS
+ if (setCbConfig->cbEnabled == 2) { //Enable all CBS
+ cmd_str = g_strdup_printf("AT+CSCB=1");
+ } else if ((setCbConfig->cbEnabled == 1) && (setCbConfig->msgIdRangeCount == 0)) { // Special case: Enable all CBS
cmd_str = g_strdup_printf("AT+CSCB=1");
- } else if (setCbConfig->cbEnabled == 0) { // AT+CSCB=0: Disable CBS
+ } else if (setCbConfig->cbEnabled == 0) {//AT+CSCB=0: Disable CBS
cmd_str = g_strdup_printf("AT+CSCB=0");
} else {
mids_GString = g_string_new("AT+CSCB=0,\"");
- for (ctr1 = 0; ctr1 < setCbConfig->msgIdRangeCount; ctr1++) {
- if (setCbConfig->msgIDs[ctr1].net3gpp.selected == FALSE)
+ for(ctr1 = 0; ctr1 < setCbConfig->msgIdRangeCount; ctr1++ ) {
+ if( setCbConfig->msgIDs[ctr1].net3gpp.selected == FALSE )
continue;
- if (SMS_GSM_SMS_CBMI_LIST_SIZE_MAX <= (setCbConfig->msgIDs[ctr1].net3gpp.toMsgId - setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId)) {
+ if( SMS_GSM_SMS_CBMI_LIST_SIZE_MAX <= (setCbConfig->msgIDs[ctr1].net3gpp.toMsgId - setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId) ) {
+ g_string_free(mids_GString, TRUE);
mids_GString = g_string_new("AT+CSCB=1");
break;
}
appendMsgId = setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId;
- for (ctr2 = 0; (ctr2 <= ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))); ctr2++) {
- dbg("%x", appendMsgId);
- mids_GString = g_string_append(mids_GString, g_strdup_printf("%d", appendMsgId));
+ for( ctr2 = 0; (ctr2 <= ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))); ctr2++ ) {
+ gchar *append_str = NULL;
+ dbg( "%x", appendMsgId);
+ append_str = g_strdup_printf("%d", appendMsgId);
+ g_string_append(mids_GString, append_str);
+ g_free(append_str);
if (ctr2 == ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))) {
- mids_GString = g_string_append(mids_GString, "\""); // Mids string termination
+ g_string_append(mids_GString, "\""); //Mids string termination
} else {
- mids_GString = g_string_append(mids_GString, ",");
+ g_string_append(mids_GString, ",");
}
appendMsgId++;
}
- }
+ }
mids_str = g_string_free(mids_GString, FALSE);
- cmd_str = g_strdup_printf("%s", mids_str);
+ cmd_str = g_strdup_printf("%s", mids_str);
g_free(mids_str);
}
pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *) cmd_str, NULL, TCORE_AT_NO_RESULT);
- if (NULL == cmd_str || NULL == atreq || NULL == pending) {
+ atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
+ if(NULL == cmd_str || NULL == atreq || NULL == pending) {
err("Out of memory. Unable to proceed");
dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
- // free memory we own
+ //free memory we own
g_free(cmd_str);
util_sms_free_memory(atreq);
util_sms_free_memory(pending);
return TCORE_RETURN_ENOMEM;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
tcore_pending_set_request_data(pending, 0, atreq);
tcore_pending_set_response_callback(pending, on_response_set_cb_config, NULL);
dbg("Exit");
return TCORE_RETURN_EINVAL;
}
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
dbg("memory_status: %d", setMemStatus->memory_status);
- if (setMemStatus->memory_status < SMS_PDA_MEMORY_STATUS_AVAILABLE
+ if(setMemStatus->memory_status < SMS_PDA_MEMORY_STATUS_AVAILABLE
|| setMemStatus->memory_status > SMS_PDA_MEMORY_STATUS_FULL) {
err("Invalid memory_status");
}
switch (setMemStatus->memory_status) {
- case SMS_PDA_MEMORY_STATUS_AVAILABLE:
- memoryStatus = AT_MEMORY_AVAILABLE;
- break;
+ case SMS_PDA_MEMORY_STATUS_AVAILABLE:
+ memoryStatus = AT_MEMORY_AVAILABLE;
+ break;
- case SMS_PDA_MEMORY_STATUS_FULL:
- memoryStatus = AT_MEMORY_FULL;
- break;
+ case SMS_PDA_MEMORY_STATUS_FULL:
+ memoryStatus = AT_MEMORY_FULL;
+ break;
- default:
- err("Invalid memory_status");
- dbg("Exit");
- return TCORE_RETURN_EINVAL;
+ default:
+ err("Invalid memory_status");
+ dbg("Exit");
+ return TCORE_RETURN_EINVAL;
}
cmd_str = g_strdup_printf("AT+XTESM=%d", memoryStatus);
pending = tcore_pending_new(obj, 0);
- atreq = tcore_at_request_new((const char *) cmd_str, NULL, TCORE_AT_NO_RESULT);
+ atreq = tcore_at_request_new((const char *)cmd_str, NULL, TCORE_AT_NO_RESULT);
if (NULL == cmd_str || NULL == atreq || NULL == pending) {
err("Out of memory. Unable to proceed");
dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
- // free memory we own
+ //free memory we own
g_free(cmd_str);
util_sms_free_memory(atreq);
util_sms_free_memory(pending);
return TCORE_RETURN_ENOMEM;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
tcore_pending_set_request_data(pending, 0, atreq);
tcore_pending_set_response_callback(pending, on_response_set_mem_status, NULL);
static TReturn set_delivery_report(CoreObject *obj, UserRequest *ur)
{
- struct tresp_sms_set_delivery_report respSetDeliveryReport = {0, };
+ struct tresp_sms_set_delivery_report respSetDeliveryReport = {0,};
respSetDeliveryReport.result = SMS_SUCCESS;
dbg("Entry");
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(obj))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
dbg("CP takes care of sending SMS ack to network for all classes of SMS. Sending default success.");
const struct treq_sms_set_msg_status *msg_status = NULL;
dbg("Entry");
-
+ hal = tcore_object_get_hal(obj);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
msg_status = tcore_user_request_ref_data(ur, NULL);
- cmd_str = g_strdup_printf("AT+CRSM=178,28476,%d,4,%d", (msg_status->index + 1), AT_EF_SMS_RECORD_LEN);
- atreq = tcore_at_request_new((const char *) cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
+ cmd_str = g_strdup_printf("AT+CRSM=178,28476,%d,4,%d", (msg_status->index+1), PDU_LEN_MAX);
+ atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
pending = tcore_pending_new(obj, 0);
if (NULL == cmd_str || NULL == atreq || NULL == pending) {
err("Out of memory. Unable to proceed");
dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
- // free memory we own
+ //free memory we own
g_free(cmd_str);
util_sms_free_memory(atreq);
util_sms_free_memory(pending);
return TCORE_RETURN_ENOMEM;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
tcore_pending_set_request_data(pending, 0, atreq);
tcore_pending_set_response_callback(pending, _response_get_efsms_data, NULL);
TcoreATRequest *atreq = NULL;
TcorePending *pending = NULL;
const struct treq_sms_get_params *getSmsParams = NULL;
- int record_len = 0, *smsp_record_len = NULL;
+ int record_len = 0 , *smsp_record_len = NULL;
dbg("Entry");
dbg("Exit");
return TCORE_RETURN_EINVAL;
}
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
smsp_record_len = tcore_plugin_ref_property(tcore_object_ref_plugin(obj), "SMSPRECORDLEN");
record_len = *smsp_record_len;
dbg("record len from property %d", record_len);
- // AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
+ //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
cmd_str = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d", (getSmsParams->index + 1), record_len);
- dbg("cmd_str is %s", cmd_str);
+ dbg("cmd_str is %s",cmd_str);
- atreq = tcore_at_request_new((const char *) cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
+ atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
pending = tcore_pending_new(obj, 0);
if (NULL == cmd_str || NULL == atreq || NULL == pending) {
err("Out of memory. Unable to proceed");
dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
- // free memory we own
+ //free memory we own
g_free(cmd_str);
util_sms_free_memory(atreq);
util_sms_free_memory(pending);
return TCORE_RETURN_ENOMEM;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
tcore_pending_set_request_data(pending, 0, atreq);
tcore_pending_set_response_callback(pending, on_response_get_sms_params, NULL);
char *encoded_data = NULL;
unsigned char *temp_data = NULL;
int SMSPRecordLen = 0;
+ int *smsp_record_len;
TcoreHal *hal = NULL;
TcoreATRequest *atreq = NULL;
dbg("setSmsParams: [%p], hal: [%p]", setSmsParams, hal);
return FALSE;
}
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
- // EFsmsp file size is 28 +Y bytes (Y is alpha id size)
- SMSPRecordLen = 28 + setSmsParams->params.alphaIdLen;
- temp_data = calloc(SMSPRecordLen, 1);
- encoded_data = calloc(SMSPRecordLen * 2 + 1, 1);
+ //EFsmsp file size is 28 +Y bytes (Y is alpha id size)
+ smsp_record_len = tcore_plugin_ref_property(tcore_object_ref_plugin(obj), "SMSPRECORDLEN");
+ if (NULL == smsp_record_len) {
+ err("SMSP record is NULL");
+ return TCORE_RETURN_FAILURE;
+ }
+ SMSPRecordLen = *smsp_record_len;
+ if (SMSPRecordLen < nDefaultSMSPWithoutAlphaId)
+ return FALSE;
+
+ temp_data = g_malloc0(SMSPRecordLen);
+ encoded_data = g_malloc0(SMSPRecordLen*2 + 1);
_tcore_util_sms_encode_smsParameters(&(setSmsParams->params), temp_data, SMSPRecordLen);
- util_byte_to_hex((const char *) temp_data, (char *) encoded_data, SMSPRecordLen);
+ util_byte_to_hex((const char *)temp_data, (char *)encoded_data,SMSPRecordLen);
encoded_data_len = ((SMSPRecordLen) * 2);
hal = tcore_object_get_hal(obj);
pending = tcore_pending_new(obj, 0);
- dbg("alpha id len %d encoded data %s. Encoded data len %d", setSmsParams->params.alphaIdLen, encoded_data, encoded_data_len);
- cmd_str = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"", (setSmsParams->params.recordIndex + 1), SMSPRecordLen, encoded_data);
+ dbg("alpha id len %d encoded data %s. Encoded data len %d",setSmsParams->params.alphaIdLen,encoded_data, encoded_data_len);
+ cmd_str = g_strdup_printf("AT+CRSM=220,28482,%d,4,%d,\"%s\"",(setSmsParams->params.recordIndex+1),SMSPRecordLen,encoded_data);
- dbg("cmd str is %s", cmd_str);
- atreq = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
+ dbg("cmd str is %s",cmd_str);
+ atreq = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
if (NULL == cmd_str || NULL == atreq || NULL == pending) {
err("Out of memory. Unable to proceed");
dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
- // free memory we own
+ //free memory we own
g_free(cmd_str);
util_sms_free_memory(atreq);
util_sms_free_memory(pending);
return TCORE_RETURN_ENOMEM;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
- tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_request_data(pending, 0,atreq);
tcore_pending_set_response_callback(pending, on_response_set_sms_params, NULL);
tcore_pending_link_user_request(pending, ur);
tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
util_sms_free_memory(temp_data);
util_sms_free_memory(encoded_data);
- return TRUE;
+ return TCORE_RETURN_SUCCESS;
}
static TReturn get_paramcnt(CoreObject *obj, UserRequest *ur)
dbg("Exit");
return TCORE_RETURN_EINVAL;
}
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
- // AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
+ //AT+CRSM=command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
cmd_str = g_strdup_printf("AT+CRSM=192,28482");
- atreq = tcore_at_request_new((const char *) cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
+ atreq = tcore_at_request_new((const char *)cmd_str, "+CRSM", TCORE_AT_SINGLELINE);
pending = tcore_pending_new(obj, 0);
if (NULL == cmd_str || NULL == atreq || NULL == pending) {
err("NULL pointer. Unable to proceed");
dbg("cmd_str: [%p], atreq: [%p], pending: [%p]", cmd_str, atreq, pending);
- // free memory we own
+ //free memory we own
g_free(cmd_str);
util_sms_free_memory(atreq);
util_sms_free_memory(pending);
return TCORE_RETURN_FAILURE;
}
- util_hex_dump(" ", strlen(cmd_str), (void *) cmd_str);
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
tcore_pending_set_request_data(pending, 0, atreq);
tcore_pending_set_response_callback(pending, on_response_get_paramcnt, NULL);
.read_msg = read_msg,
.save_msg = save_msg,
.delete_msg = delete_msg,
- .get_storedMsgCnt = get_storedMsgCnt,
+ .get_storedMsgCnt = get_stored_msg_cnt,
.get_sca = get_sca,
.set_sca = set_sca,
.get_cb_config = get_cb_config,
.get_paramcnt = get_paramcnt,
};
-gboolean s_sms_init(TcorePlugin *plugin, TcoreHal *hal)
+gboolean imc_sms_init(TcorePlugin *cp, CoreObject *co_sms)
{
- CoreObject *obj = NULL;
- struct property_sms_info *data = NULL;
- GQueue *work_queue = NULL;
- int *smsp_record_len = NULL;
-
+ int *smsp_record_len;
dbg("Entry");
- dbg("plugin: [%p]", plugin);
- dbg("hal: [%p]", hal);
-
- obj = tcore_sms_new(plugin, "umts_sms", &sms_ops, hal);
-
- data = calloc(sizeof(struct property_sms_info), 1);
- if (NULL == obj || NULL == data) {
- err("Unable to initialize. Exiting");
- s_sms_exit(plugin);
-
- dbg("Exit");
- return FALSE;
- }
+ /* Set operations */
+ tcore_sms_set_ops(co_sms, &sms_ops);
- work_queue = g_queue_new();
- tcore_object_link_user_data(obj, work_queue);
+ /* Registering for SMS notifications */
+ tcore_object_add_callback(co_sms, "+CMTI:", on_event_class2_sms_incom_msg, NULL);
+ tcore_object_add_callback(co_sms, "\e+CMT:", on_event_sms_incom_msg, NULL);
- // Registering for SMS notifications
- tcore_object_add_callback(obj, "\e+CMTI", on_event_class2_sms_incom_msg, NULL);
- tcore_object_add_callback(obj, "\e+CMT", on_event_sms_incom_msg, NULL);
+ tcore_object_add_callback(co_sms, "\e+CDS", on_event_sms_incom_msg, NULL);
+ tcore_object_add_callback(co_sms, "+XSMSMMSTAT", on_event_sms_memory_status, NULL);
+ tcore_object_add_callback(co_sms, "+CMS", on_event_sms_memory_status, NULL);
- tcore_object_add_callback(obj, "\e+CDS", on_event_sms_incom_msg, NULL);
- tcore_object_add_callback(obj, "+XSMSMMSTAT", on_event_sms_memory_status, NULL);
- tcore_object_add_callback(obj, "+CMS", on_event_sms_memory_status, NULL);
+ tcore_object_add_callback(co_sms, "+CBMI:", on_event_sms_cb_incom_msg, NULL);
+ tcore_object_add_callback(co_sms, "\e+CBM:", on_event_sms_cb_incom_msg, NULL);
- tcore_object_add_callback(obj, "\e+CBMI", on_event_sms_cb_incom_msg, NULL);
- tcore_object_add_callback(obj, "\e+CBM", on_event_sms_cb_incom_msg, NULL);
- tcore_object_add_callback(obj, "+XSIM", on_event_sms_ready_status, NULL);
-
- tcore_plugin_link_property(plugin, "SMS", data);
-
- // storing smsp record length
- smsp_record_len = calloc(sizeof(int), 1);
- tcore_plugin_link_property(plugin, "SMSPRECORDLEN", smsp_record_len);
+ /* Storing SMSP record length */
+ smsp_record_len = g_new0(int, 1);
+ tcore_plugin_link_property(cp, "SMSPRECORDLEN", smsp_record_len);
dbg("Exit");
return TRUE;
}
-void s_sms_exit(TcorePlugin *plugin)
+void imc_sms_exit(TcorePlugin *cp, CoreObject *co_sms)
{
- CoreObject *obj = NULL;
- struct property_sms_info *data = NULL;
-
- dbg("Entry");
- dbg("plugin: [%p]", plugin);
+ int *smsp_record_len;
- obj = tcore_plugin_ref_core_object(plugin, "umts_sms");
- if (NULL == obj) {
- err("NULL core object. Nothing to do.");
- return;
- }
- tcore_sms_free(obj);
-
- data = tcore_plugin_ref_property(plugin, "SMS");
- util_sms_free_memory(data);
+ smsp_record_len = tcore_plugin_ref_property(cp, "SMSPRECORDLEN");
+ g_free(smsp_record_len);
dbg("Exit");
- return;
}
#include <server.h>
#include <at.h>
-#include "s_common.h"
-#include "s_ss.h"
+#include "imc_common.h"
+#include "imc_ss.h"
#define NUM_TYPE_INTERNATIONAL 0x01
#define NUM_PLAN_ISDN 0x01
static TReturn _ss_waiting_get(CoreObject *o, UserRequest *ur, enum telephony_ss_class class, enum tcore_response_command resp);
-static TReturn s_ss_barring_activate(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_barring_deactivate(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_barring_change_password(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_barring_get_status(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_barring_activate(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_barring_deactivate(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_barring_change_password(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_barring_get_status(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_forwarding_activate(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_forwarding_deactivate(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_forwarding_register(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_forwarding_deregister(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_forwarding_get_status(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_forwarding_activate(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_forwarding_deactivate(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_forwarding_register(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_forwarding_deregister(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_forwarding_get_status(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_waiting_activate(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_waiting_deactivate(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_waiting_get_status(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_waiting_activate(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_waiting_deactivate(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_waiting_get_status(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_cli_activate(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_cli_deactivate(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_cli_get_status(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_cli_activate(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_cli_deactivate(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_cli_get_status(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_send_ussd(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_send_ussd(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_set_aoc(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_get_aoc(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_set_aoc(CoreObject *o, UserRequest *ur);
+static TReturn imc_ss_get_aoc(CoreObject *o, UserRequest *ur);
-static TReturn s_ss_manage_call_0_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
-static TReturn s_ss_manage_call_1_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
-static TReturn s_ss_manage_call_1x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data);
-static TReturn s_ss_manage_call_2_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
-static TReturn s_ss_manage_call_2x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data);
-static TReturn s_ss_manage_call_3_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
-static TReturn s_ss_manage_call_4_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
-static TReturn s_ss_manage_call_4dn_send(CoreObject *o, UserRequest *ur, const char *number, ConfirmCallback cb, void *user_data);
+static TReturn imc_ss_manage_call_0_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
+static TReturn imc_ss_manage_call_1_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
+static TReturn imc_ss_manage_call_1x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data);
+static TReturn imc_ss_manage_call_2_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
+static TReturn imc_ss_manage_call_2x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data);
+static TReturn imc_ss_manage_call_3_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
+static TReturn imc_ss_manage_call_4_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data);
+static TReturn imc_ss_manage_call_4dn_send(CoreObject *o, UserRequest *ur, const char *number, ConfirmCallback cb, void *user_data);
static void on_confirmation_ss_message_send(TcorePending *p, gboolean result, void *user_data);
} else {
err("User Request is NULL, is this internal request??");
}
- // HAL
+
hal = tcore_object_get_hal(o);
// Send request to HAL
memset(&resp, 0x0, sizeof(struct tresp_ss_ussd));
resp.type = type;
resp.status = status;
- resp.err = FALSE;
+ resp.err = SS_ERROR_NONE;
dbg("ussd_str = %s resp.type - %d resp.status - %d", ussd_str, resp.type, resp.status);
if (ussd_str) {
}
dbg("noti.str - %s", noti.str);
- core_obj = tcore_plugin_ref_core_object(p, "ss");
+ core_obj = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_SS);
tcore_server_send_notification(tcore_plugin_ref_server(p),
core_obj,
TNOTI_SS_USSD,
lines = (GSList *) data;
if (1 != g_slist_length(lines)) {
dbg("unsolicited msg but multiple line");
- goto OUT;
+ return TRUE;
}
cmd = (char *) (lines->data);
// parse ussd status
if (str) {
memset(str, 0x00, strlen(ussd_string) - 1);
} else {
- dbg("malloc failed")
+ dbg("malloc failed");
+ if (NULL != tokens) {
+ tcore_at_tok_free(tokens);
+ }
return FALSE;
}
len = strlen(ussd_string) - 1;
tcore_ss_ussd_get_session_data(ussd_session, (void **) &ur);
if (!ur) {
dbg("[ error ] ur : (0)");
- return FALSE;
+ goto CATCH;
}
type = (enum telephony_ss_ussd_type) tcore_ss_ussd_get_session_type(ussd_session);
_ss_ussd_response(ur, ussd_str, type, status);
}
+
+CATCH:
+ if (NULL != tokens) {
+ tcore_at_tok_free(tokens);
+ }
+
+ if (NULL != str) {
+ free(str);
+ }
return FALSE;
}
tcore_ss_ussd_get_session_data(ussd_session, (void **) &ur);
if (!ur) {
dbg("[ error ] ur : (0)");
+ if (NULL != tokens) {
+ tcore_at_tok_free(tokens);
+ }
+
+ if (NULL != str) {
+ free(str);
+ }
+
+ if (ussd_str) {
+ g_free(ussd_str);
+ }
return FALSE;
}
type = (enum telephony_ss_ussd_type) tcore_ss_ussd_get_session_type(ussd_session);
break;
}
-OUT:
- if (NULL != tokens)
+ if (NULL != tokens) {
tcore_at_tok_free(tokens);
+ }
- if (NULL != str)
+ if (NULL != str) {
free(str);
+ }
+
dbg("Exit");
return TRUE;
}
+
static gboolean on_notification_ss_info(CoreObject *o, const void *data, void *user_data)
{
TcorePlugin *plugin = 0;
dbg("function enter");
plugin = tcore_object_ref_plugin(o);
- co = tcore_plugin_ref_core_object(plugin, "call");
+ co = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL);
if (!co) {
dbg("[ error ] plugin_ref_core_object : call");
return FALSE;
return TRUE;
}
buf = calloc(pos - cmd + 2, 1);
+ if (!buf) {
+ dbg("Memory allocation failed");
+ return TRUE;
+ }
memcpy(buf, cmd, pos - cmd);
dbg("buf is %s", buf);
}
}
OUT:
- if (NULL != tokens)
+ if (NULL != tokens) {
tcore_at_tok_free(tokens);
- if (NULL != number)
- g_free(number);
+ }
+
+ g_free(number);
return TRUE;
}
enum telephony_ss_class class;
CoreObject *o = 0;
UserRequest *ur;
- struct tresp_ss_general resp;
+ struct tresp_ss_barring resp = {0, };
UserRequest *ur_dup = 0;
GSList *tokens = NULL;
const char *line;
- int err;
+ int error;
const TcoreATResponse *response;
dbg("function enter");
o = tcore_pending_ref_core_object(p);
ur = tcore_pending_ref_user_request(p);
- info = (struct ss_confirm_info *) user_data;
+ info = (struct ss_confirm_info *)user_data;
class = info->class;
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = SS_ERROR_NONE;
} else {
dbg("RESPONSE NOT OK");
- line = (const char *) response->final_response;
+ line = (const char *)response->final_response;
tokens = tcore_at_tok_new(line);
if (g_slist_length(tokens) < 1) {
dbg("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = SS_ERROR_SYSTEMFAILURE;
} else {
- err = atoi(g_slist_nth_data(tokens, 0));
- // TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ error = atoi(g_slist_nth_data(tokens, 0));
+ err("Error: [%d]", error);
+ /* TODO: CMEE error mapping is required. */
+ resp.err = SS_ERROR_SYSTEMFAILURE;
}
tcore_at_tok_free(tokens);
}
}
} else {
if (ur) {
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_general), &resp);
+ tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_barring), &resp);
} else {
dbg("[ error ] ur is 0");
}
}
+ g_free(user_data);
}
static void on_response_ss_barring_change_pwd(TcorePending *p, int data_len, const void *data, void *user_data)
struct ss_confirm_info *info = 0;
UserRequest *ur;
struct tresp_ss_general resp;
- int err;
+ int error;
GSList *tokens = NULL;
const char *line;
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = SS_ERROR_NONE;
} else {
dbg("RESPONSE NOT OK");
if (g_slist_length(tokens) < 1) {
dbg("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = SS_ERROR_SYSTEMFAILURE;
} else {
- err = atoi(g_slist_nth_data(tokens, 0));
+ error = atoi(g_slist_nth_data(tokens, 0));
+ err("Error: [%d]", error);
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = SS_ERROR_SYSTEMFAILURE;
}
tcore_at_tok_free(tokens);
}
CoreObject *o = 0;
UserRequest *ur = 0, *dup_ur = 0;
struct ss_confirm_info *info = 0;
- struct tresp_ss_general resp;
+ struct tresp_ss_forwarding resp = {0,};
GSList *tokens = NULL;
const char *line;
- int err;
+ int error;
const TcoreATResponse *response;
dbg("function enter");
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = SS_ERROR_NONE;
} else {
dbg("RESPONSE NOT OK");
+ /* Extract Error */
line = (const char *) response->final_response;
tokens = tcore_at_tok_new(line);
if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ dbg("Error cause not specified or string corrupted");
+ resp.err = SS_ERROR_SYSTEMFAILURE;
} else {
- err = atoi(g_slist_nth_data(tokens, 0));
+ error = atoi(g_slist_nth_data(tokens, 0));
+ err("Error: [%d]", error);
// / TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = SS_ERROR_SYSTEMFAILURE;
}
tcore_at_tok_free(tokens);
if (info->flavor_type == SS_CF_MODE_CF_ALL ||
info->flavor_type == SS_CF_MODE_CFC) {
if (ur) {
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_general), &resp);
+ tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
} else {
dbg("[ error ] ur is 0");
}
}
} else {
if (ur) {
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_general), &resp);
+ tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
} else {
dbg("[ error ] ur is 0");
}
UserRequest *ur = 0;
UserRequest *ur_dup = 0;
struct ss_confirm_info *info = 0;
- struct tresp_ss_general resp;
+ struct tresp_ss_waiting resp = {0,};
GSList *tokens = NULL;
const char *line;
- int err;
+ int error;
const TcoreATResponse *response;
dbg("function enter");
core_obj = tcore_pending_ref_core_object(p);
ur = tcore_pending_ref_user_request(p);
- info = (struct ss_confirm_info *) user_data;
+ info = (struct ss_confirm_info *)user_data;
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = SS_ERROR_NONE;
} else {
dbg("RESPONSE NOT OK");
+ /* Extract Error */
line = (const char *) response->final_response;
tokens = tcore_at_tok_new(line);
if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ dbg("Error cause not specified or string corrupted");
+ resp.err = SS_ERROR_SYSTEMFAILURE;
} else {
- err = atoi(g_slist_nth_data(tokens, 0));
- // / TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ error = atoi(g_slist_nth_data(tokens, 0));
+ err("Error: [%d]", error);
+ /* TODO: CMEE error mapping is required. */
+ resp.err = SS_ERROR_SYSTEMFAILURE;
}
+
+ /* Free tokens */
tcore_at_tok_free(tokens);
}
- dbg("on_response_ss_waiting_set - rsp.err : %d, ur : %x, class : %d", resp.err, ur, info->class);
-
- if (resp.err == TCORE_RETURN_SUCCESS) {
+ dbg("Call Waiting - Error: [%d], UR: [0x%x] class: [0x%2x]", resp.err, ur, info->class);
+ if (resp.err == SS_ERROR_NONE) {
ur_dup = tcore_user_request_ref(ur);
- dbg("Get waiting call status");
+
+ dbg("Get Call Waiting status");
_ss_waiting_get(core_obj, ur_dup, info->class, info->resp);
} else {
if (ur) {
- tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_general), &resp);
+ tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_waiting), &resp);
} else {
- dbg("[ error ] ur is 0");
+ err("User request is NULL");
}
}
g_free(user_data);
UserRequest *ur = NULL, *ussd_ur = NULL;
GSList *tokens = NULL;
const char *line;
- int err;
+ int error;
UssdSession *ussd_s = NULL;
enum tcore_ss_ussd_type type = TCORE_SS_USSD_TYPE_MAX;
const TcoreATResponse *response;
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = SS_ERROR_NONE;
} else {
dbg("RESPONSE NOT OK");
if (g_slist_length(tokens) < 1) {
dbg("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = SS_ERROR_SYSTEMFAILURE;
} else {
- err = atoi(g_slist_nth_data(tokens, 0));
+ error = atoi(g_slist_nth_data(tokens, 0));
+ err("Error: [%d]", error);
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = SS_ERROR_SYSTEMFAILURE;
}
tcore_at_tok_free(tokens);
}
static void on_response_ss_barring_get(TcorePending *p, int data_len, const void *data, void *user_data)
{
UserRequest *ur = 0;
- int status = 0, classx = 0, err = 0;
+ int status = 0, classx = 0, ss_err = 0;
GSList *respdata;
struct ss_confirm_info *info = 0;
struct tresp_ss_barring resp;
dbg("total records : %d", countRecords);
} else {
countRecords = 0;
- dbg("no active status - return to user")
+ dbg("no active status - return to user");
}
resp.record_num = countRecords;
-
+ resp.record = 0;
if (resp.record_num > 0) {
resp.record = g_new0(struct barring_info, resp.record_num);
for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
dbg("valid count :%d", countValidRecords);
resp.record_num = countValidRecords;
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = SS_ERROR_NONE;
} else {
- dbg("no active status - return to user")
+ dbg("no active status - return to user");
}
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = SS_ERROR_NONE;
} else {
dbg("RESPONSE NOT OK");
resp.err = TCORE_RETURN_FAILURE;
+ resp.record = 0;
+ resp.record_num = 0;
line = (const char *) response->final_response;
tokens = tcore_at_tok_new(line);
if (g_slist_length(tokens) < 1) {
dbg("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = SS_ERROR_SYSTEMFAILURE;
} else {
- err = atoi(g_slist_nth_data(tokens, 0));
+ ss_err = atoi(g_slist_nth_data(tokens, 0));
+ err("Error: [%d]", ss_err);
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = SS_ERROR_SYSTEMFAILURE;
}
tcore_at_tok_free(tokens);
}
static void on_response_ss_forwarding_get(TcorePending *p, int data_len, const void *data, void *user_data)
{
UserRequest *ur = 0;
- int classx = 0, err = 0, time = 0;
+ int classx = 0, ss_err = 0, time = 0;
char *num;
struct ss_confirm_info *info = 0;
struct tresp_ss_forwarding resp;
dbg("total records : %d", countRecords);
} else {
countRecords = 0;
- dbg("no active status - return to user")
+ dbg("no active status - return to user");
}
resp.record_num = countRecords;
-
+ resp.record = 0;
if (resp.record_num > 0) {
resp.record = g_new0(struct forwarding_info, resp.record_num);
ton = g_slist_nth_data(tokens, 3);
if (ton) {
- resp.record[countValidRecords].number_type = atoi(ton);
- dbg("number type - %d", resp.record[countValidRecords].number_type);
+ resp.record[countValidRecords].ton = atoi(ton);
+ dbg("number type - %d", resp.record[countValidRecords].ton);
}
}
}
dbg("valid count :%d", countValidRecords);
resp.record_num = countValidRecords;
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = SS_ERROR_NONE;
} else {
- dbg("no active status - return to user")
+ dbg("no active status - return to user");
}
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = SS_ERROR_NONE;
} else {
dbg("RESPONSE NOT OK");
+ resp.record = 0;
+ resp.record_num = 0;
line = (const char *) response->final_response;
tokens = tcore_at_tok_new(line);
if (g_slist_length(tokens) < 1) {
dbg("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = SS_ERROR_SYSTEMFAILURE;
} else {
- err = atoi(g_slist_nth_data(tokens, 0));
+ ss_err = atoi(g_slist_nth_data(tokens, 0));
+ err("Error: [%d]", ss_err);
/* TODO: CMEE error mapping is required. */
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = SS_ERROR_SYSTEMFAILURE;
}
tcore_at_tok_free(tokens);
}
{
UserRequest *ur = 0;
GSList *respdata, *tokens = NULL;
- int classx = 0, err = 0;
+ int classx = 0, ss_err = 0;
struct ss_confirm_info *info = 0;
struct tresp_ss_waiting resp;
int countRecords = 0, countValidRecords = 0;
char *classx_str, *status;
const TcoreATResponse *response;
- dbg("function enter")
+ dbg("function enter");
response = data;
ur = tcore_pending_ref_user_request(p);
info = (struct ss_confirm_info *) user_data;
dbg("total records : %d", countRecords);
} else {
countRecords = 0;
- dbg("no active status - return to user")
+ dbg("no active status - return to user");
}
resp.record_num = countRecords;
+ resp.record = 0;
if (resp.record_num > 0) {
resp.record = g_new0(struct waiting_info, resp.record_num);
dbg("valid count :%d", countValidRecords);
resp.record_num = countValidRecords;
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = SS_ERROR_NONE;
} else {
- dbg("no active status - return to user")
+ dbg("no active status - return to user");
}
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = SS_ERROR_NONE;
} else {
dbg("RESPONSE NOT OK");
+ resp.record = 0;
+ resp.record_num = 0;
line = (const char *) response->final_response;
tokens = tcore_at_tok_new(line);
if (g_slist_length(tokens) < 1) {
dbg("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = SS_ERROR_SYSTEMFAILURE;
} else {
- err = atoi(g_slist_nth_data(tokens, 0));
+ ss_err = atoi(g_slist_nth_data(tokens, 0));
+ err("Error: [%d]", ss_err);
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = SS_ERROR_SYSTEMFAILURE;
}
tcore_at_tok_free(tokens);
}
struct tresp_ss_cli resp;
enum telephony_ss_cli_type *p_type = NULL;
char *line = NULL, *status;
- int err = FALSE;
+ int error = FALSE;
int cli_adj, stat;
GSList *tokens = NULL;
const TcoreATResponse *response;
- dbg("function enter")
+ dbg("function enter");
response = data;
ur = tcore_pending_ref_user_request(p);
p_type = (enum telephony_ss_cli_type *) (user_data);
if (*p_type == SS_CLI_TYPE_CLIR) {
// +CLIR: <n> <m>
- dbg("CLI type is CLIR")
+ dbg("CLI type is CLIR");
// parse <n>
status = g_slist_nth_data(tokens, 0);
if (response->success > 0) {
dbg("RESPONSE OK");
- resp.err = TCORE_RETURN_SUCCESS;
+ resp.err = SS_ERROR_NONE;
} else {
dbg("RESPONSE NOT OK");
if (g_slist_length(tokens) < 1) {
dbg("err cause not specified or string corrupted");
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = SS_ERROR_SYSTEMFAILURE;
} else {
- err = atoi(g_slist_nth_data(tokens, 0));
+ error = atoi(g_slist_nth_data(tokens, 0));
+ err("Error: [%d]", error);
// TODO: CMEE error mapping is required.
- resp.err = TCORE_RETURN_3GPP_ERROR;
+ resp.err = SS_ERROR_SYSTEMFAILURE;
}
tcore_at_tok_free(tokens);
}
}
static struct tcore_ss_operations ss_ops = {
- .barring_activate = s_ss_barring_activate,
- .barring_deactivate = s_ss_barring_deactivate,
- .barring_change_password = s_ss_barring_change_password,
- .barring_get_status = s_ss_barring_get_status,
- .forwarding_activate = s_ss_forwarding_activate,
- .forwarding_deactivate = s_ss_forwarding_deactivate,
- .forwarding_register = s_ss_forwarding_register,
- .forwarding_deregister = s_ss_forwarding_deregister,
- .forwarding_get_status = s_ss_forwarding_get_status,
- .waiting_activate = s_ss_waiting_activate,
- .waiting_deactivate = s_ss_waiting_deactivate,
- .waiting_get_status = s_ss_waiting_get_status,
- .cli_activate = s_ss_cli_activate,
- .cli_deactivate = s_ss_cli_deactivate,
- .cli_get_status = s_ss_cli_get_status,
- .send_ussd = s_ss_send_ussd,
- .set_aoc = s_ss_set_aoc,
- .get_aoc = s_ss_get_aoc,
+ .barring_activate = imc_ss_barring_activate,
+ .barring_deactivate = imc_ss_barring_deactivate,
+ .barring_change_password = imc_ss_barring_change_password,
+ .barring_get_status = imc_ss_barring_get_status,
+ .forwarding_activate = imc_ss_forwarding_activate,
+ .forwarding_deactivate = imc_ss_forwarding_deactivate,
+ .forwarding_register = imc_ss_forwarding_register,
+ .forwarding_deregister = imc_ss_forwarding_deregister,
+ .forwarding_get_status = imc_ss_forwarding_get_status,
+ .waiting_activate = imc_ss_waiting_activate,
+ .waiting_deactivate = imc_ss_waiting_deactivate,
+ .waiting_get_status = imc_ss_waiting_get_status,
+ .cli_activate = imc_ss_cli_activate,
+ .cli_deactivate = imc_ss_cli_deactivate,
+ .cli_get_status = imc_ss_cli_get_status,
+ .send_ussd = imc_ss_send_ussd,
+ .set_aoc = imc_ss_set_aoc,
+ .get_aoc = imc_ss_get_aoc,
};
struct treq_ss_barring *barring = 0;
struct ss_confirm_info *user_data = 0;
char *cmd_str = NULL;
- TcoreHal *hal;
TcorePending *pending = NULL;
TcoreATRequest *req;
char passwd[MAX_SS_BARRING_PASSWORD_LEN + 1];
dbg("classx - %d", classx);
+ user_data = g_new0(struct ss_confirm_info, 1);
+ if (!user_data) {
+ dbg("[ error ] failed to allocate memory");
+ return TCORE_RETURN_ENOMEM;
+ }
+
// null-ended pwd handling added - unexpected 0x11 value observed in req string
memcpy(passwd, barring->password, MAX_SS_BARRING_PASSWORD_LEN);
passwd[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
dbg("passwd - %s", passwd);
- hal = tcore_object_get_hal(o);
pending = tcore_pending_new(o, 0);
cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,\"%s\",%d", facility, opco, passwd, classx);
dbg("request command : %s", cmd_str);
req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
- user_data = g_new0(struct ss_confirm_info, 1);
if (op == SS_OPCO_ACTIVATE) {
user_data->resp = TRESP_SS_BARRING_ACTIVATE;
} else if (op == SS_OPCO_DEACTIVATE) {
user_data->resp = TRESP_SS_BARRING_DEACTIVATE;
} else {
dbg("[ error ] wrong ss opco (0x%x)", op);
+ if (user_data != NULL) {
+ g_free(user_data);
+ }
+ g_free(cmd_str);
+ tcore_pending_free(pending);
+ tcore_at_request_free(req);
return TCORE_RETURN_FAILURE;
}
user_data->flavor_type = (int) (barring->mode);
g_free(cmd_str);
if (!ret) {
- dbg("AT request sent failed ")
+ dbg("AT request sent failed ");
+ if (user_data != NULL) {
+ g_free(user_data);
+ tcore_pending_free(pending);
+ tcore_at_request_free(req);
+ }
return TCORE_RETURN_FAILURE;
}
return TCORE_RETURN_SUCCESS;
char *cmd_str = NULL;
int opco, classx;
char *facility = NULL;
- TcoreHal *hal;
TcorePending *pending = NULL;
TcoreATRequest *req;
break;
case SS_BARR_MODE_AB:
- facility = "AB";
- break;
-
case SS_BARR_MODE_AOB:
- facility = "AG";
- break;
-
case SS_BARR_MODE_AIB:
- facility = "AC";
- break;
-
case SS_BARR_MODE_BIC_NOT_SIM:
default:
- dbg("unspported mode %d", mode);
+ dbg("unsupported mode %d", mode);
return TCORE_RETURN_FAILURE;
}
dbg("unsupported class %d. set to default : 7", class);
break;
}
- dbg("class - %d", classx);
+ user_data = g_new0(struct ss_confirm_info, 1);
+ if (!user_data) {
+ dbg("[ error ] failed to allocate memory");
+ return TCORE_RETURN_ENOMEM;
+ }
+
+ dbg("class - %d", classx);
if (classx == 7)
cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d", facility, opco);
else
dbg("request command : %s", cmd_str);
- hal = tcore_object_get_hal(o);
pending = tcore_pending_new(o, 0);
req = tcore_at_request_new(cmd_str, "+CLCK", TCORE_AT_MULTILINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
- user_data = g_new0(struct ss_confirm_info, 1);
user_data->resp = resp;
user_data->flavor_type = (int) (mode);
user_data->class = class;
g_free(cmd_str);
if (!ret) {
- dbg("AT request sent failed ")
+ dbg("AT request sent failed ");
+ if (user_data != NULL) {
+ g_free(user_data);
+ tcore_pending_free(pending);
+ tcore_at_request_free(req);
+ }
return TCORE_RETURN_FAILURE;
}
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_ss_barring_activate(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_barring_activate(CoreObject *o, UserRequest *ur)
{
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
return _ss_barring_set(o, ur, SS_OPCO_ACTIVATE);
}
-static TReturn s_ss_barring_deactivate(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_barring_deactivate(CoreObject *o, UserRequest *ur)
{
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
return _ss_barring_set(o, ur, SS_OPCO_DEACTIVATE);
}
-static TReturn s_ss_barring_change_password(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_barring_change_password(CoreObject *o, UserRequest *ur)
{
- TcoreHal *hal;
TcorePending *pending = NULL;
TcoreATRequest *req;
struct treq_ss_barring_change_password *barring = 0;
char new_password[MAX_SS_BARRING_PASSWORD_LEN + 1];
dbg("function enter");
- barring = (struct treq_ss_barring_change_password *) tcore_user_request_ref_data(ur, 0);
- if (barring->password_old == NULL || barring->password_new == NULL) {
- dbg("[error]password is null");
- return TCORE_RETURN_FAILURE;
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
}
+
+ barring = (struct treq_ss_barring_change_password *) tcore_user_request_ref_data(ur, 0);
+
memcpy(old_password, barring->password_old, MAX_SS_BARRING_PASSWORD_LEN);
old_password[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
memcpy(new_password, barring->password_new, MAX_SS_BARRING_PASSWORD_LEN);
new_password[MAX_SS_BARRING_PASSWORD_LEN] = '\0';
+ user_data = g_new0(struct ss_confirm_info, 1);
+ if (!user_data) {
+ dbg("[ error ] failed to allocate memory");
+ return TCORE_RETURN_ENOMEM;
+ }
+ user_data->resp = TRESP_SS_BARRING_CHANGE_PASSWORD;
+
dbg("old passwd - %s new passwd- %s", old_password, new_password);
cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", "AB", old_password, new_password);
dbg("request command : %s", cmd_str);
- hal = tcore_object_get_hal(o);
pending = tcore_pending_new(o, 0);
req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
- user_data = g_new0(struct ss_confirm_info, 1);
- user_data->resp = TRESP_SS_BARRING_CHANGE_PASSWORD;
-
ret = _ss_request_message(pending, o, ur, on_response_ss_barring_change_pwd, user_data);
g_free(cmd_str);
if (!ret) {
- dbg("AT request sent failed ")
+ dbg("AT request sent failed ");
+ if (user_data != NULL) {
+ g_free(user_data);
+ }
+ tcore_pending_free(pending);
+ tcore_at_request_free(req);
return TCORE_RETURN_FAILURE;
}
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_ss_barring_get_status(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_barring_get_status(CoreObject *o, UserRequest *ur)
{
struct treq_ss_barring *barring = 0;
+
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
barring = (struct treq_ss_barring *) tcore_user_request_ref_data(ur, 0);
return _ss_barring_get(o, ur, barring->class, barring->mode, TRESP_SS_BARRING_GET_STATUS);
char *cmd_str = NULL;
char *tmp_str = NULL;
int reason = 0, mode = 0, num_type = 0, classx = 0, time = 0;
- gboolean valid_num = FALSE;
- TcoreHal *hal;
TcorePending *pending = NULL;
TcoreATRequest *req;
// number
len = strlen(forwarding->number);
if (len > 0) {
- valid_num = TRUE;
if (forwarding->number[0] == '+')
num_type = ((NUM_TYPE_INTERNATIONAL << 4) | NUM_PLAN_ISDN);
else
dbg("number = %s", forwarding->number);
user_data = g_new0(struct ss_confirm_info, 1);
+ if (!user_data) {
+ dbg("[ error ] failed to allocate memory");
+ return TCORE_RETURN_ENOMEM;
+ }
switch (op) {
case SS_OPCO_REG:
}
dbg("request command : %s", cmd_str);
- hal = tcore_object_get_hal(o);
pending = tcore_pending_new(o, 0);
req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ g_free(tmp_str);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
g_free(cmd_str);
if (!ret) {
- dbg("AT request sent failed ")
+ dbg("AT request sent failed ");
+ if (user_data != NULL) {
+ g_free(user_data);
+ }
return TCORE_RETURN_FAILURE;
}
gboolean ret = FALSE;
char *cmd_str = NULL;
int reason = 0, mode = 0, classx = 0;
- TcoreHal *hal;
TcorePending *pending = NULL;
TcoreATRequest *req;
// query status - mode set to 2
mode = 2;
user_data = g_new0(struct ss_confirm_info, 1);
+ if (!user_data) {
+ dbg("[ error ] failed to allocate memory");
+ return TCORE_RETURN_ENOMEM;
+ }
user_data->resp = resp;
user_data->class = class;
user_data->flavor_type = type;
dbg("request command : %s", cmd_str);
- hal = tcore_object_get_hal(o);
pending = tcore_pending_new(o, 0);
req = tcore_at_request_new(cmd_str, "+CCFC", TCORE_AT_MULTILINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
g_free(cmd_str);
if (!ret) {
- dbg("AT request sent failed ")
+ dbg("AT request sent failed ");
+ if (user_data != NULL) {
+ g_free(user_data);
+ tcore_pending_free(pending);
+ tcore_at_request_free(req);
+ }
return TCORE_RETURN_FAILURE;
}
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_ss_forwarding_activate(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_forwarding_activate(CoreObject *o, UserRequest *ur)
{
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
return _ss_forwarding_set(o, ur, SS_OPCO_ACTIVATE);
}
-static TReturn s_ss_forwarding_deactivate(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_forwarding_deactivate(CoreObject *o, UserRequest *ur)
{
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
return _ss_forwarding_set(o, ur, SS_OPCO_DEACTIVATE);
}
-static TReturn s_ss_forwarding_register(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_forwarding_register(CoreObject *o, UserRequest *ur)
{
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
return _ss_forwarding_set(o, ur, SS_OPCO_REG);
}
-static TReturn s_ss_forwarding_deregister(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_forwarding_deregister(CoreObject *o, UserRequest *ur)
{
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
return _ss_forwarding_set(o, ur, SS_OPCO_DEREG);
}
-static TReturn s_ss_forwarding_get_status(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_forwarding_get_status(CoreObject *o, UserRequest *ur)
{
struct treq_ss_forwarding *forwarding = 0;
+
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
forwarding = (struct treq_ss_forwarding *) tcore_user_request_ref_data(ur, 0);
return _ss_forwarding_get(o, ur, forwarding->class, forwarding->mode, TRESP_SS_FORWARDING_GET_STATUS);
gboolean ret = FALSE;
int mode = 0, classx = 0;
char *cmd_str;
- TcoreHal *hal;
TcorePending *pending = NULL;
TcoreATRequest *req;
dbg("function enter ");
waiting = (struct treq_ss_waiting *) tcore_user_request_ref_data(ur, 0);
user_data = g_new0(struct ss_confirm_info, 1);
+ if (!user_data) {
+ dbg("[ error ] failed to allocate memory");
+ return TCORE_RETURN_ENOMEM;
+ }
if (opco == SS_OPCO_ACTIVATE) {
user_data->resp = TRESP_SS_WAITING_ACTIVATE;
cmd_str = g_strdup_printf("AT+CCWA=1,%d,%d", mode, classx); // always enable +CCWA: unsolicited cmd
dbg("request command : %s", cmd_str);
- hal = tcore_object_get_hal(o);
pending = tcore_pending_new(o, 0);
req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_set, user_data);
g_free(cmd_str);
if (!ret) {
- dbg("AT request sent failed ")
+ dbg("AT request sent failed ");
+ if (user_data != NULL) {
+ g_free(user_data);
+ tcore_pending_free(pending);
+ tcore_at_request_free(req);
+ }
return TCORE_RETURN_FAILURE;
}
return TCORE_RETURN_SUCCESS;
gboolean ret = FALSE;
int classx; // mode,
char *cmd_str;
- TcoreHal *hal;
TcorePending *pending = NULL;
TcoreATRequest *req;
- dbg("function enter")
+ dbg("function enter");
switch (class) {
case SS_CLASS_ALL_TELE:
classx = 7;
dbg("allocating user data");
user_data = g_new0(struct ss_confirm_info, 1);
+ if (!user_data) {
+ dbg("[ error ] failed to allocate memory");
+ return TCORE_RETURN_ENOMEM;
+ }
user_data->resp = resp;
user_data->class = class;
cmd_str = g_strdup_printf("AT+CCWA=1,2,%d", classx); // always enable +CCWA: unsolicited cmd , mode is fixed to 2(query status)
dbg("request cmd : %s", cmd_str);
- hal = tcore_object_get_hal(o);
pending = tcore_pending_new(o, 0);
req = tcore_at_request_new(cmd_str, "+CCWA", TCORE_AT_MULTILINE);
+ if (req == NULL) {
+ err("Request is NULL");
+ g_free(cmd_str);
+ tcore_pending_free(pending);
+ return TCORE_RETURN_EINVAL;
+ }
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
ret = _ss_request_message(pending, o, ur, on_response_ss_waiting_get, user_data);
g_free(cmd_str);
if (!ret) {
- dbg("AT request sent failed ")
+ dbg("AT request sent failed ");
+ if (user_data != NULL) {
+ g_free(user_data);
+ tcore_pending_free(pending);
+ tcore_at_request_free(req);
+ }
return TCORE_RETURN_FAILURE;
}
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_ss_waiting_activate(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_waiting_activate(CoreObject *o, UserRequest *ur)
{
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
return _ss_waiting_set(o, ur, SS_OPCO_ACTIVATE);
}
-static TReturn s_ss_waiting_deactivate(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_waiting_deactivate(CoreObject *o, UserRequest *ur)
{
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
return _ss_waiting_set(o, ur, SS_OPCO_DEACTIVATE);
}
-static TReturn s_ss_waiting_get_status(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_waiting_get_status(CoreObject *o, UserRequest *ur)
{
struct treq_ss_waiting *waiting = 0;
+
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
waiting = (struct treq_ss_waiting *) tcore_user_request_ref_data(ur, 0);
return _ss_waiting_get(o, ur, waiting->class, TRESP_SS_WAITING_GET_STATUS);
}
-static TReturn s_ss_cli_activate(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_cli_activate(CoreObject *o, UserRequest *ur)
{
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_ss_cli_deactivate(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_cli_deactivate(CoreObject *o, UserRequest *ur)
{
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_ss_cli_get_status(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_cli_get_status(CoreObject *o, UserRequest *ur)
{
struct treq_ss_cli *cli = 0;
gboolean ret = FALSE;
char *cmd_prefix = NULL, *rsp_prefix = NULL, *cmd_str = NULL;
enum telephony_ss_cli_type *user_data = 0;
- TcoreHal *hal;
TcorePending *pending = NULL;
TcoreATRequest *req;
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
cli = (struct treq_ss_cli *) tcore_user_request_ref_data(ur, 0);
switch (cli->type) {
case SS_CLI_TYPE_CLIP:
dbg("request cmd : %s", cmd_str);
user_data = g_new0(enum telephony_ss_cli_type, 1);
+ if (!user_data) {
+ dbg("[ error ] failed to allocate memory");
+ g_free(cmd_str);
+ return TCORE_RETURN_ENOMEM;
+ }
*user_data = cli->type;
- hal = tcore_object_get_hal(o);
pending = tcore_pending_new(o, 0);
req = tcore_at_request_new(cmd_str, rsp_prefix, TCORE_AT_SINGLELINE);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
ret = _ss_request_message(pending, o, ur, on_response_ss_cli_get, user_data);
g_free(cmd_str);
if (!ret) {
- dbg("AT request sent failed ")
+ dbg("AT request sent failed ");
+ if (user_data != NULL) {
+ g_free(user_data);
+ tcore_pending_free(pending);
+ tcore_at_request_free(req);
+ }
return TCORE_RETURN_FAILURE;
}
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_ss_send_ussd(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_send_ussd(CoreObject *o, UserRequest *ur)
{
UssdSession *ussd_s = 0;
struct treq_ss_ussd *ussd = 0;
struct ss_confirm_info *user_data = 0;
gboolean ret = FALSE;
char *cmd_str;
- TcoreHal *hal;
TcorePending *pending = NULL;
TcoreATRequest *req;
dbg("function enter");
+
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
ussd = (struct treq_ss_ussd *) tcore_user_request_ref_data(ur, 0);
- cmd_str = g_strdup_printf("AT+CUSD=1,\"%s\",%d", ussd->str, 0x0f); // always enable +CUSD: unsolicited cmd. set to dcs to 0x0f. only supports HEX type
- dbg("request command : %s", cmd_str);
user_data = g_new0(struct ss_confirm_info, 1);
+ if (!user_data) {
+ dbg("[ error ] failed to allocate memory");
+ return TCORE_RETURN_ENOMEM;
+ }
user_data->resp = TRESP_SS_SEND_USSD;
ussd_s = tcore_ss_ussd_get_session(o);
if (!ussd_s) {
tcore_ss_ussd_set_session_type(ussd_s, (enum tcore_ss_ussd_type) ussd->type);
}
- hal = tcore_object_get_hal(o);
+ cmd_str = g_strdup_printf("AT+CUSD=1,\"%s\",%d", ussd->str, 0x0f); // always enable +CUSD: unsolicited cmd. set to dcs to 0x0f. only supports HEX type
+ dbg("request command : %s", cmd_str);
+
pending = tcore_pending_new(o, 0);
req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ g_free(cmd_str);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
g_free(cmd_str);
if (!ret) {
- dbg("AT request sent failed ")
+ dbg("AT request sent failed ");
+ if (user_data != NULL) {
+ g_free(user_data);
+ tcore_pending_free(pending);
+ tcore_at_request_free(req);
+ }
return TCORE_RETURN_FAILURE;
}
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_ss_set_aoc(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_set_aoc(CoreObject *o, UserRequest *ur)
{
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
dbg("[ error ] unsupported function");
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_ss_get_aoc(CoreObject *o, UserRequest *ur)
+static TReturn imc_ss_get_aoc(CoreObject *o, UserRequest *ur)
{
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
dbg("[ error ] unsupported function");
return TCORE_RETURN_SUCCESS;
}
static struct tcore_call_control_operations call_ops = {
- .answer_hold_and_accept = s_ss_manage_call_2_send,
- .answer_replace = s_ss_manage_call_1_send,
- .answer_reject = s_ss_manage_call_0_send,
- .end_specific = s_ss_manage_call_1x_send,
- .end_all_active = s_ss_manage_call_1_send,
- .end_all_held = s_ss_manage_call_0_send,
- .active = s_ss_manage_call_2_send,
- .hold = s_ss_manage_call_2_send,
- .swap = s_ss_manage_call_2_send,
- .join = s_ss_manage_call_3_send,
- .split = s_ss_manage_call_2x_send,
- .transfer = s_ss_manage_call_4_send,
- .deflect = s_ss_manage_call_4dn_send,
+ .answer_hold_and_accept = imc_ss_manage_call_2_send,
+ .answer_replace = imc_ss_manage_call_1_send,
+ .answer_reject = imc_ss_manage_call_0_send,
+ .end_specific = imc_ss_manage_call_1x_send,
+ .end_all_active = imc_ss_manage_call_1_send,
+ .end_all_held = imc_ss_manage_call_0_send,
+ .active = imc_ss_manage_call_2_send,
+ .hold = imc_ss_manage_call_2_send,
+ .swap = imc_ss_manage_call_2_send,
+ .join = imc_ss_manage_call_3_send,
+ .split = imc_ss_manage_call_2x_send,
+ .transfer = imc_ss_manage_call_4_send,
+ .deflect = imc_ss_manage_call_4dn_send,
};
-static TReturn s_ss_manage_call_send(CoreObject *o, UserRequest *ur, const char *cmd, ConfirmCallback cb, void *user_data)
+static TReturn imc_ss_manage_call_send(CoreObject *o, UserRequest *ur, const char *cmd, ConfirmCallback cb, void *user_data)
{
TcorePending *pending = NULL;
TcoreATRequest *req;
pending = tcore_pending_new(o, 0);
req = tcore_at_request_new(cmd, NULL, TCORE_AT_NO_RESULT);
+ if (req == NULL) {
+ tcore_pending_free(pending);
+ return TCORE_RETURN_FAILURE;
+ }
dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
tcore_pending_set_request_data(pending, 0, req);
ret = _ss_request_message(pending, o, ur, (TcorePendingResponseCallback) cb, user_data);
if (!ret) {
- dbg("AT request sent failed ")
+ dbg("AT request sent failed ");
return TCORE_RETURN_FAILURE;
}
return TCORE_RETURN_SUCCESS;
}
-static TReturn s_ss_manage_call_0_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
+static TReturn imc_ss_manage_call_0_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
{
char *cmd_str = NULL;
gboolean ret = FALSE;
cmd_str = g_strdup_printf("%s", "AT+CHLD=0");
dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
+ ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
g_free(cmd_str);
return ret;
}
-static TReturn s_ss_manage_call_1_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
+static TReturn imc_ss_manage_call_1_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
{
char *cmd_str = NULL;
gboolean ret = FALSE;
cmd_str = g_strdup_printf("%s", "AT+CHLD=1");
dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
+ ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
g_free(cmd_str);
return ret;
}
-static TReturn s_ss_manage_call_1x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
+static TReturn imc_ss_manage_call_1x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
{
char *cmd_str = NULL;
gboolean ret = FALSE;
cmd_str = g_strdup_printf("%s%d", "AT+CHLD=1", id);
dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
+ ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
g_free(cmd_str);
return ret;
}
-static TReturn s_ss_manage_call_2_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
+static TReturn imc_ss_manage_call_2_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
{
char *cmd_str = NULL;
gboolean ret = FALSE;
cmd_str = g_strdup_printf("%s", "AT+CHLD=2");
dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
+ ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
g_free(cmd_str);
return ret;
}
-static TReturn s_ss_manage_call_2x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
+static TReturn imc_ss_manage_call_2x_send(CoreObject *o, UserRequest *ur, const int id, ConfirmCallback cb, void *user_data)
{
char *cmd_str = NULL;
gboolean ret = FALSE;
cmd_str = g_strdup_printf("%s%d", "AT+CHLD=2", id);
dbg("cmd : %s, prefix(if any) : %s, cmd_len : %d", cmd_str, "N/A", strlen(cmd_str));
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
+ ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
g_free(cmd_str);
return ret;
}
-static TReturn s_ss_manage_call_3_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
+static TReturn imc_ss_manage_call_3_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
{
char *cmd_str = NULL;
gboolean ret = FALSE;
dbg("function enter");
cmd_str = g_strdup_printf("%s", "AT+CHLD=3");
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
+ ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
g_free(cmd_str);
return ret;
}
-static TReturn s_ss_manage_call_4_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
+static TReturn imc_ss_manage_call_4_send(CoreObject *o, UserRequest *ur, ConfirmCallback cb, void *user_data)
{
char *cmd_str = NULL;
gboolean ret = FALSE;
dbg("function enter");
cmd_str = g_strdup_printf("%s", "AT+CHLD=4");
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
+ ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
g_free(cmd_str);
return ret;
}
-static TReturn s_ss_manage_call_4dn_send(CoreObject *o, UserRequest *ur, const char *number, ConfirmCallback cb, void *user_data)
+static TReturn imc_ss_manage_call_4dn_send(CoreObject *o, UserRequest *ur, const char *number, ConfirmCallback cb, void *user_data)
{
char *cmd_str = NULL;
gboolean ret = FALSE;
dbg("function enter");
cmd_str = g_strdup_printf("%s%s", "AT+CHLD=4", number);
- ret = s_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
+ ret = imc_ss_manage_call_send(o, ur, cmd_str, cb, user_data);
g_free(cmd_str);
return ret;
}
-gboolean s_ss_init(TcorePlugin *p, TcoreHal *h)
+gboolean imc_ss_init(TcorePlugin *cp, CoreObject *co_ss)
{
- CoreObject *so = 0, *co = 0;
- struct property_call_info *data = 0;
+ CoreObject *co_call = NULL;
- so = tcore_ss_new(p, "ss", &ss_ops, h);
- if (!so) {
- dbg("[ error ] ss_new()");
- return FALSE;
- }
+ /* Set operations */
+ tcore_ss_set_ops(co_ss, &ss_ops);
- co = tcore_plugin_ref_core_object(p, "call");
- if (!co) {
- dbg("[ error ] plugin_ref_core_object");
+
+ co_call = tcore_plugin_ref_core_object(cp,
+ CORE_OBJECT_TYPE_CALL);
+ if (co_call == NULL) {
+ err("Can't find CALL core object");
return FALSE;
}
- tcore_call_control_set_operations(co, &call_ops);
+ /* Set operations */
+ tcore_call_control_set_operations(co_call, &call_ops);
- tcore_object_add_callback(so, "+CSSU", on_notification_ss_info, 0);
- tcore_object_add_callback(so, "+CSSI", on_notification_ss_info, 0);
- tcore_object_add_callback(so, "+CUSD", on_notification_ss_ussd, 0);
-
- data = calloc(sizeof(struct property_call_info *), 1);
- tcore_plugin_link_property(p, "SS", data);
+ tcore_object_add_callback(co_ss, "+CSSU", on_notification_ss_info, NULL);
+ tcore_object_add_callback(co_ss, "+CSSI", on_notification_ss_info, NULL);
+ tcore_object_add_callback(co_ss, "+CUSD", on_notification_ss_ussd, NULL);
return TRUE;
}
-void s_ss_exit(TcorePlugin *p)
+void imc_ss_exit(TcorePlugin *cp, CoreObject *co_ss)
{
- CoreObject *o;
- struct property_network_info *data;
-
- o = tcore_plugin_ref_core_object(p, "ss");
-
- data = tcore_plugin_ref_property(p, "SS");
- if (data)
- free(data);
-
- tcore_ss_free(o);
+ dbg("Exit");
}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Paresh Agarwal <paresh.agwl@samsung.com>
+ *
+ * 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 <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <glib.h>
+#include <string.h>
+
+#include <sys/stat.h>
+#include <tcore.h>
+#include "nvm/nvm.h"
+
+/* NVM file type */
+#define NVM_TYPE_CALIB 0
+#define NVM_TYPE_STATIC 1
+#define NVM_TYPE_DYNAMIC 2
+#define NVM_FILE_TYPE_POS 36
+
+/* NVM Payload information */
+#define NVM_PAYLOAD_OFFSET_0 48
+#define NVM_PAYLOAD_LENGTH_0 52
+#define NVM_PAYLOAD_OFFSET_1 64
+#define NVM_PAYLOAD_LENGTH_1 68
+#define NVM_DATA_LEN_POS 80
+
+/* Image Path information */
+#define MODEM_IMAGE_PATH "/opt/modem/modem.bin"
+#define NVM_DIR_PATH "/csa/nv"
+#define NV_FILE_PATH NVM_DIR_PATH "/nvdata.bin"
+
+/* NV offsets and size */
+#define MODEM_NV_OFFSET 0xA00000
+#define MAX_NVDATA_SIZE 0x200000
+#define NVM_CALIB_OFFSET 0x80000
+#define NVM_STATIC_OFFSET 0x100000
+
+struct nvm_payload_info {
+ unsigned long m_offset_0;
+ unsigned long m_length_0;
+ unsigned long m_offset_1;
+ unsigned long m_length_1;
+};
+
+static nvm_error __nvm_file_write(int nvm_type, const char *update_buf, int update_len, int offset)
+{
+ int nv_fd;
+ nvm_error ret_val = NVM_NO_ERR;
+ int ret;
+
+ char err_str[256] = {0, };
+ errno = 0;
+ dbg("Entered");
+
+ if (NULL == update_buf) {
+ err("Buffer is invalid!!!");
+ return NVM_WRITE_ERR;
+ }
+
+ switch (nvm_type) {
+ case NVM_TYPE_CALIB:
+ msg(" [NVM File] calib.nvm");
+ offset = offset + NVM_CALIB_OFFSET;
+ break;
+
+ case NVM_TYPE_STATIC:
+ msg(" [NVM File] static.nvm");
+ offset = offset + NVM_STATIC_OFFSET;
+ break;
+
+ case NVM_TYPE_DYNAMIC:
+ msg(" [NVM File] dynamic.nvm");
+ break;
+
+ default:
+ err("[NVM File] Wrong NVM file type: [%d]", nvm_type);
+ return NVM_FILE_ERR;
+ }
+
+ /* Open NVM file for Write operation */
+ nv_fd = open(NV_FILE_PATH, O_RDWR);
+ if (nv_fd < 0) {
+ strerror_r(errno, err_str, 255);
+ err("[OPEN] Failed: [%s]", err_str);
+ return NVM_READ_ERR;
+ }
+
+ /* Seek the offset */
+ ret = lseek(nv_fd, (long)offset, SEEK_SET);
+ if (ret < 0) {
+ strerror_r(errno, err_str, 255);
+ err("[SEEK] Failed: [%s]", err_str);
+ ret_val = NVM_RES_LEN_ERR;
+ } else {
+ dbg("Buffer: [0x%x] length: [%d]", update_buf, update_len);
+
+ /* Write the buffer to file */
+ ret = write(nv_fd, update_buf, update_len);
+ if (ret > 0) {
+ dbg("[WRITE] Successfully updated NVM data");
+ } else if (ret == 0) {
+ strerror_r(errno, err_str, 255);
+ dbg("[WRITE] Nothing is written: [%s]", err_str);
+ } else {
+ strerror_r(errno, err_str, 255);
+ err("[WRITE] Failed: [%s]", err_str);
+ ret_val = NVM_MEM_FULL_ERR;
+ }
+ }
+
+ /* Close 'fd' */
+ close(nv_fd);
+
+ return ret_val;
+}
+
+static nvm_error __nvm_write_payload_1(int nvm_type,
+ const char *p_bin_buff, struct nvm_payload_info *nvm1)
+{
+ const char *p_buf_ptr = p_bin_buff;
+
+ /* Write to file */
+ return __nvm_file_write(nvm_type,
+ (p_buf_ptr + NVM_DATA_LEN_POS + nvm1->m_length_0),
+ nvm1->m_length_1,
+ nvm1->m_offset_1);
+}
+
+static nvm_error __nvm_write_payload_0(int nvm_type,
+ const char *p_bin_buff, struct nvm_payload_info *nvm)
+{
+ nvm_error ret_val;
+
+ /* Write to file */
+ ret_val = __nvm_file_write(nvm_type,
+ (p_bin_buff + NVM_DATA_LEN_POS),
+ nvm->m_length_0,
+ nvm->m_offset_0);
+ if (NVM_NO_ERR == ret_val) {
+ /* The payload_0 has been done, so calls this method to write payload_1 to file */
+ ret_val = __nvm_write_payload_1(nvm_type, p_bin_buff, nvm);
+ } else {
+ err("Failed to write to NV data file!!!");
+ }
+
+ return ret_val;
+}
+
+int nvm_sum_4_bytes(const char *pos)
+{
+ int sum = 0;
+ sum = sum | (*(pos+3)) << 24;
+ sum = sum | (*(pos+2)) << 16;
+ sum = sum | (*(pos+1)) << 8;
+ sum = sum | *pos;
+ return sum;
+}
+
+nvm_error nvm_process_nv_update(const char *data)
+{
+ struct nvm_payload_info nvm_info;
+ int nvm_type;
+ nvm_error ret_val;
+ dbg("Entered");
+
+ memset(&nvm_info, 0x0, sizeof(struct nvm_payload_info));
+
+ /* Determine lengths from the little-endian 4 bytes */
+ nvm_info.m_length_0 = nvm_sum_4_bytes(&data[NVM_PAYLOAD_LENGTH_0]);
+ nvm_info.m_offset_0 = nvm_sum_4_bytes(&data[NVM_PAYLOAD_OFFSET_0]);
+ nvm_info.m_length_1 = nvm_sum_4_bytes(&data[NVM_PAYLOAD_LENGTH_1]);
+ nvm_info.m_offset_1 = nvm_sum_4_bytes(&data[NVM_PAYLOAD_OFFSET_1]);
+ dbg("Offsets - 0th: [%d] 1st: [%d]", nvm_info.m_offset_0, nvm_info.m_offset_1);
+
+ nvm_type = *(data + NVM_FILE_TYPE_POS);
+ if ((NVM_TYPE_CALIB <= nvm_type)
+ && (NVM_TYPE_DYNAMIC >= nvm_type)) {
+ dbg("NVM type: [%d]", nvm_type);
+
+ /* Write NVM data to file */
+ ret_val = __nvm_write_payload_0(nvm_type, data, &nvm_info);
+ } else {
+ err("Wrong NVM file type: [%d]", nvm_type);
+ ret_val = NVM_RES_ERR;
+ }
+
+ return ret_val;
+}
+
+gboolean nvm_create_nvm_data()
+{
+ int modem_fd;
+ int nv_fd;
+ char *buffer = NULL;
+ char err_str[256] = {0, };
+
+ gboolean ret_val = FALSE;
+ dbg("Entered");
+
+ /* Open modem binary */
+ modem_fd = open(MODEM_IMAGE_PATH, O_RDONLY | O_NDELAY);
+ if (modem_fd < 0) {
+ strerror_r(errno, err_str, 255);
+ err("[OPEN] Failed for (%s): [%s]", MODEM_IMAGE_PATH, err_str);
+ return ret_val;
+ }
+
+ /* Create NV data folder if it doesn't exist */
+ if (mkdir(NVM_DIR_PATH, 0755) < 0) {
+ if (errno != EEXIST) {
+ strerror_r(errno, err_str, 255);
+ err("mkdir() failed: [%s]", err_str);
+
+ /* Close 'modem_fd' */
+ close(modem_fd);
+ return ret_val;
+ } else if ((nv_fd = open(NV_FILE_PATH, O_EXCL)) >= 0) {
+ /* NV data file already exists */
+ dbg("File exists: [%s]", NV_FILE_PATH);
+
+ /* Close 'modem_fd' */
+ close(modem_fd);
+ close(nv_fd);
+ return TRUE;
+ } else {
+ dbg("File does't exsits... need to create!!!");
+ }
+ }
+
+ /* Change directory permissions */
+ if (chmod(NVM_DIR_PATH, 0755) < 0) {
+ strerror_r(errno, err_str, 255);
+ err("chmod() failed: [%s]", err_str);
+
+ /* Close 'modem_fd' */
+ close(modem_fd);
+ return ret_val;
+ }
+
+ /* Open NV data file for different file operations */
+ nv_fd = open(NV_FILE_PATH, O_RDWR | O_CREAT | O_SYNC, S_IRWXU);
+ if (nv_fd < 0) {
+ strerror_r(errno, err_str, 255);
+ err("[OPEN] Failed for (%s): %s", NV_FILE_PATH, err_str);
+
+ /* Close 'modem_fd' */
+ close(modem_fd);
+ return ret_val;
+ }
+
+ dbg("Setting the file descriptor offset to NV data in modem.bin");
+ do {
+ /* Seek pre-defined offset in modem binary */
+ if (lseek(modem_fd, MODEM_NV_OFFSET, SEEK_SET) < 0) {
+ strerror_r(errno, err_str, 255);
+ err("[SEEK] Failed: [%s]", err_str);
+ break;
+ }
+
+ /* Allocate memory */
+ buffer = g_try_malloc0(MAX_NVDATA_SIZE);
+ if (NULL == buffer) {
+ err("Failed to allocate memory");
+ break;
+ }
+
+ /* Read NV data from modem binary */
+ if (read(modem_fd, buffer, MAX_NVDATA_SIZE) < 0) {
+ strerror_r(errno, err_str, 255);
+ err("[READ] Failed: [%s]", err_str);
+ break;
+ }
+
+ /* Write the data read from modem binary to nvdata */
+ if (write(nv_fd, buffer, MAX_NVDATA_SIZE) < 0) {
+ strerror_r(errno, err_str, 255);
+ err("[WRITE} Failed: [%s]", err_str);
+ break;
+ }
+
+ ret_val = TRUE;
+ } while (0);
+
+ if (ret_val == FALSE) {
+ err("nvdata (%s) creation Failed!!!", NV_FILE_PATH);
+ } else {
+ dbg("nvdata (%s) created Success", NV_FILE_PATH);
+ }
+
+ /* Close 'fds' */
+ close(modem_fd);
+ close(nv_fd);
+
+ /* Free 'buffer' */
+ g_free(buffer);
+
+ return ret_val;
+}
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Harish Bishnoi <hbishnoi@samsung.com>
- *
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <glib.h>
-
-#include <tcore.h>
-#include <hal.h>
-#include <core_object.h>
-#include <plugin.h>
-#include <queue.h>
-#include <co_modem.h>
-#include <storage.h>
-#include <server.h>
-#include <at.h>
-#include <mux.h>
-
-#include "s_common.h"
-#include "s_modem.h"
-
-
-#define ID_RESERVED_AT 0x0229
-
-#define MAX_VERSION_LEN 32
-#define TAPI_MISC_ME_SN_LEN_MAX 32
-#define TAPI_MISC_PRODUCT_CODE_LEN_MAX 32
-#define TAPI_MISC_MODEL_ID_LEN_MAX 17
-#define TAPI_MISC_PRL_ERI_VER_LEN_MAX 17
-
-#define CPAS_RES_READY 0
-#define CPAS_RES_UNAVAIL 1
-#define CPAS_RES_UNKNOWN 2
-#define CPAS_RES_RINGING 3
-#define CPAS_RES_CALL_PROGRESS 4
-#define CPAS_RES_ASLEEP 5
-#define AT_VER_LEN 20
-
-
-enum cp_state {
- CP_STATE_OFFLINE,
- CP_STATE_CRASH_RESET,
- CP_STATE_CRASH_EXIT,
- CP_STATE_BOOTING,
- CP_STATE_ONLINE,
- CP_STATE_NV_REBUILDING,
- CP_STATE_LOADER_DONE,
-};
-
-typedef enum {
- TAPI_MISC_ME_IMEI = 0x00, /**< 0x00: IMEI, GSM/UMTS device */
- TAPI_MISC_ME_ESN = 0x01, /**< 0x01: ESN(Electronic Serial Number), It`s essentially run out. CDMA device */
- TAPI_MISC_ME_MEID = 0x02, /**< 0x02: MEID, This value can have hexa decimal digits. CDMA device */
- TAPI_MISC_ME_MAX = 0xff /**< 0xff: reserved */
-} TelMiscSNIndexType_t;
-
-typedef struct {
- TelMiscSNIndexType_t sn_index; /**< serial number index */
- int sn_len; /**< Length */
- unsigned char szNumber[TAPI_MISC_ME_SN_LEN_MAX]; /**< Number */
-} TelMiscSNInformation;
-
-/**
- * Mobile Equipment Version Information
- */
-typedef struct {
- unsigned char ver_mask; /**< version mask - 0x01:SW_ver, 0x02:HW_ver, 0x04:RF_CAL_date, 0x08:Product_code, 0x10:Model_ID, 0x20:PRL, 0x04:ERI, 0xff:all */
- unsigned char szSwVersion[MAX_VERSION_LEN]; /**< Software version, null termination */
- unsigned char szHwVersion[MAX_VERSION_LEN]; /**< Hardware version, null termination */
- unsigned char szRfCalDate[MAX_VERSION_LEN]; /**< Calculation Date, null termination */
- unsigned char szProductCode[TAPI_MISC_PRODUCT_CODE_LEN_MAX]; /**< product code, null termination */
- unsigned char szModelId[TAPI_MISC_MODEL_ID_LEN_MAX]; /**< model id (only for CDMA), null termination */
- unsigned char prl_nam_num; /**< number of PRL NAM fields */
- unsigned char szPrlVersion[TAPI_MISC_PRL_ERI_VER_LEN_MAX * 3]; /**< prl version (only for CDMA), null termination */
- unsigned char eri_nam_num; /**< number of PRL NAM fields */
- unsigned char szEriVersion[TAPI_MISC_PRL_ERI_VER_LEN_MAX * 3]; /**< eri version (only for CDMA), null termination */
-} TelMiscVersionInformation;
-
-
-void prepare_and_send_pending_request(TcorePlugin *plugin, char *co_name, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback);
-static void on_confirmation_modem_message_send(TcorePending *p, gboolean result, void *user_data); // from Kernel
-void on_response_bootup_subscription(TcorePending *p, int data_len, const void *data, void *user_data);
-void on_response_last_bootup_subscription(TcorePending *p, int data_len, const void *data, void *user_data);
-static void on_timeout_modem_poweron(TcorePending *p, void *user_data);
-static void on_response_enable_proactive_command(TcorePending *p, int data_len, const void *data, void *user_data);
-
-static void on_timeout_modem_poweron(TcorePending *p, void *user_data)
-{
- unsigned int data_len = 0;
- char data[] = "AT+CPAS";
- dbg("TIMEOUT for 1st AT Command !!!!! NO Response for initial AT command. Resending it");
- data_len = sizeof(data);
-
- /* Retransmit 1st AT command directly via HAL, don't disturb pending queue. */
- /* HAL was passed as user_data, re-use it */
- if (user_data) {
- tcore_hal_send_data(user_data, data_len, (void *) data);
- }
-}
-
-static void on_confirmation_modem_message_send(TcorePending *p, gboolean result, void *user_data)
-{
- dbg("on_confirmation_modem_message_send - msg out from queue.\n");
-
- if (result == FALSE) {
- /* Fail */
- dbg("SEND FAIL");
- } else {
- dbg("SEND OK");
- }
-}
-
-static void on_response_enable_proactive_command(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
-
- if (resp->success > 0) {
- dbg("RESPONSE OK proactive command enabled");
- } else {
- dbg("RESPONSE NOK proactive command disabled");
- }
-}
-
-void prepare_and_send_pending_request(TcorePlugin *plugin, char *co_name, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
-{
- TcoreATRequest *req = NULL;
- TcoreHal *hal = NULL;
- CoreObject *o = NULL;
- TcorePending *pending = NULL;
- TReturn ret;
-
- o = tcore_plugin_ref_core_object(plugin, co_name);
- hal = tcore_object_get_hal(o);
- dbg("hal: %p", hal);
-
- pending = tcore_pending_new(o, 0);
- if (!pending)
- dbg("Pending is NULL");
- req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, callback, NULL);
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
- tcore_pending_link_user_request(pending, NULL); // set user request to NULL - this is intenal request
- ret = tcore_hal_send_request(hal, pending);
- return;
-}
-
-void on_response_bootup_subscription(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- dbg("entry of on_response_bootup_subscription() - response comes\n");
-
- if (resp->success) {
- dbg("result OK");
- } else {
- dbg("result ERROR");
- }
-}
-
-void on_response_last_bootup_subscription(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- dbg("enry of on_response_last_bootup_subscription() - final response comes\n");
- if (resp->success) {
- dbg("SEND OK");
- } else {
- dbg("SEND FAIL");
- }
- dbg("Response for AT+CLIP. Boot-up configration completed for IMC modem. Bring CP to online based on Flightmode status\n");
- on_event_modem_power(NULL, NULL, tcore_pending_ref_plugin(p));
-}
-
-static void on_response_power_off(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *o = 0;
- TcoreHal *h = 0;
- o = tcore_pending_ref_core_object(p);
- h = tcore_object_get_hal(o);
-
- dbg("modem power off");
-
- tcore_hal_set_power_state(h, FALSE);
-}
-
-static void on_response_set_flight_mode(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *o = NULL;
- UserRequest *ur = NULL;
- const TcoreATResponse *ATresp = data;
- GSList *tokens = NULL;
- const char *line = NULL;
- struct tresp_modem_set_flightmode res = {0};
- int response = 0;
- struct tnoti_modem_flight_mode modem_flight_mode = {0};
- const struct treq_modem_set_flightmode *req_data = NULL;
-
- o = tcore_pending_ref_core_object(p);
-
- if (ATresp->success > 0) {
- dbg("RESPONSE OK - flight mode operation finished");
- res.result = TCORE_RETURN_SUCCESS;
- } else {
- dbg("RESPONSE NOK");
- line = (const char *) ATresp->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- res.result = TCORE_RETURN_3GPP_ERROR;
- } else {
- response = atoi(g_slist_nth_data(tokens, 0));
- /* TODO: CMEE error mapping is required. */
- res.result = TCORE_RETURN_3GPP_ERROR;
- }
- }
-
- ur = tcore_pending_ref_user_request(p);
- if (NULL == ur) {
- dbg("No user request. Internal request created during boot-up sequence");
-
- if (ATresp->success > 0) {
- modem_flight_mode.enable = tcore_modem_get_flight_mode_state(o);
- dbg("sucess case - Sending Flight Mode Notification (%d) to Telephony Server", modem_flight_mode.enable);
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_MODEM_FLIGHT_MODE,
- sizeof(struct tnoti_modem_flight_mode), &modem_flight_mode);
- }
- } else {
- dbg("Sending response for Flight mode operation");
- tcore_user_request_send_response(ur, TRESP_MODEM_SET_FLIGHTMODE, sizeof(struct tresp_modem_set_flightmode), &res);
-
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (req_data->enable == 0) {
- dbg("Flight mode is disabled, trigger COPS to register on network");
- /* Trigger Network registration (for the moment automatic) */
- prepare_and_send_pending_request(tcore_object_ref_plugin(o), "modem", "AT+COPS=0", NULL, TCORE_AT_NO_RESULT, NULL);
- }
- }
-
- tcore_at_tok_free(tokens);
-}
-
-static void on_response_imei(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- TcorePlugin *plugin = NULL;
- struct tresp_modem_get_imei res;
- TelMiscSNInformation *imei_property = NULL;
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- const char *line;
- int response = 0;
-
- memset(&res, 0, sizeof(struct tresp_modem_get_imei));
-
- 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) != 1) {
- msg("invalid message");
- goto OUT;
- }
- }
- res.result = TCORE_RETURN_SUCCESS;
- strncpy(res.imei, g_slist_nth_data(tokens, 0), 16);
-
- dbg("imei = [%s]", res.imei);
-
- plugin = tcore_pending_ref_plugin(p);
- imei_property = tcore_plugin_ref_property(plugin, "IMEI");
- if (imei_property) {
- imei_property->sn_index = TAPI_MISC_ME_IMEI;
- imei_property->sn_len = strlen(res.imei);
- memcpy(imei_property->szNumber, res.imei, imei_property->sn_len);
- }
- } else {
- dbg("RESPONSE NOK");
- if (resp->lines) {
- line = (const char *) resp->lines->data;
- tokens = tcore_at_tok_new(line);
- }
-
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- res.result = TCORE_RETURN_3GPP_ERROR;
- } else {
- response = atoi(g_slist_nth_data(tokens, 0));
- /* TODO: CMEE error mapping is required. */
- res.result = TCORE_RETURN_3GPP_ERROR;
- }
- }
-
- ur = tcore_pending_ref_user_request(p);
- tcore_user_request_send_response(ur, TRESP_MODEM_GET_IMEI, sizeof(struct tresp_modem_get_imei), &res);
-
-OUT:
- if (tokens != NULL)
- tcore_at_tok_free(tokens);
-
- return;
-}
-
-static void on_response_version(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- TcorePlugin *plugin = NULL;
- struct tresp_modem_get_version res = {0};
- TelMiscVersionInformation *vi_property = NULL;
- TelMiscVersionInformation *vi = NULL;
- UserRequest *ur = NULL;
- GSList *tokens = NULL;
- const char *line = NULL;
- char *swver = NULL;
- char *hwver = NULL;
- char *caldate = NULL;
- char *pcode = NULL;
- char *id = NULL;
-
- int response = 0;
-
- 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) != 5) {
- msg("invalid message");
- goto OUT;
- }
- }
-
- swver = g_slist_nth_data(tokens, 0);
- hwver = g_slist_nth_data(tokens, 1);
- caldate = g_slist_nth_data(tokens, 2);
- pcode = g_slist_nth_data(tokens, 3);
- id = g_slist_nth_data(tokens, 4);
-
- dbg("version: sw=[%s], hw=[%s], rf_cal=[%s], product_code=[%s], model_id=[%s]", swver, hwver, caldate, pcode, id);
-
- vi = calloc(sizeof(TelMiscVersionInformation), 1);
- if (NULL != swver)
- memcpy(vi->szSwVersion, swver, strlen(swver));
- if (NULL != hwver)
- memcpy(vi->szHwVersion, hwver, strlen(hwver));
- if (NULL != caldate)
- memcpy(vi->szRfCalDate, caldate, strlen(caldate));
- if (NULL != pcode)
- memcpy(vi->szProductCode, pcode, strlen(pcode));
- if (NULL != id)
- memcpy(vi->szModelId, id, strlen(id));
-
- memset(&res, 0, sizeof(struct tresp_modem_get_version));
-
- if (NULL != swver)
- snprintf(res.software, (AT_VER_LEN > strlen(swver) ? strlen(swver) : AT_VER_LEN), "%s", swver);
- if (NULL != hwver)
- snprintf(res.hardware, (AT_VER_LEN > strlen(hwver) ? strlen(hwver) : AT_VER_LEN), "%s", hwver);
-
- plugin = tcore_pending_ref_plugin(p);
- vi_property = tcore_plugin_ref_property(plugin, "VERSION");
- memcpy(vi_property, vi, sizeof(TelMiscVersionInformation));
- free(vi);
- } else {
- dbg("RESPONSE NOK");
- if (resp->lines) {
- line = (const char *) resp->lines->data;
- tokens = tcore_at_tok_new(line);
- }
-
- memset(&res, 0, sizeof(struct tresp_modem_get_version));
-
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- res.result = TCORE_RETURN_3GPP_ERROR;
- } else {
- response = atoi(g_slist_nth_data(tokens, 0));
- /* TODO: CMEE error mapping is required. */
- res.result = TCORE_RETURN_3GPP_ERROR;
- }
- }
-
- ur = tcore_pending_ref_user_request(p);
- tcore_user_request_send_response(ur, TRESP_MODEM_GET_VERSION, sizeof(struct tresp_modem_get_version), &res);
-
-OUT:
- if (tokens != NULL)
- tcore_at_tok_free(tokens);
-
- return;
-}
-
-static gboolean on_event_bootup_sim_status(CoreObject *o, const void *event_info, void *user_data)
-{
- GSList *tok = NULL;
- GSList *lines = NULL;
- int value = -1;
- char *line = NULL;
-
- lines = (GSList *) event_info;
- if (1 != g_slist_length(lines)) {
- dbg("unsolicited msg but multiple line");
- goto OUT;
- }
- line = (char *) (lines->data);
- dbg("on_bootup_event_sim_status notification : %s", line);
-
- tok = tcore_at_tok_new(line);
- value = atoi(g_slist_nth_data(tok, 0));
-
- if (7 == value) {
- dbg("SIM ready. request COPS & remove callback");
- dbg("power on done set for proactive command receiving mode");
- prepare_and_send_pending_request(tcore_object_ref_plugin(o), "sat", "AT+CFUN=6", NULL, TCORE_AT_NO_RESULT, on_response_enable_proactive_command);
- prepare_and_send_pending_request(tcore_object_ref_plugin(o), "umts_network", "AT+COPS=0", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
- return FALSE;
- }
-
-OUT:
- if (tok != NULL)
- tcore_at_tok_free(tok);
-
- return TRUE;
-}
-
-
-
-gboolean on_event_modem_power(TcoreAT *at, const char *line, TcorePlugin *p)
-{
- CoreObject *o = NULL;
- struct treq_modem_set_flightmode flight_mode_set = {0};
- struct tnoti_modem_power modem_power = {0};
- TcoreHal *h = NULL;
- Storage *strg = NULL;
-
- o = tcore_plugin_ref_core_object(p, "modem");
-
- strg = tcore_server_find_storage(tcore_plugin_ref_server(p), "vconf");
- flight_mode_set.enable = tcore_storage_get_bool(strg, STORAGE_KEY_SETAPPL_FLIGHT_MODE_BOOL);
-
- h = tcore_object_get_hal(o);
- tcore_hal_set_power_state(h, TRUE);
-
- /* Set Flight mode as per AP settings */
- if (flight_mode_set.enable) { /* Radio Off */
- prepare_and_send_pending_request(p, "modem", "AT+CFUN=4", NULL, TCORE_AT_NO_RESULT, on_response_set_flight_mode);
- tcore_modem_set_flight_mode_state(o, TRUE);
- } else { /* Radio On */
- prepare_and_send_pending_request(p, "modem", "AT+CFUN=1", NULL, TCORE_AT_NO_RESULT, on_response_set_flight_mode);
- tcore_modem_set_flight_mode_state(o, FALSE);
- }
-
- /* Get IMEI */
- prepare_and_send_pending_request(p, "modem", "AT+CGSN", NULL, TCORE_AT_NUMERIC, on_response_imei);
-
- /* Get Version Number */
- prepare_and_send_pending_request(p, "modem", "AT+CGMR", NULL, TCORE_AT_SINGLELINE, on_response_version);
-
- tcore_modem_set_powered(o, TRUE);
-
- modem_power.state = MODEM_STATE_ONLINE;
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_MODEM_POWER,
- sizeof(struct tnoti_modem_power), &modem_power);
-
- return TRUE;
-}
-
-static void _modem_subscribe_events(TcorePlugin *plugin)
-{
- dbg("Entry");
-
- /* XCALLSTAT subscription */
- prepare_and_send_pending_request(plugin, "call", "at+xcallstat=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- /* XSIMSTATE subscription */
- prepare_and_send_pending_request(plugin, "sim", "at+xsimstate=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- prepare_and_send_pending_request(plugin, "umts_sms", "at+xsimstate=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
- prepare_and_send_pending_request(plugin, "modem", "at+xsimstate=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- /* CREG subscription */
- prepare_and_send_pending_request(plugin, "umts_network", "at+creg=2", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- /* CGREG subscription */
- prepare_and_send_pending_request(plugin, "umts_network", "at+cgreg=2", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- /* Allow automatic time Zone updation via NITZ */
- prepare_and_send_pending_request(plugin, "umts_network", "at+ctzu=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- /* TZ, time & daylight changing event reporting subscription */
- prepare_and_send_pending_request(plugin, "umts_network", "at+ctzr=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- /* XMER subscription */
- prepare_and_send_pending_request(plugin, "umts_network", "at+xmer=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- /* CGEREP subscription */
- prepare_and_send_pending_request(plugin, "umts_ps", "at+cgerep=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- /* XDATASTAT subscription */
- prepare_and_send_pending_request(plugin, "umts_ps", "at+xdatastat=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- /* CSSN subscription */
- prepare_and_send_pending_request(plugin, "call", "at+cssn=1,1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- /* CUSD subscription */
- prepare_and_send_pending_request(plugin, "call", "at+cusd=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- /* XDNS subscription */
- prepare_and_send_pending_request(plugin, "umts_ps", "at+xdns=1,1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- /* CLIP subscription */
- prepare_and_send_pending_request(plugin, "call", "at+clip=1", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- /*CMEE subscription*/
- prepare_and_send_pending_request(plugin, "umts_ps", "at+cmee=2", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- /*incoming sms,cb,status report subscription*/
- prepare_and_send_pending_request(plugin, "umts_sms", "at+cnmi=1,2,2,1,0", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
-
- /* text/pdu mode subscription*/
- prepare_and_send_pending_request(plugin, "umts_sms", "at+cmgf=0", NULL, TCORE_AT_NO_RESULT, on_response_last_bootup_subscription);
-
- dbg("Exit");
- return;
-}
-
-
-static void on_response_setupmux(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- TcorePlugin *plugin = NULL;
- TcoreHal *hal = NULL;
- TReturn ret;
- dbg("Entry");
-
- /* IMC Plugin dereferenced from pending request */
- plugin = tcore_pending_ref_plugin(p);
-
- /* Actual HAL - like svnet(2) */
- hal = (TcoreHal *) user_data;
-
- /* Initialize CMUX */
- ret = tcore_cmux_init(plugin, hal);
- if (TCORE_RETURN_SUCCESS == ret) {
- dbg("Successfully initialized CMUX");
- } else {
- err("Failed to initialize CMUX");
- }
-
- dbg("Exit");
- return;
-}
-
-
-
-static void setup_mux(CoreObject *o)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- dbg("Entered");
-
- /* HAL has type itself,
- * e.g.) TCORE_HAL_MODE_AT
- */
- hal = tcore_object_get_hal(o);
-
- pending = tcore_at_pending_new(o, "AT+CMUX=0,0,,1509,10,3,30,,", "+CMUX", TCORE_AT_NO_RESULT, on_response_setupmux, hal);
-
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
-
- /* Send callback */
- tcore_hal_send_request(hal, pending);
-
- dbg("Exit");
- return;
-}
-
-
-static gboolean on_event_mux_channel_up(CoreObject *o, const void *event_info, void *user_data)
-{
- TcorePlugin *plugin = NULL;
- dbg("Entry");
-
- plugin = (TcorePlugin *) user_data;
- _modem_subscribe_events(plugin);
- dbg("Exit");
- return TRUE;
-}
-
-
-static void on_response_enable_logging(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- TcorePlugin *plugin = NULL;
-
- plugin = tcore_pending_ref_plugin(p);
-
- /* DELETE ME: only for DEBUG */
- if (!resp)
- dbg("no data");
-
- dbg("response...(result = %d, final_response = '%s')", resp->success, resp->final_response);
-
- if (resp->success) {
- dbg("RESPONSE OK");
- dbg("Enabling CP logging is success !!!\n");
- } else {
- dbg("RESPONSE NOK");
- dbg("Enabling CP logging is failed !!!\n");
- }
-
- dbg("Calling setup_mux");
- setup_mux(tcore_pending_ref_core_object(p));
-
-
- dbg("Exit");
- return;
-}
-
-static void _send_enable_logging_command(CoreObject *o)
-{
- TcoreATRequest *req = NULL;
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- TReturn ret = 0;
-
- /* DLELTE ME */
- dbg("Send Trace enabling command for CP logging. \n");
-
- if (!o) {
- dbg("Co-object is Null !!\n");
- // goto error;
- }
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
- req = tcore_at_request_new("at+xsystrace=1,\"digrf=1;bb_sw=1;3g_sw=1\",\"digrf=0x84\",\"oct=4\";+xsystrace=11;+trace=1", NULL, TCORE_AT_NO_RESULT);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_enable_logging, hal);
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
-
- ret = tcore_hal_send_request(hal, pending);
- if (ret != TCORE_RETURN_SUCCESS)
- dbg("tcore_hal_send_request fail !!! (hal: 0x%x, pending: 0x%x)\n", hal, pending);
-}
-
-static void on_response_poweron(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- GSList *tokens = NULL;
- const char *line = NULL;
- gboolean bpoweron = FALSE;
- int response = 0;
-
- if (resp->success) {
- dbg("RESPONSE OK");
- /* Parse AT Response */
- if (resp->lines) {
- line = (const char *) resp->lines->data;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) != 1) {
- dbg("invalid message");
- bpoweron = FALSE;
- goto error;
- }
- }
-
- response = atoi(g_slist_nth_data(tokens, 0));
-
- dbg("CPAS: response %d", response);
-
- switch (response) {
- case CPAS_RES_READY:
- case CPAS_RES_RINGING:
- case CPAS_RES_CALL_PROGRESS:
- case CPAS_RES_ASLEEP:
- bpoweron = TRUE;
- break;
-
- case CPAS_RES_UNAVAIL:
- case CPAS_RES_UNKNOWN:
- default:
- dbg("value is unvail/unknown - but CP responded - proceed poweron");
- // bpoweron = FALSE;
- bpoweron = TRUE;
- break;
- }
- } else {
- dbg("CPAS: RESPONSE NOK");
- bpoweron = FALSE;
- }
-
-error:
- /* DELE ME: AT request & response are freed after AT processing in HAL.
- * ref.) _emit_pending_response (libtcore/src/at.c)
- */
- if (tokens != NULL)
- tcore_at_tok_free(tokens);
-
- if (bpoweron == TRUE) {
- dbg("Power on NOTI received, (pending: 0x%x, co: 0x%x)\n", p, tcore_pending_ref_core_object(p));
-
- _send_enable_logging_command(tcore_pending_ref_core_object(p));
- } else {
- dbg("CP is not ready, let us send CPAS once again");
- s_modem_send_poweron(tcore_object_ref_plugin(tcore_pending_ref_core_object(p)));
- }
- return;
-}
-
-static TReturn power_off(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
-
- req = tcore_at_request_new("AT+CFUN=0", NULL, TCORE_AT_NO_RESULT);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_power_off, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn get_imei(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
-
- req = tcore_at_request_new("AT+CGSN", NULL, TCORE_AT_NUMERIC);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_imei, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-
-static TReturn get_version(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
-
- req = tcore_at_request_new("AT+CGMR", NULL, TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_version, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn set_flight_mode(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- const struct treq_modem_set_flightmode *req_data = NULL;
- char *cmd_str = NULL;
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
-
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (req_data->enable) {
- dbg("Flight mode on/n");
- cmd_str = g_strdup("AT+CFUN=4");
- } else {
- dbg("Flight mode off/n");
- cmd_str = g_strdup("AT+CFUN=1");
- }
-
- req = tcore_at_request_new((const char *) cmd_str, NULL, TCORE_AT_NO_RESULT);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_set_flight_mode, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- return TCORE_RETURN_SUCCESS;
-}
-
-
-static struct tcore_modem_operations modem_ops = {
- .power_on = NULL,
- .power_off = power_off,
- .power_reset = NULL,
- .set_flight_mode = set_flight_mode,
- .get_imei = get_imei,
- .get_version = get_version,
- .get_sn = NULL,
- .dun_pin_ctrl = NULL,
-};
-
-gboolean s_modem_init(TcorePlugin *p, TcoreHal *h)
-{
- CoreObject *o = NULL;
- GQueue *work_queue = NULL;
- TelMiscVersionInformation *vi_property = NULL;
- TelMiscSNInformation *imei_property = NULL;
- TelMiscSNInformation *sn_property = NULL;
-
- o = tcore_modem_new(p, "modem", &modem_ops, h);
- if (!o)
- return FALSE;
-
- work_queue = g_queue_new();
- tcore_object_link_user_data(o, work_queue);
-
- vi_property = calloc(sizeof(TelMiscVersionInformation), 1);
- tcore_plugin_link_property(p, "VERSION", vi_property);
-
- imei_property = calloc(sizeof(TelMiscSNInformation), 1);
- tcore_plugin_link_property(p, "IMEI", imei_property);
-
- sn_property = calloc(sizeof(TelMiscSNInformation), 1);
- tcore_plugin_link_property(p, "SN", sn_property);
-
- dbg("Registerind for CMUX-UP event");
- tcore_object_add_callback(o, "CMUX-UP", on_event_mux_channel_up, p);
-
- dbg("Registering for +XSIM event");
- tcore_object_add_callback(o, "+XSIM", on_event_bootup_sim_status, NULL);
-
- return TRUE;
-}
-
-void s_modem_exit(TcorePlugin *p)
-{
- CoreObject *o = NULL;
- GQueue *work_queue = NULL;
- TelMiscVersionInformation *vi_property = NULL;
- TelMiscSNInformation *imei_property = NULL;
- TelMiscSNInformation *sn_property = NULL;
-
- if (!p)
- return;
-
- o = tcore_plugin_ref_core_object(p, "modem");
-
- work_queue = tcore_object_ref_user_data(o);
- g_queue_free(work_queue);
-
- vi_property = tcore_plugin_ref_property(p, "VERSION");
- if (vi_property)
- free(vi_property);
-
- imei_property = tcore_plugin_ref_property(p, "IMEI");
- if (imei_property)
- free(imei_property);
-
- sn_property = tcore_plugin_ref_property(p, "SN");
- if (sn_property)
- free(sn_property);
-
- tcore_modem_free(o);
- return;
-}
-
-gboolean s_modem_send_poweron(TcorePlugin *p)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
- CoreObject *o;
-
- o = tcore_plugin_ref_core_object(p, "modem");
- hal = tcore_object_get_hal(o);
-
- pending = tcore_pending_new(o, 0);
-
- req = tcore_at_request_new("AT+CPAS", "+CPAS", TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_timeout(pending, 10);
- tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
- tcore_pending_set_timeout_callback(pending, on_timeout_modem_poweron, hal);
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_poweron, hal);
- tcore_pending_set_send_callback(pending, on_confirmation_modem_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- return TRUE;
-}
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Arun Shukla <arun.shukla@samsung.com>
- *
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <glib.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-
-#include <tcore.h>
-#include <hal.h>
-#include <core_object.h>
-#include <plugin.h>
-#include <queue.h>
-#include <co_ps.h>
-#include <co_context.h>
-#include <storage.h>
-#include <server.h>
-#include <at.h>
-#include <util.h>
-#include <type/ps.h>
-
-#include "s_common.h"
-#include "s_ps.h"
-
-
-
-#define VNET_CH_PATH_BOOT0 "/dev/umts_boot0"
-#define IOCTL_CG_DATA_SEND _IO('o', 0x37)
-
-/*Invalid Session ID*/
-#define PS_INVALID_CID 999 /*Need to check */
-
-/*Maximum String length Of the Command*/
-#define MAX_AT_CMD_STR_LEN 150
-
-/*Command for PDP activation and Deactivation*/
-#define AT_PDP_ACTIVATE 1
-#define AT_PDP_DEACTIVATE 0
-
-#define AT_XDNS_ENABLE 1
-#define AT_XDNS_DISABLE 0
-#define AT_SESSION_DOWN 0
-static void _ps_free(void *ptr)
-{
- dbg("Entered");
- if (ptr) {
- (void) free(ptr);
- ptr = NULL;
- }
- dbg("Exit");
- return;
-}
-static void _unable_to_get_pending(CoreObject *co_ps, CoreObject *ps_context)
-{
- struct tnoti_ps_call_status data_resp = {0};
- dbg("Entered");
- data_resp.context_id = tcore_context_get_id(ps_context);
- data_resp.state = AT_SESSION_DOWN; /*check value of state*/
- data_resp.result = 0xFF; /*check error value*/
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,
- TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), &data_resp);
- (void) tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
- dbg("Exit");
-}
-static TReturn _pdp_device_control(unsigned int cid)
-{
- int fd = -1;
- int ret = -1;
- fd = open(VNET_CH_PATH_BOOT0, O_RDWR);
- if (fd < 0) {
- dbg("error : open [ %s ] [ %s ]", VNET_CH_PATH_BOOT0, strerror(errno));
- return -1;
- }
- /*To Do for different Cids*/
- dbg("Send IOCTL: arg 0x05 (0101) HSIC1, cid=%d \n", cid);
- if (cid == 1) {
- ret = ioctl(fd, IOCTL_CG_DATA_SEND, 0x05);
- } else if (cid == 2) {
- ret = ioctl(fd, IOCTL_CG_DATA_SEND, 0xA);
- } else {
- dbg("More Than 2 context are not supported right Now");
- }
- close(fd);
- if (ret < 0) {
- dbg("[ error ] send IOCTL_CG_DATA_SEND (0x%x) fail!! \n", IOCTL_CG_DATA_SEND);
- return TCORE_RETURN_FAILURE;
- } else {
- dbg("[ ok ] send IOCTL_CG_DATA_SEND (0x%x) success!! \n", IOCTL_CG_DATA_SEND);
- return TCORE_RETURN_SUCCESS;
- }
-}
-
-static gboolean on_event_cgev_handle(CoreObject *co_ps, const void *data, void *user_data)
-{
- char *token = NULL;
- GSList *tokens = NULL;
- GSList *lines = NULL;
- const char *line = NULL;
- char *noti_data = NULL;
- int i = 0;
- int value = 20;
- int state = -1;
- struct tnoti_ps_call_status data_resp = {0};
-
- dbg("Entered");
- lines = (GSList *) data;
- line = (const char *) lines->data;
- dbg("Lines->data :-%s", line);
-
- tokens = tcore_at_tok_new(line);
- switch (g_slist_length(tokens)) {
- case 0:
- {
- dbg("No token present: Ignore +CGEV Notifications ");
- return TRUE;
- }
-
- case 1:
- {
- dbg("one Token present");
- noti_data = g_slist_nth_data(tokens, 0);
- dbg("notification data :-%s", noti_data);
- if (0 == strcmp(noti_data, "ME CLASS B")) {
- dbg("ME Class B notification received");
- goto ignore;
- }
- if (0 == strcmp(noti_data, "NW CLASS A")) {
- dbg("NW Class A notification received");
- goto ignore;
- }
- token = strtok(noti_data, " ");
- while (token != NULL) {
- if ((i == 0) && (0 != strcmp(token, "ME"))) {
- break;
- }
- if ((i == 1) && (0 != strcmp(token, "PDN"))) {
- break;
- }
- if ((i == 2) && (0 == strcmp(token, "ACT"))) {
- state = 1;
- }
- if ((i == 2) && (0 == strcmp(token, "DEACT"))) {
- state = 0;
- }
- if (i == 3) {
- value = atoi(token);
- break;
- }
- i++;
- token = strtok(NULL, " ");
- }
- dbg("value:%d ", value);
- i = 0;
- break;
- }
-
- case 3:
- {
- i = 0;
- state = 0;
- value = 0;
- dbg("Three Token present");
- noti_data = g_slist_nth_data(tokens, 0);
- dbg("notification data :-%s", noti_data);
- token = strtok(noti_data, " ");
- while (token != NULL) {
- if ((i == 0) && (0 == strcmp(token, "ME"))) {
- state = 1;
- }
- if ((i == 1) && (0 != strcmp(token, "DEACT"))) {
- break;
- }
- if ((i == 2) && (0 == strcmp(token, "\"IP\"")) && (0 == state)) {
- dbg("MObile Deactiavted the Context");
- value = 10;
- break;
- }
- if ((i == 2) && (0 == strcmp(token, "\"IP\"")) && (1 == state)) {
- dbg("NW Deactiavted the Context");
- value = 10;
- break;
- }
- i++;
- token = strtok(NULL, " ");
- }
- if (value == 10 && state == 0) {
- dbg("Recieved Notification for Context deactivations from network");
- noti_data = g_slist_nth_data(tokens, 1);
- dbg("PDP Address :- %s", noti_data);
- noti_data = g_slist_nth_data(tokens, 2);
- dbg("CID got deactivated :- %d", atoi(noti_data));
- }
- if (value == 10 && state == 1) {
- dbg("Recieved Notification for Context deactivations from Mobile");
- noti_data = g_slist_nth_data(tokens, 1);
- dbg("PDP Address :- %s", noti_data);
- noti_data = g_slist_nth_data(tokens, 2);
- dbg("CID got deactivated :- %d", atoi(noti_data));
- }
- data_resp.context_id = atoi(noti_data);
- data_resp.state = 3; /*check value of state*/
- dbg("State of the service :- %d", data_resp.state);
- data_resp.result = 0xFF; /*check error value*/
- dbg("Sending the notification");
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,
- TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), &data_resp);
-
- state = 100;
- value = 100;
-
- break;
- }
-
- default:
- {
- dbg("Ignore +CGEV Notifications ");
- }
- }
- if (state == 1) {
- dbg("Notification recieved for Activation of CID:-%d", value);
- } else if (state == 0) {
- dbg("Notification recieved for Deactivation of CID:-%d", value);
- } else {
- dbg("ignore");
- }
-ignore:
- tcore_at_tok_free(tokens);
- return TRUE;
-}
-
-static gboolean on_event_dun_call_notification(CoreObject *o, const void *data, void *user_data)
-{
- GSList *tokens = NULL;
- const char *line = NULL;
- int value = 0;
- GSList *lines = NULL;
- dbg("Entered");
-
- lines = (GSList *) data;
- if (1 != g_slist_length(lines)) {
- dbg("unsolicited msg but multiple line");
- goto OUT;
- }
- line = (char *) (lines->data);
- tokens = tcore_at_tok_new(line);
- value = atoi(g_slist_nth_data(tokens, 0));
-
- /*
- <status> may be
- 0: DUN activation in progress
- 1: DUN deactivation in progress
- 2: DUN activated
- 3: DUN deactivated
- */
- switch (value) {
- case 0: /*Fall Through*/
- case 1:
- {
- break;
- }
-
- case 2:
- {
- /*To Do:- Fill Data structure : data*/
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
- TNOTI_PS_EXTERNAL_CALL, sizeof(struct tnoti_ps_external_call), &data);
- }
-
- case 3:
- {
- /*To Do:- Fill Data structure : data*/
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o,
- TNOTI_PS_EXTERNAL_CALL, sizeof(struct tnoti_ps_external_call), &data);
- }
- break;
-
- default:
- goto OUT;
- }
-OUT:
- if (NULL != tokens) {
- tcore_at_tok_free(tokens);
- }
- return TRUE;
-}
-static void on_response_undefine_context_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *co_ps = NULL;
- const TcoreATResponse *resp = data;
- CoreObject *ps_context = user_data;
- dbg("Entered");
- co_ps = tcore_pending_ref_core_object(p);
- if (resp->success) {
- dbg("Response Ok");
- return;
- }
- dbg("Response NOk");
- _unable_to_get_pending(co_ps, ps_context);
- return;
-}
-
-static void send_undefine_context_cmd(CoreObject *co_ps, CoreObject *ps_context)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- char cmd_str[MAX_AT_CMD_STR_LEN];
- int cid = 0;
-
- dbg("Entered");
- memset(cmd_str, 0x0, MAX_AT_CMD_STR_LEN);
-
- /* FIXME: Before MUX setup, use PHY HAL directly. */
- hal = tcore_object_get_hal(co_ps);
-
- /*Getting Context ID from Core Object*/
- cid = tcore_context_get_id(ps_context);
-
- (void) sprintf(cmd_str, "AT+CGDCONT=%d", cid);
- pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
- on_response_undefine_context_cmd, ps_context);
- if (NULL == pending) {
- err("Unable to get the create a AT request ");
- goto error;
- }
- tcore_hal_send_request(hal, pending);
- dbg("Exit: Successfully");
- return;
-error:
- {
- dbg("Exit: With error");
- _unable_to_get_pending(co_ps, ps_context);
- return;
- }
-}
-static void on_response_data_counter_command(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *ps_context = user_data;
- const TcoreATResponse *resp = data;
- CoreObject *co_ps = tcore_pending_ref_core_object(p);
-
- GSList *tokens = NULL;
- GSList *pRespData;
- const char *line = NULL;
- int no_pdp_active = 0;
- unsigned long long Rx;
- unsigned long long Tx;
- int cid = tcore_context_get_id(ps_context);
- dbg("Entered");
-
- if (resp->final_response) {
- dbg("Response OK");
- dbg(" response lines : -%s", resp->lines);
- if (resp->lines) {
- pRespData = (GSList *) resp->lines;
- no_pdp_active = g_slist_length(pRespData);
- dbg("Total Number of Active PS Context :- %d", no_pdp_active);
-
- if (no_pdp_active == 0) {
- return;
- }
- while (pRespData) {
- dbg("Entered the Loop pRespData");
-
- line = (const char *) pRespData->data;
- dbg("Response->lines->data :%s", line);
- tokens = tcore_at_tok_new(line);
- if (cid == atoi(g_slist_nth_data(tokens, 0))) {
- dbg("Found the data for our CID");
- Tx = (unsigned long long) g_ascii_strtoull((g_slist_nth_data(tokens, 1)), NULL, 10);
- dbg("Tx: %d", Tx);
-
- Rx = (unsigned long long) g_ascii_strtoull((g_slist_nth_data(tokens, 2)), NULL, 10);
- dbg("Rx: %d", Rx);
-
- tcore_at_tok_free(tokens);
- tokens = NULL;
- dbg("Exiting the Loop pRespData");
- break;
- }
- tcore_at_tok_free(tokens);
- tokens = NULL;
- pRespData = pRespData->next;
- }
- dbg("Sending Data counter notifications");
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,
- TNOTI_PS_CURRENT_SESSION_DATA_COUNTER, 0, NULL);
- return;
- } else {
- dbg("No Active PS Context");
- }
- }
- dbg("Response NOK");
-}
-
-static TReturn send_data_counter_command(CoreObject *co_ps, CoreObject *ps_context)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- char cmd_str[MAX_AT_CMD_STR_LEN];
-
- dbg("Enetered");
- memset(cmd_str, 0x0, MAX_AT_CMD_STR_LEN);
-
- hal = tcore_object_get_hal(co_ps);
-
- (void) sprintf(cmd_str, "AT+XGCNTRD");
- pending = tcore_at_pending_new(co_ps, cmd_str, "+XGCNTRD", TCORE_AT_MULTILINE,
- on_response_data_counter_command, ps_context);
- if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
- return TCORE_RETURN_SUCCESS;
- }
- _unable_to_get_pending(co_ps, ps_context);
- return TCORE_RETURN_FAILURE;
-/*Add code if unable to get the data usage*/
-}
-static void on_response_deactivate_ps_context(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *co_ps = tcore_pending_ref_core_object(p);
- CoreObject *ps_context = user_data;
- const TcoreATResponse *resp = data;
- int cid;
-
- cid = tcore_context_get_id(ps_context);
- if (resp->success) {
- dbg("Response OK");
- /*get the data usage and report it application*/
- (void) send_data_counter_command(co_ps, ps_context);
- /*get the HSDPA status and report it to server*/
- } else {
- dbg("Response NOK");
- send_undefine_context_cmd(co_ps, ps_context);
- }
- return;
-}
-
-static TReturn deactivate_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- unsigned int cid = PS_INVALID_CID;
- char cmd_str[MAX_AT_CMD_STR_LEN];
-
- dbg("Entered");
- memset(cmd_str, 0x0, MAX_AT_CMD_STR_LEN);
-
- /*Getting Context ID from Core Object*/
- cid = tcore_context_get_id(ps_context);
-
- /* FIXME: Before MUX setup, use PHY HAL directly. */
- hal = tcore_object_get_hal(co_ps);
-
- (void) sprintf(cmd_str, "AT+CGACT=%d,%d", AT_PDP_DEACTIVATE, cid);
- dbg("At commands :- %s", cmd_str);
-
- pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
- on_response_deactivate_ps_context, ps_context);
- if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
- (void) tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATING);
- return TCORE_RETURN_SUCCESS;
- }
- _unable_to_get_pending(co_ps, ps_context);
- return TCORE_RETURN_FAILURE;
-}
-
-static void on_response_get_dns_cmnd(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- struct tnoti_ps_pdp_ipconfiguration noti = {0};
- struct tnoti_ps_call_status data_status = {0};
- char devname[10] = {0, };
- char *dns_prim = NULL;
- char *dns_sec = NULL;
- char *pdp_address = NULL;
- char addr[4] = {0};
- GSList *tokens = NULL;
- GSList *pRespData;
- const char *line = NULL;
- char *token_dns = NULL;
- char *token_add = NULL;
-
- char *token_pdp_address = NULL;
- int no_pdp_active = 0;
- int index = 0;
-
- CoreObject *ps_context = user_data;
- const TcoreATResponse *resp = data;
- CoreObject *co_ps = tcore_pending_ref_core_object(p);
- int cid = tcore_context_get_id(ps_context);
-
- dbg("Entered");
-
- if (resp->final_response) {
- dbg("Response OK");
- if (resp->lines) {
- dbg("DNS data present in the Response");
- pRespData = (GSList *) resp->lines;
- no_pdp_active = g_slist_length(pRespData);
- dbg("Total Number of Active PS Context :- %d", no_pdp_active);
- if (0 == no_pdp_active) {
- goto exit_fail;
- }
- while (pRespData) {
- dbg("traversing the DNS data for each active context");
- line = (const char *) pRespData->data;
- dbg("Response->lines->data :%s", line);
- tokens = tcore_at_tok_new(line);
- if (cid == atoi(g_slist_nth_data(tokens, 0))) {
- dbg("Found the DNS details for the Current context");
- dbg("Context Id of The Context : %d", atoi(g_slist_nth_data(tokens, 0)));
- break;
- }
- tcore_at_tok_free(tokens);
- tokens = NULL;
- pRespData = pRespData->next;
- }
- { /* Read primary DNS */
- token_dns = g_slist_nth_data(tokens, 1);
- /* Strip off starting " and ending " from this token to read actual PDP address */
- dns_prim = util_removeQuotes((void *) token_dns);
- dbg("Token_dns :%s", token_dns);
- dbg("Primary DNS :- %s", dns_prim);
- index = 0;
- token_add = strtok(dns_prim, ".");
- while (token_add != NULL) {
- noti.primary_dns[index++] = atoi(token_add);
- token_add = strtok(NULL, ".");
- }
- _ps_free(dns_prim);
- }
- { /* Read Secondary DNS */
- token_add = NULL;
- token_dns = g_slist_nth_data(tokens, 2);
- dns_sec = util_removeQuotes((void *) token_dns);
-
- dbg("Token_dns :%s", token_dns);
- dbg("Secondary DNS :- %s", dns_sec);
- index = 0;
- token_add = strtok(dns_sec, ".");
- while (token_add != NULL) {
- noti.secondary_dns[index++] = atoi(token_add);
- token_add = strtok(NULL, ".");
- }
- _ps_free(dns_sec);
- }
- tcore_at_tok_free(tokens);
- tokens = NULL;
- goto exit_success;
- } else {
- dbg("No data present in the Response");
- }
- }
- dbg("Response NOK");
-exit_fail:
- {
- dbg("Adding default DNS");
- dbg("Adding the Primary DNS");
- noti.primary_dns[0] = 8;
- noti.primary_dns[1] = 8;
- noti.primary_dns[2] = 8;
- noti.primary_dns[3] = 8;
- dbg("Adding Secondary DNS");
- noti.secondary_dns[0] = 8;
- noti.secondary_dns[1] = 8;
- noti.secondary_dns[2] = 4;
- noti.secondary_dns[3] = 4;
- }
-exit_success:
- {
- dbg("Able to get the DNS from the DNS Query");
- token_pdp_address = tcore_context_get_address(ps_context);
- pdp_address = util_removeQuotes((void *) token_pdp_address);
-
- dbg("PDP address :- %s", pdp_address);
- /* Store IP address in char array, Telephony expected IP address in this format */
- token_add = strtok(pdp_address, ".");
- index = 0;
- while ((token_add != NULL) && (index < 4)) { /* Currently only IPv4 is supported */
- addr[index++] = atoi(token_add);
- token_add = strtok(NULL, ".");
- }
- _ps_free(pdp_address);
- _ps_free((void *) token_pdp_address);
- noti.field_flag = (0x0001 & 0x0002 & 0x0004);
- noti.err = 0;
- noti.context_id = cid;
- memcpy(¬i.ip_address, &addr, 4);
- if (_pdp_device_control(cid) != TCORE_RETURN_SUCCESS) {
- dbg("_pdp_device_control() failed. errno=%d", errno);
- }
- snprintf(devname, 10, "pdp%d", cid - 1);
- memcpy(noti.devname, devname, 10);
- dbg("devname = [%s]", devname);
- if (tcore_util_netif_up(devname) != TCORE_RETURN_SUCCESS) {
- dbg("util_netif_up() failed. errno=%d", errno);
- }
-
- dbg("Send Notification upwards of IP address");
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps, TNOTI_PS_PDP_IPCONFIGURATION,
- sizeof(struct tnoti_ps_pdp_ipconfiguration), ¬i);
-
- data_status.context_id = cid;
- data_status.state = 1;
- data_status.result = 0;
-
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(co_ps)), co_ps,
- TNOTI_PS_CALL_STATUS, sizeof(struct tnoti_ps_call_status), &data_status);
- dbg("EXIT : Without error");
- return;
- }
-}
-
-static TReturn send_get_dns_cmd(CoreObject *co_ps, CoreObject *ps_context)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- char cmd_str[MAX_AT_CMD_STR_LEN];
-
- memset(cmd_str, 0x0, MAX_AT_CMD_STR_LEN);
-
- dbg("Entered");
- hal = tcore_object_get_hal(co_ps);
-
- (void) sprintf(cmd_str, "AT+XDNS?");
- pending = tcore_at_pending_new(co_ps, cmd_str, "+XDNS", TCORE_AT_MULTILINE,
- on_response_get_dns_cmnd, ps_context);
- if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
- return TCORE_RETURN_SUCCESS;
- }
- _unable_to_get_pending(co_ps, ps_context);
- return TCORE_RETURN_FAILURE;
-}
-
-static void on_response_get_pdp_address(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- CoreObject *co_ps = tcore_pending_ref_core_object(p);
- CoreObject *ps_context = user_data;
- GSList *tokens = NULL;
- const char *line;
- char *token_pdp_address;
- dbg("Enetered");
- if (resp->final_response) {
- dbg("RESPONSE OK");
- if (resp->lines != NULL) {
- dbg("resp->lines present ");
- line = (const char *) resp->lines->data;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < 2) {
- msg("invalid message");
- goto error;
- }
- dbg("line:- %s", line);
- /* CID is already stored in ps_context, skip over & read PDP address */
- token_pdp_address = g_slist_nth_data(tokens, 1);
-
- dbg("token_pdp_address :- %s", token_pdp_address);
- /* Strip off starting " and ending " from this token to read actual PDP address */
- (void) tcore_context_set_address(ps_context, (const char *) token_pdp_address);
- }
-
- (void) send_get_dns_cmd(co_ps, ps_context);
- } else {
- dbg("Response NOK");
- /*without PDP address we will not be able to start packet service*/
- (void) deactivate_ps_context(co_ps, ps_context, NULL);
- }
-error:
- tcore_at_tok_free(tokens);
- return;
-}
-
-static TReturn send_get_pdp_address_cmd(CoreObject *co_ps, CoreObject *ps_context)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- unsigned int cid = PS_INVALID_CID;
- char cmd_str[MAX_AT_CMD_STR_LEN] = {0};
-
- dbg("Entered");
- hal = tcore_object_get_hal(co_ps);
-
- cid = tcore_context_get_id(ps_context);
- (void) sprintf(cmd_str, "AT+CGPADDR=%d", cid);
- pending = tcore_at_pending_new(co_ps, cmd_str, "+CGPADDR", TCORE_AT_SINGLELINE,
- on_response_get_pdp_address, ps_context);
- if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
- return TCORE_RETURN_SUCCESS;
- }
- _unable_to_get_pending(co_ps, ps_context);
- return TCORE_RETURN_FAILURE;
-}
-
-static void on_response_send_pdp_activate_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- CoreObject *co_ps = NULL;
- const TcoreATResponse *resp = data;
- CoreObject *ps_context = user_data;
-
- int cid;
- cid = tcore_context_get_id(ps_context);
-
-
- dbg("Entered");
- if (!p) {
- goto error;
- }
- co_ps = tcore_pending_ref_core_object(p);
-
- if (resp->success) {
- dbg("Response Ok");
- /*getting the IP address and DNS from the modem*/
- dbg("Getting the IP Address");
- (void) send_get_pdp_address_cmd(co_ps, ps_context);
- return;
- } else {
- dbg("Unable to actiavte PDP context for CID: %d ", cid);
- dbg("Undefineing the PDP context");
- (void) tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED);
- send_undefine_context_cmd(co_ps, ps_context);
- return;
- }
-error:
- {
- _unable_to_get_pending(co_ps, ps_context);
- return;
- }
-}
-
-static TReturn send_pdp_activate_cmd(CoreObject *co_ps, CoreObject *ps_context)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- char cmd_str[MAX_AT_CMD_STR_LEN] = {0};
- int cid = 0;
- dbg("Entered");
- /* FIXME: Before MUX setup, use PHY HAL directly. */
- hal = tcore_object_get_hal(co_ps);
-
- /*Getting Context ID from Core Object*/
- cid = tcore_context_get_id(ps_context);
- (void) sprintf(cmd_str, "AT+CGACT=%d,%d", AT_PDP_ACTIVATE, cid);
- pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
- on_response_send_pdp_activate_cmd, ps_context);
- if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
- return TCORE_RETURN_SUCCESS;
- }
- _unable_to_get_pending(co_ps, ps_context);
- return TCORE_RETURN_FAILURE;
-}
-
-static void on_response_xdns_enable_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- TcoreATResponse *resp = (TcoreATResponse *) data;
- CoreObject *co_ps = tcore_pending_ref_core_object(p);
- CoreObject *ps_context = user_data;
- dbg("Entered");
- if (resp->success) {
- dbg("Response OK");
- dbg("DNS address getting is Enabled");
- } else {
- dbg("Response NOK");
- /*If response to enable the DNS NOK then we will use google DNS for the PDP context*/
- }
- (void) send_pdp_activate_cmd(co_ps, ps_context);
- return;
-}
-
-static TReturn send_xdns_enable_cmd(CoreObject *co_ps, CoreObject *ps_context)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- int cid = -1;
- char cmd_str[MAX_AT_CMD_STR_LEN];
-
- dbg("Entered");
- memset(cmd_str, 0x0, MAX_AT_CMD_STR_LEN);
-
- hal = tcore_object_get_hal(co_ps);
- cid = tcore_context_get_id(ps_context);
-
- (void) sprintf(cmd_str, "AT+XDNS=%d,%d", cid, AT_XDNS_ENABLE);
- pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
- on_response_xdns_enable_cmd, ps_context);
- if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
- return TCORE_RETURN_SUCCESS;
- }
- _unable_to_get_pending(co_ps, ps_context);
- return TCORE_RETURN_FAILURE;
-}
-
-static void on_response_define_pdp_context(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- CoreObject *ps_context = (CoreObject *) user_data;
- CoreObject *co_ps = tcore_pending_ref_core_object(p);
-
- dbg("Entered");
- if (resp->success) {
- dbg("Response OK");
- send_xdns_enable_cmd(co_ps, ps_context);
- } else {
- dbg("response NOK");
- _unable_to_get_pending(co_ps, ps_context);
- dbg("Exiting");
- }
- return;
-}
-
-static TReturn send_define_pdp_context_cmd(CoreObject *co_ps, CoreObject *ps_context)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- char *apn = NULL;
- char cmd_str[MAX_AT_CMD_STR_LEN] = {0};
- char pdp_type_str[10] = {0};
- unsigned int cid = PS_INVALID_CID;
- enum co_context_type pdp_type;
- enum co_context_d_comp d_comp;
- enum co_context_h_comp h_comp;
-
- dbg("Entered");
-
- cid = tcore_context_get_id(ps_context);
- pdp_type = tcore_context_get_type(ps_context);
- d_comp = tcore_context_get_data_compression(ps_context);
- h_comp = tcore_context_get_header_compression(ps_context);
- apn = tcore_context_get_apn(ps_context);
-
- hal = tcore_object_get_hal(co_ps);
- switch (pdp_type) {
- case CONTEXT_TYPE_X25:
- {
- dbg("CONTEXT_TYPE_X25");
- strcpy(pdp_type_str, "X.25");
- break;
- }
-
- case CONTEXT_TYPE_IP:
- {
- dbg("CONTEXT_TYPE_IP");
- strcpy(pdp_type_str, "IP");
- }
- break;
-
- case CONTEXT_TYPE_PPP:
- {
- dbg("CONTEXT_TYPE_PPP");
- strcpy(pdp_type_str, "PPP");
- }
- break;
-
- case CONTEXT_TYPE_IPV6:
- {
- dbg("CONTEXT_TYPE_IPV6");
- strcpy(pdp_type_str, "IPV6");
- break;
- }
-
- default:
- {
- /*PDP Type not supported supported*/
- dbg("Unsupported PDP type :- %d returning ", pdp_type);
- return TCORE_RETURN_FAILURE;
- }
- }
- dbg("Activating context for CID :- %d", cid);
- (void) sprintf(cmd_str, "AT+CGDCONT=%d,\"%s\",\"%s\",,%d,%d", cid, pdp_type_str, apn, d_comp, h_comp);
-
- pending = tcore_at_pending_new(co_ps, cmd_str, NULL, TCORE_AT_NO_RESULT,
- on_response_define_pdp_context, ps_context);
- if (TCORE_RETURN_SUCCESS == tcore_hal_send_request(hal, pending)) {
- (void) tcore_context_set_state(ps_context, CONTEXT_STATE_ACTIVATING);
- return TCORE_RETURN_SUCCESS;
- }
- _unable_to_get_pending(co_ps, ps_context);
- return TCORE_RETURN_FAILURE;
-}
-
-static TReturn activate_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
-{
- dbg("Entered");
- return send_define_pdp_context_cmd(co_ps, ps_context);
-}
-
-
-static struct tcore_ps_operations ps_ops = {
- .activate_context = activate_ps_context,
- .deactivate_context = deactivate_ps_context
-};
-
-gboolean s_ps_init(TcorePlugin *p, TcoreHal *hal)
-{
- CoreObject *o;
- struct context *context_table = NULL;
-
- dbg("Entered");
- o = tcore_ps_new(p, "umts_ps", &ps_ops, hal);
-
- if (!o)
- return FALSE;
- tcore_object_link_user_data(o, (void *) context_table);
-
- tcore_object_add_callback(o, "+CGEV", on_event_cgev_handle, p);
- tcore_object_add_callback(o, "+XNOTIFYDUNSTATUS", on_event_dun_call_notification, p);
-
- dbg("Exiting");
- return TRUE;
-}
-
-void s_ps_exit(TcorePlugin *p)
-{
- CoreObject *o;
-
- dbg("Entered");
- o = tcore_plugin_ref_core_object(p, "umts_ps");
- if (!o)
- return;
-
- tcore_ps_free(o);
- dbg("Exiting");
-}
+++ /dev/null
-/*
- * tel-plugin-imc
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Ankit Jogi <ankit.jogi@samsung.com>
- *
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-#include <tcore.h>
-#include <hal.h>
-#include <core_object.h>
-#include <plugin.h>
-#include <queue.h>
-#include <co_sim.h>
-#include <storage.h>
-#include <user_request.h>
-#include <server.h>
-#include <at.h>
-
-#include "s_common.h"
-#include "s_sim.h"
-
-#define ID_RESERVED_AT 0x0229
-
-#define SWAPBYTES16(x) \
- { \
- unsigned short int data = *(unsigned short int *) &(x); \
- data = ((data & 0xff00) >> 8) | \
- ((data & 0x00ff) << 8); \
- *(unsigned short int *) &(x) = data; \
- }
-
-enum s_sim_file_type_e {
- SIM_FTYPE_DEDICATED = 0x00, /**< Dedicated */
- SIM_FTYPE_TRANSPARENT = 0x01, /**< Transparent -binary type*/
- SIM_FTYPE_LINEAR_FIXED = 0x02, /**< Linear fixed - record type*/
- SIM_FTYPE_CYCLIC = 0x04, /**< Cyclic - record type*/
- SIM_FTYPE_INVALID_TYPE = 0xFF /**< Invalid type */
-};
-
-enum s_sim_sec_op_e {
- SEC_PIN1_VERIFY,
- SEC_PIN2_VERIFY,
- SEC_PUK1_VERIFY,
- SEC_PUK2_VERIFY,
- SEC_SIM_VERIFY,
- SEC_ADM_VERIFY,
- SEC_PIN1_CHANGE,
- SEC_PIN2_CHANGE,
- SEC_PIN1_ENABLE,
- SEC_PIN1_DISABLE,
- SEC_PIN2_ENABLE,
- SEC_PIN2_DISABLE, // 10
- SEC_SIM_ENABLE,
- SEC_SIM_DISABLE,
- SEC_NET_ENABLE,
- SEC_NET_DISABLE,
- SEC_NS_ENABLE,
- SEC_NS_DISABLE,
- SEC_SP_ENABLE,
- SEC_SP_DISABLE,
- SEC_CP_ENABLE,
- SEC_CP_DISABLE, // 20
- SEC_FDN_ENABLE,
- SEC_FDN_DISABLE,
- SEC_PIN1_STATUS,
- SEC_PIN2_STATUS,
- SEC_FDN_STATUS,
- SEC_NET_STATUS,
- SEC_NS_STATUS,
- SEC_SP_STATUS,
- SEC_CP_STATUS,
- SEC_SIM_STATUS,
- SEC_SIM_UNKNOWN = 0xff
-};
-
-struct s_sim_property {
- gboolean b_valid; /**< Valid or not */
- enum tel_sim_file_id file_id; /**< File identifier */
- enum s_sim_file_type_e file_type; /**< File type and structure */
- int rec_length; /**< Length of one record in file */
- int rec_count; /**< Number of records in file */
- int data_size; /**< File size */
- int current_index; /**< current index to read */
- enum tel_sim_status first_recv_status;
- enum s_sim_sec_op_e current_sec_op; /**< current index to read */
- struct tresp_sim_read files;
-};
-
-static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt);
-static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret);
-static gboolean _get_sim_type(CoreObject *o);
-static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef);
-static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length);
-static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length);
-static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status);
-static void on_confirmation_sim_message_send(TcorePending *p, gboolean result, void *user_data); // from Kernel
-extern gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
-
-static void on_confirmation_sim_message_send(TcorePending *p, gboolean result, void *user_data)
-{
- dbg("on_confirmation_sim_message_send - msg out from queue.\n");
-
- if (result == FALSE) {
- /* Fail */
- dbg("SEND FAIL");
- } else {
- dbg("SEND OK");
- }
-}
-
-static enum tcore_response_command _find_resp_command(UserRequest *ur)
-{
- enum tcore_request_command command;
-
- command = tcore_user_request_get_command(ur);
- switch (command) {
- case TREQ_SIM_VERIFY_PINS:
- return TRESP_SIM_VERIFY_PINS;
- break;
-
- case TREQ_SIM_VERIFY_PUKS:
- return TRESP_SIM_VERIFY_PUKS;
- break;
-
- case TREQ_SIM_CHANGE_PINS:
- return TRESP_SIM_CHANGE_PINS;
- break;
-
- case TREQ_SIM_GET_FACILITY_STATUS:
- return TRESP_SIM_GET_FACILITY_STATUS;
- break;
-
- case TREQ_SIM_DISABLE_FACILITY:
- return TRESP_SIM_DISABLE_FACILITY;
- break;
-
- case TREQ_SIM_ENABLE_FACILITY:
- return TRESP_SIM_ENABLE_FACILITY;
- break;
-
- case TREQ_SIM_GET_LOCK_INFO:
- return TRESP_SIM_GET_LOCK_INFO;
- break;
-
- case TREQ_SIM_TRANSMIT_APDU:
- return TRESP_SIM_TRANSMIT_APDU;
- break;
-
- case TREQ_SIM_GET_ATR:
- return TRESP_SIM_GET_ATR;
- break;
-
- case TREQ_SIM_GET_ECC:
- return TRESP_SIM_GET_ECC;
- break;
-
- case TREQ_SIM_GET_LANGUAGE:
- return TRESP_SIM_GET_LANGUAGE;
- break;
-
- case TREQ_SIM_SET_LANGUAGE:
- return TRESP_SIM_SET_LANGUAGE;
- break;
-
- case TREQ_SIM_GET_ICCID:
- return TRESP_SIM_GET_ICCID;
- break;
-
- case TREQ_SIM_GET_MAILBOX:
- return TRESP_SIM_GET_MAILBOX;
- break;
-
- case TREQ_SIM_GET_CALLFORWARDING:
- return TRESP_SIM_GET_CALLFORWARDING;
- break;
-
- case TREQ_SIM_SET_CALLFORWARDING:
- return TRESP_SIM_SET_CALLFORWARDING;
- break;
-
- case TREQ_SIM_GET_MESSAGEWAITING:
- return TRESP_SIM_GET_MESSAGEWAITING;
- break;
-
- case TREQ_SIM_GET_CPHS_INFO:
- return TRESP_SIM_GET_CPHS_INFO;
- break;
-
- case TREQ_SIM_GET_MSISDN:
- return TRESP_SIM_GET_MSISDN;
- break;
-
- case TREQ_SIM_GET_SPN:
- return TRESP_SIM_GET_SPN;
- break;
-
- case TREQ_SIM_GET_SPDI:
- return TRESP_SIM_GET_SPDI;
- break;
-
- case TREQ_SIM_GET_OPL:
- return TRESP_SIM_GET_OPL;
- break;
-
- case TREQ_SIM_GET_PNN:
- return TRESP_SIM_GET_PNN;
- break;
-
- case TREQ_SIM_GET_CPHS_NETNAME:
- return TRESP_SIM_GET_CPHS_NETNAME;
- break;
-
- case TREQ_SIM_GET_OPLMNWACT:
- return TRESP_SIM_GET_OPLMNWACT;
- break;
-
- case TREQ_SIM_REQ_AUTHENTICATION:
- return TRESP_SIM_REQ_AUTHENTICATION;
- break;
-
- default:
- break;
- }
- return TRESP_UNKNOWN;
-}
-
-static int _sim_get_current_pin_facility(enum s_sim_sec_op_e op)
-{
- int ret_type = 0;
-
- dbg("current sec_op[%d]", op);
-
- switch (op) {
- case SEC_PIN1_VERIFY:
- case SEC_PIN1_CHANGE:
- ret_type = SIM_PTYPE_PIN1;
- break;
-
- case SEC_PIN2_VERIFY:
- case SEC_PIN2_CHANGE:
- ret_type = SIM_PTYPE_PIN2;
- break;
-
- case SEC_PUK1_VERIFY:
- ret_type = SIM_PTYPE_PUK1;
- break;
-
- case SEC_PUK2_VERIFY:
- ret_type = SIM_PTYPE_PUK2;
- break;
-
- case SEC_SIM_VERIFY:
- ret_type = SIM_PTYPE_SIM;
- break;
-
- case SEC_ADM_VERIFY:
- ret_type = SIM_PTYPE_ADM;
- break;
-
- case SEC_PIN1_ENABLE:
- case SEC_PIN1_DISABLE:
- case SEC_PIN1_STATUS:
- ret_type = SIM_FACILITY_SC;
- break;
-
- case SEC_SIM_ENABLE:
- case SEC_SIM_DISABLE:
- case SEC_SIM_STATUS:
- ret_type = SIM_FACILITY_PS;
- break;
-
- case SEC_NET_ENABLE:
- case SEC_NET_DISABLE:
- case SEC_NET_STATUS:
- ret_type = SIM_FACILITY_PN;
- break;
-
- case SEC_NS_ENABLE:
- case SEC_NS_DISABLE:
- case SEC_NS_STATUS:
- ret_type = SIM_FACILITY_PU;
- break;
-
- case SEC_SP_ENABLE:
- case SEC_SP_DISABLE:
- case SEC_SP_STATUS:
- ret_type = SIM_FACILITY_PP;
- break;
-
- case SEC_CP_ENABLE:
- case SEC_CP_DISABLE:
- case SEC_CP_STATUS:
- ret_type = SIM_FACILITY_PC;
- break;
-
- case SEC_FDN_ENABLE:
- case SEC_FDN_DISABLE:
- case SEC_FDN_STATUS:
- ret_type = SIM_FACILITY_FD;
- break;
-
- default:
- dbg("not handled current sec op[%d]", op)
- break;
- }
- return ret_type;
-}
-
-static enum tel_sim_access_result _decode_status_word(unsigned short status_word1, unsigned short status_word2)
-{
- enum tel_sim_access_result rst = SIM_ACCESS_FAILED;
-
- if (status_word1 == 0x93 && status_word2 == 0x00) {
- rst = SIM_ACCESS_FAILED;
- /*Failed SIM request command*/
- dbg(" error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
- } else if (status_word1 == 0x94 && status_word2 == 0x00) {
- rst = SIM_ACCESS_FAILED;
- /*Failed SIM request command*/
- dbg(" error - No EF Selected [%x][%x]", status_word1, status_word2);
- } else if (status_word1 == 0x94 && status_word2 == 0x02) {
- rst = SIM_ACCESS_FAILED;
- /*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) {
- rst = SIM_ACCESS_FILE_NOT_FOUND;
- /*Failed SIM request command*/
- dbg(" error - File ID not found [%x][%x]", status_word1, status_word2);
- } else if (status_word1 == 0x94 && status_word2 == 0x08) {
- rst = SIM_ACCESS_FAILED; /* MOdem not support */
- /*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) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- /*Failed SIM request command*/
- dbg(" error - CHV not initialized [%x][%x]", status_word1, status_word2);
- } else if (status_word1 == 0x98 && status_word2 == 0x04) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- /*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) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- /*Failed SIM request command*/
- dbg(" error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
- } else if (status_word1 == 0x98 && status_word2 == 0x10) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- /*Failed SIM request command*/
- dbg(" error - Contradiction with invalidation status [%x][%x]",
- status_word1, status_word2);
- } else if (status_word1 == 0x98 && status_word2 == 0x40) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- /*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) {
- rst = SIM_ACCESS_FAILED;
- dbg(" error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
- } else if (status_word1 == 0x6B && status_word2 == 0x00) {
- rst = SIM_ACCESS_FAILED;
- dbg(" error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
- } else if (status_word1 == 0x6D && status_word2 == 0x00) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
- } else if (status_word1 == 0x6E && status_word2 == 0x00) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- dbg(" error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
- } else if (status_word1 == 0x69 && status_word2 == 0x82) {
- rst = SIM_ACCESS_CONDITION_NOT_SATISFIED;
- dbg(" error -Access denied [%x][%x]", status_word1, status_word2);
- } else if (status_word1 == 0x6A && status_word2 == 0x87) {
- rst = SIM_ACCESS_FAILED;
- dbg(" error -Incorrect parameters [%x][%x]", status_word1, status_word2);
- } else if (status_word1 == 0x6A && status_word2 == 0x82) {
- rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
- dbg(" error -File Not found [%x][%x]", status_word1, status_word2);
- } else if (status_word1 == 0x6A && status_word2 == 0x83) {
- rst = SIM_ACCESS_FILE_NOT_FOUND; // not sure of the SW1 and SW2 meaning here
- dbg(" error -Record Not found [%x][%x]", status_word1, status_word2);
- } else {
- rst = SIM_ACCESS_CARD_ERROR;
- dbg(" error -Unknown state [%x][%x]", status_word1, status_word2);
- }
- return rst;
-}
-
-static gboolean _sim_check_identity(CoreObject *o, struct tel_sim_imsi *imsi)
-{
- Server *s = NULL;
- Storage *strg = NULL;
- char *old_imsi = NULL;
- char new_imsi[15 + 1] = {0, };
-
- s = tcore_plugin_ref_server(tcore_object_ref_plugin(o));
- if (!s) {
- dbg("there is no valid server at this point");
- return FALSE;
- }
- strg = (Storage *) tcore_server_find_storage(s, "vconf");
- if (!strg) {
- dbg("there is no valid storage plugin");
- return FALSE;
- }
- memcpy(&new_imsi, imsi->plmn, strlen(imsi->plmn));
- memcpy(&new_imsi[strlen(imsi->plmn)], imsi->msin, strlen(imsi->msin));
- new_imsi[strlen(imsi->plmn) + strlen(imsi->msin)] = '\0';
-
- old_imsi = tcore_storage_get_string(strg, STORAGE_KEY_TELEPHONY_IMSI);
- dbg("old_imsi[%s],newImsi[%s]", old_imsi, new_imsi);
-
- if (old_imsi != NULL) {
- if (strncmp(old_imsi, new_imsi, 15) != 0) {
- dbg("NEW SIM");
- if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *) &new_imsi) == FALSE) {
- dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
- }
- tcore_sim_set_identification(o, TRUE);
- } else {
- dbg("SAME SIM");
- tcore_sim_set_identification(o, FALSE);
- }
- } else {
- dbg("OLD SIM VALUE IS NULL. NEW SIM");
- if (tcore_storage_set_string(strg, STORAGE_KEY_TELEPHONY_IMSI, (const char *) &new_imsi) == FALSE) {
- dbg("[FAIL] UPDATE STORAGE_KEY_TELEPHONY_IMSI");
- }
- tcore_sim_set_identification(o, TRUE);
- }
- return 1;
-}
-
-static void _next_from_get_file_info(CoreObject *o, UserRequest *ur, enum tel_sim_file_id ef, enum tel_sim_access_result rt)
-{
- struct tresp_sim_read resp = {0, };
- struct s_sim_property *file_meta = NULL;
-
- dbg("EF[0x%x] access Result[%d]", ef, rt);
-
- resp.result = rt;
- memset(&resp.data, 0x00, sizeof(resp.data));
- file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
-
- if ((ef != SIM_EF_ELP && ef != SIM_EF_LP && ef != SIM_EF_USIM_PL && ef != SIM_EF_CPHS_CPHS_INFO)
- && (rt != SIM_ACCESS_SUCCESS)) {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &resp);
- return;
- }
-
- switch (ef) {
- case SIM_EF_ELP:
- if (rt == SIM_ACCESS_SUCCESS) {
- dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
- /* if (po->language_file == 0x00)
- po->language_file = SIM_EF_ELP;*/
- _get_file_data(o, ur, ef, 0, file_meta->data_size);
- } else {
- if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
- 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 */
- _get_file_info(o, ur, SIM_EF_LP);
- } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
- dbg(
- " [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05)). Request SIM_EF_ECC(0x6FB7) info");
- /* EFELPand EFLI not present at this point. */
- /* po->language.lang_cnt = 0;*/
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_read), &resp);
- return;
- }
- }
- break;
-
- case SIM_EF_LP: // same with SIM_EF_USIM_LI
- if (rt == SIM_ACCESS_SUCCESS) {
- dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
- _get_file_data(o, ur, ef, 0, file_meta->data_size);
- } else {
- dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]",
- tcore_sim_get_type(o));
- if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_read), &resp);
- return;
- }
- /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
- else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
- dbg("[SIM DATA] try USIM EFPL(0x2F05)");
- _get_file_info(o, ur, SIM_EF_ELP);
- }
- }
- break;
-
- case SIM_EF_USIM_PL:
- if (rt == SIM_ACCESS_SUCCESS) {
- dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
- _get_file_data(o, ur, SIM_EF_ELP, 0, file_meta->data_size);
- } 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");
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_read), &resp);
- return;
- }
- break;
-
- case SIM_EF_ECC:
- if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
- _get_file_data(o, ur, ef, 0, file_meta->data_size);
- } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
- if (file_meta->rec_count > SIM_ECC_RECORD_CNT_MAX) {
- file_meta->rec_count = SIM_ECC_RECORD_CNT_MAX;
- }
-
- file_meta->current_index++;
- _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
- }
- break;
-
- case SIM_EF_ICCID:
- case SIM_EF_IMSI:
- case SIM_EF_SST:
- case SIM_EF_SPN:
- case SIM_EF_SPDI:
- case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
- case SIM_EF_CPHS_VOICE_MSG_WAITING:
- case SIM_EF_CPHS_OPERATOR_NAME_STRING:
- case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
- case SIM_EF_CPHS_DYNAMICFLAGS:
- case SIM_EF_CPHS_DYNAMIC2FLAG:
- case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
- case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
- _get_file_data(o, ur, ef, 0, file_meta->data_size);
- break;
-
- case SIM_EF_CPHS_CPHS_INFO:
- if (rt == SIM_ACCESS_SUCCESS) {
- tcore_sim_set_cphs_status(o, TRUE);
- if (!tcore_user_request_ref_communicator(ur)) {
- dbg("internal CPHS INFO request before sim status update");
- _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
- } else {
- dbg("external CPHS INFO request");
- _get_file_data(o, ur, ef, 0, file_meta->data_size);
- }
- } else {
- tcore_sim_set_cphs_status(o, FALSE);
- if (!tcore_user_request_ref_communicator(ur)) {
- dbg("internal CPHS INFO request before sim status update");
- _sim_status_update(o, SIM_STATUS_INIT_COMPLETED);
- } else {
- dbg("external CPHS INFO request");
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_read), &resp);
- }
- }
- break;
-
-
- case SIM_EF_USIM_CFIS:
- if (file_meta->rec_count > SIM_CF_RECORD_CNT_MAX) {
- file_meta->rec_count = SIM_CF_RECORD_CNT_MAX;
- }
- file_meta->current_index++;
- _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
- break;
-
- case SIM_EF_OPL:
- case SIM_EF_PNN:
- case SIM_EF_USIM_MWIS:
- case SIM_EF_USIM_MBI:
- case SIM_EF_MBDN:
- case SIM_EF_CPHS_MAILBOX_NUMBERS:
- case SIM_EF_CPHS_INFORMATION_NUMBERS:
- file_meta->current_index++;
- _get_file_record(o, ur, ef, file_meta->current_index, file_meta->rec_length);
- break;
-
- default:
- dbg("error - File id for get file info [0x%x]", ef);
- break;
- }
- return;
-}
-
-static void _next_from_get_file_data(CoreObject *o, UserRequest *ur, enum tel_sim_access_result rt, int decode_ret)
-{
- struct s_sim_property *file_meta = NULL;
-
- dbg("Entry");
-
- file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
- dbg("[SIM]EF[0x%x] read rt[%d] Decode rt[%d]", file_meta->file_id, rt, decode_ret);
- switch (file_meta->file_id) {
- case SIM_EF_ELP:
- case SIM_EF_USIM_PL:
- case SIM_EF_LP:
- case SIM_EF_USIM_LI:
- if (decode_ret == TRUE) {
- if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
-/* po->language_file = SIM_EF_LP;*/
- } else if (file_meta->file_id == SIM_EF_ELP || file_meta->file_id == SIM_EF_USIM_PL) {
-/* po->language_file = SIM_EF_ELP;*/
- }
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- } else {
- /* 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 (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
- if (file_meta->file_id == SIM_EF_LP) {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- } else {
- _get_file_info(o, ur, SIM_EF_LP);
- }
- } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
- if (file_meta->file_id == SIM_EF_LP || file_meta->file_id == SIM_EF_USIM_LI) {
- _get_file_info(o, ur, SIM_EF_ELP);
- } else {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- }
- }
- }
- break;
-
- case SIM_EF_ECC:
- if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
- if (file_meta->current_index == file_meta->rec_count) {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- } else {
- file_meta->current_index++;
- _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
- }
- } else if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- } else {
- dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", tcore_sim_get_type(o));
- }
- break;
-
- case SIM_EF_IMSI:
- ur = tcore_user_request_new(NULL, NULL); // this is for using ur metainfo set/ref functionality.
- _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
- break;
-
- case SIM_EF_MSISDN:
- if (file_meta->current_index == file_meta->rec_count) {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- } else {
- file_meta->current_index++;
- _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
- }
- break;
-
- case SIM_EF_OPL:
- if (file_meta->current_index == file_meta->rec_count) {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- } else {
- file_meta->current_index++;
- _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
- }
- break;
-
- case SIM_EF_PNN:
- if (file_meta->current_index == file_meta->rec_count) {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- } else {
- file_meta->current_index++;
- _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
- }
- break;
-
- case SIM_EF_USIM_CFIS:
- case SIM_EF_USIM_MWIS:
- case SIM_EF_USIM_MBI:
- case SIM_EF_MBDN:
- case SIM_EF_CPHS_MAILBOX_NUMBERS:
- case SIM_EF_CPHS_INFORMATION_NUMBERS:
- if (file_meta->current_index == file_meta->rec_count) {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- } else {
- file_meta->current_index++;
- _get_file_record(o, ur, file_meta->file_id, file_meta->current_index, file_meta->rec_length);
- }
- break;
-
- case SIM_EF_CPHS_OPERATOR_NAME_STRING:
- file_meta->files.result = rt;
- if (decode_ret == TRUE && rt == SIM_ACCESS_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));
- }
- _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING);
- break;
-
- case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
- if (file_meta->files.result == SIM_ACCESS_SUCCESS || file_meta->files.result == SIM_ACCESS_SUCCESS) {
- file_meta->files.result = SIM_ACCESS_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));
- }
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- break;
-
- case SIM_EF_ICCID:
- case SIM_EF_SST:
- case SIM_EF_SPN:
- case SIM_EF_SPDI:
- case SIM_EF_OPLMN_ACT:
- case SIM_EF_CPHS_CPHS_INFO:
- case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
- case SIM_EF_CPHS_VOICE_MSG_WAITING:
- case SIM_EF_CPHS_DYNAMICFLAGS:
- case SIM_EF_CPHS_DYNAMIC2FLAG:
- case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
- case SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_read), &file_meta->files);
- break;
-
- default:
- dbg("File id not handled [0x%x]", file_meta->file_id);
- break;
- }
-}
-
-static void _sim_status_update(CoreObject *o, enum tel_sim_status sim_status)
-{
- struct tnoti_sim_status noti_data = {0, };
-
- dbg("tcore_sim_set_status and send noti w/ [%d]", sim_status);
- tcore_sim_set_status(o, sim_status);
- noti_data.sim_status = sim_status;
- tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SIM_STATUS,
- sizeof(struct tnoti_sim_status), ¬i_data);
-}
-
-static void _response_get_sim_type(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- enum tel_sim_type sim_type = SIM_TYPE_UNKNOWN;
- const char *line;
- int state;
-
- dbg(" Function entry ");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(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) != 1) {
- msg("invalid message");
- tcore_at_tok_free(tokens);
- return;
- }
- }
- state = atoi(g_slist_nth_data(tokens, 0));
- dbg("SIM Type is %d", state);
-
- if (state == 0) {
- sim_type = SIM_TYPE_GSM;
- } else if (state == 1) {
- sim_type = SIM_TYPE_USIM;
- } else {
- sim_type = SIM_TYPE_UNKNOWN;
- }
- } else {
- dbg("RESPONSE NOK");
- sim_type = SIM_TYPE_UNKNOWN;
- }
-
- tcore_sim_set_type(co_sim, sim_type);
- _sim_status_update(co_sim, sp->first_recv_status);
- tcore_at_tok_free(tokens);
- dbg(" Function exit");
-}
-
-static void _response_get_file_info(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *file_meta = NULL;
- GSList *tokens = NULL;
- enum tel_sim_access_result rt;
- const char *line = NULL;
- int sw1 = 0;
- int sw2 = 0;
-
- dbg(" Function entry ");
-
- co_sim = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
- file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
-
- 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; /* 1 or 2 bytes ??? */
- 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;
-
- /* handling only last 3 bits */
- unsigned char file_type_tag = 0x07;
- unsigned char *ptr_data;
-
- char *hexData;
- char *tmp;
- char *recordData = NULL;
- hexData = g_slist_nth_data(tokens, 2);
- dbg("hexData: %s", hexData);
- dbg("hexData: %s", hexData + 1);
-
- tmp = util_removeQuotes(hexData);
- recordData = util_hexStringToBytes(tmp);
- util_hex_dump(" ", strlen(hexData) / 2, recordData);
- free(tmp);
-
- ptr_data = (unsigned char *) recordData;
- if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
- /*
- 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++;
- /* unsigned char file_desc_len = *ptr_data++;*/
- /* dbg("file descriptor length: [%d]", file_desc_len);*/
- /* TBD: currently capture only file type : ignore sharable, non sharable, working, internal etc*/
- /* 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 = SIM_FTYPE_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 */
- SWAPBYTES16(record_len);
- ptr_data = ptr_data + 2;
- num_of_records = *ptr_data++;
- /* Data lossy conversation from enum (int) to unsigned char */
- file_type = SIM_FTYPE_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 */
- SWAPBYTES16(record_len);
- ptr_data = ptr_data + 2;
- num_of_records = *ptr_data++;
- file_type = SIM_FTYPE_CYCLIC;
- break;
-
- default:
- dbg("not handled file type [0x%x]", *ptr_data);
- break;
- }
- } else {
- dbg("INVALID FCP received - DEbug!");
- return;
- }
-
- /*File identifier - file id?? */ // 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 */
- SWAPBYTES16(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!");
- free(recordData);
- 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("<RX> operation state -deactivated");
- ptr_data++;
- break;
-
- case 0x05:
- case 0x07:
- dbg("<RX> operation state -activated");
- ptr_data++;
- break;
-
- default:
- dbg("<RX> 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 */
- SWAPBYTES16(arr_file_id);
- ptr_data = ptr_data + 2;
- arr_file_id_rec_num = *ptr_data++;
- } 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);
- free(recordData);
- 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 */
- SWAPBYTES16(file_size);
- ptr_data = ptr_data + 2;
- } else {
- dbg("INVALID FCP received - DEbug!");
- free(recordData);
- return;
- }
-
- /* total file size including structural info*/
- if (*ptr_data == 0x81) {
- int len;
- /* increment to next byte */
- ptr_data++;
- /* length */
- len = *ptr_data;
- /* 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! */
- /* return -1; */
- }
- /*short file identifier ignored*/
- if (*ptr_data == 0x88) {
- dbg("0x88: Do Nothing");
- /*DO NOTHING*/
- }
- } else {
- dbg("INVALID FCP received - DEbug!");
- free(recordData);
- return;
- }
- } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
- 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 */
- SWAPBYTES16(file_size);
- /* parsed file size */
- ptr_data = ptr_data + 2;
- /* file id */
- memcpy(&file_id, ptr_data, 2);
- SWAPBYTES16(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) ? SIM_FTYPE_TRANSPARENT : SIM_FTYPE_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 = SIM_FTYPE_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;
- 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 {
- dbg(" Card Type - UNKNOWN [%d]", tcore_sim_get_type(co_sim));
- }
-
- 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
- rt = SIM_ACCESS_SUCCESS;
- free(recordData);
- } else {
- /*2. SIM access fail case*/
- dbg("error to get ef[0x%x]", file_meta->file_id);
- dbg("error to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
- rt = _decode_status_word(sw1, sw2);
- }
- ur = tcore_user_request_ref(ur);
-
- dbg("Calling _next_from_get_file_info");
- _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
- tcore_at_tok_free(tokens);
- } else {
- dbg("RESPONSE NOK");
- dbg("error to get ef[0x%x]", file_meta->file_id);
- dbg("error to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
- rt = SIM_ACCESS_FAILED;
-
- ur = tcore_user_request_ref(ur);
- _next_from_get_file_info(co_sim, ur, file_meta->file_id, rt);
- }
- dbg(" Function exit");
-}
-
-static void _response_get_file_data(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *file_meta = NULL;
- GSList *tokens = NULL;
- enum tel_sim_access_result rt;
- struct tel_sim_imsi imsi;
- struct tel_sim_ecc ecc;
- struct tel_sim_msisdn msisdn;
- struct tel_sim_opl opl;
- struct tel_sim_pnn pnn;
- gboolean dr = FALSE;
- const char *line = NULL;
- char *res = NULL;
- char *tmp = NULL;
- int res_len;
- int sw1 = 0;
- int sw2 = 0;
-
- dbg(" Function entry ");
-
- co_sim = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
- file_meta = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
-
- 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) != 3) {
- 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 = util_removeQuotes(res);
- res = util_hexStringToBytes(tmp);
- res_len = strlen((const char *) res);
- dbg("res: %s res_len: %d", res, res_len);
-
- if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
- rt = SIM_ACCESS_SUCCESS;
- file_meta->files.result = rt;
- dbg("file_meta->file_id : %x", file_meta->file_id);
-
- switch (file_meta->file_id) {
- case SIM_EF_IMSI:
- {
- dbg("res: %s", res);
- dr = tcore_sim_decode_imsi(&imsi, (unsigned char *) res, res_len);
- if (dr == FALSE) {
- dbg("imsi decoding failed");
- } else {
- _sim_check_identity(co_sim, &imsi);
- tcore_sim_set_imsi(co_sim, &imsi);
- }
- break;
- }
-
- case SIM_EF_ICCID:
- dr = tcore_sim_decode_iccid(&file_meta->files.data.iccid, (unsigned char *) res, res_len);
- break;
-
- case SIM_EF_ELP: /* 2G EF - 2 bytes decoding*/
- case SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding*/
- case SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding*/
- case SIM_EF_LP: /* 1 byte encoding*/
- if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM && file_meta->file_id == SIM_EF_LP) {
- /*2G LP(0x6F05) has 1 byte for each language*/
- dr = tcore_sim_decode_lp(&file_meta->files.data.language, (unsigned char *) res, res_len);
- } else {
- /*3G LI(0x6F05)/PL(0x2F05), 2G ELP(0x2F05) has 2 bytes for each language*/
- dr = tcore_sim_decode_li(file_meta->file_id, &file_meta->files.data.language, (unsigned char *) res, res_len);
- }
- break;
-
- case SIM_EF_SPN:
- dr = tcore_sim_decode_spn(&file_meta->files.data.spn, (unsigned char *) res, res_len);
- break;
-
- case SIM_EF_SPDI:
- dr = tcore_sim_decode_spdi(&file_meta->files.data.spdi, (unsigned char *) res, res_len);
- break;
-
- case SIM_EF_ECC:
- if (tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
- dr = tcore_sim_decode_ecc(&file_meta->files.data.ecc, (unsigned char *) res, res_len);
- } else if (tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
- dbg("decode w/ index [%d]", file_meta->current_index);
- memset(&ecc, 0x00, sizeof(struct tel_sim_ecc));
- dr = tcore_sim_decode_uecc(&ecc, (unsigned char *) res, res_len);
- if (dr == TRUE) {
- memcpy(&file_meta->files.data.ecc.ecc[file_meta->files.data.ecc.ecc_count], &ecc, sizeof(struct tel_sim_ecc));
- file_meta->files.data.ecc.ecc_count++;
- }
- } else {
- dbg("err not handled tcore_sim_get_type(o)[%d] in here", tcore_sim_get_type(co_sim));
- }
- break;
-
- case SIM_EF_MSISDN:
- dbg("decode w/ index [%d]", file_meta->current_index);
- memset(&msisdn, 0x00, sizeof(struct tel_sim_msisdn));
- dr = tcore_sim_decode_msisdn(&msisdn, (unsigned char *) res, res_len);
- if (dr == TRUE) {
- memcpy(&file_meta->files.data.msisdn_list.msisdn[file_meta->files.data.msisdn_list.count], &msisdn, sizeof(struct tel_sim_msisdn));
- file_meta->files.data.msisdn_list.count++;
- }
- break;
-
- case SIM_EF_OPL:
- dbg("decode w/ index [%d]", file_meta->current_index);
- memset(&opl, 0x00, sizeof(struct tel_sim_opl));
- dr = tcore_sim_decode_opl(&opl, (unsigned char *) res, res_len);
- if (dr == TRUE) {
- memcpy(&file_meta->files.data.opl.opl[file_meta->files.data.opl.opl_count], &opl, sizeof(struct tel_sim_opl));
- file_meta->files.data.opl.opl_count++;
- }
- break;
-
- case SIM_EF_PNN:
- dbg("decode w/ index [%d]", file_meta->current_index);
- memset(&pnn, 0x00, sizeof(struct tel_sim_pnn));
- dr = tcore_sim_decode_pnn(&pnn, (unsigned char *) res, res_len);
- if (dr == TRUE) {
- memcpy(&file_meta->files.data.pnn.pnn[file_meta->files.data.pnn.pnn_count], &opl, sizeof(struct tel_sim_pnn));
- file_meta->files.data.pnn.pnn_count++;
- }
- break;
-
- case SIM_EF_OPLMN_ACT:
- dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa, (unsigned char *) res, res_len);
- break;
-
- case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
- dr = tcore_sim_decode_cff(&file_meta->files.data.cf, (unsigned char *) res, res_len);
- break;
-
- case SIM_EF_CPHS_VOICE_MSG_WAITING:
- dr = tcore_sim_decode_vmwf(&file_meta->files.data.mw.mw_data_u.cphs_mw, (unsigned char *) res, res_len);
- break;
-
- case SIM_EF_USIM_MWIS:
- dr = tcore_sim_decode_mwis(&file_meta->files.data.mw.mw_data_u.mw, (unsigned char *) res, res_len);
- break;
-
- case SIM_EF_USIM_CFIS:
- dr = tcore_sim_decode_cfis(&file_meta->files.data.cf, (unsigned char *) res, res_len);
- break;
-
- case SIM_EF_CPHS_SERVICE_STRING_TABLE:
- dbg(" not handled -SIM_EF_CPHS_SERVICE_STRING_TABLE ");
- break;
-
- case SIM_EF_CPHS_OPERATOR_NAME_STRING:
- dr = tcore_sim_decode_ons((unsigned char *) &file_meta->files.data.cphs_net.full_name, (unsigned char *) res, res_len);
- 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 SIM_EF_CPHS_CPHS_INFO:
- dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs, (unsigned char *) res, res_len);
- break;
-
- case SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
- dr = tcore_sim_decode_short_ons((unsigned char *) &file_meta->files.data.cphs_net.short_name, (unsigned char *) res, res_len);
- break;
-
- default:
- dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id);
- dr = 0;
- break;
- }
- } else {
- rt = _decode_status_word(sw1, sw2);
- file_meta->files.result = rt;
- }
- free(tmp);
- tcore_at_tok_free(tokens);
- } else {
- dbg("RESPONSE NOK");
- dbg("error to get ef[0x%x]", file_meta->file_id);
- rt = SIM_ACCESS_FAILED;
- }
- ur = tcore_user_request_ref(ur);
-
- dbg("Calling _next_from_get_file_data");
- _next_from_get_file_data(tcore_pending_ref_core_object(p), ur, rt, dr);
- dbg(" Function exit");
-}
-
-static void _on_response_get_retry_count(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- const char *line = NULL;
- struct tresp_sim_verify_pins v_pin = {0, };
- struct tresp_sim_verify_puks v_puk = {0, };
- struct tresp_sim_change_pins change_pin = {0, };
- struct tresp_sim_disable_facility dis_facility = {0, };
- struct tresp_sim_enable_facility en_facility = {0, };
- int lock_type = 0;
- int attempts_left = 0;
- int time_penalty = 0;
-
- dbg(" Function entry ");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(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) < 3) {
- msg("invalid message");
- tcore_at_tok_free(tokens);
- return;
- }
- }
- lock_type = atoi(g_slist_nth_data(tokens, 0));
- attempts_left = atoi(g_slist_nth_data(tokens, 1));
- time_penalty = atoi(g_slist_nth_data(tokens, 2));
-
- dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
- lock_type, attempts_left, time_penalty);
-
- switch (sp->current_sec_op) {
- case SEC_PIN1_VERIFY:
- case SEC_PIN2_VERIFY:
- case SEC_SIM_VERIFY:
- case SEC_ADM_VERIFY:
- v_pin.result = SIM_INCORRECT_PASSWORD;
- v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- v_pin.retry_count = attempts_left;
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_verify_pins), &v_pin);
- break;
-
- case SEC_PUK1_VERIFY:
- case SEC_PUK2_VERIFY:
- v_puk.result = SIM_INCORRECT_PASSWORD;
- v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- v_puk.retry_count = attempts_left;
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_verify_puks), &v_puk);
- break;
-
- case SEC_PIN1_CHANGE:
- case SEC_PIN2_CHANGE:
- change_pin.result = SIM_INCORRECT_PASSWORD;
- change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- change_pin.retry_count = attempts_left;
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_change_pins), &change_pin);
- break;
-
- case SEC_PIN1_DISABLE:
- case SEC_PIN2_DISABLE:
- case SEC_FDN_DISABLE:
- case SEC_SIM_DISABLE:
- case SEC_NET_DISABLE:
- case SEC_NS_DISABLE:
- case SEC_SP_DISABLE:
- case SEC_CP_DISABLE:
- dis_facility.result = SIM_INCORRECT_PASSWORD;
- dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
- dis_facility.retry_count = attempts_left;
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_disable_facility), &dis_facility);
- break;
-
- case SEC_PIN1_ENABLE:
- case SEC_PIN2_ENABLE:
- case SEC_FDN_ENABLE:
- case SEC_SIM_ENABLE:
- case SEC_NET_ENABLE:
- case SEC_NS_ENABLE:
- case SEC_SP_ENABLE:
- case SEC_CP_ENABLE:
- en_facility.result = SIM_INCORRECT_PASSWORD;
- en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
- en_facility.retry_count = attempts_left;
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_enable_facility), &en_facility);
- break;
-
- default:
- dbg("not handled sec op[%d]", sp->current_sec_op);
- break;
- }
- tcore_at_tok_free(tokens);
- }
- dbg(" Function exit");
-}
-
-static gboolean _get_sim_type(CoreObject *o)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- UserRequest *ur = NULL;
- char *cmd_str = NULL;
-
- dbg(" Function entry ");
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
-
- cmd_str = g_strdup_printf("AT+XUICC?");
- req = tcore_at_request_new(cmd_str, "+XUICC:", TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, _response_get_sim_type, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TRUE;
-}
-
-static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef)
-{
- TcoreHal *hal = NULL;
- TcorePending *pending = NULL;
- struct s_sim_property file_meta = {0, };
- char *cmd_str = NULL;
- int trt = 0;
-
- dbg(" Function entry ");
-
- file_meta.file_id = ef;
- dbg("file_meta.file_id: %d", file_meta.file_id);
- hal = tcore_object_get_hal(o);
- dbg("hal: %x", hal);
- pending = tcore_pending_new(o, 0);
-
- trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
- dbg("trt[%d]", trt);
- cmd_str = g_strdup_printf("AT+CRSM=192, %d", ef); /*command - 192 : GET RESPONSE*/
- dbg("cmd_str: %x", cmd_str);
-
- pending = tcore_at_pending_new(o, cmd_str, "+CRSM:", TCORE_AT_SINGLELINE, _response_get_file_info, NULL);
- tcore_pending_link_user_request(pending, ur);
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static gboolean _get_file_data(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int offset, const int length)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- int p1 = 0;
- int p2 = 0;
- int p3 = 0;
-
- dbg(" Function entry ");
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
-
- dbg("file_id: %x", ef);
-
- p1 = (unsigned char) (offset & 0xFF00) >> 8;
- p2 = (unsigned char) offset & 0x00FF; // offset low
- p3 = (unsigned char) length;
-
- cmd_str = g_strdup_printf("AT+CRSM=176, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 176 : READ BINARY*/
-
- req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TRUE;
-}
-
-static gboolean _get_file_record(CoreObject *o, UserRequest *ur, const enum tel_sim_file_id ef, const int index, const int length)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- int p1 = 0;
- int p2 = 0;
- int p3 = 0;
-
- dbg(" Function entry ");
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
-
- p1 = (unsigned char) index;
- p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
- p3 = (unsigned char) length;
-
- cmd_str = g_strdup_printf("AT+CRSM=178, %d, %d, %d, %d", ef, p1, p2, p3); /*command - 178 : READ RECORD*/
-
- req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, _response_get_file_data, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TRUE;
-}
-
-static TReturn _get_retry_count(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- int lock_type = 0;
- struct s_sim_property *sp = NULL;
- const struct treq_sim_get_lock_info *req_data = NULL;
-
- dbg(" Function entry ");
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
- sp = tcore_sim_ref_userdata(o);
-
- switch (sp->current_sec_op) {
- case SEC_PIN1_VERIFY:
- case SEC_PIN1_CHANGE:
- case SEC_PIN1_ENABLE:
- case SEC_PIN1_DISABLE:
- lock_type = 1;
- break;
-
- case SEC_PIN2_VERIFY:
- case SEC_PIN2_CHANGE:
- case SEC_PIN2_ENABLE:
- case SEC_PIN2_DISABLE:
- case SEC_FDN_ENABLE:
- case SEC_FDN_DISABLE:
- lock_type = 2;
- break;
-
- case SEC_PUK1_VERIFY:
- lock_type = 3;
- break;
-
- case SEC_PUK2_VERIFY:
- lock_type = 4;
- break;
-
- case SEC_NET_ENABLE:
- case SEC_NET_DISABLE:
- lock_type = 5;
- break;
-
- case SEC_NS_ENABLE:
- case SEC_NS_DISABLE:
- lock_type = 6;
- break;
-
- case SEC_SP_ENABLE:
- case SEC_SP_DISABLE:
- lock_type = 7;
- break;
-
- case SEC_CP_ENABLE:
- case SEC_CP_DISABLE:
- lock_type = 8;
- break;
-
- case SEC_ADM_VERIFY:
- lock_type = 9;
- break;
-
- default:
- break;
- }
-
- cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
- req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, _on_response_get_retry_count, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-
-static gboolean on_event_facility_lock_status(CoreObject *o, const void *event_info, void *user_data)
-{
- struct s_sim_property *sp = NULL;
- char *line = NULL;
- GSList *tokens = NULL;
- GSList *lines = NULL;
-
- dbg("Function entry");
- return TRUE;
-
- sp = tcore_sim_ref_userdata(o);
- lines = (GSList *) event_info;
- if (1 != g_slist_length(lines)) {
- dbg("unsolicited msg but multiple line");
- goto OUT;
- }
- line = (char *) (lines->data);
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) != 1) {
- msg("invalid message");
- tcore_at_tok_free(tokens);
- return TRUE;
- }
-
-OUT:
- dbg(" Function exit");
- if (NULL != tokens)
- tcore_at_tok_free(tokens);
- return TRUE;
-}
-
-
-static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void *user_data)
-{
- UserRequest *ur = NULL;
- struct s_sim_property *sp = NULL;
- enum tel_sim_status sim_status = SIM_STATUS_INITIALIZING;
- GSList *tokens = NULL;
- GSList *lines = NULL;
- const char *line = NULL;
- int sim_state = 0;
-
- dbg(" Function entry ");
-
- sp = tcore_sim_ref_userdata(o);
-
- lines = (GSList *) event_info;
- if (1 != g_slist_length(lines)) {
- dbg("unsolicited msg but multiple line");
- goto OUT;
- }
- line = (char *) (lines->data);
-
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) != 1) {
- msg("invalid message");
- tcore_at_tok_free(tokens);
- return TRUE;
- }
- sim_state = atoi(g_slist_nth_data(tokens, 0));
-
- switch (sim_state) {
- case 0: // sim state = SIM not present
- sim_status = SIM_STATUS_CARD_NOT_PRESENT;
- dbg("NO SIM");
- break;
-
- case 1: // sim state = PIN verification needed
- sim_status = SIM_STATUS_PIN_REQUIRED;
- dbg(" PIN required");
- break;
-
- case 2: // sim state = PIN verification not needed \96 Ready
- case 3: // sim state = PIN verified \96 Ready
- sim_status = SIM_STATUS_INITIALIZING;
- dbg(" Inside PIN disabled at BOOT UP");
- break;
-
- case 4: // sim state = PUK verification needed
- sim_status = SIM_STATUS_PUK_REQUIRED;
- dbg(" PUK required");
- break;
-
- case 5: // sim state = SIM permanently blocked
- sim_status = SIM_STATUS_CARD_BLOCKED;
- dbg(" Card permanently blocked");
- break;
-
- case 6: // sim state = SIM error
- sim_status = SIM_STATUS_CARD_ERROR;
- dbg("SIM card error ");
- break;
-
- case 7: // sim state = ready for attach (+COPS)
- sim_status = SIM_STATUS_INIT_COMPLETED;
- dbg("Modem init completed");
- break;
-
- case 8: // sim state = SIM Technical Problem
- sim_status = SIM_STATUS_CARD_ERROR;
- dbg("SIM unavailable");
- break;
-
- case 9: // sim state = SIM removed
- sim_status = SIM_STATUS_CARD_REMOVED;
- dbg("SIM removed");
- break;
-
- case 99: // sim state = SIM State Unknown
- sim_status = SIM_STATUS_UNKNOWN;
- dbg("SIM State Unknown");
- break;
-
- case 12:
- dbg("SIM Status : %d", sim_status);
- goto OUT;
-
- default:
- dbg(" not handled SEC lock type ");
- break;
- }
-
- switch (sim_status) {
- case SIM_STATUS_INIT_COMPLETED:
- ur = tcore_user_request_new(NULL, NULL); // this is for using ur metainfo set/ref functionality.
- _get_file_info(o, ur, SIM_EF_IMSI);
- break;
-
- case SIM_STATUS_INITIALIZING:
- case SIM_STATUS_PIN_REQUIRED:
- case SIM_STATUS_PUK_REQUIRED:
- case SIM_STATUS_CARD_BLOCKED:
- case SIM_STATUS_NCK_REQUIRED:
- case SIM_STATUS_NSCK_REQUIRED:
- case SIM_STATUS_SPCK_REQUIRED:
- case SIM_STATUS_CCK_REQUIRED:
- case SIM_STATUS_LOCK_REQUIRED:
- if (sp->first_recv_status == SIM_STATUS_UNKNOWN) {
- dbg("first received sim status[%d]", sim_status);
- sp->first_recv_status = sim_status;
- _get_sim_type(o);
- } else {
- dbg("second or later received lock status[%d]", sim_status);
- if (tcore_sim_get_status(o) != SIM_STATUS_INIT_COMPLETED) {
- dbg("sim is not init complete in telephony side yet");
- _sim_status_update(o, sim_status);
- }
- }
- break;
-
- case SIM_STATUS_CARD_REMOVED:
- case SIM_STATUS_CARD_NOT_PRESENT:
- case SIM_STATUS_CARD_ERROR:
- if (sim_status == SIM_STATUS_CARD_NOT_PRESENT && tcore_sim_get_status(o) != SIM_STATUS_UNKNOWN) {
- dbg("[SIM]SIM CARD REMOVED!!");
- sim_status = SIM_STATUS_CARD_REMOVED;
- }
- _sim_status_update(o, sim_status);
- break;
-
- default:
- dbg("not handled status[%d]", sim_status);
-
- break;
- }
-OUT:
- dbg(" Function exit");
- if (NULL != tokens)
- tcore_at_tok_free(tokens);
- return TRUE;
-}
-
-
-
-static void on_response_verify_pins(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- struct tresp_sim_verify_pins res;
- GQueue *queue = NULL;
- const char *line;
- int err;
-
- dbg(" Function entry ");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(p);
-
- memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
-
- if (resp->success > 0) {
- dbg("RESPONSE OK");
- res.result = SIM_PIN_OPERATION_SUCCESS;
- res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- if (res.pin_type == SIM_PTYPE_PIN1 || res.pin_type == SIM_PTYPE_SIM) {
- if (tcore_sim_get_status(co_sim) != SIM_STATUS_INIT_COMPLETED)
- _sim_status_update(co_sim, SIM_STATUS_INITIALIZING);
- }
- tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PINS, sizeof(struct tresp_sim_verify_pins), &res);
- } else {
- dbg("RESPONSE NOK");
- line = (const char *) resp->final_response;
- tokens = tcore_at_tok_new(line);
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- res.result = TCORE_RETURN_3GPP_ERROR;
- } else {
- err = atoi(g_slist_nth_data(tokens, 0));
- dbg("on_response_verify_pins: err = %d", err);
- queue = tcore_object_ref_user_data(co_sim);
- ur = tcore_user_request_ref(ur);
- _get_retry_count(co_sim, ur);
- }
- tcore_at_tok_free(tokens);
- }
- dbg(" Function exit");
-}
-
-static void on_response_verify_puks(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- struct tresp_sim_verify_puks res;
- GQueue *queue = NULL;
- const char *line;
- int err;
-
- dbg(" Function entry ");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(p);
-
- memset(&res, 0, sizeof(struct tresp_sim_verify_pins));
-
- if (resp->success > 0) {
- dbg("RESPONSE OK");
- res.result = SIM_PIN_OPERATION_SUCCESS;
- res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- tcore_user_request_send_response(ur, TRESP_SIM_VERIFY_PUKS, sizeof(struct tresp_sim_verify_pins), &res);
- } else {
- dbg("RESPONSE NOK");
- line = (const char *) resp->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- res.result = TCORE_RETURN_3GPP_ERROR;
- } else {
- err = atoi(g_slist_nth_data(tokens, 0));
- queue = tcore_object_ref_user_data(co_sim);
- ur = tcore_user_request_ref(ur);
- _get_retry_count(co_sim, ur);
- }
- tcore_at_tok_free(tokens);
- }
- dbg(" Function exit");
-}
-
-static void on_response_change_pins(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- struct tresp_sim_change_pins res;
- GQueue *queue;
- const char *line;
- int err;
-
- dbg(" Function entry ");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(p);
-
- memset(&res, 0, sizeof(struct tresp_sim_change_pins));
-
- if (resp->success > 0) {
- dbg("RESPONSE OK");
- res.result = SIM_PIN_OPERATION_SUCCESS;
- res.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- tcore_user_request_send_response(ur, TRESP_SIM_CHANGE_PINS, sizeof(struct tresp_sim_change_pins), &res);
- } else {
- dbg("RESPONSE NOK");
- line = (const char *) resp->final_response;
- tokens = tcore_at_tok_new(line);
-
- if (g_slist_length(tokens) < 1) {
- dbg("err cause not specified or string corrupted");
- res.result = TCORE_RETURN_3GPP_ERROR;
- } else {
- err = atoi(g_slist_nth_data(tokens, 0));
- queue = tcore_object_ref_user_data(co_sim);
- ur = tcore_user_request_ref(ur);
- _get_retry_count(co_sim, ur);
- }
- tcore_at_tok_free(tokens);
- }
- dbg(" Function exit");
-}
-
-static void on_response_get_facility_status(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- struct tresp_sim_get_facility_status res;
- const char *line;
-
- dbg(" Function entry ");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(p);
-
- memset(&res, 0, sizeof(struct tresp_sim_get_facility_status));
-
- res.result = SIM_PIN_OPERATION_SUCCESS;
- res.type = _sim_get_current_pin_facility(sp->current_sec_op);
-
- 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) != 1) {
- msg("invalid message");
- tcore_at_tok_free(tokens);
- return;
- }
- }
- res.b_enable = atoi(g_slist_nth_data(tokens, 0));
- } else {
- dbg("RESPONSE NOK");
- res.result = SIM_INCOMPATIBLE_PIN_OPERATION;
- }
-
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_SIM_GET_FACILITY_STATUS,
- sizeof(struct tresp_sim_get_facility_status), &res);
- }
- tcore_at_tok_free(tokens);
- dbg(" Function exit");
-}
-
-static void on_response_enable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- struct tresp_sim_enable_facility res;
- GQueue *queue;
- const char *line;
-
- dbg(" Function entry ");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(p);
-
- memset(&res, 0, sizeof(struct tresp_sim_enable_facility));
-
- res.result = SIM_PIN_OPERATION_SUCCESS;
- res.type = _sim_get_current_pin_facility(sp->current_sec_op);
-
- 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) != 1) {
- msg("invalid message");
- tcore_at_tok_free(tokens);
- return;
- }
- }
- res.result = SIM_PIN_OPERATION_SUCCESS;
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_SIM_ENABLE_FACILITY,
- sizeof(struct tresp_sim_enable_facility), &res);
- }
- tcore_at_tok_free(tokens);
- } else {
- dbg("RESPONSE NOK");
- queue = tcore_object_ref_user_data(co_sim);
- ur = tcore_user_request_ref(ur);
- _get_retry_count(co_sim, ur);
- }
- dbg(" Function exit");
-}
-
-static void on_response_disable_facility(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- struct tresp_sim_disable_facility res;
- GQueue *queue;
- const char *line;
-
- dbg(" Function entry ");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(p);
-
- memset(&res, 0, sizeof(struct tresp_sim_disable_facility));
-
- res.result = SIM_PIN_OPERATION_SUCCESS;
- res.type = _sim_get_current_pin_facility(sp->current_sec_op);
-
- 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) != 1) {
- msg("invalid message");
- tcore_at_tok_free(tokens);
- return;
- }
- }
- res.result = SIM_PIN_OPERATION_SUCCESS;
- if (ur) {
- tcore_user_request_send_response(ur, TRESP_SIM_DISABLE_FACILITY,
- sizeof(struct tresp_sim_disable_facility), &res);
- }
- tcore_at_tok_free(tokens);
- } else {
- dbg("RESPONSE NOK");
- queue = tcore_object_ref_user_data(co_sim);
- ur = tcore_user_request_ref(ur);
- _get_retry_count(co_sim, ur);
- }
- dbg(" Function exit");
-}
-
-static void on_response_get_lock_info(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- const char *line;
- struct tresp_sim_verify_pins v_pin = {0, };
- struct tresp_sim_verify_puks v_puk = {0, };
- struct tresp_sim_change_pins change_pin = {0, };
- struct tresp_sim_disable_facility dis_facility = {0, };
- struct tresp_sim_enable_facility en_facility = {0, };
- int lock_type;
- int attempts_left = 0;
- int time_penalty = 0;
-
- dbg(" Function entry ");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(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) != 3) {
- msg("invalid message");
- tcore_at_tok_free(tokens);
- return;
- }
- }
- lock_type = atoi(g_slist_nth_data(tokens, 0));
- attempts_left = atoi(g_slist_nth_data(tokens, 1));
- time_penalty = atoi(g_slist_nth_data(tokens, 2));
-
- switch (sp->current_sec_op) {
- case SEC_PIN1_VERIFY:
- case SEC_PIN2_VERIFY:
- case SEC_SIM_VERIFY:
- case SEC_ADM_VERIFY:
- v_pin.result = SIM_INCORRECT_PASSWORD;
- v_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- v_pin.retry_count = attempts_left;
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_verify_pins), &v_pin);
- break;
-
- case SEC_PUK1_VERIFY:
- case SEC_PUK2_VERIFY:
- v_puk.result = SIM_INCORRECT_PASSWORD;
- v_puk.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- v_puk.retry_count = attempts_left;
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_verify_puks), &v_puk);
- break;
-
- case SEC_PIN1_CHANGE:
- case SEC_PIN2_CHANGE:
- change_pin.result = SIM_INCORRECT_PASSWORD;
- change_pin.pin_type = _sim_get_current_pin_facility(sp->current_sec_op);
- change_pin.retry_count = attempts_left;
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_change_pins), &change_pin);
- break;
-
- case SEC_PIN1_DISABLE:
- case SEC_PIN2_DISABLE:
- case SEC_FDN_DISABLE:
- case SEC_SIM_DISABLE:
- case SEC_NET_DISABLE:
- case SEC_NS_DISABLE:
- case SEC_SP_DISABLE:
- case SEC_CP_DISABLE:
- dis_facility.result = SIM_INCORRECT_PASSWORD;
- dis_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
- dis_facility.retry_count = attempts_left;
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_disable_facility), &dis_facility);
- break;
-
- case SEC_PIN1_ENABLE:
- case SEC_PIN2_ENABLE:
- case SEC_FDN_ENABLE:
- case SEC_SIM_ENABLE:
- case SEC_NET_ENABLE:
- case SEC_NS_ENABLE:
- case SEC_SP_ENABLE:
- case SEC_CP_ENABLE:
- en_facility.result = SIM_INCORRECT_PASSWORD;
- en_facility.type = _sim_get_current_pin_facility(sp->current_sec_op);
- en_facility.retry_count = attempts_left;
- tcore_user_request_send_response(ur, _find_resp_command(ur),
- sizeof(struct tresp_sim_enable_facility), &en_facility);
- break;
-
- default:
- dbg("not handled sec op[%d]", sp->current_sec_op);
- break;
- }
- tcore_at_tok_free(tokens);
- }
- dbg(" Function exit");
-}
-
-static void on_response_update_file(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct tresp_sim_set_callforwarding resp_cf = {0, };
- struct tresp_sim_set_language resp_language = {0, };
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- enum tel_sim_access_result result;
- const char *line;
- int sw1 = 0;
- int sw2 = 0;
-
- dbg(" Function entry ");
-
- co_sim = tcore_pending_ref_core_object(p);
- ur = tcore_pending_ref_user_request(p);
- sp = (struct s_sim_property *) tcore_user_request_ref_metainfo(ur, NULL);
-
- 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));
-
- if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
- result = SIM_ACCESS_SUCCESS;
- } else {
- result = _decode_status_word(sw1, sw2);
- }
- } else {
- dbg("RESPONSE NOK");
- result = SIM_ACCESS_FAILED;
- }
-
- switch (sp->file_id) {
- case SIM_EF_CPHS_CALL_FORWARD_FLAGS:
- case SIM_EF_USIM_CFIS:
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_set_callforwarding), &resp_cf);
- break;
-
- case SIM_EF_ELP:
- case SIM_EF_LP:
- case SIM_EF_USIM_LI:
- case SIM_EF_USIM_PL:
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_set_language), &resp_language);
- break;
-
- default:
- dbg("Invalid File ID - %d", sp->file_id)
- break;
- }
- tcore_at_tok_free(tokens);
- dbg(" Function exit");
-}
-
-static void on_response_transmit_apdu(TcorePending *p, int data_len, const void *data, void *user_data)
-{
- const TcoreATResponse *resp = data;
- UserRequest *ur = NULL;
- CoreObject *co_sim = NULL;
- struct s_sim_property *sp = NULL;
- GSList *tokens = NULL;
- struct tresp_sim_transmit_apdu res;
- const char *line;
-
- dbg(" Function entry ");
-
- co_sim = tcore_pending_ref_core_object(p);
- sp = tcore_sim_ref_userdata(co_sim);
- ur = tcore_pending_ref_user_request(p);
-
- memset(&res, 0, sizeof(struct tresp_sim_transmit_apdu));
-
- if (resp->success > 0) {
- dbg("RESPONSE OK");
- res.result = SIM_ACCESS_SUCCESS;
- 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;
- }
- }
- res.apdu_resp_length = atoi(g_slist_nth_data(tokens, 0));
- strncpy((char *) res.apdu_resp, (const char *) g_slist_nth_data(tokens, 1), res.apdu_resp_length);
- } else {
- dbg("RESPONSE NOK");
- res.result = SIM_ACCESS_FAILED;
- }
- ur = tcore_pending_ref_user_request(p);
- if (ur) {
- tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_sim_transmit_apdu), &res);
- }
- tcore_at_tok_free(tokens);
- dbg(" Function exit");
-}
-
-static TReturn s_verify_pins(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sim_verify_pins *req_data = NULL;
- struct s_sim_property *sp = NULL;
-
- dbg(" Function entry ");
-
- hal = tcore_object_get_hal(o);
- sp = tcore_sim_ref_userdata(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- if (req_data->pin_type == SIM_PTYPE_PIN1) {
- sp->current_sec_op = SEC_PIN1_VERIFY;
- cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
- } else if (req_data->pin_type == SIM_PTYPE_PIN2) {
- sp->current_sec_op = SEC_PIN2_VERIFY;
- cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", req_data->pin);
- } else if (req_data->pin_type == SIM_PTYPE_SIM) {
- sp->current_sec_op = SEC_SIM_VERIFY;
- cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
- } else if (req_data->pin_type == SIM_PTYPE_ADM) {
- sp->current_sec_op = SEC_ADM_VERIFY;
- cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", req_data->pin);
- } else {
- return TCORE_RETURN_EINVAL;
- }
-
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_verify_pins, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_verify_puks(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sim_verify_puks *req_data;
- struct s_sim_property *sp = NULL;
-
- dbg(" Function entry ");
-
- hal = tcore_object_get_hal(o);
- sp = tcore_sim_ref_userdata(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- if (req_data->puk_type == SIM_PTYPE_PUK1) {
- sp->current_sec_op = SEC_PUK1_VERIFY;
- cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"", req_data->puk, req_data->pin);
- } else if (req_data->puk_type == SIM_PTYPE_PUK2) {
- sp->current_sec_op = SEC_PUK2_VERIFY;
- cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"", req_data->puk, req_data->pin);
- } else {
- return TCORE_RETURN_EINVAL;
- }
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_verify_puks, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_change_pins(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sim_change_pins *req_data;
- struct s_sim_property *sp = NULL;
- char *pin1 = "SC";
- char *pin2 = "P2";
-
- dbg(" Function entry ");
-
- hal = tcore_object_get_hal(o);
- sp = tcore_sim_ref_userdata(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- if (req_data->type == SIM_PTYPE_PIN1) {
- sp->current_sec_op = SEC_PIN1_CHANGE;
- cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin1, req_data->old_pin, req_data->new_pin);
- } else if (req_data->type == SIM_PTYPE_PIN2) {
- sp->current_sec_op = SEC_PIN2_CHANGE;
- cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"", pin2, req_data->old_pin, req_data->new_pin);
- } else {
- return TCORE_RETURN_EINVAL;
- }
- req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_change_pins, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sim_get_facility_status *req_data;
- struct s_sim_property *sp = NULL;
- char *fac = "SC";
- int mode = 2; /* 0:unlock, 1:lock, 2:query*/
-
- dbg(" Function entry ");
-
- hal = tcore_object_get_hal(o);
- sp = tcore_sim_ref_userdata(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- if (req_data->type == SIM_FACILITY_PS) {
- fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
- } else if (req_data->type == SIM_FACILITY_SC) {
- fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
- } else if (req_data->type == SIM_FACILITY_FD) {
- fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
- } else if (req_data->type == SIM_FACILITY_PN) {
- fac = "PN"; /*Network Personalization*/
- } else if (req_data->type == SIM_FACILITY_PU) {
- fac = "PU"; /*network sUbset Personalization*/
- } else if (req_data->type == SIM_FACILITY_PP) {
- fac = "PP"; /*service Provider Personalization*/
- } else if (req_data->type == SIM_FACILITY_PC) {
- fac = "PC"; /*Corporate Personalization*/
- } else {
- return TCORE_RETURN_EINVAL;
- }
- cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
- req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_get_facility_status, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_enable_facility(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sim_enable_facility *req_data;
- struct s_sim_property *sp = NULL;
- char *fac = "SC";
- int mode = 1; /* 0:unlock, 1:lock, 2:query*/
-
- dbg(" Function entry ");
-
- hal = tcore_object_get_hal(o);
- sp = tcore_sim_ref_userdata(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- if (req_data->type == SIM_FACILITY_PS) {
- fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
- sp->current_sec_op = SEC_SIM_ENABLE;
- } else if (req_data->type == SIM_FACILITY_SC) {
- fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
- sp->current_sec_op = SEC_PIN1_ENABLE;
- } else if (req_data->type == SIM_FACILITY_FD) {
- fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
- sp->current_sec_op = SEC_FDN_ENABLE;
- } else if (req_data->type == SIM_FACILITY_PN) {
- fac = "PN"; /*Network Personalization*/
- sp->current_sec_op = SEC_NET_ENABLE;
- } else if (req_data->type == SIM_FACILITY_PU) {
- fac = "PU"; /*network sUbset Personalization*/
- sp->current_sec_op = SEC_NS_ENABLE;
- } else if (req_data->type == SIM_FACILITY_PP) {
- fac = "PP"; /*service Provider Personalization*/
- sp->current_sec_op = SEC_SP_ENABLE;
- } else if (req_data->type == SIM_FACILITY_PC) {
- fac = "PC"; /*Corporate Personalization*/
- sp->current_sec_op = SEC_CP_ENABLE;
- } else {
- return TCORE_RETURN_EINVAL;
- }
- cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
- req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_enable_facility, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_disable_facility(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- const struct treq_sim_enable_facility *req_data;
- struct s_sim_property *sp = NULL;
- char *fac = "SC";
- int mode = 0; /* 0:unlock, 1:lock, 2:query*/
-
- dbg(" Function entry ");
-
- hal = tcore_object_get_hal(o);
- sp = tcore_sim_ref_userdata(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- if (req_data->type == SIM_FACILITY_PS) {
- fac = "PS"; /*PH-SIM, Lock PHone to SIM/UICC card*/
- sp->current_sec_op = SEC_SIM_DISABLE;
- } else if (req_data->type == SIM_FACILITY_SC) {
- fac = "SC"; /*Lock SIM/UICC card, simply PIN1*/
- sp->current_sec_op = SEC_PIN1_DISABLE;
- } else if (req_data->type == SIM_FACILITY_FD) {
- fac = "FD"; /*Fixed Dialing Number feature, need PIN2*/
- sp->current_sec_op = SEC_FDN_DISABLE;
- } else if (req_data->type == SIM_FACILITY_PN) {
- fac = "PN"; /*Network Personalization*/
- sp->current_sec_op = SEC_NET_DISABLE;
- } else if (req_data->type == SIM_FACILITY_PU) {
- fac = "PU"; /*network sUbset Personalization*/
- sp->current_sec_op = SEC_NS_DISABLE;
- } else if (req_data->type == SIM_FACILITY_PP) {
- fac = "PP"; /*service Provider Personalization*/
- sp->current_sec_op = SEC_SP_DISABLE;
- } else if (req_data->type == SIM_FACILITY_PC) {
- fac = "PC"; /*Corporate Personalization*/
- sp->current_sec_op = SEC_CP_DISABLE;
- } else {
- return TCORE_RETURN_EINVAL;
- }
- cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"", fac, mode, req_data->password);
- req = tcore_at_request_new(cmd_str, "+CLCK:", TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_disable_facility, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_get_lock_info(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- char *lock_type = NULL;
- const struct treq_sim_get_lock_info *req_data;
- struct s_sim_property *sp = NULL;
-
- dbg(" Function entry ");
-
- hal = tcore_object_get_hal(o);
- sp = tcore_sim_ref_userdata(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- switch (req_data->type) {
- case SIM_FACILITY_PS:
- lock_type = "PS";
- break;
-
- case SIM_FACILITY_SC:
- lock_type = "SC";
- break;
-
- case SIM_FACILITY_FD:
- lock_type = "FD";
- break;
-
- case SIM_FACILITY_PN:
- lock_type = "PN";
- break;
-
- case SIM_FACILITY_PU:
- lock_type = "PU";
- break;
-
- case SIM_FACILITY_PP:
- lock_type = "PP";
- break;
-
- case SIM_FACILITY_PC:
- lock_type = "PC";
- break;
-
- default:
- break;
- }
- cmd_str = g_strdup_printf("AT+XPINCNT =\"%s\"", lock_type);
- req = tcore_at_request_new(cmd_str, "+XPINCNT:", TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_get_lock_info, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_read_file(CoreObject *o, UserRequest *ur)
-{
- TReturn api_ret = TCORE_RETURN_SUCCESS;
- enum tcore_request_command command;
-
- command = tcore_user_request_get_command(ur);
-
- dbg(" Function entry ");
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- switch (command) {
- case TREQ_SIM_GET_ECC:
- api_ret = _get_file_info(o, ur, SIM_EF_ECC);
- break;
-
- case TREQ_SIM_GET_LANGUAGE:
- if (tcore_sim_get_type(o) == SIM_TYPE_GSM)
- api_ret = _get_file_info(o, ur, SIM_EF_ELP);
- else if (tcore_sim_get_type(o) == SIM_TYPE_USIM)
- api_ret = _get_file_info(o, ur, SIM_EF_LP);
- else
- api_ret = TCORE_RETURN_ENOSYS;
- break;
-
- case TREQ_SIM_GET_ICCID:
- api_ret = _get_file_info(o, ur, SIM_EF_ICCID);
- break;
-
- case TREQ_SIM_GET_MAILBOX:
- if (tcore_sim_get_cphs_status(o))
- api_ret = _get_file_info(o, ur, SIM_EF_CPHS_MAILBOX_NUMBERS);
- else
- api_ret = _get_file_info(o, ur, SIM_EF_MBDN);
- break;
-
- case TREQ_SIM_GET_CALLFORWARDING:
- if (tcore_sim_get_cphs_status(o))
- api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CALL_FORWARD_FLAGS);
- else
- api_ret = _get_file_info(o, ur, SIM_EF_USIM_CFIS);
- break;
-
- case TREQ_SIM_GET_MESSAGEWAITING:
- if (tcore_sim_get_cphs_status(o))
- api_ret = _get_file_info(o, ur, SIM_EF_CPHS_VOICE_MSG_WAITING);
- else
- api_ret = _get_file_info(o, ur, SIM_EF_USIM_MWIS);
- break;
-
- case TREQ_SIM_GET_CPHS_INFO:
- api_ret = _get_file_info(o, ur, SIM_EF_CPHS_CPHS_INFO);
- break;
-
- case TREQ_SIM_GET_MSISDN:
- api_ret = _get_file_info(o, ur, SIM_EF_MSISDN);
- break;
-
- case TREQ_SIM_GET_SPN:
- dbg("enter case SPN");
- api_ret = _get_file_info(o, ur, SIM_EF_SPN);
- break;
-
- case TREQ_SIM_GET_SPDI:
- api_ret = _get_file_info(o, ur, SIM_EF_SPDI);
- break;
-
- case TREQ_SIM_GET_OPL:
- api_ret = _get_file_info(o, ur, SIM_EF_OPL);
- break;
-
- case TREQ_SIM_GET_PNN:
- api_ret = _get_file_info(o, ur, SIM_EF_PNN);
- break;
-
- case TREQ_SIM_GET_CPHS_NETNAME:
- api_ret = _get_file_info(o, ur, SIM_EF_CPHS_OPERATOR_NAME_STRING);
- break;
-
- case TREQ_SIM_GET_OPLMNWACT:
- api_ret = _get_file_info(o, ur, SIM_EF_OPLMN_ACT);
- break;
-
- default:
- dbg("error - not handled read treq command[%d]", command);
- api_ret = TCORE_RETURN_EINVAL;
- break;
- }
- dbg(" Function exit");
- return api_ret;
-}
-
-static TReturn s_update_file(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal;
- TcoreATRequest *req;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- TReturn api_ret = TCORE_RETURN_SUCCESS;
- char *encoded_data = NULL;
- int encoded_len = 0;
- enum tcore_request_command command;
- enum tel_sim_file_id ef = SIM_EF_INVALID;
- const struct treq_sim_set_callforwarding *cf;
- const struct treq_sim_set_language *cl;
- struct s_sim_property file_meta = {0, };
- int p1 = 0;
- int p2 = 0;
- int p3 = 0;
- int cmd = 0;
- int out_length = 0;
- int trt = 0;
- struct tel_sim_language sim_language;
- char *tmp = NULL;
- gboolean result;
-
- command = tcore_user_request_get_command(ur);
-
- dbg(" Function entry ");
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
-
- if (!o || !ur) {
- return TCORE_RETURN_EINVAL;
- }
-
- switch (command) {
- case TREQ_SIM_SET_LANGUAGE:
- cl = tcore_user_request_ref_data(ur, NULL);
- memset(&sim_language, 0x00, sizeof(struct tel_sim_language));
- cmd = 214;
-
- sim_language.language_count = 1;
- sim_language.language[0] = cl->language;
- dbg("language %d", cl->language);
-
- if (tcore_sim_get_type(o) == SIM_TYPE_GSM) {
- dbg("2G");
- ef = SIM_EF_LP;
- tmp = tcore_sim_encode_lp(&out_length, &sim_language);
-
- encoded_data = (char *) malloc(2 * (sim_language.language_count) + 1);
- memset(encoded_data, 0x00, (2 * sim_language.language_count) + 1);
- result = util_byte_to_hex(tmp, encoded_data, out_length);
-
- p1 = 0;
- p2 = 0;
- p3 = out_length;
- dbg("encoded_data - %s ---", encoded_data);
- dbg("out_length - %d ---", out_length);
- } else if (tcore_sim_get_type(o) == SIM_TYPE_USIM) {
- dbg("3G");
- ef = SIM_EF_LP;
- tmp = tcore_sim_encode_li(&out_length, &sim_language);
-
- encoded_data = (char *) malloc(2 * (out_length) + 1);
- memset(encoded_data, 0x00, (2 * out_length) + 1);
- result = util_byte_to_hex(tmp, encoded_data, out_length);
-
- p1 = 0;
- p2 = 0;
- p3 = out_length;
- dbg("encoded_data - %s ---", encoded_data);
- dbg("out_length - %d ---", out_length);
- } else {
- api_ret = TCORE_RETURN_ENOSYS;
- }
- break;
-
- case TREQ_SIM_SET_CALLFORWARDING:
- cf = tcore_user_request_ref_data(ur, NULL);
- if (tcore_sim_get_cphs_status(o)) {
- tmp = tcore_sim_encode_cff((const struct tel_sim_callforwarding *) cf);
- ef = SIM_EF_CPHS_CALL_FORWARD_FLAGS;
- p1 = 0;
- p2 = 0;
- p3 = strlen(tmp);
- encoded_data = (char *) malloc(2 * (p3) + 1);
- memset(encoded_data, 0x00, (2 *p3) + 1);
- result = util_byte_to_hex(tmp, encoded_data, p3);
- cmd = 214; /*command - 214 : UPDATE BINARY*/
- } else {
- tmp = tcore_sim_encode_cfis(&encoded_len, (const struct tel_sim_callforwarding *) cf);
- ef = SIM_EF_USIM_CFIS;
- p1 = 1;
- p2 = 0x04;
- p3 = encoded_len;
- encoded_data = (char *) malloc(2 * (encoded_len) + 1);
- memset(encoded_data, 0x00, (2 * encoded_len) + 1);
- result = util_byte_to_hex(tmp, encoded_data, encoded_len);
- cmd = 220; /*command - 220 : UPDATE RECORD*/
- }
- break;
-
- default:
- dbg("error - not handled update treq command[%d]", command);
- api_ret = TCORE_RETURN_EINVAL;
- break;
- }
- file_meta.file_id = ef;
- dbg("file_meta.file_id: %d", file_meta.file_id);
-
- trt = tcore_user_request_set_metainfo(ur, sizeof(struct s_sim_property), &file_meta);
- dbg("trt[%d]", trt);
-
- cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"", cmd, ef, p1, p2, p3, encoded_data);
- req = tcore_at_request_new(cmd_str, "+CRSM:", TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_update_file, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
-
- tcore_hal_send_request(hal, pending);
- if (NULL != encoded_data) {
- g_free(encoded_data);
- }
- free(cmd_str);
-
- if (tmp) {
- free(tmp);
- }
-
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static TReturn s_transmit_apdu(CoreObject *o, UserRequest *ur)
-{
- TcoreHal *hal = NULL;
- TcoreATRequest *req = NULL;
- TcorePending *pending = NULL;
- char *cmd_str = NULL;
- char *apdu = NULL;
- int result = 0;
- const struct treq_sim_transmit_apdu *req_data;
-
- dbg(" Function entry ");
-
- hal = tcore_object_get_hal(o);
- pending = tcore_pending_new(o, 0);
- req_data = tcore_user_request_ref_data(ur, NULL);
-
- if (!o || !ur)
- return TCORE_RETURN_EINVAL;
-
- apdu = (char *) malloc((2 * req_data->apdu_length) + 1);
- memset(apdu, 0x00, (2 * req_data->apdu_length) + 1);
- result = util_byte_to_hex((const char *) req_data->apdu, apdu, req_data->apdu_length);
-
- cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", req_data->apdu_length * 2, apdu);
-
- req = tcore_at_request_new(cmd_str, "+CSIM:", TCORE_AT_SINGLELINE);
-
- dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
-
- tcore_pending_set_request_data(pending, 0, req);
- tcore_pending_set_response_callback(pending, on_response_transmit_apdu, hal);
- tcore_pending_link_user_request(pending, ur);
- tcore_pending_set_send_callback(pending, on_confirmation_sim_message_send, NULL);
- tcore_hal_send_request(hal, pending);
-
- free(cmd_str);
- free(apdu);
- dbg(" Function exit");
- return TCORE_RETURN_SUCCESS;
-}
-
-static struct tcore_sim_operations sim_ops = {
- .verify_pins = s_verify_pins,
- .verify_puks = s_verify_puks,
- .change_pins = s_change_pins,
- .get_facility_status = s_get_facility_status,
- .enable_facility = s_enable_facility,
- .disable_facility = s_disable_facility,
- .get_lock_info = s_get_lock_info,
- .read_file = s_read_file,
- .update_file = s_update_file,
- .transmit_apdu = s_transmit_apdu,
- /*ToDo - Need to be implemented in Phase-2*/
- /*.get_atr = s_get_atr,
- .req_authentication = s_req_authentication*/
-};
-
-gboolean s_sim_init(TcorePlugin *p, TcoreHal *h)
-{
- CoreObject *o;
- struct s_sim_property *file_meta = NULL;
- GQueue *work_queue;
-
- dbg("entry");
-
- o = tcore_sim_new(p, "sim", &sim_ops, h);
-
- if (!o)
- return FALSE;
-
- file_meta = calloc(sizeof(struct s_sim_property), 1);
- if (!file_meta)
- return FALSE;
-
- work_queue = g_queue_new();
- tcore_object_link_user_data(o, work_queue);
-
- file_meta->first_recv_status = SIM_STATUS_UNKNOWN;
- tcore_sim_link_userdata(o, file_meta);
-
- tcore_object_add_callback(o, "+XLOCK", on_event_facility_lock_status, NULL);
- tcore_object_add_callback(o, "+XSIM", on_event_pin_status, NULL);
-
- dbg("exit");
- return TRUE;
-}
-
-void s_sim_exit(TcorePlugin *p)
-{
- CoreObject *o;
-
- o = tcore_plugin_ref_core_object(p, "sim");
- if (!o)
- return;
- tcore_sim_free(o);
-}
<manifest>
<request>
- <domain name="_"/>
+ <domain name="telephony_framework"/>
+ </request>
+ <assign>
+ <filesystem path="/usr/lib/telephony/plugins/imc-plugin.so" label="telephony_framework"/>
+ </assign>
+ <request>
+ <domain name="telephony_framework"/>
</request>
</manifest>