--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(imc-plugin C)
+
+#INCLUDE(FindPkgConfig)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(INCLUDEDIR "\${prefix}/include")
+
+# Set required packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED glib-2.0 tcore dlog db-util)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include/)
+
+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("-DTCORE_LOG_TAG=\"TEL_PLUGIN_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/s_phonebook.c
+ src/s_sap.c
+)
+
+
+
+# library build
+ADD_LIBRARY(imc-plugin SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(imc-plugin ${pkgs_LDFLAGS})
+SET_TARGET_PROPERTIES(imc-plugin PROPERTIES PREFIX "" OUTPUT_NAME imc-plugin)
+
+
+# install
+INSTALL(TARGETS imc-plugin
+ LIBRARY DESTINATION lib/telephony/plugins)
+
+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
+TARGET = imc-plugin.so
+
+SRCS = desc.c s_hal.c s_phonet.c s_rfs.c s_nvdata.c s_dispatch.c s_common.c \
+ s_network.c \
+ s_sim.c
+OBJS = $(SRCS:.c=.o)
+PKGS = glib-2.0 lcm tapi tcore
+
+CC = gcc
+CFLAGS = -Wall -g -fPIC `pkg-config --cflags $(PKGS)` -I.
+LIBS = -rdynamic -fPIC -ldl \
+ `pkg-config --libs $(PKGS)`
+
+
+all: $(TARGET)
+
+$(TARGET): $(OBJS)
+ $(CC) $^ $(LIBS) -shared -o $(TARGET)
+
+.c.o: $(SRCS)
+ $(CC) $(CFLAGS) -c $^ -o $@
+
+clean:
+ rm -f $(OBJS) $(TARGET)
--- /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 the Apache License, Version 2.0 (the "License");
+You may obtain a copy of the License at
+http://www.apache.org/licenses/LICENSE-2.0.
--- /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
--- /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.
+ */
+
+/**
+ * @open
+ * @ingroup TelephonyAPI
+ * @addtogroup COMMON_TAPI COMMON
+ * @{
+ * These error codes are used by Applications.
+ */
+
+
+#ifndef _TEL_ERR_H_
+#define _TEL_ERR_H_
+/*==================================================================================================
+ INCLUDE FILES
+==================================================================================================*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*==================================================================================================
+ CONSTANTS
+==================================================================================================*/
+
+
+/*==================================================================================================
+ MACROS
+==================================================================================================*/
+
+
+/*==================================================================================================
+ ENUMS
+==================================================================================================*/
+
+/************************************************************
+** Errors defined in "+CME ERROR" ,
+** - see 3GPP TS 27.007
+** - ranges are 0x00 ~ 0x7FFF
+************************************************************/
+/**
+ Error codes sent by the modem in response to the above operations.
+*/
+typedef enum {
+ /* GENERAL ERRORS */
+ TAPI_OP_GEN_ERR_PHONE_FAILURE = 0, /* 0 */
+ TAPI_OP_GEN_ERR_NO_CONNECTION_TO_PHONE, /* 1 */
+ TAPI_OP_GEN_ERR_PHONE_ADAPTOR_LINK_RESERVED, /* 2 */
+ TAPI_OP_GEN_ERR_OPER_NOT_ALLOWED, /* 3 */
+ TAPI_OP_GEN_ERR_OPER_NOT_SUPPORTED, /* 4 */
+ TAPI_OP_GEN_ERR_PH_SIM_PIN_REQU, /* 5 */
+ TAPI_OP_GEN_ERR_PH_FSIM_PIN_REQU, /* 6 */
+ TAPI_OP_GEN_ERR_PH_FSIM_PUK_REQU, /* 7 */
+ TAPI_OP_GEN_ERR_SIM_NOT_INSERTED = 10, /* 10 */
+ TAPI_OP_GEN_ERR_SIM_PIN_REQU, /* 11 */
+ TAPI_OP_GEN_ERR_SIM_PUK_REQU, /* 12 */
+ TAPI_OP_GEN_ERR_SIM_FAILURE, /* 13 */
+ TAPI_OP_GEN_ERR_SIM_BUSY, /* 14 */
+ TAPI_OP_GEN_ERR_SIM_WRONG, /* 15 */
+ TAPI_OP_GEN_ERR_INCORRECT_PW, /* 16 */
+ TAPI_OP_GEN_ERR_SIM_PIN2_REQU, /* 17 */
+ TAPI_OP_GEN_ERR_SIM_PUK2_REQU, /* 18 */
+ TAPI_OP_GEN_ERR_MEM_FULL = 20, /* 20 */
+ TAPI_OP_GEN_ERR_INVALID_INDEX, /* 21 */
+ TAPI_OP_GEN_ERR_NOT_FOUND, /* 22 */
+ TAPI_OP_GEN_ERR_MEM_FAILURE, /* 23 */
+ TAPI_OP_GEN_ERR_TEXT_STR_TOO_LONG, /* 24 */
+ TAPI_OP_GEN_ERR_INVALID_CHARACTERS_IN_TEXT_STR, /* 25 */
+ TAPI_OP_GEN_ERR_DIAL_STR_TOO_LONG, /* 26 */
+ TAPI_OP_GEN_ERR_INVALID_CHARACTERS_IN_DIAL_STR, /* 27 */
+ TAPI_OP_GEN_ERR_NO_NET_SVC = 30, /* 30 */
+ TAPI_OP_GEN_ERR_NET_TIMEOUT, /* 31 */
+ TAPI_OP_GEN_ERR_NET_NOT_ALLOWED_EMERGENCY_CALLS_ONLY, /* 32 */
+ TAPI_OP_GEN_ERR_NET_PERS_PIN_REQU = 40, /* 40 */
+ TAPI_OP_GEN_ERR_NET_PERS_PUK_REQU, /* 41 */
+ TAPI_OP_GEN_ERR_NET_SUBSET_PERS_PIN_REQU, /* 42 */
+ TAPI_OP_GEN_ERR_NET_SUBSET_PERS_PUK_REQU, /* 43 */
+ TAPI_OP_GEN_ERR_SVC_PROVIDER_PERS_PIN_REQU, /* 44 */
+ TAPI_OP_GEN_ERR_SVC_PROVIDER_PERS_PUK_REQU, /* 45 */
+ TAPI_OP_GEN_ERR_CORPORATE_PERS_PIN_REQU, /* 46 */
+ TAPI_OP_GEN_ERR_CORPORATE_PERS_PUK_REQU, /* 47 */
+ TAPI_OP_GEN_ERR_HIDDEN_KEY_REQU, /* 48 */
+ TAPI_OP_GEN_ERR_UNKNOWN = 100, /* 100 */
+
+ /* Errors related to a failure to perform an Attach */
+ TAPI_OP_GEN_ERR_ILLEGAL_MS = 103, /* 103 */
+ TAPI_OP_GEN_ERR_ILLEGAL_ME = 106, /* 106 */
+ TAPI_OP_GEN_ERR_GPRS_SVC_NOT_ALLOWED, /* 107 */
+ TAPI_OP_GEN_ERR_PLMN_NOT_ALLOWED = 111, /* 111 */
+ TAPI_OP_GEN_ERR_LOCATION_AREA_NOT_ALLOWED, /* 112 */
+ TAPI_OP_GEN_ERR_ROAMING_NOT_ALLOWED_IN_THIS_LOCATION_AREA, /* 113 */
+
+ /* Errors related to a failure to Activate a Context */
+ TAPI_OP_GEN_ERR_SVC_OPT_NOT_SUPPORTED = 132, /* 132 */
+ TAPI_OP_GEN_ERR_REQ_SVC_OPT_NOT_SUBSCRIBED, /* 133 */
+ TAPI_OP_GEN_ERR_SVC_OPT_TEMPORARILY_OUT_OF_ORDER, /* 134 */
+ TAPI_OP_GEN_ERR_UNSPECIFIED_GPRS_ERR = 148, /* 148 */
+ TAPI_OP_GEN_ERR_PDP_AUTHENTICATION_FAILURE, /* 149 */
+ TAPI_OP_GEN_ERR_INVALID_MOBILE_CLASS, /* 150 */
+
+ /* VBS / VGCS and eMLPP -related errors */
+ TAPI_OP_GEN_ERR_VBS_VGCS_NOT_SUPPORTED_BY_THE_NET = 151, /* 151 */
+ TAPI_OP_GEN_ERR_NO_SVC_SUBSCRIPTION_ON_SIM, /* 152 */
+ TAPI_OP_GEN_ERR_NO_SUBSCRIPTION_FOR_GROUP_ID, /* 153 */
+ TAPI_OP_GEN_ERR_GROUP_ID_NOT_ACTIVATED_ON_SIM, /* 154 */
+ TAPI_OP_GEN_ERR_NO_MATCHING_NOTI = 155, /* 155 */
+ TAPI_OP_GEN_ERR_VBS_VGCS_CALL_ALREADY_PRESENT, /* 156 */
+ TAPI_OP_GEN_ERR_CONGESTION, /* 157 */
+ TAPI_OP_GEN_ERR_NET_FAILURE, /* 158 */
+ TAPI_OP_GEN_ERR_UPLINK_BUSY, /* 159 */
+ TAPI_OP_GEN_ERR_NO_ACCESS_RIGHTS_FOR_SIM_FILE = 160, /* 160 */
+ TAPI_OP_GEN_ERR_NO_SUBSCRIPTION_FOR_PRIORITY, /* 161 */
+ TAPI_OP_GEN_ERR_OPER_NOT_APPLICABLE_OR_NOT_POSSIBLE, /* 162 */
+
+
+ /************************************************************
+ ** SAMSUNG ADDED ERRORS
+ ************************************************************/
+ TAPI_OP_GEN_ERR_NONE = 0x8000, /* 0x8000 : No Errors */
+
+ /* General Common Errors : 0x8000 - 0x80FF */
+ TAPI_OP_GEN_ERR_INVALID_FORMAT, /* 0x8001 : Invalid Parameter or Format */
+ TAPI_OP_GEN_ERR_PHONE_OFFLINE, /* 0x8002 : */
+ TAPI_OP_GEN_ERR_CMD_NOT_ALLOWED, /* 0x8003 : */
+ TAPI_OP_GEN_ERR_PHONE_IS_INUSE, /* 0x8004 : */
+ TAPI_OP_GEN_ERR_INVALID_STATE = 0x8005, /* 0x8005 : */
+
+ TAPI_OP_GEN_ERR_NO_BUFFER, /* 0x8006 : No internal free buffers */
+ TAPI_OP_GEN_ERR_OPER_REJ, /* 0x8007 : Operation Rejected */
+ TAPI_OP_GEN_ERR_INSUFFICIENT_RESOURCE, /* 0x8008 : insufficient resource */
+ TAPI_OP_GEN_ERR_NET_NOT_RESPOND, /* 0x8009 : Network not responding */
+ TAPI_OP_GEN_ERR_SIM_PIN_ENABLE_REQ = 0x800A, /* 0x800A : SIM Pin Enable Required */
+ TAPI_OP_GEN_ERR_SIM_PERM_BLOCKED, /* 0x800B : SIM Permanent Blocked */
+ TAPI_OP_GEN_ERR_SIM_PHONEBOOK_RESTRICTED, /*0x800C: SIM Phonebook Restricted*/
+ TAPI_OP_GEM_ERR_FIXED_DIALING_NUMBER_ONLY, /*0x800D: Restricted By FDN Mode */
+
+ /* Reserved : 0x800E ~ 0x80FF */
+ TAPI_OP_GEN_ERR_800E_RESERVED_START = 0x800E, /* 0x800E */
+
+ TAPI_OP_GEN_ERR_80FF_RESERVED_END = 0x80ff, /* 0x80FF */
+
+ /* the other errors */
+ TAPI_OP_GEN_ERR_OTHERS = 0xFFFE, /* 0xFFFE */
+
+ TAPI_OP_GEN_ERR_MAX = 0xFFFF
+} tapi_phone_err_t;
+
+
+/*==================================================================================================
+ STRUCTURES AND OTHER TYPEDEFS
+==================================================================================================*/
+
+
+/*==================================================================================================
+ FUNCTION PROTOTYPES
+==================================================================================================*/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _TEL_ERR_H_
+
+/**
+* @}
+*/
--- /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.
+ */
+
+#ifndef __S_CALL_H__
+#define __S_CALL_H__
+
+gboolean s_call_init(TcorePlugin *p, TcoreHal *h);
+void s_call_exit(TcorePlugin *p);
+
+#endif
--- /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
--- /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.
+ */
+
+#ifndef __S_GPS_H__
+#define __S_GPS_H__
+
+gboolean s_gps_init(TcorePlugin *p, TcoreHal *h);
+void s_gps_exit(TcorePlugin *p);
+
+#endif
--- /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_MODEM_H__
+#define __S_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);
+
+#endif
--- /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.
+ */
+
+#ifndef __S_NETWORK_H__
+#define __S_NETWORK_H__
+
+gboolean s_network_init(TcorePlugin *p, TcoreHal *h);
+void s_network_exit(TcorePlugin *p);
+
+#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_PHONEBOOK_H_
+#define S_PHONEBOOK_H_
+
+gboolean s_phonebook_init(TcorePlugin *p, TcoreHal *h);
+void s_phonebook_exit(TcorePlugin *p);
+
+#endif /* S_PHONEBOOK_H_ */
--- /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.
+ */
+
+#ifndef __S_PS_H__
+#define __S_PS_H__
+
+gboolean s_ps_init(TcorePlugin *p, TcoreHal *hal);
+void s_ps_exit(TcorePlugin *p);
+
+#endif /*__S_PS_H__*/
--- /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_SAP_H_
+#define S_SAP_H_
+
+gboolean s_sap_init(TcorePlugin *p, TcoreHal *h);
+void s_sap_exit(TcorePlugin *p);
+
+#endif /* S_SAP_H_ */
--- /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.
+ */
+
+
+#ifndef S_SAT_H_
+#define S_SAT_H_
+
+gboolean s_sat_init(TcorePlugin *p, TcoreHal *h);
+void s_sat_exit(TcorePlugin *p);
+
+#endif /* S_SAT_H_ */
--- /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.
+ */
+
+#ifndef __S_SIM_H__
+#define __S_SIM_H__
+
+gboolean s_sim_init(TcorePlugin *p, TcoreHal *h);
+void s_sim_exit(TcorePlugin *p);
+
+#endif
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Madhavi Akella <madhavi.a@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_SMS_H_
+#define S_SMS_H_
+
+gboolean s_sms_init(TcorePlugin *p, TcoreHal *h);
+void s_sms_exit(TcorePlugin *p);
+
+#endif // S_SMS_H_
--- /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.
+ */
+
+#ifndef __S_SS_H__
+#define __S_SS_H__
+
+gboolean s_ss_init(TcorePlugin *p, TcoreHal *h);
+void s_ss_exit(TcorePlugin *p);
+
+#endif
--- /dev/null
+From a748999e2015a9546f84d7169c6480ed8f6aa0ee Mon Sep 17 00:00:00 2001
+From: Philippe Nunes <philippe.nunes@linux.intel.com>
+Date: Tue, 18 Sep 2012 17:35:02 +0200
+Subject: [PATCH 01/23] desc: CP name is imc-pr3 for Intel device
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+---
+ src/desc.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/src/desc.c b/src/desc.c
+index d165ca0..7a5ef93 100644
+--- a/src/desc.c
++++ b/src/desc.c
+@@ -123,6 +123,18 @@ static int _get_cp_name(char **name)
+ uname(&u);
+
+ dbg("u.nodename : [ %s ]", u.nodename);
++ dbg("u.__domainname : [ %s ]", u.__domainname);
++ dbg("u.machine : [ %s ]", u.machine);
++ dbg("u.release : [ %s ]", u.release);
++ dbg("u.sysname : [ %s ]", u.sysname);S
++ dbg("u.version : [ %s ]", u.version);
++
++ /* By default, SUNRISE IMC modem is returned */
++ if (!strcmp(u.nodename, "(none)")) {
++ *name = g_new0(char, 8);
++ strcpy(*name, "imc-pr3");
++ return 8;
++ }
+
+ for (i = 0; svnet1_models[i]; i++) {
+ if (!strcmp(u.nodename, svnet1_models[i])) {
+--
+1.7.10.4
+
--- /dev/null
+From 389f7a04eefccdec5f2597df0d6c836a0010b268 Mon Sep 17 00:00:00 2001
+From: Philippe Nunes <philippe.nunes@linux.intel.com>
+Date: Tue, 18 Sep 2012 17:47:49 +0200
+Subject: [PATCH 02/23] s_modem: CGMR response parsing is compatible with IMC
+ PR3 modem
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+---
+ src/s_modem.c | 21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+diff --git a/src/s_modem.c b/src/s_modem.c
+index 88a06a7..edd1ca9 100644
+--- a/src/s_modem.c
++++ b/src/s_modem.c
+@@ -360,20 +360,23 @@ static void on_response_version(TcorePending *p, int data_len, const void *data,
+ if (resp->lines) {
+ line = (const char *) resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+- if (g_slist_length(tokens) != 5) {
++ 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;
+ }
+ }
+
+- 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));
+--
+1.7.10.4
+
--- /dev/null
+From 7e83caa59a5a98f169a45b58b9767fc8f65e61bf Mon Sep 17 00:00:00 2001
+From: Philippe Nunes <philippe.nunes@linux.intel.com>
+Date: Tue, 18 Sep 2012 17:45:58 +0200
+Subject: [PATCH 03/23] s-modem: Cleanup
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+Conflicts:
+ src/s_modem.c
+---
+ src/s_modem.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/s_modem.c b/src/s_modem.c
+index edd1ca9..dd8899b 100644
+--- a/src/s_modem.c
++++ b/src/s_modem.c
+@@ -250,6 +250,7 @@ static void on_response_set_flight_mode(TcorePending *p, int data_len, const voi
+ }
+ } 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);
+
+@@ -787,7 +788,7 @@ static TReturn get_imei(CoreObject *o, UserRequest *ur)
+ TcorePending *pending = NULL;
+
+ hal = tcore_object_get_hal(o);
+- if(FALSE == tcore_hal_get_power_state(hal)){
++ if (FALSE == tcore_hal_get_power_state(hal)) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+--
+1.7.10.4
+
--- /dev/null
+From 18e1f3c2d0e927ff7ff4d8e6c6dd16ba701e9523 Mon Sep 17 00:00:00 2001
+From: Philippe Nunes <philippe.nunes@linux.intel.com>
+Date: Tue, 18 Sep 2012 17:50:08 +0200
+Subject: [PATCH 04/23] s-modem: Add notification hook for SIM status
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+---
+ src/s_modem.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/src/s_modem.c b/src/s_modem.c
+index dd8899b..2c71457 100644
+--- a/src/s_modem.c
++++ b/src/s_modem.c
+@@ -465,6 +465,20 @@ OUT:
+ }
+
+
++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)
++{
++ const struct tnoti_sim_status *sim = data;
++
++ if (sim->sim_status == SIM_STATUS_INIT_COMPLETED) {
++ dbg("SIM ready for attach");
++ dbg("Enable STK and Fetching of proactive Commands");
++ prepare_and_send_pending_request(tcore_object_ref_plugin(source), "sat", "AT+CFUN=6", NULL, TCORE_AT_NO_RESULT, on_response_enable_proactive_command);
++ prepare_and_send_pending_request(tcore_object_ref_plugin(source), "umts_network", "AT+COPS=0", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
++ }
++
++ return TCORE_HOOK_RETURN_CONTINUE;
++}
+
+ gboolean on_event_modem_power(TcoreAT *at, const char *line, TcorePlugin *p)
+ {
+@@ -917,6 +931,8 @@ gboolean s_modem_init(TcorePlugin *p, TcoreHal *h)
+ dbg("Registering for +XSIM event");
+ tcore_object_add_callback(o, "+XSIM", on_event_bootup_sim_status, NULL);
+
++ tcore_server_add_notification_hook(tcore_plugin_ref_server(p), TNOTI_SIM_STATUS, on_hook_sim_status, o);
++
+ return TRUE;
+ }
+
+--
+1.7.10.4
+
--- /dev/null
+From 65c222ac5b39065cc7a26b94d2e0ba2b985c7d86 Mon Sep 17 00:00:00 2001
+From: Philippe Nunes <philippe.nunes@linux.intel.com>
+Date: Tue, 18 Sep 2012 17:53:42 +0200
+Subject: [PATCH 05/23] s-sim: Query SIM state when modem is powered up
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+With IMC PR3 modem, the SIM state is not received after enabling XSIM ur codes
+(+XSIMSTATE=1)
+We need to do a +XSIMSTATE query to get the current SIM state.
+---
+ src/s_sim.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 64 insertions(+), 3 deletions(-)
+
+diff --git a/src/s_sim.c b/src/s_sim.c
+index 77287cf..5ab702a 100644
+--- a/src/s_sim.c
++++ b/src/s_sim.c
+@@ -115,6 +115,33 @@ 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 sim_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_sim_message_send, NULL);
++ tcore_pending_link_user_request(pending, NULL); // set user request to NULL - this is internal request
++ ret = tcore_hal_send_request(hal, pending);
++ return;
++}
++
+ 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");
+@@ -1686,7 +1713,7 @@ static TReturn _get_file_info(CoreObject *o, UserRequest *ur, const enum tel_sim
+ 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);
++ dbg("cmd_str: %s", 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);
+@@ -1914,12 +1941,16 @@ static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void
+ line = (char *) (lines->data);
+
+ tokens = tcore_at_tok_new(line);
+- if (g_slist_length(tokens) != 1) {
++
++ if (g_slist_length(tokens) == 4) {
++ sim_state = atoi(g_slist_nth_data(tokens, 1));
++ } else if (g_slist_length(tokens) == 1)
++ sim_state = atoi(g_slist_nth_data(tokens, 0));
++ else {
+ 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
+@@ -2033,6 +2064,34 @@ OUT:
+ }
+
+
++static void on_response_get_sim_status(TcorePending *p, int data_len, const void *data, void *user_data)
++{
++ const TcoreATResponse *resp = data;
++ CoreObject *co_sim = NULL;
++
++ dbg(" Function entry ");
++
++ co_sim = tcore_pending_ref_core_object(p);
++
++ if (resp->success > 0) {
++ dbg("RESPONSE OK");
++ if (resp->lines)
++ on_event_pin_status(co_sim, resp->lines, NULL);
++ } else {
++ dbg("RESPONSE NOK");
++ }
++
++ dbg(" Function 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)
++{
++ dbg("Get SIM status");
++ sim_prepare_and_send_pending_request(tcore_object_ref_plugin(source), "sim", "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)
+ {
+@@ -3279,6 +3338,8 @@ gboolean s_sim_init(TcorePlugin *p, TcoreHal *h)
+ tcore_object_add_callback(o, "+XLOCK", on_event_facility_lock_status, NULL);
+ tcore_object_add_callback(o, "+XSIM", on_event_pin_status, NULL);
+
++ tcore_server_add_notification_hook(tcore_plugin_ref_server(p), TNOTI_MODEM_POWER, on_hook_modem_power, o);
++
+ dbg("exit");
+ return TRUE;
+ }
+--
+1.7.10.4
+
--- /dev/null
+From 86510097b43f9a60f50547511fb176cf6d97e9b2 Mon Sep 17 00:00:00 2001
+From: Philippe Nunes <philippe.nunes@linux.intel.com>
+Date: Thu, 20 Sep 2012 17:28:07 +0200
+Subject: [PATCH 06/23] common: Fix warning errors
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+---
+ src/s_common.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/s_common.c b/src/s_common.c
+index 0c83ac5..9b8c4a3 100644
+--- a/src/s_common.c
++++ b/src/s_common.c
+@@ -226,9 +226,9 @@ char _util_unpackb(const char *src, int pos, int len)
+ 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;
+
+--
+1.7.10.4
+
--- /dev/null
+From 3da4bb2f70c4a15d1d61187e89d2f28ab33ca383 Mon Sep 17 00:00:00 2001
+From: Philippe Nunes <philippe.nunes@linux.intel.com>
+Date: Fri, 21 Sep 2012 16:46:54 +0200
+Subject: [PATCH 07/23] s_sim: Get the SIM type when SIM is ready
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+---
+ src/s_sim.c | 33 +++++++++++++++------------------
+ 1 file changed, 15 insertions(+), 18 deletions(-)
+
+diff --git a/src/s_sim.c b/src/s_sim.c
+index 5ab702a..1d7e5c6 100644
+--- a/src/s_sim.c
++++ b/src/s_sim.c
+@@ -98,7 +98,6 @@ struct s_sim_property {
+ 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 tel_sim_mbi_list mbi_list;
+ struct tel_sim_mb_number mb_list[SIM_MSP_CNT_MAX*5];
+@@ -841,7 +840,13 @@ static void _response_get_sim_type(TcorePending *p, int data_len, const void *da
+ }
+
+ tcore_sim_set_type(co_sim, sim_type);
+- _sim_status_update(co_sim, sp->first_recv_status);
++
++ 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(co_sim, ur, SIM_EF_IMSI);
++ }
++
+ tcore_at_tok_free(tokens);
+ dbg(" Function exit");
+ }
+@@ -1921,7 +1926,6 @@ OUT:
+
+ 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;
+@@ -1986,7 +1990,7 @@ static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void
+
+ case 7: // sim state = ready for attach (+COPS)
+ sim_status = SIM_STATUS_INIT_COMPLETED;
+- dbg("Modem init completed");
++ dbg("SIM is ready for attach");
+ break;
+
+ case 8: // sim state = SIM Technical Problem
+@@ -2015,8 +2019,10 @@ static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void
+
+ 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);
++ if (tcore_sim_get_type(o) == SIM_TYPE_UNKNOWN)
++ _get_sim_type(o);
++ else
++ _sim_status_update(o, sim_status);
+ break;
+
+ case SIM_STATUS_INITIALIZING:
+@@ -2028,17 +2034,7 @@ static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void
+ 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);
+- }
+- }
++ _sim_status_update(o, sim_status);
+ break;
+
+ case SIM_STATUS_CARD_REMOVED:
+@@ -2048,6 +2044,8 @@ static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void
+ dbg("[SIM]SIM CARD REMOVED!!");
+ sim_status = SIM_STATUS_CARD_REMOVED;
+ }
++
++ tcore_sim_set_type(o, SIM_TYPE_UNKNOWN);
+ _sim_status_update(o, sim_status);
+ break;
+
+@@ -3332,7 +3330,6 @@ gboolean s_sim_init(TcorePlugin *p, TcoreHal *h)
+ 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);
+--
+1.7.10.4
+
--- /dev/null
+From 5c4fbd80accf435889b6f7b16eae14b47a6cba09 Mon Sep 17 00:00:00 2001
+From: Caiwen Zhang <caiwen.zhang@intel.com>
+Date: Tue, 25 Sep 2012 21:28:07 +0800
+Subject: [PATCH 08/23] Fix SCA(service center address) length checking error
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+For the address field used by SM-RL(short message relay layer),
+the length byte represents octets of the whole field(include itself
+and TOA byte - type of address). Please refer to 3GPP 31.102 4.2.27
+and 3GPP 24.011 8.2.5.2
+
+For the address field used by SM-TP(transfer layer), the length
+represents semi-octets within the address(exclude itself and TOA
+byte). Please refer to 3GPP 23.040 9.1.2.5.
+
+SCA is an address filed of SM-RL. SMS_MAX_SMS_SERVICE_CENTER_ADDR
+should be 12.
+
+But currently in the struct telephony_sms_DataPaclageInfo, SM-TP
+address filed is used to represent the SCA.
+
+As we currently can't access libtcore and msg_service packages,
+temporarily change the SCA length checking here to make SMS sending
+work.
+---
+ src/s_sms.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/s_sms.c b/src/s_sms.c
+index 874f08e..2b3cd4f 100644
+--- a/src/s_sms.c
++++ b/src/s_sms.c
+@@ -2218,7 +2218,7 @@ static TReturn send_umts_msg(CoreObject *obj, UserRequest *ur)
+
+ if ((sendUmtsMsg->msgDataPackage.msgLength > 0)
+ && (sendUmtsMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX)
+- && (ScLength <= SMS_SCADDRESS_LEN_MAX)) {
++ && (ScLength <= (SMS_MAX_SMS_SERVICE_CENTER_ADDR - 2) * 2)) {
+ if (ScLength == 0) { // ScAddress not specified
+ buf[0] = '0';
+ buf[1] = '0';
+--
+1.7.10.4
+
--- /dev/null
+From a2b5d447eb38825e0af9e57dde07b6e941d48389 Mon Sep 17 00:00:00 2001
+From: Philippe Nunes <philippe.nunes@linux.intel.com>
+Date: Wed, 26 Sep 2012 17:26:42 +0200
+Subject: [PATCH 09/23] s_modem: Add XGENDATA query to get firmware
+ information
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+---
+ src/s_modem.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/src/s_modem.c b/src/s_modem.c
+index 2c71457..22adfa3 100644
+--- a/src/s_modem.c
++++ b/src/s_modem.c
+@@ -275,6 +275,33 @@ static void on_response_set_flight_mode(TcorePending *p, int data_len, const voi
+ tcore_at_tok_free(tokens);
+ }
+
++static void on_response_xgendata(TcorePending *p, int data_len, const void *data, void *user_data)
++{
++ const TcoreATResponse *resp = data;
++ GSList *tokens = NULL;
++ const char *line;
++
++ 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;
++ }
++ }
++
++ dbg("XGENDATA = [%s]", g_slist_nth_data(tokens, 0));
++ }
++
++OUT:
++ if (tokens != NULL)
++ tcore_at_tok_free(tokens);
++
++ return;
++}
++
+ static void on_response_imei(TcorePending *p, int data_len, const void *data, void *user_data)
+ {
+ const TcoreATResponse *resp = data;
+@@ -511,6 +538,9 @@ gboolean on_event_modem_power(TcoreAT *at, const char *line, TcorePlugin *p)
+ /* Get Version Number */
+ prepare_and_send_pending_request(p, "modem", "AT+CGMR", NULL, TCORE_AT_SINGLELINE, on_response_version);
+
++ /* Get XGENDATA info */
++ prepare_and_send_pending_request(p, "modem", "AT+XGENDATA", "+XGENDATA:", TCORE_AT_MULTILINE, on_response_xgendata);
++
+ tcore_modem_set_powered(o, TRUE);
+
+ modem_power.state = MODEM_STATE_ONLINE;
+--
+1.7.10.4
+
--- /dev/null
+From 0ab2df1acdc37d1ada019d0e4c1ccb81913637ef Mon Sep 17 00:00:00 2001
+From: Philippe Nunes <philippe.nunes@linux.intel.com>
+Date: Wed, 26 Sep 2012 17:30:40 +0200
+Subject: [PATCH 10/23] s_sim: Extend XSIMSTATE parsing to get SMS service
+ state
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+---
+ src/s_sim.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/src/s_sim.c b/src/s_sim.c
+index 1d7e5c6..7bff6dd 100644
+--- a/src/s_sim.c
++++ b/src/s_sim.c
+@@ -28,12 +28,14 @@
+ #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 "s_common.h"
++#include "s_sms.h"
+ #include "s_sim.h"
+
+ #define ID_RESERVED_AT 0x0229
+@@ -1932,6 +1934,7 @@ static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void
+ GSList *lines = NULL;
+ const char *line = NULL;
+ int sim_state = 0;
++ int sms_state = 0;
+
+ dbg(" Function entry ");
+
+@@ -1948,6 +1951,7 @@ static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void
+
+ if (g_slist_length(tokens) == 4) {
+ sim_state = atoi(g_slist_nth_data(tokens, 1));
++ sms_state = atoi(g_slist_nth_data(tokens, 3));
+ } else if (g_slist_length(tokens) == 1)
+ sim_state = atoi(g_slist_nth_data(tokens, 0));
+ else {
+@@ -2023,6 +2027,20 @@ static gboolean on_event_pin_status(CoreObject *o, const void *event_info, void
+ _get_sim_type(o);
+ else
+ _sim_status_update(o, sim_status);
++
++ if (sms_state) {
++ struct tnoti_sms_ready_status readyStatusInfo = {0, };
++ CoreObject *sms;
++ TcorePlugin *plugin;
++
++ dbg("SMS Ready");
++ readyStatusInfo.status = TRUE;
++ plugin = tcore_object_ref_plugin(o);
++ sms = tcore_plugin_ref_core_object(plugin, "umts_sms");
++ tcore_sms_set_ready_status(sms, readyStatusInfo.status);
++
++ tcore_server_send_notification(tcore_plugin_ref_server(plugin), sms, TNOTI_SMS_DEVICE_READY, sizeof(struct tnoti_sms_ready_status), &readyStatusInfo);
++ }
+ break;
+
+ case SIM_STATUS_INITIALIZING:
+--
+1.7.10.4
+
--- /dev/null
+From ee0731a4b1c6cb4727910320d9b8e5f96bad9f4b Mon Sep 17 00:00:00 2001
+From: Caiwen Zhang <caiwen.zhang@intel.com>
+Date: Fri, 28 Sep 2012 18:28:10 +0800
+Subject: [PATCH 11/23] set modem power saving mode
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+---
+ src/s_modem.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/s_modem.c b/src/s_modem.c
+index 22adfa3..a0fe4dc 100644
+--- a/src/s_modem.c
++++ b/src/s_modem.c
+@@ -703,6 +703,8 @@ static void on_response_enable_logging(TcorePending *p, int data_len, const void
+ dbg("Calling setup_mux");
+ setup_mux(tcore_pending_ref_core_object(p));
+
++ /* sets the powersaving-mode */
++ prepare_and_send_pending_request(plugin, "modem", "at+xpow=0,0,0", NULL, TCORE_AT_NO_RESULT, NULL);
+
+ dbg("Exit");
+ return;
+--
+1.7.10.4
+
--- /dev/null
+From 3b7a430088ee269c53bb3d107ad13da23e795a7b Mon Sep 17 00:00:00 2001
+From: Caiwen Zhang <caiwen.zhang@intel.com>
+Date: Fri, 28 Sep 2012 18:31:58 +0800
+Subject: [PATCH 12/23] Fix EFsmsp size error
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+EFsmsp record size 28 + Y (Y is the bytes remained for saving alpha
+id). Y always be (record size - 28), it doesn't depends on the alpha
+string length, if the alpha string is longer than Y, the string should
+be cut short, if it is shorter than Y, should padding with 0xFF.
+---
+ src/s_sms.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/src/s_sms.c b/src/s_sms.c
+index 2b3cd4f..20067a3 100644
+--- a/src/s_sms.c
++++ b/src/s_sms.c
+@@ -3046,6 +3046,7 @@ static TReturn set_sms_params(CoreObject *obj, UserRequest *ur)
+ char *encoded_data = NULL;
+ unsigned char *temp_data = NULL;
+ int SMSPRecordLen = 0;
++ int *smsp_record_len;
+
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+@@ -3067,11 +3068,15 @@ static TReturn set_sms_params(CoreObject *obj, UserRequest *ur)
+ 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");
++ SMSPRecordLen = *smsp_record_len;
++ if (SMSPRecordLen < nDefaultSMSPWithoutAlphaId)
++ return FALSE;
++
++ temp_data = calloc(SMSPRecordLen, 1);
++ encoded_data = calloc(SMSPRecordLen * 2 + 1, 1);
++
+ _tcore_util_sms_encode_smsParameters(&(setSmsParams->params), temp_data, SMSPRecordLen);
+
+ util_byte_to_hex((const char *)temp_data, (char *)encoded_data,SMSPRecordLen);
+--
+1.7.10.4
+
--- /dev/null
+From 2a49ea5039f838a3bad9d08cb80284e66c7cc97d Mon Sep 17 00:00:00 2001
+From: Nicolas Bertrand <nicolas.bertrand@linux.intel.com>
+Date: Wed, 3 Oct 2012 15:07:16 +0200
+Subject: [PATCH 13/23] s_call: use hal set sound path function
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+---
+ src/s_call.c | 339 ++++++++++++++++------------------------------------------
+ 1 file changed, 92 insertions(+), 247 deletions(-)
+
+diff --git a/src/s_call.c b/src/s_call.c
+index e48e900..2a2b027 100644
+--- a/src/s_call.c
++++ b/src/s_call.c
+@@ -23,6 +23,8 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <glib.h>
++#include <unistd.h>
++
+
+ #include <tcore.h>
+ #include <hal.h>
+@@ -43,9 +45,10 @@
+ #define STATUS_CONNECTED 7
+ #define COMMA 0X2c
+
+-static gboolean setsoundpath = FALSE;
+ static gboolean soundvolume = FALSE;
+
++extern 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);
++
+ // End Cause field - Call state end cause
+
+ typedef enum {
+@@ -372,6 +375,66 @@ static gboolean on_notification_call_clip_info(CoreObject *o, const void *data,
+ return TRUE;
+ }
+
++static gboolean on_notification_call_audio_info(CoreObject *o, const void *data, void *user_data)
++{
++ GSList *tokens = NULL;
++ GSList *lines = NULL;
++ TcoreHal *hal = NULL;
++ const char *line = NULL;
++ char *stat;
++ int status;
++ TcorePlugin *plugin;
++
++ dbg("Entry");
++
++ lines = (GSList *) data;
++ if (1 != g_slist_length(lines)) {
++ err("Unsolicited message, BUT multiple lines present");
++ goto OUT;
++ }
++
++ line = (char *) (lines->data);
++ tokens = tcore_at_tok_new(line);
++
++ stat = g_slist_nth_data(tokens, 1);
++ if (!stat) {
++ dbg("Stat is missing from +XPROGRESS indiaction");
++ } else {
++ status = atoi(stat);
++ dbg("status = %d", status);
++
++ switch (status) {
++
++ case 11: /*igonre Connected state. */
++ dbg("audio disconnected")
++ plugin = tcore_object_ref_plugin(o);
++
++ hal = tcore_object_get_hal(o);
++ tcore_hal_set_sound_path(hal, 0x0);
++
++ // amc disable
++ usleep(1000); // Time to disable MSIC...
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,3,3", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S1_RX
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,3,4", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S2_RX
++ // amc route: AMC_RADIO_RX => AMC_PCM_GENERALD
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,6,0,4", NULL, TCORE_AT_NO_RESULT, NULL);
++ usleep(80000); // Time to Disable modem I2S...
++ break;
++
++ default:
++ dbg("audio continue");
++ break;
++ }
++ }
++
++ /* Free tokens */
++ tcore_at_tok_free(tokens);
++
++OUT:
++ dbg("Exit");
++ return TRUE;
++}
++
+ static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data)
+ {
+ GSList *tokens = NULL;
+@@ -1468,179 +1531,6 @@ static void on_confirmation_call_swap(TcorePending *p, int data_len, const void
+ return;
+ }
+
+-static void on_confirmation_call_set_source_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
+-{
+- UserRequest *ur = NULL;
+- GSList *tokens = NULL;
+- const char *line = NULL;
+- const TcoreATResponse *response = data;
+- char *resp_str = NULL;
+- struct tresp_call_sound_set_path resp;
+- gboolean error;
+-
+- dbg("Entry");
+- ur = tcore_pending_ref_user_request(p);
+-
+- // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
+- 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 = TRUE;
+- goto OUT;
+- }
+-
+- if (!g_slist_nth_data(tokens, 1)) {
+- err(" function_id is missing");
+- resp.err = TRUE;
+- 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 = FALSE;
+- } else {
+- resp.err = TRUE;
+- }
+- }
+-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 = TRUE;
+- } else {
+- error = atoi(g_slist_nth_data(tokens, 0));
+-
+- // TODO: CMEE error mapping is required.
+- resp.err = TRUE;
+- }
+-
+- // Free tokens
+- tcore_at_tok_free(tokens);
+- }
+-
+- if (ur) {
+- 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);
+- setsoundpath = TRUE;
+- }
+- } else {
+- err("User Request is NULL");
+- }
+-
+- dbg("Exit");
+- return;
+-}
+-
+-static void on_confirmation_call_set_destination_sound_path(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_sound_set_path resp;
+- const TcoreATResponse *response = data;
+- gboolean error;
+-
+- dbg("Entry");
+-
+- ur = tcore_pending_ref_user_request(p);
+- // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
+-
+- if (!response) {
+- err("Input data is NULL");
+- return;
+- }
+-
+- if (ur) {
+- 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)) {
+- dbg("group_id is missing");
+- resp.err = TRUE;
+- goto OUT;
+- }
+-
+- if (!g_slist_nth_data(tokens, 1)) {
+- dbg("function_id is missing");
+- resp.err = TRUE;
+- 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 = FALSE;
+- } else {
+- resp.err = TRUE;
+- }
+- }
+-
+-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 = TRUE;
+- } else {
+- error = atoi(g_slist_nth_data(tokens, 0));
+- // TODO: CMEE error mapping is required.
+- resp.err = TRUE;
+- }
+-
+- // Free tokens
+- tcore_at_tok_free(tokens);
+- }
+-
+- if (setsoundpath == TRUE) {
+- 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);
+- }
+- } else {
+- dbg("User Request is NULL");
+- }
+-
+- dbg("Exit");
+- return;
+-}
+-
+ static void on_confirmation_call_set_source_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
+ {
+ UserRequest *ur = NULL;
+@@ -2978,90 +2868,44 @@ static TReturn s_call_send_dtmf(CoreObject *o, UserRequest *ur)
+
+ static TReturn s_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_sound_set_path *sound_path = 0;
+- gboolean ret = FALSE;
++ struct tresp_call_sound_set_path resp;
++ struct treq_call_sound_set_path *SoundPathP;
++ TcoreHal *hal = NULL;
++ TcorePlugin *plugin;
+
+ dbg("function entrance");
+
+- 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_sound_set_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;
++ SoundPathP = (struct treq_call_sound_set_path *) tcore_user_request_ref_data(ur, 0);
+
+- case CALL_SOUND_PATH_HEADSET_3_5PI:
+- device_type = 3;
+- break;
+-
+- case CALL_SOUND_PATH_SPEAKER:
+- device_type = 4;
+- break;
++ dbg("deviceId is %d", SoundPathP->path);
+
+- case CALL_SOUND_PATH_HANDFREE:
+- device_type = 5;
+- break;
+-
+- case CALL_SOUND_PATH_HEADSET_HAC:
+- device_type = 6;
+- break;
++ plugin = tcore_object_ref_plugin(o);
+
+- case CALL_SOUND_PATH_BLUETOOTH:
+- case CALL_SOUND_PATH_STEREO_BLUETOOTH:
+- device_type = 7;
+- break;
++ // Configure modem I2S1
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,4,3,0,1,0,8,0,1,0,2,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,5,2,0,1,0,8,0,1,0,2,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
+
+- 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;
+- }
++ // Configure modem I2S2 and do the modem routing
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,4,4,0,0,0,8,0,1,0,2,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,5,3,0,0,0,8,0,1,0,2,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,6,0,4", NULL, TCORE_AT_NO_RESULT, NULL);
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,6,3,0", NULL, TCORE_AT_NO_RESULT, NULL);
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,6,4,2", NULL, TCORE_AT_NO_RESULT, NULL);
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,6,5,2", NULL, TCORE_AT_NO_RESULT, NULL);
+
+- 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);
+- 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);
++ // amc enable
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,2,4", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S2_RX
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,2,3", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S1_RX
++ // amc route: AMC_RADIO_RX => AMC_I2S1_TX
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,6,0,2", NULL, TCORE_AT_NO_RESULT, NULL);
+
+- if (!ret) {
+- dbg("At request(%s) sent failed", req->cmd);
+- return TCORE_RETURN_FAILURE;
+- }
++ usleep(40000); // Time to Enable modem I2S...
+
+- 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);
+- 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);
++ hal = tcore_object_get_hal(o);
++ tcore_hal_set_sound_path(hal, SoundPathP->path);
+
+- if (!ret) {
+- dbg("AT request %s has failed ", req1->cmd);
+- return TCORE_RETURN_FAILURE;
+- }
++ resp.err = TCORE_RETURN_SUCCESS;
++ tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_sound_set_path), &resp);
+
+ return TCORE_RETURN_SUCCESS;
+ }
+@@ -4060,6 +3904,7 @@ gboolean s_call_init(TcorePlugin *p, TcoreHal *h)
+ // 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);
++ tcore_object_add_callback(o, "+XPROGRESS", on_notification_call_audio_info, NULL);
+
+ // User Data
+ data = calloc(sizeof(struct property_call_info *), 1);
+--
+1.7.10.4
+
--- /dev/null
+From 96005a4ba04e16b3ae22db6b6f71ea54c88257c8 Mon Sep 17 00:00:00 2001
+From: Guillaume Zajac <guillaume.zajac@linux.intel.com>
+Date: Mon, 8 Oct 2012 15:41:21 +0200
+Subject: [PATCH 14/23] Add core objects and link them to HAL
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+Conflicts:
+ src/s_modem.c
+---
+ src/s_call.c | 7 +++----
+ src/s_modem.c | 8 ++++++--
+ src/s_network.c | 4 +++-
+ src/s_ps.c | 5 ++++-
+ src/s_sat.c | 4 +++-
+ src/s_sim.c | 4 +++-
+ src/s_sms.c | 4 +++-
+ src/s_ss.c | 4 +++-
+ 8 files changed, 28 insertions(+), 12 deletions(-)
+
+diff --git a/src/s_call.c b/src/s_call.c
+index 2a2b027..2d2b711 100644
+--- a/src/s_call.c
++++ b/src/s_call.c
+@@ -272,7 +272,6 @@ const call_end_cause_info call_end_cause_table[] = // call end cause table to
+ 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)) {
+@@ -3888,16 +3887,17 @@ 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);
++ o = tcore_call_new(p, "call", &call_ops, NULL);
+ if (!o) {
+ err("Failed to create Call Core Object");
+ return FALSE;
+ }
+
++ tcore_hal_link_object(h, o);
++
+ // Set Call Operations
+ tcore_call_information_set_operations(o, &call_information_ops);
+
+@@ -3918,7 +3918,6 @@ void s_call_exit(TcorePlugin *p)
+ {
+ CoreObject *o = NULL;
+ struct property_network_info *data = NULL;
+-
+ dbg("Entry");
+
+ o = tcore_plugin_ref_core_object(p, "call");
+diff --git a/src/s_modem.c b/src/s_modem.c
+index a0fe4dc..6212467 100644
+--- a/src/s_modem.c
++++ b/src/s_modem.c
+@@ -163,7 +163,7 @@ void prepare_and_send_pending_request(TcorePlugin *plugin, char *co_name, const
+ 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
++ tcore_pending_link_user_request(pending, NULL); // set user request to NULL - this is internal request
+ ret = tcore_hal_send_request(hal, pending);
+ return;
+ }
+@@ -941,10 +941,14 @@ gboolean s_modem_init(TcorePlugin *p, TcoreHal *h)
+ TelMiscSNInformation *imei_property = NULL;
+ TelMiscSNInformation *sn_property = NULL;
+
+- o = tcore_modem_new(p, "modem", &modem_ops, h);
++ dbg("Entry");
++
++ o = tcore_modem_new(p, "modem", &modem_ops, NULL);
+ if (!o)
+ return FALSE;
+
++ tcore_hal_link_object(h, o);
++
+ work_queue = g_queue_new();
+ tcore_object_link_user_data(o, work_queue);
+
+diff --git a/src/s_network.c b/src/s_network.c
+index 7c5e8d9..0cbdc23 100644
+--- a/src/s_network.c
++++ b/src/s_network.c
+@@ -2169,10 +2169,12 @@ gboolean s_network_init(TcorePlugin *p, TcoreHal *h)
+ {
+ CoreObject *o = NULL;
+
+- o = tcore_network_new(p, "umts_network", &network_ops, h);
++ o = tcore_network_new(p, "umts_network", &network_ops, NULL);
+ if (!o)
+ return FALSE;
+
++ tcore_hal_link_object(h, o);
++
+ 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);
+diff --git a/src/s_ps.c b/src/s_ps.c
+index e87e943..78bb9c7 100644
+--- a/src/s_ps.c
++++ b/src/s_ps.c
+@@ -945,10 +945,13 @@ gboolean s_ps_init(TcorePlugin *p, TcoreHal *hal)
+ struct context *context_table = NULL;
+
+ dbg("Entered");
+- o = tcore_ps_new(p, "umts_ps", &ps_ops, hal);
++ o = tcore_ps_new(p, "umts_ps", &ps_ops, NULL);
+
+ if (!o)
+ return FALSE;
++
++ tcore_hal_link_object(hal, o);
++
+ tcore_object_link_user_data(o, (void *) context_table);
+
+ tcore_object_add_callback(o, "+CGEV", on_event_cgev_handle, p);
+diff --git a/src/s_sat.c b/src/s_sat.c
+index ebacea0..774388c 100644
+--- a/src/s_sat.c
++++ b/src/s_sat.c
+@@ -451,12 +451,14 @@ gboolean s_sat_init(TcorePlugin *p, TcoreHal *h)
+ CoreObject *o = NULL;
+
+ dbg("Entry");
+- o = tcore_sat_new(p, "sat", &sat_ops, h);
++ o = tcore_sat_new(p, "sat", &sat_ops, NULL);
+ if (!o) {
+ dbg("CoreObject NULL !!");
+ return FALSE;
+ }
+
++ tcore_hal_link_object(h, o);
++
+ 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);
+diff --git a/src/s_sim.c b/src/s_sim.c
+index 7bff6dd..a74bf7c 100644
+--- a/src/s_sim.c
++++ b/src/s_sim.c
+@@ -3336,11 +3336,13 @@ gboolean s_sim_init(TcorePlugin *p, TcoreHal *h)
+
+ dbg("entry");
+
+- o = tcore_sim_new(p, "sim", &sim_ops, h);
++ o = tcore_sim_new(p, "sim", &sim_ops, NULL);
+
+ if (!o)
+ return FALSE;
+
++ tcore_hal_link_object(h, o);
++
+ file_meta = calloc(sizeof(struct s_sim_property), 1);
+ if (!file_meta)
+ return FALSE;
+diff --git a/src/s_sms.c b/src/s_sms.c
+index 20067a3..06b4dcd 100644
+--- a/src/s_sms.c
++++ b/src/s_sms.c
+@@ -3207,7 +3207,7 @@ gboolean s_sms_init(TcorePlugin *plugin, TcoreHal *hal)
+ dbg("plugin: [%p]", plugin);
+ dbg("hal: [%p]", hal);
+
+- obj = tcore_sms_new(plugin, "umts_sms", &sms_ops, hal);
++ obj = tcore_sms_new(plugin, "umts_sms", &sms_ops, NULL);
+
+ data = calloc(sizeof(struct property_sms_info), 1);
+
+@@ -3219,6 +3219,8 @@ gboolean s_sms_init(TcorePlugin *plugin, TcoreHal *hal)
+ return FALSE;
+ }
+
++ tcore_hal_link_object(hal, obj);
++
+ work_queue = g_queue_new();
+ tcore_object_link_user_data(obj, work_queue);
+
+diff --git a/src/s_ss.c b/src/s_ss.c
+index 0781ac7..7a7e050 100644
+--- a/src/s_ss.c
++++ b/src/s_ss.c
+@@ -2756,7 +2756,7 @@ gboolean s_ss_init(TcorePlugin *p, TcoreHal *h)
+ CoreObject *so = 0, *co = 0;
+ struct property_call_info *data = 0;
+
+- so = tcore_ss_new(p, "ss", &ss_ops, h);
++ so = tcore_ss_new(p, "ss", &ss_ops, NULL);
+ if (!so) {
+ dbg("[ error ] ss_new()");
+ return FALSE;
+@@ -2768,6 +2768,8 @@ gboolean s_ss_init(TcorePlugin *p, TcoreHal *h)
+ return FALSE;
+ }
+
++ tcore_hal_link_object(h, so);
++
+ tcore_call_control_set_operations(co, &call_ops);
+
+ tcore_object_add_callback(so, "+CSSU", on_notification_ss_info, 0);
+--
+1.7.10.4
+
--- /dev/null
+From 658e94ca29da1e7fc52b036a4dc231db1500f3ff Mon Sep 17 00:00:00 2001
+From: Guillaume Zajac <guillaume.zajac@linux.intel.com>
+Date: Mon, 8 Oct 2012 15:42:12 +0200
+Subject: [PATCH 15/23] Change the way imc plugin is initialized
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+Conflicts:
+ src/desc.c
+ src/s_modem.c
+---
+ src/desc.c | 90 ++++++++++++++++++---------------------------------------
+ src/s_modem.c | 69 +------------------------------------------
+ 2 files changed, 29 insertions(+), 130 deletions(-)
+
+diff --git a/src/desc.c b/src/desc.c
+index 7a5ef93..0cf4542 100644
+--- a/src/desc.c
++++ b/src/desc.c
+@@ -44,51 +44,6 @@
+ #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()
+ {
+@@ -126,7 +81,7 @@ static int _get_cp_name(char **name)
+ dbg("u.__domainname : [ %s ]", u.__domainname);
+ dbg("u.machine : [ %s ]", u.machine);
+ dbg("u.release : [ %s ]", u.release);
+- dbg("u.sysname : [ %s ]", u.sysname);S
++ dbg("u.sysname : [ %s ]", u.sysname);
+ dbg("u.version : [ %s ]", u.version);
+
+ /* By default, SUNRISE IMC modem is returned */
+@@ -165,11 +120,35 @@ static int _get_cp_name(char **name)
+ return 0;
+ }
+
++static void on_hal_set_power(TcoreHal *hal, void *user_data)
++{
++ TcorePlugin *p = user_data;
++ CoreObject *o;
++
++ dbg("Entry");
++
++ s_modem_init(p, hal);
++ s_sim_init(p, hal);
++ s_sat_init(p, hal);
++ s_network_init(p, hal);
++ s_ps_init(p, hal);
++ s_call_init(p, hal);
++ s_ss_init(p, hal);
++ s_sms_init(p, hal);
++ s_gps_init(p, hal);
++
++ o = tcore_plugin_ref_core_object(p, "modem");
++ tcore_server_send_notification(tcore_plugin_ref_server(p), o, TNOTI_MODEM_ADDED, 0, NULL);
++
++ s_modem_send_poweron(p);
++
++ dbg("Exit");
++}
++
+ static gboolean on_init(TcorePlugin *p)
+ {
+ TcoreHal *h;
+ struct global_data *gd;
+- // char *cp_name = 0;
+ int len = 0;
+
+ if (!p)
+@@ -208,25 +187,12 @@ static gboolean on_init(TcorePlugin *p)
+
+ 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);
++ g_free(cp_name);
+
+- 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);
+- s_phonebook_init(p, h);
+- s_sap_init(p, h);
++ tcore_hal_set_power(h, TRUE, on_hal_set_power, p);
+
+ 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;
+ }
+
+diff --git a/src/s_modem.c b/src/s_modem.c
+index 6212467..47c6c63 100644
+--- a/src/s_modem.c
++++ b/src/s_modem.c
+@@ -616,69 +616,6 @@ static void _modem_subscribe_events(TcorePlugin *plugin)
+ 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;
+@@ -700,8 +637,7 @@ static void on_response_enable_logging(TcorePending *p, int data_len, const void
+ dbg("Enabling CP logging is failed !!!\n");
+ }
+
+- dbg("Calling setup_mux");
+- setup_mux(tcore_pending_ref_core_object(p));
++ _modem_subscribe_events(plugin);
+
+ /* sets the powersaving-mode */
+ prepare_and_send_pending_request(plugin, "modem", "at+xpow=0,0,0", NULL, TCORE_AT_NO_RESULT, NULL);
+@@ -961,9 +897,6 @@ gboolean s_modem_init(TcorePlugin *p, TcoreHal *h)
+ 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);
+
+--
+1.7.10.4
+
--- /dev/null
+From 18cd0f7d5a979252b30a35537fa3bbaea60fdc5f Mon Sep 17 00:00:00 2001
+From: Guillaume Zajac <guillaume.zajac@linux.intel.com>
+Date: Wed, 10 Oct 2012 11:32:22 +0200
+Subject: [PATCH 16/23] s_ps: Remove plateform dependencies to setup pdp
+ context
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+---
+ src/s_ps.c | 130 +++++++++++++++++++++++++++++-------------------------------
+ 1 file changed, 62 insertions(+), 68 deletions(-)
+
+diff --git a/src/s_ps.c b/src/s_ps.c
+index 78bb9c7..107d672 100644
+--- a/src/s_ps.c
++++ b/src/s_ps.c
+@@ -43,11 +43,6 @@
+ #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 */
+
+@@ -61,6 +56,7 @@
+ #define AT_XDNS_ENABLE 1
+ #define AT_XDNS_DISABLE 0
+ #define AT_SESSION_DOWN 0
++
+ static void _ps_free(void *ptr)
+ {
+ dbg("Entered");
+@@ -83,33 +79,6 @@ static void _unable_to_get_pending(CoreObject *co_ps, CoreObject *ps_context)
+ (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)
+ {
+@@ -445,10 +414,15 @@ static void on_response_deactivate_ps_context(TcorePending *p, int data_len, con
+
+ cid = tcore_context_get_id(ps_context);
+ if (resp->success) {
++ char *devname = tcore_context_get_ipv4_devname(ps_context);
++
+ 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*/
++ dbg("Removing interface %s", devname);
++ if (tcore_util_netif_down(devname) != TCORE_RETURN_SUCCESS)
++ dbg("util_netif_down() failed.");
+ } else {
+ dbg("Response NOK");
+ send_undefine_context_cmd(co_ps, ps_context);
+@@ -489,11 +463,38 @@ static TReturn deactivate_ps_context(CoreObject *co_ps, CoreObject *ps_context,
+ return TCORE_RETURN_FAILURE;
+ }
+
+-static void on_response_get_dns_cmnd(TcorePending *p, int data_len, const void *data, void *user_data)
++static void on_setup_pdp(CoreObject *co_ps, const char *iname, void *user_data)
+ {
+- struct tnoti_ps_pdp_ipconfiguration noti = {0};
++ struct tnoti_ps_pdp_ipconfiguration *noti = user_data;
+ struct tnoti_ps_call_status data_status = {0};
+- char devname[10] = {0, };
++
++ dbg("entry");
++
++ memcpy(¬i->devname, iname, strlen(iname));
++ dbg("devname = [%s]", iname);
++ if (tcore_util_netif_up(iname) != TCORE_RETURN_SUCCESS) {
++ dbg("util_netif_up() failed.");
++ }
++
++ 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), noti);
++
++ data_status.context_id = noti->context_id;
++ 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);
++
++ g_free(noti);
++
++ dbg("exit");
++}
++
++static void on_response_get_dns_cmnd(TcorePending *p, int data_len, const void *data, void *user_data)
++{
++ struct tnoti_ps_pdp_ipconfiguration *noti;
+ char *dns_prim = NULL;
+ char *dns_sec = NULL;
+ char *pdp_address = NULL;
+@@ -512,6 +513,14 @@ static void on_response_get_dns_cmnd(TcorePending *p, int data_len, const void *
+ const TcoreATResponse *resp = data;
+ CoreObject *co_ps = tcore_pending_ref_core_object(p);
+ int cid = tcore_context_get_id(ps_context);
++ TcorePlugin *plugin = tcore_object_ref_plugin(co_ps);
++ TcoreHal *h;
++ struct global_data *gd;
++
++ noti = g_new0(struct tnoti_ps_pdp_ipconfiguration, 1);
++
++ gd = tcore_plugin_ref_user_data(plugin);
++ h = gd->hal;
+
+ dbg("Entered");
+
+@@ -548,7 +557,7 @@ static void on_response_get_dns_cmnd(TcorePending *p, int data_len, const void *
+ index = 0;
+ token_add = strtok(dns_prim, ".");
+ while (token_add != NULL) {
+- noti.primary_dns[index++] = atoi(token_add);
++ noti->primary_dns[index++] = atoi(token_add);
+ token_add = strtok(NULL, ".");
+ }
+ _ps_free(dns_prim);
+@@ -563,7 +572,7 @@ static void on_response_get_dns_cmnd(TcorePending *p, int data_len, const void *
+ index = 0;
+ token_add = strtok(dns_sec, ".");
+ while (token_add != NULL) {
+- noti.secondary_dns[index++] = atoi(token_add);
++ noti->secondary_dns[index++] = atoi(token_add);
+ token_add = strtok(NULL, ".");
+ }
+ _ps_free(dns_sec);
+@@ -580,15 +589,15 @@ 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;
++ 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;
++ noti->secondary_dns[0] = 8;
++ noti->secondary_dns[1] = 8;
++ noti->secondary_dns[2] = 4;
++ noti->secondary_dns[3] = 4;
+ }
+ exit_success:
+ {
+@@ -606,32 +615,17 @@ exit_success:
+ }
+ _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);
++ noti->field_flag = (0x0001 & 0x0002 & 0x0004);
++ noti->err = 0;
++ noti->context_id = cid;
++ memcpy(¬i->ip_address, &addr, 4);
+
+- data_status.context_id = cid;
+- data_status.state = 1;
+- data_status.result = 0;
++ if (tcore_hal_setup_pdp(h, co_ps, on_setup_pdp, noti, cid) != TCORE_RETURN_SUCCESS) {
++ err("setup PDP context failed");
++ return;
++ }
+
+- 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;
+ }
+ }
+
+--
+1.7.10.4
+
--- /dev/null
+From ddcdf41b670a51aee4f30bd3dc2574836e6e324b Mon Sep 17 00:00:00 2001
+From: Caiwen Zhang <caiwen.zhang@intel.com>
+Date: Fri, 19 Oct 2012 23:16:45 +0800
+Subject: [PATCH 17/23] Fix the issue that system is waken up by modem
+ frequently
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+Disable modem unsolicited message when screen is off, enable modem
+unsolicted message when screen is on.
+
+Conflicts:
+ CMakeLists.txt
+ packaging/tel-plugin-imc.spec
+---
+ CMakeLists.txt | 6 ++++--
+ src/s_network.c | 24 ++++++++++++++++++++++++
+ 2 files changed, 28 insertions(+), 2 deletions(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 9bbaec3..101137c 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -10,13 +10,15 @@ 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")
+
+diff --git a/src/s_network.c b/src/s_network.c
+index 0cbdc23..ce1ce34 100644
+--- a/src/s_network.c
++++ b/src/s_network.c
+@@ -23,6 +23,8 @@
+ #include <string.h>
+
+ #include <glib.h>
++#include <vconf.h>
++#include <glib-object.h>
+
+ #include <tcore.h>
+ #include <hal.h>
+@@ -103,6 +105,7 @@ static unsigned int lookup_tbl_access_technology[] = {
+ [AT_COPS_ACT_E_UTRAN] = NETWORK_ACT_GSM_UTRAN,
+ };
+
++extern 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 gboolean get_serving_network(CoreObject *o, UserRequest *ur);
+
+
+@@ -2165,6 +2168,23 @@ static struct tcore_network_operations network_ops = {
+ .get_serving_network = get_serving_network,
+ };
+
++static void on_screen_status_changed(keynode_t *key, void* data)
++{
++ TcorePlugin *plugin = NULL;
++ int state;
++ dbg("Entry");
++
++ plugin = (TcorePlugin *) data;
++ if( vconf_keynode_get_type(key) == VCONF_TYPE_INT) {
++ state = vconf_keynode_get_int(key);
++
++ if (state == VCONFKEY_PM_STATE_NORMAL) //screen on
++ prepare_and_send_pending_request(plugin, "umts_network", "AT+CREG=2;+XREG=2;+XCSQ=1;+XMER=1;+XFDOR=3", NULL, TCORE_AT_NO_RESULT, NULL);
++ else if (state == VCONFKEY_PM_STATE_LCDOFF) //screen off
++ prepare_and_send_pending_request(plugin, "umts_network", "AT+CREG=0;+XREG=0;+XCSQ=0;+XMER=0;+XFDOR=2", NULL, TCORE_AT_NO_RESULT, NULL);
++ }
++}
++
+ gboolean s_network_init(TcorePlugin *p, TcoreHal *h)
+ {
+ CoreObject *o = NULL;
+@@ -2184,6 +2204,8 @@ gboolean s_network_init(TcorePlugin *p, TcoreHal *h)
+
+ tcore_server_add_notification_hook(tcore_plugin_ref_server(p), TNOTI_SIM_STATUS, on_hook_sim_init, o);
+
++ vconf_notify_key_changed(VCONFKEY_PM_STATE, on_screen_status_changed, p);
++
+ _insert_mcc_mnc_oper_list(p, o);
+
+ return TRUE;
+@@ -2193,6 +2215,8 @@ void s_network_exit(TcorePlugin *p)
+ {
+ CoreObject *o;
+
++ vconf_ignore_key_changed(VCONFKEY_PM_STATE, on_screen_status_changed);
++
+ o = tcore_plugin_ref_core_object(p, "umts_network");
+
+ tcore_network_free(o);
+--
+1.7.10.4
+
--- /dev/null
+From 759e70d4743828cb902f093a3cee8a7af76f2440 Mon Sep 17 00:00:00 2001
+From: "Zhang,Vivian" <vivian.zhang@intel.com>
+Date: Wed, 28 Nov 2012 21:55:54 +0800
+Subject: [PATCH 18/23] Configure modem I2s1 to 8khz,mono if routing to
+ bluetooth, fixed TZSP-3943: modem configuration to
+ support HFP
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+---
+ src/s_call.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/src/s_call.c b/src/s_call.c
+index 2d2b711..762fb24 100644
+--- a/src/s_call.c
++++ b/src/s_call.c
+@@ -2880,11 +2880,17 @@ static TReturn s_call_set_sound_path(CoreObject *o, UserRequest *ur)
+
+ plugin = tcore_object_ref_plugin(o);
+
+- // Configure modem I2S1
+- prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,4,3,0,1,0,8,0,1,0,2,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
+- prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,5,2,0,1,0,8,0,1,0,2,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
++ /* Configure modem I2S1 to 8khz, mono, PCM if routing to bluetooth */
++ if (SoundPathP->path == CALL_SOUND_PATH_BLUETOOTH) {
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,4,3,0,1,0,0,0,0,0,0,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,5,2,0,1,0,0,0,0,0,0,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
++ }
++ else {
++ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,4,3,0,1,0,8,0,1,0,2,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
++ prepare_and_send_pending_request(plugin, "call", "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
++ /* Configure modem I2S2 and do the modem routing */
+ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,4,4,0,0,0,8,0,1,0,2,0,21", NULL, TCORE_AT_NO_RESULT, NULL);
+ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,5,3,0,0,0,8,0,1,0,2,0,22", NULL, TCORE_AT_NO_RESULT, NULL);
+ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,6,0,4", NULL, TCORE_AT_NO_RESULT, NULL);
+@@ -2892,10 +2898,10 @@ static TReturn s_call_set_sound_path(CoreObject *o, UserRequest *ur)
+ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,6,4,2", NULL, TCORE_AT_NO_RESULT, NULL);
+ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,6,5,2", NULL, TCORE_AT_NO_RESULT, NULL);
+
+- // amc enable
++ /* amc enable */
+ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,2,4", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S2_RX
+ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,2,3", NULL, TCORE_AT_NO_RESULT, NULL); //AMC_I2S1_RX
+- // amc route: AMC_RADIO_RX => AMC_I2S1_TX
++ /* amc route: AMC_RADIO_RX => AMC_I2S1_TX */
+ prepare_and_send_pending_request(plugin, "call", "AT+XDRV=40,6,0,2", NULL, TCORE_AT_NO_RESULT, NULL);
+
+ usleep(40000); // Time to Enable modem I2S...
+--
+1.7.10.4
+
--- /dev/null
+From b8f8e626877bc32412c18294a72c4e3c60f733bc Mon Sep 17 00:00:00 2001
+From: Philippe Nunes <philippe.nunes@linux.intel.com>
+Date: Thu, 22 Nov 2012 17:34:28 +0100
+Subject: [PATCH 19/23] s_sat.c: Fix envelope cmd and enable Setup Event List
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+The format specifier used to build the envelope command is now x86 compatible
+If the Setup Event List proactive command is not supported, it prevents to
+initiate a SAT session. So, I enabled the proactive command even though
+events are not monitored.
+---
+ src/s_sat.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/src/s_sat.c b/src/s_sat.c
+index 774388c..4a18518 100644
+--- a/src/s_sat.c
++++ b/src/s_sat.c
+@@ -221,7 +221,7 @@ static gboolean on_event_sat_proactive_command(CoreObject *o, const void *event_
+ 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;
+@@ -355,10 +355,11 @@ static TReturn s_envelope(CoreObject *o, UserRequest *ur)
+ 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 %02hhX", envelope_cmd[count]);
++ sprintf(pbuffer, "%02hhX", 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);
+--
+1.7.10.4
+
--- /dev/null
+From 6c206b12570762126bf0a35f6c0054edc14aa14b Mon Sep 17 00:00:00 2001
+From: Philippe Nunes <philippe.nunes@linux.intel.com>
+Date: Fri, 11 Jan 2013 17:20:31 +0100
+Subject: [PATCH 20/23] s_sim.c: Fix get lock info
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+The "lock_type" parameter used by the AT command AT+XPINCNT[=lock_type]
+shall be an integer type when used with our PR3 modem whereas this is
+a string for the Lunchbox modem.
+---
+ src/s_sim.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/src/s_sim.c b/src/s_sim.c
+index a74bf7c..a96594b 100644
+--- a/src/s_sim.c
++++ b/src/s_sim.c
+@@ -2961,7 +2961,7 @@ static TReturn s_get_lock_info(CoreObject *o, UserRequest *ur)
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+- char *lock_type = NULL;
++ int lock_type = 0;
+ const struct treq_sim_get_lock_info *req_data;
+ struct s_sim_property *sp = NULL;
+
+@@ -2981,37 +2981,37 @@ static TReturn s_get_lock_info(CoreObject *o, UserRequest *ur)
+
+ switch (req_data->type) {
+ case SIM_FACILITY_PS:
+- lock_type = "PS";
++ lock_type = 9; // IMSI lock
+ break;
+
+ case SIM_FACILITY_SC:
+- lock_type = "SC";
++ lock_type = 1;
+ break;
+
+ case SIM_FACILITY_FD:
+- lock_type = "FD";
++ lock_type = 2;
+ break;
+
+ case SIM_FACILITY_PN:
+- lock_type = "PN";
++ lock_type = 5;
+ break;
+
+ case SIM_FACILITY_PU:
+- lock_type = "PU";
++ lock_type = 6;
+ break;
+
+ case SIM_FACILITY_PP:
+- lock_type = "PP";
++ lock_type = 7;
+ break;
+
+ case SIM_FACILITY_PC:
+- lock_type = "PC";
++ lock_type = 8;
+ break;
+
+ default:
+ break;
+ }
+- cmd_str = g_strdup_printf("AT+XPINCNT =\"%s\"", lock_type);
++ 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));
+--
+1.7.10.4
+
--- /dev/null
+From ea2ee872e3b4177da0665e4c1daff61ba1644599 Mon Sep 17 00:00:00 2001
+From: Guillaume Zajac <guillaume.zajac@linux.intel.com>
+Date: Wed, 16 Jan 2013 11:55:33 +0100
+Subject: [PATCH 21/23] s_sim: Fix multiple sim facility status query
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+---
+ src/s_sim.c | 28 +++++++++++++---------------
+ 1 file changed, 13 insertions(+), 15 deletions(-)
+
+diff --git a/src/s_sim.c b/src/s_sim.c
+index a96594b..0720bb1 100644
+--- a/src/s_sim.c
++++ b/src/s_sim.c
+@@ -2249,22 +2249,15 @@ static void on_response_get_facility_status(TcorePending *p, int data_len, const
+ {
+ 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;
++ struct tresp_sim_get_facility_status *res = user_data;
+ 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);
++ res->result = SIM_PIN_OPERATION_SUCCESS;
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+@@ -2277,17 +2270,18 @@ static void on_response_get_facility_status(TcorePending *p, int data_len, const
+ return;
+ }
+ }
+- res.b_enable = atoi(g_slist_nth_data(tokens, 0));
++ res->b_enable = atoi(g_slist_nth_data(tokens, 0));
+ } else {
+ dbg("RESPONSE NOK");
+- res.result = SIM_INCOMPATIBLE_PIN_OPERATION;
++ 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);
++ sizeof(struct tresp_sim_get_facility_status), res);
+ }
+ tcore_at_tok_free(tokens);
++ g_free(res);
+ dbg(" Function exit");
+ }
+
+@@ -2771,6 +2765,7 @@ static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_sim_get_facility_status *req_data;
++ struct tresp_sim_get_facility_status *res;
+ struct s_sim_property *sp = NULL;
+ char *fac = "SC";
+ int mode = 2; /* 0:unlock, 1:lock, 2:query*/
+@@ -2787,8 +2782,11 @@ static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
+ pending = tcore_pending_new(o, 0);
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+- if (!o || !ur)
+- return TCORE_RETURN_EINVAL;
++ res = g_try_new0(struct tresp_sim_get_facility_status, 1);
++ if (!res)
++ 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*/
+@@ -2813,7 +2811,7 @@ static TReturn s_get_facility_status(CoreObject *o, UserRequest *ur)
+ 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_set_response_callback(pending, on_response_get_facility_status, res);
+ 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);
+--
+1.7.10.4
+
--- /dev/null
+From 733bcfef07745bc6b8b8861bcbdee8639f2f4aef Mon Sep 17 00:00:00 2001
+From: Philippe Nunes <philippe.nunes@linux.intel.com>
+Date: Wed, 16 Jan 2013 16:23:46 +0100
+Subject: [PATCH 23/23] s_network.c: By default, display the plmn in case SPN
+ name is void
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+---
+ src/s_network.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/s_network.c b/src/s_network.c
+index ce1ce34..2965022 100644
+--- a/src/s_network.c
++++ b/src/s_network.c
+@@ -1669,6 +1669,10 @@ static void on_sim_resp_hook_get_netname(UserRequest *ur, enum tcore_response_co
+ 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);
+ }
+ }
+
+--
+1.7.10.4
+
--- /dev/null
+From e8ae3b0057dad62602dd539c7e8ea5839d527e8a Mon Sep 17 00:00:00 2001
+From: Nicolas Bertrand <nicolas.bertrand@linux.intel.com>
+Date: Fri, 8 Feb 2013 11:21:45 +0100
+Subject: [PATCH] Use plugin mfld-blackbay
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+---
+ src/desc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/desc.c b/src/desc.c
+index 61833f9..01385a2 100644
+--- a/src/desc.c
++++ b/src/desc.c
+@@ -86,8 +86,8 @@ static int _get_cp_name(char **name)
+
+ /* By default, SUNRISE IMC modem is returned */
+ if (!strcmp(u.nodename, "(none)")) {
+- *name = g_new0(char, 8);
+- strcpy(*name, "imc-pr3");
++ *name = g_new0(char, 14);
++ strcpy(*name, "mfld-blackbay");
+ return 8;
+ }
+
+--
+1.7.10.4
+
--- /dev/null
+#sbs-git:slp/pkgs/t/tel-plugin-imc
+Name: tel-plugin-imc
+Summary: imc plugin for telephony
+Version: 0.1.36
+Release: 1
+Group: Development/Libraries
+License: Apache
+Source0: tel-plugin-imc-%{version}.tar.gz
+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)
+BuildRequires: pkgconfig(libxml-2.0)
+BuildRequires: pkgconfig(vconf)
+%ifarch %ix86
+%if "%{simulator}" != "1"
+patch0: 0001-desc-CP-name-is-imc-pr3-for-Intel-device.patch
+patch1: 0002-s_modem-CGMR-response-parsing-is-compatible-with-IMC.patch
+patch2: 0003-s-modem-Cleanup.patch
+patch3: 0004-s-modem-Add-notification-hook-for-SIM-status.patch
+patch4: 0005-s-sim-Query-SIM-state-when-modem-is-powered-up.patch
+patch5: 0006-common-Fix-warning-errors.patch
+patch6: 0007-s_sim-Get-the-SIM-type-when-SIM-is-ready.patch
+patch7: 0008-Fix-SCA-service-center-address-length-checking-error.patch
+patch8: 0009-s_modem-Add-XGENDATA-query-to-get-firmware-informati.patch
+patch9: 0010-s_sim-Extend-XSIMSTATE-parsing-to-get-SMS-service-st.patch
+patch10: 0011-set-modem-power-saving-mode.patch
+patch11: 0012-Fix-EFsmsp-size-error.patch
+patch12: 0013-s_call-use-hal-set-sound-path-function.patch
+patch13: 0014-Add-core-objects-and-link-them-to-HAL.patch
+patch14: 0015-Change-the-way-imc-plugin-is-initialized.patch
+patch15: 0016-s_ps-Remove-plateform-dependencies-to-setup-pdp-cont.patch
+patch16: 0017-Fix-the-issue-that-system-is-waken-up-by-modem-frequ.patch
+patch17: 0018-Configure-modem-I2s1-to-8khz-mono-if-routing-to-blue.patch
+patch18: 0019-s_sat.c-Fix-envelope-cmd-and-enable-Setup-Event-List.patch
+patch19: 0020-s_sim.c-Fix-get-lock-info.patch
+patch20: 0021-s_sim-Fix-multiple-sim-facility-status-query.patch
+patch21: 0023-s_network.c-By-default-display-the-plmn-in-case-SPN-.patch
+patch22: 0024-Use-plugin-mfld-blackbay.patch
+%endif
+%endif
+
+%description
+IMC plugin for telephony
+
+%prep
+%setup -q
+%ifarch %ix86
+%if "%{simulator}" != "1"
+%patch0 -p1
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
+%patch21 -p1
+%patch22 -p1
+%endif
+%endif
+
+%build
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix}
+make %{?jobs:-j%jobs}
+
+%post
+/sbin/ldconfig
+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
+
+%postun -p /sbin/ldconfig
+
+%install
+rm -rf %{buildroot}
+%make_install
+mkdir -p %{buildroot}/usr/share/license
+
+%files
+
+%defattr(-,root,root,-)
+
+%{_libdir}/telephony/plugins/*
+/tmp/mcc_mnc_oper_list.sql
+/usr/share/license/tel-plugin-imc
--- /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 <string.h>
+
+#define TABLE_NAME "mcc_mnc_oper_list"
+#define TABLE_SCHEMA "create table " TABLE_NAME " (id integer primary key, country char(3), mcc integer, mnc char(3), oper char(45));"
+
+#define dbg(fmt, args ...) fprintf(stderr, fmt, ## args)
+
+int main(int argc, char *argv[])
+{
+ FILE *fp_in;
+
+ char buf[255];
+ char brand[255];
+ char oper[255];
+ char *pos1, *pos2;
+ char country[10];
+ char mnc[10];
+ char *oper_select;
+ int mcc;
+
+ if (argc != 2) {
+ printf("%s filename.csv\n", argv[0]);
+ return -1;
+ }
+
+ fp_in = fopen(argv[1], "r");
+ if (fp_in == NULL) {
+ printf("faild.\n");
+ return -1;
+ }
+
+ printf("%s\n", TABLE_SCHEMA);
+
+ printf("BEGIN;\n");
+ while (1) {
+ fgets(buf, 255, fp_in);
+
+ if (feof(fp_in)) {
+ break;
+ }
+
+ // remove '\n'
+ buf[strlen(buf) - 1] = '\0';
+
+ dbg("\n%s\n", buf);
+
+ pos1 = strchr(buf, ',');
+ memset(country, 0, 10);
+ memcpy(country, buf, pos1 - buf);
+
+ dbg("country=[%s]\n", country);
+
+ sscanf(pos1 + 1, "%d", &mcc);
+ dbg("mcc=[%d]\n", mcc);
+
+ // get mnc
+ pos1 = strchr(pos1 + 1, ',');
+ pos2 = strchr(pos1 + 1, ',');
+
+ dbg("mnc=[%s]\n", pos1 + 1);
+
+ memset(mnc, 0, 10);
+ strncpy(mnc, pos1 + 1, pos2 - pos1 - 1);
+
+ // get brand
+ pos1 = pos2;
+ pos2 = strchr(pos1 + 1, ',');
+
+ dbg("brand=[%s]\n", pos1 + 1);
+
+ memset(brand, 0, 255);
+ strncpy(brand, pos1 + 1, pos2 - pos1 - 1);
+
+ // get oper
+ pos1 = pos2;
+ pos2 = strchr(pos1 + 1, ',');
+
+ dbg("oper=[%s]\n", pos1 + 1);
+
+ memset(oper, 0, 255);
+ strcpy(oper, pos1 + 1);
+
+ oper_select = brand;
+ if (strlen(brand) == 0)
+ oper_select = oper;
+
+ if (oper_select[0] == '\"') {
+ memset(buf, 0, 255);
+ snprintf(buf, strlen(oper_select) - 2, "%s", oper_select + 1);
+ snprintf(oper_select, 255, "%s", buf);
+ }
+
+ snprintf(buf, 255, "insert into %s "
+ " (country, mcc, mnc, oper) "
+ " values (\"%s\", %d, \"%s\", \"%s\");",
+ TABLE_NAME, country, mcc, mnc, oper_select);
+ printf("%s\n", buf);
+ }
+ printf("COMMIT;\n");
+
+ fclose(fp_in);
+}
--- /dev/null
+Country,MCC,MNC,Brand,Operator
+__,001,01,TEST,Test Network
+GE,289,67,Aquafon,Aquafon
+GE,289,88,A-Mobile,A-Mobile
+AF,412,01,AWCC,Afghan Wireless Communication Company
+AF,412,20,Roshan,Telecom Development Company Afghanistan Ltd.
+AF,412,40,MTN,MTN Group Afghanistan
+AF,412,50,Etisalat,Etisalat Afghanistan
+AL,76,01,AMC,Albanian Mobile Communications
+AL,276,02,Vodafone,Vodafone Albania
+AL,276,03,Eagle Mobile,Eagle Mobile
+AL,276,04,Plus Communication,Plus Communication
+DZ,603,01,Mobilis,ATM Mobilis
+DZ,603,02,Djezzy,Orascom Telecom Algerie Spa
+DZ,603,03,Nedjma,Wataniya Telecom Algerie
+AS,44,11,Bluesky,Bluesky
+AD,213,03,Mobiland,Servei De Tele. DAndorra
+AO,631,02,UNITEL,UNITEL S.a.r.l.
+AO,631,04,MOVICEL,MOVICEL Telecommunications S.a.
+AI,365,010,,Weblinks Limited
+AI,365,840,,Cable & Wireless
+AG,344,030,APUA,Antigua Public Utilities Authority
+AG,344,920,LIME,Cable & Wireless Caribbean Cellular (Antigua) Limited
+AG,338,050,Digicel,Antigua Wireless Ventures Limited
+AR,722,010,Movistar,Telefonica Móviles Argentina SA
+AR,722,020,Nextel,NII Holdings
+AR,722,070,Movistar,Telefonica Móviles Argentina SA
+AR,722,310,Claro,AMX Argentina S.A
+AR,722,320,Claro,AMX Argentina S.A
+AR,722,330,Claro,AMX Argentina S.A
+AR,722,34,Personal,Telecom Personal SA
+AR,722,341,Personal,Telecom Personal SA
+AR,722,350,,Hutchinson (PORT HABLE)
+AR,722,36,Personal,Telecom Personal SA
+AM,283,01,Beeline,ArmenTel
+AM,283,05,VivaCell-MTS,K Telecom CJSC
+AM,283,10,Orange,
+AW,363,01,SETAR,Servicio di Telecomunicacion di Aruba
+AW,363,02,Digicel,
+AU,505,01,Telstra,Telstra Corporation Limited
+AU,505,02,Optus,Singtel Optus Proprietary Limited
+AU,505,03,Vodafone,Vodafone Hutchison Australia Proprietary Limited
+AU,505,04,,Department of Defence
+AU,505,05,Ozitel,
+AU,505,06,3,Vodafone Hutchison Australia Proprietary Limited
+AU,505,08,One.Tel,One.Tel Limited
+AU,505,09,Airnet,
+AU,505,12,3,Vodafone Hutchison Australia Proprietary Limited
+AU,505,13,Railcorp,Rail Corporation New South Wales
+AU,505,14,AAPT,Telecom New Zealand
+AU,505,15,3GIS,
+AU,505,16,Victorian Rail Track,
+AU,505,21,SOUL,TPG Telecom Limited
+AU,505,24,Advance Communications Technologies Pty. Ltd.,
+AU,505,38,Crazy John's,Vodafone Hutchison Australia Proprietary Limited
+AU,505,71,Telstra,Telstra Corporation Limited
+AU,505,72,Telstra,Telstra Corporation Limited
+AU,505,88,Localstar Holding Pty. Ltd.,
+AU,505,90,Optus,Singtel Optus Proprietary Limited
+AU,505,99,One.Tel,One.Tel
+AT,232,01,A1,A1 Telekom Austria
+AT,232,03,T-Mobile,T-Mobile Austria
+AT,232,05,Orange,Orange Austria
+AT,232,07,tele.ring,T-Mobile Austria
+AT,232,09,A1,A1 Telekom Austria
+AT,232,10,3,Hutchison 3G
+AT,232,11,bob,A1 Telekom Austria
+AT,232,12,yesss,yesss
+AT,232,14,3,Hutchison 3G
+AT,232,15,Barablu,Barablu Mobile Ltd.
+AT,232,91,GSM-R A,ÖBB
+AZ,400,01,Azercell,
+AZ,400,02,Bakcell,
+AZ,400,03,FONEX,CATEL
+AZ,400,04,Nar Mobile,Azerfon
+BS,364,390,BaTelCo,The Bahamas Telecommunications Company Ltd
+BH,426,01,Batelco,Bahrain Telecommunications Company
+BH,426,02,zain BH,Zain Bahrain
+BH,426,04,VIVA,Viva Bahrain
+BD,470,01,Grameenphone,GrameenPhone Ltd
+BD,470,02,Robi,Axiata Bangladesh Ltd.
+BD,470,03,Banglalink,Orascom Telecom Holding
+BD,470,04,TeleTalk,
+BD,470,05,Citycell,
+BD,470,06,Airtel formerly Warid Telcom,Bharti airtel Bangladesh Ltd.
+BB,342,600,LIME,LIME (formerly known as Cable & Wireless)
+BB,342,750,Digicel,Digicel (Barbados) Limited
+BB,342,820,,Sunbeach Communications
+BY,257,01,velcom,
+BY,257,02,MTS,Mobile TeleSystems
+BY,257,03,DIALLOG,BelCel
+BY,257,04,life:),Belarussian Telecommunications Network
+BY,257,501,BelCel JV,
+BE,206,01,Proximus,Belgacom Mobile
+BE,206,05,Telenet,Telenet
+BE,206,10,Mobistar,France Telecom
+BE,206,20,BASE,KPN
+BZ,702,67,DigiCell,Belize Telemedia
+BZ,702,99,Smart,SpeedNet Communications Limited
+BJ,616,01,Libercom,Benin Telecoms Mobile
+BJ,616,02,Moov,Telecel Benin
+BJ,616,03,MTN,Spacetel Benin
+BJ,616,04,BBCOM,Bell Benin Communications
+BJ,616,05,Glo,Glo Communication Benin
+BM,350,01,Digicel Bermuda,Telecommunications (Bermuda & West Indies) Ltd
+BM,350,02,Mobility,M3 Wireless
+BM,338,050,Digicel Bermuda,
+BM,310,59,Cellular One,
+BT,402,11,B-Mobile,B-Mobile
+BT,402,77,TashiCell,Tashi InfoComm Limited
+BO,736,01,Nuevatel,Nuevatel PCS De Bolivia SA
+BO,736,02,Entel,Entel SA
+BO,736,03,Tigo,Telefonica Celular De Bolivia S.A
+BA,218,03,HT-ERONET,Public Enterprise Croatian Telecom Ltd.
+BA,218,05,m:tel,RS Telecommunications JSC Banja Luka
+BA,218,90,BH Mobile,BH Telecom
+BW,652,01,Mascom,Mascom Wireless (Pty) Limited
+BW,652,02,Orange,Orange (Botswana) Pty Limited
+BW,652,04,BTC Mobile,Botswana Telecommunications Corporation
+BR,724,00,Nextel,"NII Holdings, Inc."
+BR,724,02,TIM,Telecom Italia Mobile
+BR,724,03,TIM,Telecom Italia Mobile
+BR,724,04,TIM,Telecom Italia Mobile
+BR,724,05,Claro BR,Claro
+BR,724,06,Vivo,Vivo S.A.
+BR,724,07,Sercomtel,Sercomtel Celular
+BR,724,10,Vivo,Vivo S.A.
+BR,724,11,Vivo,Vivo S.A.
+BR,724,15,CTBC Celular,CTBC Celular S.A.
+BR,724,16,Brasil Telecom GSM,Brasil Telecom GSM
+BR,724,23,Vivo,Vivo S.A.
+BR,724,31,Oi,TNL PCS
+BR,724,32,CTBC Celular,CTBC Celular S.A.
+BR,724,33,CTBC Celular,CTBC Celular S.A.
+BR,724,34,CTBC Celular,CTBC Celular S.A.
+BR,724,39,Nextel,"NII Holdings, Inc."
+VG,348,170,LIME,Cable & Wireless
+VG,348,570,CCT Boatphone,Caribbean Cellular Telephone
+VG,348,770,Digicel,Digicel (BVI) Limited
+BN,528,01,,Jabatan Telekom Brunei
+BN,528,02,B-Mobile,B-Mobile Communications Sdn Bhd
+BN,528,11,DSTCom,Data Stream Technology
+BG,284,01,M-Tel,Mobiltel
+BG,284,03,Vivacom,BTC
+BG,284,04,Undisclosed,Undisclosed
+BG,284,05,GLOBUL,Cosmo Bulgaria Mobile
+BF,613,01,Telmob,Onatal
+BF,613,02,Zain,Celtel Burkina Faso
+BF,613,03,Telecel Faso,Telecel Faso SA
+BI,642,01,Spacetel,Econet Wireless Burundi PLC
+BI,642,02,Africell,Africell PLC
+BI,642,03,Onatel,Onatel
+BI,642,07,Smart Mobile,LACELL SU
+BI,642,08,HiTs Telecom,HiTs Telecom
+BI,642,82,U-COM Burundi,U-COM Burundi S.A.
+KH,456,01,Mobitel,CamGSM
+KH,456,02,hello,Telekom Malaysia International (Cambodia) Co. Ltd
+KH,456,03,,S Telecom
+KH,456,04,qb,Cambodia Advance Communications Co. Ltd
+KH,456,05,Star-Cell,APPLIFONE CO. LTD.
+KH,456,06,Smart Mobile,"Latelz Co., Ltd"
+KH,456,18,Mfone,Camshin / Shinawatra
+KH,456,11,Excell,
+KH,456,09,Beeline,Sotelco Ltd.
+KH,456,08,Metfone,Viettel
+CM,624,01,MTN Cameroon,Mobile Telephone Network Cameroon Ltd
+CM,624,02,Orange,Orange Cameroun S.A.
+CA,302,220,Telus,Telus Mobility
+CA,302,221,Telus,Telus Mobility
+CA,302,270,unknown,EastLink
+CA,302,290,,Airtel Wireless
+CA,302,320,Mobilicity,DAVE Wireless
+CA,302,350,FIRST,FIRST Networks Operations
+CA,302,360,MiKe,Telus Mobility
+CA,302,361,Telus,Telus Mobility
+CA,302,370,Fido,Fido Solutions (Rogers Wireless)
+CA,302,380,DMTS,Dryden Mobility
+CA,302,490,WIND Mobile,Globalive Communications
+CA,302,500,Videotron,Videotron
+CA,302,510,Videotron,Videotron
+CA,302,610,Bell,Bell Mobility
+CA,302,610,Bell,Virgin Mobile Canada
+CA,302,620,ICE Wireless,ICE Wireless
+CA,302,640,Bell,Bell Mobility
+CA,302,652,,BC Tel Mobility (Telus)
+CA,302,653,Telus,Telus Mobility
+CA,302,655,MTS,MTS Mobility
+CA,302,656,TBay,Thunder Bay Telephone Mobility
+CA,302,657,Telus,Telus Mobility
+CA,302,660,MTS,MTS Mobility
+CA,302,680,SaskTel,SaskTel Mobility
+CA,302,701,,MB Tel Mobility
+CA,302,702,,MT&T Mobility (Aliant)
+CA,302,703,,New Tel Mobility (Aliant)
+CA,302,710,Globalstar,
+CA,302,720,Rogers Wireless,Rogers Communications
+CA,302,780,SaskTel,SaskTel Mobility
+CA,302,880,Bell / Telus / SaskTel,"Shared Telus, Bell, and SaskTel"
+CV,625,01,CVMOVEL,"CVMovel, S.A."
+CV,625,02,T+,T+
+KY,346,140,LIME,Cable & Wireless (Cayman Islands) Limited
+KY,346,50,Digicel,Digicel Cayman Ltd.
+CF,623,01,CTP,Centrafrique Telecom Plus
+CF,623,02,TC,Telecel Centrafrique
+CF,623,03,Orange,Orange RCA
+CF,623,04,Nationlink,Nationlink Telecom RCA
+TD,622,01,Airtel,Bharti Airtel SA
+TD,622,02,,Tchad Mobile
+TD,622,03,,TIGO - Millicom
+TD,622,04,Salam,Sotel Mobile
+CL,730,01,entel,Entel PCS Telecomunicaciones S.A.
+CL,730,02,movistar,Telefónica Móvil de Chile
+CL,730,03,Claro,Claro Chile S.A.
+CL,730,04,Nextel,Centennial Cayman Corp. Chile
+CL,730,08,VTR Móvil,VTR S.A.
+CL,730,09,Nextel,Centennial Cayman Corp. Chile
+CL,730,10,entel,Entel Telefonía Móvil S.A.
+CL,730,99,Will,WILL Telefonía
+CN,460,00,China Mobile,China Mobile
+CN,460,01,China Unicom,China Unicom
+CN,460,02,China Mobile,China Mobile
+CN,460,03,China Telecom,China Telecom
+CN,460,05,China Telecom,China Telecom
+CN,460,06,China Unicom,China Unicom
+CN,460,07,China Mobile,China Mobile
+CN,460,20,China Tietong,China Tietong
+CO,732,001,,Colombia Telecomunicaciones S.A.
+CO,732,002,Edatel,Edatel S.A.
+CO,732,101,Comcel,Comcel Colombia
+CO,732,102,movistar,Bellsouth Colombia
+CO,732,103,Tigo,Colombia Móvil
+CO,732,111,Tigo,Colombia Móvil
+CO,732,123,movistar,Telefónica Móviles Colombia
+KM,654,01,,HURI - SNPT
+CG,629,01,Airtel,Celtel Congo
+CG,629,10,Libertis Telecom,MTN CONGO S.A
+CG,629,07,,Warid Telecom
+CK,548,01,,Telecom Cook
+CR,712,01,Kolbi ICE,Instituto Costarricense de Electricidad
+CR,712,02,Kolbi ICE,Instituto Costarricense de Electricidad
+CR,712,03,Claro,Claro CR Telecomunicaciones
+CR,712,04,movistar,Telefonica Móviles Costa Rica
+HR,219,01,T-Mobile,T-Mobile Croatia
+HR,219,02,Tele2,Tele2
+HR,219,10,Vip,Vipnet
+CU,368,01,CUBACEL,"Empresa de Telecomunicaciones de Cuba, SA"
+CY,280,01,Cytamobile-Vodafone,Cyprus Telecommunications Auth
+CY,280,10,MTN,Areeba Ltd
+CZ,230,01,T-Mobile,T-Mobile Czech Republic
+CZ,230,02,O2,Telefónica Czech Republic
+CZ,230,03,Vodafone,Vodafone Czech Republic
+CZ,230,04,U:fon,"MobilKom, a. s."
+CZ,230,05,,"TRAVEL TELEKOMMUNIKATION, s.r.o."
+CZ,230,06,,"OSNO TELECOMUNICATION, s.r.o."
+CZ,230,98,,"Správa železniční dopravní cesty, s.o."
+CZ,230,99,Vodafone,Vodafone Czech Republic
+CD,630,01,Vodacom,Vodacom Congo RDC sprl
+CD,630,02,Zain,Celtel Congo
+CD,630,04,,Cellco
+CD,630,05,Supercell,Supercell SPRL
+CD,630,10,Libertis Telecom,
+CD,630,86,CCT,Congo-Chine Telecom s.a.r.l.
+CD,630,89,SAIT Telecom,OASIS SPRL
+DK,238,01,TDC,TDC A/S
+DK,238,02,Telenor,Telenor Denmark
+DK,238,03,,MIGway A/S
+DK,238,05,,ApS KBUS
+DK,238,06,3,Hi3G Denmark ApS
+DK,238,07,,Barablu Mobile Ltd.
+DK,238,09,,Dansk Beredskabskommunikation A/S
+DK,238,10,TDC,TDC A/S
+DK,238,11,,Dansk Beredskabskommunikation A/S
+DK,238,12,,Lycamobile Denmark Ltd
+DK,238,20,Telia,
+DK,238,30,Telia,Telia Nättjänster Norden AB
+DK,238,40,,Ericsson Danmark A/S
+DK,238,77,Telenor,Telenor Denmark
+DJ,638,01,Evatis,Djibouti Telecom SA
+DM,366,020,Digicel,Digicel Group Limited
+DM,366,110,,Cable & Wireless
+DO,370,01,Orange,Orange Dominicana
+DO,370,02,Claro,"Compañía Dominicana de Teléfonos, C por"
+DO,370,03,Tricom,Tricom S.A.
+DO,370,04,Viva,"Trilogy Dominicana, S.A."
+TL,514,02,,Timor Telecom
+EC,740,00,Movistar,Otecel S.A.
+EC,740,01,Claro,CONECEL S.A.
+EC,740,02,Alegro,Corporación Nacional de Telecomunicaciones CNT EP
+EG,602,01,Mobinil,ECMS-Mobinil
+EG,602,02,Vodafone,Vodafone Egypt
+EG,602,03,Etisalat,Etisalat Egypt
+SV,706,01,CTE Telecom Personal,CTE Telecom Personal SA de CV
+SV,706,02,digicel,Digicel Group
+SV,706,03,Tigo,Telemovil EL Salvador S.A.
+SV,706,04,movistar,Telefónica Móviles El Salvador
+SV,706,11,Claro,América Móvil
+GQ,627,01,Orange GQ,GETESA
+GQ,627,03,Hits GQ,HiTs EG.SA
+ER,657,01,Eritel,Eritrea Telecommunications Services Corporation
+EE,248,01,EMT,Estonian Mobile Telecom
+EE,248,02,Elisa,Elisa Eesti
+EE,248,03,Tele 2,Tele 2 Eesti
+EE,248,04,,OY Top Connect
+EE,248,05,,AS Bravocom Mobiil
+EE,248,06,,Progroup Holding
+ET,636,01,ETH-MTN,Ethio Telecom
+FO,288,01,Faroese Telecom,Faroese Telecom
+FO,288,02,Vodafone,Vodafone Faroe Islands
+FJ,542,01,Vodafone,Vodafone Fiji
+FJ,542,02,Digicel,Digicel Fiji
+FI,244,03,DNA,DNA Oy
+FI,244,05,Elisa,Elisa Oyj
+FI,244,07,Nokia,Nokia Test Network
+FI,244,08,,Unknown
+FI,244,10,,TDC Oy
+FI,244,11,VIRVE,Suomen Erillisverkot Oy
+FI,244,12,DNA,DNA Oy
+FI,244,14,AMT,Ålands Mobiltelefon
+FI,244,15,SAMK,Samk student network
+FI,244,21,Saunalahti,Elisa Oyj
+FI,244,29,,Scnl Truphone
+FI,244,91,Sonera,TeliaSonera Finland Oyj
+FR,208,00,Orange,France Télécom
+FR,208,01,Orange,France Télécom
+FR,208,02,Orange,France Télécom
+FR,208,05,,Globalstar Europe
+FR,208,06,,Globalstar Europe
+FR,208,07,,Globalstar Europe
+FR,208,10,SFR,Vivendi
+FR,208,11,SFR,Vivendi
+FR,208,13,SFR,Vivendi
+FR,208,14,Free Mobile,Iliad
+FR,208,15,Free Mobile,Iliad
+FR,208,20,Bouygues,Bouygues Telecom
+FR,208,21,Bouygues,Bouygues Telecom
+FR,208,22,Transatel Mobile,Transatel
+FR,208,88,Bouygues,Bouygues Telecom
+PF,547,20,Vini,Tikiphone SA
+GA,628,01,Libertis,Gabon Telecom & Libertis S.A.
+GA,628,02,Moov,Atlantique Télécom (Etisalat Group) Gabon S.A.
+GA,628,03,Airtel,Airtel Gabon S.A.
+GA,628,04,Azur,USAN Gabon S.A.
+GM,607,01,Gamcel,Gamcel
+GM,607,02,Africel,Africel
+GM,607,03,Comium,Comium
+GM,607,04,QCell,QCell Gambia
+GE,282,01,Geocell,Geocell Limited
+GE,282,02,MagtiCom,Magticom GSM
+GE,282,03,MagtiCom,Magtifix
+GE,282,04,Beeline,Mobitel LLC
+GE,282,05,Silknet,Silknet CDMA
+DE,262,01,T-Mobile,T-Mobile Deutschland GmbH
+DE,262,02,Vodafone,Vodafone D2 GmbH
+DE,262,03,E-Plus,E-Plus Mobilfunk
+DE,262,04,Vodafone,
+DE,262,05,E-Plus,E-Plus Mobilfunk
+DE,262,06,T-Mobile,
+DE,262,07,O2,O2 (Germany) GmbH & Co. OHG
+DE,262,08,O2,
+DE,262,09,Vodafone,
+DE,262,10,,Arcor AG & Co
+DE,262,11,O2,
+DE,262,12,,Dolphin Telecom
+DE,262,13,,Mobilcom Multimedia
+DE,262,14,,Group 3G UMTS
+DE,262,15,Airdata,
+DE,262,16,Vistream,
+DE,262,42,27C3,Chaos Computer Club
+DE,262,43,LYCA,Lycamobile
+DE,262,60,,DB Telematik
+DE,262,76,,Siemens AG
+DE,262,77,E-Plus,
+DE,262,92,Nash Technologies,
+DE,262,901,Debitel,
+GH,620,01,MTN,MTN Group
+GH,620,02,Vodafone,Vodafone Group
+GH,620,03,tiGO,Millicom Ghana
+GH,620,04,Expresso,Kasapa / Hutchison Telecom
+GH,620,06,Airtel,Airtel
+GI,266,01,GibTel,Gibraltar Telecoms
+GI,266,06,CTS Mobile,CTS Gibraltar
+GR,202,01,Cosmote,COSMOTE - Mobile Telecommunications S.A.
+GR,202,05,Vodafone,Vodafone Greece
+GR,202,09,Wind,Wind Hellas Telecommunications S.A. (Q-Telecom)
+GR,202,10,Wind,Wind Hellas Telecommunications S.A.
+GL,290,01,,TELE Greenland A/S
+GD,352,030,Digicel,Digicel Grenada Ltd.
+GD,352,110,Cable & Wireless,Cable & Wireless Grenada Ltd.
+GP,340,01,Orange,Orange Caraïbe Mobiles
+GP,340,02,Outremer,Outremer Telecom
+GP,340,03,Telcell,Saint Martin et Saint Barthelemy Telcell Sarl
+GP,340,08,Dauphin,Dauphin Telecom
+GP,340,20,Digicel,DIGICEL Antilles Française Guyane
+GU,310,032,IT&E Wireless,"IT&E Overseas, Inc"
+GU,310,033,,Guam Telephone Authority
+GU,310,140,mPulse,GTA Wireless
+GU,310,370,docomo,docomo Pacific
+GU,311,250,i CAN_GSM,Wave Runner LLC
+GU,310,470,docomo,docomo Pacific
+GT,704,01,Claro,Servicios de Comunicaciones Personales Inalambricas (SERCOM)
+GT,704,02,Comcel / Tigo,Millicom / Local partners
+GT,704,03,movistar,Telefonica Móviles Guatemala (Telefónica)
+GB,234,55,Sure Mobile,Cable & Wireless Guernsey
+GB,234,50,Wave Telecom,Wave Telecom (JT-Wave)
+GB,234,03,Airtel Vodafone,Guernsey Airtel Ltd
+GN,611,01,Orange S.A.,Orange
+GN,611,02,Sotelgui,Sotelgui Lagui
+GN,611,03,Telecel Guinee,INTERCEL Guinée
+GN,611,04,MTN,Areeba Guinea
+GN,611,05,Cellcom,Cellcom
+GW,632,02,Areeba,Spacetel Guiné-Bissau S.A.
+GW,632,03,Orange,
+GY,738,01,Digicel,U-Mobile (Cellular) Inc.
+GY,738,02,GT&T Cellink Plus,Guyana Telephone & Telegraph Co.
+HT,372,01,Voila,Communication Cellulaire d'Haiti S.A.
+HT,372,02,Digicel,Unigestion Holding S.A.
+HT,372,03,NATCOM,Telecommunication S.A.
+HN,708,01,Claro,Servicios de Comunicaciones de Honduras S.A. de C.V.
+HN,708,02,Tigo,Celtel / Tigo
+HN,708,30,Hondutel,Empresa Hondureña de Telecomunicaciones
+HN,708,40,DIGICEL,Digicel de Honduras
+HK,454,00,1O1O / One2Free,CSL Limited merged New World
+HK,454,01,,CITIC Telecom 1616
+HK,454,02,,CSL Limited
+HK,454,03,3 (3G),Hutchison Telecom
+HK,454,04,3 (2G),Hutchison Telecom
+HK,454,05,3 (CDMA),Hutchison Telecom
+HK,454,06,SmarTone,SmarTone Mobile Communications Limited
+HK,454,07,,China Unicom (Hong Kong) Limited
+HK,454,08,,Trident Telecom
+HK,454,09,,China Motion Telecom
+HK,454,10,New World Mobility,CSL Limited
+HK,454,11,,China-Hong Kong Telecom
+HK,454,12,CMCC HK,China Mobile Hong Kong Company Limited
+HK,454,14,,Hutchison Telecom
+HK,454,15,,SmarTone Mobile Communications Limited
+HK,454,16,PCCW Mobile (2G),PCCW Limited
+HK,454,17,,SmarTone Mobile Communications Limited
+HK,454,18,,CSL Limited
+HK,454,19,PCCW Mobile (3G),PCCW Limited
+HK,454,29,PCCW Mobile (CDMA),PCCW Limited
+HU,216,01,Telenor,Telenor Magyarország Zrt.
+HU,216,30,T-Mobile,Magyar Telekom Plc
+HU,216,70,Vodafone,Vodafone Magyarország Zrt.
+IS,274,01,Síminn,Iceland Telecom
+IS,274,02,Vodafone,Og fjarskipti hf
+IS,274,03,Vodafone,Vodafone Iceland
+IS,274,04,Viking,IMC Island ehf
+IS,274,06,,Núll níu ehf
+IS,274,07,IceCell,IceCell ehf
+IS,274,08,On-waves,Iceland Telecom
+IS,274,11,Nova,Nova ehf
+IS,274,12,Tal,Tal hf
+IN,404,01,Vodafone IN,Haryana
+IN,404,02,AirTel,Punjab
+IN,404,03,AirTel,Himachal Pradesh
+IN,404,04,IDEA,Delhi & NCR
+IN,404,05,Vodafone IN,Gujarat
+IN,404,07,IDEA,Andhra Pradesh
+IN,404,09,Reliance,Assam
+IN,404,10,AirTel,Delhi & NCR
+IN,404,11,Vodafone IN,Delhi & NCR
+IN,404,12,IDEA,Haryana
+IN,404,13,Vodafone IN,Andhra Pradesh
+IN,404,14,IDEA,Punjab
+IN,404,15,Vodafone IN,Uttar Pradesh (East)
+IN,404,17,AIRCEL,West Bengal
+IN,404,19,IDEA,Kerala
+IN,404,20,Vodafone IN,Mumbai
+IN,404,21,Loop Mobile,Mumbai
+IN,404,22,IDEA,Maharashtra & Goa
+IN,404,24,IDEA,Gujarat
+IN,404,25,AIRCEL,Bihar
+IN,404,27,Vodafone IN,Maharashtra & Goa
+IN,404,28,AIRCEL,Orissa
+IN,404,29,AIRCEL,Assam
+IN,404,30,Vodafone IN,Kolkata
+IN,404,31,AirTel,Kolkata
+IN,404,34,CellOne,Haryana
+IN,404,36,Reliance,Bihar & Jharkhand
+IN,404,37,Aircel,Jammu & Kashmir
+IN,404,38,CellOne,Assam
+IN,404,41,Aircel,Chennai
+IN,404,42,Aircel,Tamil Nadu
+IN,404,44,IDEA,Karnataka
+IN,404,45,Airtel,Karnataka
+IN,404,46,Vodafone IN,Kerala
+IN,404,48,Dishnet Wireless,Unknown
+IN,404,49,Airtel,Andhra Pradesh
+IN,404,51,CellOne,Himachal Pradesh
+IN,404,52,Reliance,Orissa
+IN,404,53,CellOne,Punjab
+IN,404,54,CellOne,Uttar Pradesh (West)
+IN,404,55,CellOne,Uttar Pradesh (East)
+IN,404,71,CellOne,Karnataka (Bangalore)
+IN,404,56,IDEA,Uttar Pradesh (West)
+IN,404,57,CellOne,Gujarat
+IN,404,58,CellOne,Madhya Pradesh & Chhattisgarh
+IN,404,59,CellOne,Rajasthan
+IN,404,60,Vodafone IN,Rajasthan
+IN,404,62,CellOne,Jammu & Kashmir
+IN,404,64,CellOne,Chennai
+IN,404,66,CellOne,Maharashtra & Goa
+IN,404,67,Reliance GSM,Madhya Pradesh & Chhattisgarh
+IN,404,68,DOLPHIN,Delhi & NCR
+IN,404,69,DOLPHIN,Mumbai
+IN,404,72,CellOne,Kerala
+IN,404,74,CellOne,West Bengal
+IN,404,76,CellOne,Orissa
+IN,404,78,Idea Cellular Ltd,Madhya Pradesh & Chattishgarh
+IN,404,80,BSNL MOBILE,Bharat Sanchar Nigam Limited
+IN,404,81,CellOne,Kolkata
+IN,404,82,Idea,Himachal Pradesh
+IN,404,83,Reliance Smart GSM,Kolkata
+IN,404,84,Vodafone IN,Chennai
+IN,404,85,Reliance,West Bengal
+IN,404,86,Vodafone IN,Karnataka
+IN,404,87,Idea,Rajisthan
+IN,404,88,Vodafone IN,Vodafone Punjab
+IN,404,89,Idea,Uttar Pradesh (East)
+IN,404,90,AirTel,Maharashtra & Goa
+IN,404,91,AIRCEL,Kolkata
+IN,404,92,AirTel,Mumbai
+IN,404,93,AirTel,Madhya Pradesh
+IN,404,96,AirTel,Haryana
+IN,405,01,Reliance,Andhra Pradesh
+IN,405,03,Reliance,Bihar
+IN,405,04,Reliance,Chennai
+IN,405,05,Reliance,Delhi & NCR
+IN,405,09,Reliance,Jammu & Kashmir
+IN,405,10,Reliance,Karnataka
+IN,405,13,Reliance,Maharashtra & Goa
+IN,405,025,TATA Teleservice,Andhra Pradesh
+IN,405,026,TATA Teleservice,Assam
+IN,405,027,TATA Teleservice,Bihar/Jharkhand
+IN,405,029,TATA Teleservice,Delhi
+IN,405,030,TATA Teleservice,Gujarat
+IN,405,031,TATA Teleservice,Haryana
+IN,405,032,TATA Teleservice,Himachal Pradesh
+IN,405,033,TATA Teleservice,Jammu & Kashmir
+IN,405,034,TATA Teleservice,Karnataka
+IN,405,035,TATA Teleservice,Kerala
+IN,405,036,TATA Teleservice,Kolkata
+IN,405,037,TATA Teleservice,Maharashtra & Goa
+IN,405,038,TATA Teleservice,Madhya Pradesh
+IN,405,039,TATA Teleservice,Mumbai
+IN,405,041,TATA Teleservice,Orissa
+IN,405,042,TATA Teleservice,Punjab
+IN,405,043,TATA Teleservice,Rajasthan
+IN,405,044,TATA Teleservice,Tamil Nadu including Chennai
+IN,405,045,TATA Teleservice,[Uttar Pradesh (E)]
+IN,405,046,TATA Teleservice,[Uttar Pradesh (W) & Uttarkhand ]
+IN,405,047,TATA Teleservice,[West Bengal]
+IN,405,51,AirTel,West Bengal
+IN,405,52,AirTel,Bihar & Jharkhand
+IN,405,54,AirTel,Uttar Pradesh (East)
+IN,405,55,Airtel,Jammu & Kashmir
+IN,405,56,AirTel,Assam
+IN,405,66,Vodafone IN,Uttar Pradesh (West)
+IN,405,70,IDEA,Bihar & Jharkhand
+IN,405,750,Vodafone IN,Jammu & Kashmir
+IN,405,751,Vodafone IN,Assam
+IN,405,752,Vodafone IN,Bihar & Jharkhand
+IN,405,753,Vodafone IN,Orissa
+IN,405,754,Vodafone IN,Himachal Pradesh
+IN,405,755,Vodafone IN,North East
+IN,405,756,Vodafone IN,Madhya Pradesh & Chhattisgarh
+IN,405,799,IDEA,Mumbai
+IN,405,800,AIRCEL,Delhi & NCR
+IN,405,801,AIRCEL,Andhra Pradesh
+IN,405,802,AIRCEL,Gujarat
+IN,405,803,AIRCEL,Karnataka
+IN,405,804,AIRCEL,Maharashtra & Goa
+IN,405,805,AIRCEL,Mumbai
+IN,405,806,AIRCEL,Rajasthan
+IN,405,807,AIRCEL,Haryana
+IN,405,808,AIRCEL,Madhya Pradesh
+IN,405,809,AIRCEL,Kerala
+IN,405,810,AIRCEL,Uttar Pradesh (East)
+IN,405,811,AIRCEL,Uttar Pradesh (West)
+IN,405,812,AIRCEL,Punjab
+IN,405,819,Uninor,Andhra Pradesh
+IN,405,818,Uninor,Uttar Pradesh (West)
+IN,405,820,Uninor,Karnataka
+IN,405,821,Uninor,Kerala
+IN,405,822,Uninor,Kolkata
+IN,405,824,Videocon Datacom,Assam
+IN,405,827,Videocon Datacom,Gujarat
+IN,405,834,Videocon Datacom,Madhya Pradesh
+IN,405,844,Uninor,Delhi & NCR
+IN,405,845,IDEA,Assam
+IN,405,86,IDEA,Jammu & Kashmir
+IN,405,848,IDEA,Kolkata
+IN,405,850,IDEA,Orissa
+IN,405,855,Loop Mobile,Assam
+IN,405,864,Loop Mobile,Kolkata
+IN,405,865,Loop Mobile,Madhya Pradesh
+IN,405,875,Uninor,Assam
+IN,405,880,Uninor,West Bengal
+IN,405,881,S Tel,Assam
+IN,405,912,Etisalat DB(cheers),Andhra Pradesh
+IN,405,913,Etisalat DB(cheers),Delhi & NCR
+IN,405,914,Etisalat DB(cheers),Gujarat
+IN,405,917,Etisalat DB(cheers),Kerala
+IN,404,927,Uninor,Gujarat
+IN,405,929,Uninor,Maharashtra
+ID,510,00,PSN,PT Pasifik Satelit Nusantara (ACeS)
+ID,510,01,INDOSAT,PT Indonesian Satellite Corporation Tbk (INDOSAT)
+ID,510,03,StarOne,PT Indosat Tbk
+ID,510,07,TelkomFlexi,PT Telkom
+ID,510,08,AXIS,PT Natrindo Telepon Seluler
+ID,510,09,SMART,PT Smart Telecom
+ID,510,10,Telkomsel,PT Telekomunikasi Selular
+ID,510,11,XL,PT XL Axiata Tbk
+ID,510,20,TELKOMMobile,PT Telkom Indonesia Tbk
+ID,510,21,IM3,PT Indonesian Satellite Corporation Tbk (INDOSAT)
+ID,510,27,Ceria,PT Sampoerna Telekomunikasi Indonesia
+ID,510,28,Fren/Hepi,PT Mobile-8 Telecom
+ID,510,89,3,PT Hutchison CP Telecommunications
+ID,510,99,Esia,PT Bakrie Telecom
+IR,432,11,IR-MCI,Mobile Communications Company of Iran
+IR,432,14,TKC,KFZO
+IR,432,19,MTCE,Mobile Telecommunications Company of Esfahan
+IR,432,32,Taliya,Rafsanjan Industrial Complex
+IR,432,35,Irancell,Irancell Telecommunications Services Company
+IR,432,70,TCI,Telephone Communications Company of Iran
+IR,432,93,Iraphone,Iraphone
+IQ,418,05,Asia Cell,Asia Cell Telecommunications Company
+IQ,418,08,SanaTel,
+IQ,418,20,Zain,Zain Iraq
+IQ,418,30,Zain,Zain Iraq
+IQ,418,40,Korek,Korek Telecom Ltd
+IQ,418,45,Mobitel,Mobitel Co. Ltd.
+IQ,418,92,Omnnea,Omnnea Wireless
+IE,272,01,Vodafone,Vodafone Ireland
+IE,272,02,O2,O2 Ireland
+IE,272,03,Meteor,Meteor Mobile Communications
+IE,272,04,,Access Telecom
+IE,272,05,3,Hutchison 3G Ireland limited
+IE,272,07,Eircom,Eircom Mobile
+IE,272,09,,Clever Communications
+IE,272,11,,Liffey Telecom
+IM,234,58,Pronto GSM,Manx Telecom
+IM,234,09,Sure Mobile,Cable & Wireless Isle of Man Ltd.
+IL,425,01,Orange,Partner Communications Company Ltd
+IL,425,02,Cellcom,
+IL,425,03,Pelephone,
+IL,425,77,Mirs,
+IT,222,01,TIM,Telecom Italia SpA
+IT,222,02,Elsacom,
+IT,222,07,Noverca,
+IT,222,10,Vodafone,Vodafone Omnitel N.V.
+IT,222,30,RFI,Rete Ferroviaria Italiana
+IT,222,77,IPSE 2000,
+IT,222,88,Wind,Wind Telecomunicazioni SpA
+IT,222,98,Blu,
+IT,222,99,3 Italia,Hutchison 3G
+CI,612,01,,Cora de Comstar
+CI,612,02,Moov,
+CI,612,03,Orange,
+CI,612,04,KoZ,Comium Ivory Coast Inc
+CI,612,05,MTN,
+CI,612,06,ORICEL,ORICEL
+JM,338,020,LIME,Cable & Wireless
+JM,338,050,Digicel,Digicel (Jamaica) Limited
+JM,338,070,Claro,Oceanic Digital Jamaica Limited
+JM,338,180,LIME,Cable & Wireless
+JP,440,00,eMobile,EMOBILE Limited
+JP,440,01,NTT docomo,NTT docomo
+JP,440,02,NTT docomo,NTT DoCoMo Kansai
+JP,440,03,NTT docomo,NTT DoCoMo Hokuriku
+JP,440,04,SoftBank,SoftBank Mobile Corp
+JP,440,06,SoftBank,SoftBank Mobile Corp
+JP,440,07,KDDI,KDDI Corporation
+JP,440,08,KDDI,KDDI Corporation
+JP,440,09,NTT docomo,NTT DoCoMo Kansai
+JP,440,10,NTT docomo,NTT DoCoMo Kansai
+JP,440,11,NTT docomo,NTT DoCoMo Tokai
+JP,440,12,NTT docomo,NTT DoCoMo
+JP,440,13,NTT docomo,NTT DoCoMo
+JP,440,14,NTT docomo,NTT DoCoMo Tohoku
+JP,440,15,NTT docomo,NTT DoCoMo
+JP,440,16,NTT docomo,NTT DoCoMo
+JP,440,17,NTT docomo,NTT DoCoMo
+JP,440,18,NTT docomo,NTT DoCoMo Tokai
+JP,440,19,NTT docomo,NTT DoCoMo Hokkaido
+JP,440,20,SoftBank,SoftBank Mobile Corp
+JP,440,21,NTT docomo,NTT DoCoMo
+JP,440,22,NTT docomo,NTT DoCoMo Kansai
+JP,440,23,DoCoMo,NTT DoCoMo Tokai
+JP,440,24,DoCoMo,NTT DoCoMo Chugoku
+JP,440,25,DoCoMo,NTT DoCoMo Hokkaido
+JP,440,26,DoCoMo,NTT DoCoMo Kyushu
+JP,440,27,DoCoMo,NTT DoCoMoTohoku
+JP,440,28,DoCoMo,NTT DoCoMo Shikoku
+JP,440,29,DoCoMo,NTT DoCoMo
+JP,440,30,DoCoMo,NTT DoCoMo
+JP,440,31,DoCoMo,NTT DoCoMo Kansai
+JP,440,32,DoCoMo,NTT DoCoMo
+JP,440,33,DoCoMo,NTT DoCoMo Tokai
+JP,440,34,DoCoMo,NTT DoCoMo Kyushu
+JP,440,35,DoCoMo,NTT DoCoMo Kansai
+JP,440,36,DoCoMo,NTT DoCoMo
+JP,440,37,DoCoMo,NTT DoCoMo
+JP,440,38,DoCoMo,NTT DoCoMo
+JP,440,39,DoCoMo,NTT DoCoMo
+JP,440,40,SoftBank,SoftBank Mobile Corp
+JP,440,41,SoftBank,SoftBank Mobile Corp
+JP,440,42,SoftBank,SoftBank Mobile Corp
+JP,440,43,SoftBank,SoftBank Mobile Corp
+JP,440,44,SoftBank,SoftBank Mobile Corp
+JP,440,45,SoftBank,SoftBank Mobile Corp
+JP,440,46,SoftBank,SoftBank Mobile Corp
+JP,440,47,SoftBank,SoftBank Mobile Corp
+JP,440,48,SoftBank,SoftBank Mobile Corp
+JP,440,49,DoCoMo,NTT DoCoMo
+JP,440,50,KDDI,KDDI Corporation
+JP,440,51,KDDI,KDDI Corporation
+JP,440,52,KDDI,KDDI Corporation
+JP,440,53,KDDI,KDDI Corporation
+JP,440,54,KDDI,KDDI Corporation
+JP,440,55,KDDI,KDDI Corporation
+JP,440,56,KDDI,KDDI Corporation
+JP,440,58,DoCoMo,NTT DoCoMo Kansai
+JP,440,60,DoCoMo,NTT DoCoMo Kansai
+JP,440,61,DoCoMo,NTT DoCoMo Chugoku
+JP,440,62,DoCoMo,NTT DoCoMo Kyushu
+JP,440,63,DoCoMo,NTT DoCoMo
+JP,440,64,DoCoMo,NTT DoCoMo
+JP,440,65,DoCoMo,NTT DoCoMo Shikoku
+JP,440,66,DoCoMo,NTT DoCoMo
+JP,440,67,DoCoMo,NTT DoCoMo Tohoku
+JP,440,68,DoCoMo,NTT DoCoMo Kyushu
+JP,440,69,DoCoMo,NTT DoCoMo
+JP,440,70,au,KDDI Corporation
+JP,440,71,KDDI,KDDI Corporation
+JP,440,72,KDDI,KDDI Corporation
+JP,440,73,KDDI,KDDI Corporation
+JP,440,74,KDDI,KDDI Corporation
+JP,440,75,KDDI,KDDI Corporation
+JP,440,76,KDDI,KDDI Corporation
+JP,440,77,KDDI,KDDI Corporation
+JP,440,78,,Okinawa Cellular Telephone
+JP,440,79,KDDI,KDDI Corporation
+JP,440,80,TU-KA,TU-KA Cellular Tokyo
+JP,440,81,TU-KA,TU-KA Cellular Tokyo
+JP,440,82,TU-KA,TU-KA Phone Kansai
+JP,440,83,TU-KA,TU-KA Cellular Tokai
+JP,440,84,TU-KA,TU-KA Phone Kansai
+JP,440,85,TU-KA,TU-KA Cellular Tokai
+JP,440,86,TU-KA,TU-KA Cellular Tokyo
+JP,440,87,DoCoMo,NTT DoCoMo Chugoku
+JP,440,88,KDDI,KDDI Corporation
+JP,440,89,KDDI,KDDI Corporation
+JP,440,90,SoftBank,SoftBank Mobile Corp
+JP,440,92,SoftBank,SoftBank Mobile Corp
+JP,440,93,SoftBank,SoftBank Mobile Corp
+JP,440,94,SoftBank,SoftBank Mobile Corp
+JP,440,95,SoftBank,SoftBank Mobile Corp
+JP,440,96,SoftBank,SoftBank Mobile Corp
+JP,440,97,SoftBank,SoftBank Mobile Corp
+JP,440,98,SoftBank,SoftBank Mobile Corp
+JP,440,99,DoCoMo,NTT DoCoMo
+JE,234,50,JT-Wave,Jersey Telecom (JT-Wave)
+JE,234,55,Sure Mobile,Cable & Wireless Jersey Limited
+JE,234,03,Airtel Vodafone,JERSEY AIRTEL LIMITED
+JO,416,01,zain JO,Jordan Mobile Telephone Services
+JO,416,02,XPress Telecom,
+JO,416,03,Umniah,Umniah Mobile Company
+JO,416,77,Orange,Petra Jordanian Mobile Telecommunications Company (MobileCom)
+KZ,401,01,Beeline,KaR-Tel LLP
+KZ,401,02,Kcell,GSM Kazakhstan Ltd
+KZ,401,07,Dalacom,
+KZ,401,08,Kazakhtelecom,
+KZ,401,77,Mobile Telecom Service,Mobile Telecom Service LLP
+KE,639,02,Safaricom,Safaricom Limited
+KE,639,03,Airtel,B Airtel
+KE,639,07,Orange Kenya,Telkom Kenya
+KE,639,05,yu,Econet Wireless Kenya
+KI,545,09,Kiribati Frigate,Telecom Services Kiribati Ltd
+KP,467,192,Koryolink,Cheo Technology Jv Company
+KP,467,193,SunNet,Korea Posts and Telecommunications Corporation
+KR,450,02,KT,KT
+KR,450,03,Power 017,"Shinsegi Telecom, Inc."
+KR,450,04,KT,KT
+KR,450,05,SKT,SK Telecom
+KR,450,06,LGU+,LG Telecom
+KR,450,08,olleh,KT
+RKS,212,01,Vala,PTK - Directory of Post of Kosovo
+RKS,293,41,IPKO,IPKO
+RKS,212,01,Z Mobile,Dardaphone
+KW,419,02,zain KW,Zain Kuwait
+KW,419,03,Wataniya,National Mobile Telecommunications
+KW,419,04,Viva,Kuwait Telecommunication Company
+KG,437,01,Beeline,Sky Mobile LLC
+KG,437,03,Fonex,Aktel Ltd
+KG,437,05,MegaCom,Alfa Telecom CJSC
+KG,437,09,O!,NurTelecom LLC
+LA,457,01,LaoTel,Lao Shinawatra Telecom
+LA,457,02,ETL,Enterprise of Telecommunications Lao
+LA,457,03,Unitel,"Star Telecom Co., Ltd"
+LA,457,08,Tigo,Millicom Lao Co Ltd
+LV,247,01,LMT,Latvian Mobile Telephone
+LV,247,02,Tele2,Tele2
+LV,247,03,TRIATEL,Telekom Baltija
+LV,247,05,Bite,Bite Latvija
+LV,247,06,,Rigatta
+LV,247,07,MTS,Master Telecom
+LV,247,08,IZZI,IZZI
+LV,247,09,Camel Mobile,Camel Mobile
+LB,415,01,Alfa,MIC 1
+LB,415,03,mtc touch,MIC 2
+LB,415,05,Ogero Mobile,Ogero Telecom
+LS,651,01,Vodacom,Vodacom Lesotho (Pty) Ltd
+LS,651,02,,Econet Ezin-cel
+LR,618,01,Lonestar Cell,Lonestar Communications Corporation
+LR,618,02,Libercell,Atlantic Wireless (Liberia) Inc.
+LR,618,04,Comium,Comium Liberia
+LR,618,07,Cellcom,"Cellcom Telecommunications, Inc"
+LR,618,20,LIBTELCO,Liberia Telecommunications Corporation
+LY,606,00,Libyana,Libyana
+LY,606,01,Madar,Al-Madar Al-Jadeed
+LY,606,02,Al-Jeel Phone,Al-Jeel Al-Jadeed
+LY,606,03,Libya Phone,Libya Telecom and Technology (LTT)
+LY,606,06,Hatef Libya,Hatef Libya
+LI,295,01,Swisscom,Swisscom Schweiz AG
+LI,295,02,Orange,Orange Liechtenstein AG
+LI,295,05,FL1,Mobilkom Liechtenstein AG
+LI,295,77,Alpmobil,Alpcom AG
+LI,295,04,Cubic Telecom,Cubic Telecom AG
+LT,246,01,Omnitel,
+LT,246,02,BITE,UAB Bité Lietuva
+LT,246,03,Tele 2,
+LT,246,05,LitRail,Lithuanian Railways
+LT,246,06,Mediafon,UAB Mediafon
+LU,270,01,LuxGSM,P&T Luxembourg
+LU,270,77,Tango,Tango SA
+LU,270,99,Orange,Orange S.A.
+MO,455,00,SmarTone,SmarTone Macao
+MO,455,01,CTM,C.T.M. Telemovel+
+MO,455,02,China Telecom,China Telecom
+MO,455,03,3,Hutchison Telecom
+MO,455,04,CTM,C.T.M. Telemovel+
+MO,455,05,3,Hutchison Telecom
+MK,294,01,T-Mobile MK,T-Mobile Macedonia
+MK,294,02,ONE,One
+MK,294,03,Vip MK,VIP Operator
+MG,646,01,Airtel,Bharti Airtel
+MG,646,02,Orange,Orange Madagascar S.A.
+MG,646,03,Sacel,Sacel Madagascar S.A.
+MG,646,04,Telma,Telma Mobile S.A.
+MW,650,01,TNM,Telecom Network Malawi
+MW,650,10,Airtel,Bharti Airtel Limited
+MY,502,01,ATUR 450,Telekom Malaysia Bhd
+MY,502,10,,DiGi Telecommunications
+MY,502,11,TM Homeline,Telekom Malaysia Bhd [78]
+MY,502,12,Maxis,Maxis Mobile Services SDN Berhad
+MY,502,13,Celcom,Celcom Axiata Berhad
+MY,502,14,,Telekom Malaysia Berhad for PSTN SMS
+MY,502,16,DiGi,DiGi Telecommunications
+MY,502,17,Hotlink,Maxis Prepaid
+MY,502,18,U Mobile,U Mobile Sdn Bhd
+MY,502,18,TM Homeline,Telekom Malaysia Bhd
+MY,502,19,Celcom,Celcom Axiata Berhad
+MY,502,20,,Electcoms Wireless Sdn Bhd
+MY,502,150,Tune Talk,Tune Talk Sdn Bhd
+MY,502,151,,Baraka Telecom Sdn Bhd (MVNE)
+MY,502,152,Yes,YTL Communications Sdn Bhd
+MV,472,01,Dhiraagu,Dhivehi Raajjeyge Gulhun
+MV,472,02,Wataniya,Wataniya Telecom Maldives
+ML,610,01,Malitel,Malitel SA
+ML,610,02,Orange,Orange Mali SA
+MT,278,01,Vodafone,Vodafone Malta
+MT,278,21,GO,Mobisle Communications Limited
+MT,278,77,Melita,Melita Plc
+MQ,340,01,Orange,Orange Caraïbe Mobiles
+MQ,340,02,Outremer,Outremer Telecom
+MQ,340,20,Digicel,DIGICEL Antilles Française Guyane
+MR,609,01,Mattel,Mattel
+MR,609,02,Chinguitel,Chinguitel
+MR,609,10,Mauritel,Mauritel Mobiles
+MU,617,01,Orange,Cellplus Mobile Communications Ltd.
+MU,617,02,MTML,Mahanagar Telephone (Mauritius) Ltd.
+MU,617,10,Emtel,Emtel Ltd
+MX,334,010,Nextel,Nextel México
+MX,334,020,Telcel,América Móvil / Mextel
+MX,334,030,movistar,Pegaso Comunicaciones y Sistemas
+MX,334,040,Iusacell / Unefon,Iusacell / Unefon
+MX,334,050,Iusacell,Iusacell
+FM,550,01,,FSM EMMANUEL
+MD,259,01,Orange,Orange Moldova
+MD,259,02,Moldcell,
+MD,259,03,IDC,Interdnestrcom
+MD,259,03,Unité,Moldtelecom
+MD,259,04,Eventis,Eventis Telecom
+MD,259,05,Unité,Moldtelecom
+MD,259,99,Unité,Moldtelecom
+MC,212,01,Office des Telephones,Monaco Telecom
+MN,428,99,MobiCom,Mobicom Corporation
+MN,428,88,Unitel,Unitel LLC
+MN,428,91,Skytel,Skytel LLC
+MN,428,98,G.Mobile,G-Mobile LLC
+ME,297,01,Telenor,Telenor Montenegro
+ME,297,02,T-Mobile,T-Mobile Montenegro LLC
+ME,297,03,m:tel CG,MTEL CG
+ME,297,04,T-Mobile,T-Mobile Montenegro
+MA,604,00,Méditel,Medi Telecom
+MA,604,01,IAM,Ittissalat Al Maghrib (Maroc Telecom)
+MA,604,05,INWI,WANA - Groupe ONA
+MZ,643,01,mCel,Mocambique Celular S.A.
+MZ,643,04,Vodacom,"Vodacom Mozambique, S.A."
+MM,414,01,MPT,Myanmar Post and Telecommunication
+NA,649,01,MTC,MTC Namibia
+NA,649,02,switch,Telecom Namibia
+NA,649,03,Leo,Orascom Telecom Holding
+NR,536,02,Digicel,Digicel (Nauru) Corporation
+NP,429,01,Namaste / NT Mobile,Nepal Telecom
+NP,429,02,Ncell,Ncell Pvt. Ltd. Spice Nepal
+NP,429,04,SmartCell,Smart Telecom Pvt. Ltd.
+NP,429,03,Sky/C-Phone,Nepal Telecom
+NL,204,01,,VastMobiel B.V.
+NL,204,02,Tele2,Tele2 Nederland B.V.
+NL,204,03,,Voiceworks B.V.
+NL,204,04,Vodafone,hollandsnieuwe
+NL,204,05,,Elephant Talk Communications Premium Rate Services
+NL,204,06,,Mundio Mobile (Netherlands) Ltd
+NL,204,07,,Teleena (MVNE)
+NL,204,08,KPN,KPN Mobile The Netherlands B.V.
+NL,204,09,Lycamobile,Lycamobile Netherlands Limited
+NL,204,10,KPN,KPN B.V.
+NL,204,12,Telfort,KPN Mobile The Netherlands B.V.
+NL,204,13,,Unica Installatietechniek B.V.
+NL,204,14,6Gmobile,6GMOBILE B.V.
+NL,204,15,,Ziggo B.V.
+NL,204,16,T-Mobile,T-Mobile Netherlands B.V
+NL,204,17,,Intercity Mobile Communications B.V.
+NL,204,18,,UPC Nederland B.V.
+NL,204,19,,Mixe Communication Solutions B.V.
+NL,204,20,T-Mobile,T-Mobile Netherlands B.V
+NL,204,21,,ProRail B.V.
+NL,204,22,,Ministerie van Defensie
+NL,204,23,,ASPIDER Solutions Nederland B.V.
+NL,204,24,,Private Mobility Nederland B.V.
+NL,204,25,,CapX B.V.
+NL,204,26,,SpeakUp B.V.
+NL,204,27,,Breezz Nederland B.V.
+NL,204,67,,RadioAccess B.V.
+NL,204,68,,Unify Group Holding B.V.
+NL,204,69,,KPN Mobile The Netherlands B.V.
+AN,362,51,Telcell,Telcell N.V.
+AN,362,69,Digicel,Curaçao Telecom N.V.
+AN,362,91,UTS,Setel N.V.
+AN,362,95,MIO,E.O.C.G. Wireless
+AN,362,94,Bayòs,Bòbò Frus N.V.
+NC,546,01,Mobilis,OPT New Caledonia
+NZ,530,00,Telecom,Telecom New Zealand
+NZ,530,01,Vodafone,Vodafone New Zealand
+NZ,530,02,Telecom,Telecom New Zealand
+NZ,530,03,Woosh,Woosh Wireless New Zealand
+NZ,530,04,TelstraClear,TelstraClear New Zealand
+NZ,530,05,XT Mobile Network,Telecom New Zealand
+NZ,530,24,2degrees,2degrees
+NI,710,21,Claro,"Empresa Nicaragüense de Telecomunicaciones, S.A."
+NI,710,30,movistar,Telefónica Móviles de Nicaragua S.A.
+NI,710,73,SERCOM,Servicios de Comunicaciones S.A.
+NE,614,01,SahelCom,
+NE,614,02,Airtel,Bharti Airtel Limited
+NE,614,03,Telecel,Telecel Niger SA
+NE,614,04,Orange,Orange Niger
+NG,621,20,Airtel,Bharti Airtel Limited
+NG,621,30,MTN,MTN Nigeria Communications Limited
+NG,621,40,M-Tel,Nigerian Mobile Telecommunications Limited
+NG,621,50,Glo,Globacom Ltd
+NG,621,60,Etisalat,Emerging Markets Telecommunication Services Ltd (Etisalat)
+NG,621,25,Visafone,Visafone Communications Ltd.
+NU,555,01,Telecom Niue,Telecom Niue
+NF,505,10,Norfolk Telecom,Norfolk Telecom
+NO,242,01,Telenor,
+NO,242,02,NetCom,NetCom GSM
+NO,242,03,Teletopia,Teletopia
+NO,242,04,Tele2,Mobile Norway AS
+NO,242,05,Network Norway,Mobile Norway AS
+NO,242,06,Ice,Nordisk Mobiltelefon
+NO,242,07,Ventelo,Ventelo AS
+NO,242,08,TDC,TDC Mobil AS
+NO,242,09,Com4,Com4 AS [106]
+NO,242,11,SystemNet,SystemNet AS [107]
+NO,242,20,,Jernbaneverket AS
+NO,242,23,Lyca,Lyca Mobile Ltd
+OM,422,02,Oman Mobile,Oman Telecommunications Company
+OM,422,03,Nawras,Omani Qatari Telecommunications Company SAOC
+PK,410,01,Mobilink,Mobilink-PMCL
+PK,410,03,Ufone,Pakistan Telecommunication Mobile Ltd
+PK,410,04,Zong,China Mobile
+PK,410,06,Telenor,Telenor Pakistan
+PK,410,07,Warid,WaridTel
+PW,552,01,PNCC,Palau National Communications Corp.
+PW,552,80,Palau Mobile,Palau Mobile Corporation
+PS,425,05,Jawwal,"Palestine Cellular Communications, Ltd."
+PS,425,06,Wataniya,Wataniya Palestine Mobile Telecommunications Company
+PA,714,01,Cable & Wireless,Cable & Wireless Panama S.A.
+PA,714,02,movistar,"Telefonica Moviles Panama S.A, Bell South Corp. (BSC)"
+PA,714,04,Digicel,Digicel Group
+PA,714,03,Claro,América Móvil
+PG,537,01,B-Mobile,Pacific Mobile Communications
+PG,537,03,Digicel,Digicel PNG
+PY,744,01,VOX,Hola Paraguay S.A
+PY,744,02,Claro,AMX Paraguay S.A.
+PY,744,04,Tigo,Telefonica Celular Del Paraguay S.A. (Telecel)
+PY,744,05,Personal,Núcleo S.A
+PY,744,06,Copaco,Copaco S.A.
+PE,716,06,Movistar,Telefónica Móviles Perú
+PE,716,07,NEXTEL,NII Holdings
+PE,716,10,Claro,América Móvil Perú
+PH,515,01,Islacom,Globe Telecom via Innove Communications
+PH,515,02,Globe,Globe Telecom
+PH,515,03,Smart,PLDT via Smart Communications
+PH,515,05,Sun,Digital Telecommunications Philippines
+PH,515,11,,PLDT via ACeS Philippines
+PH,515,18,Cure,PLDT via Smart's Connectivity Unlimited Resources Enterprise
+PH,515,88,,Nextel
+PL,260,01,Plus,Polkomtel S.A.
+PL,260,02,T-Mobile,Polska Telefonia Cyfrowa Sp. z o.o.
+PL,260,03,Orange,Polska Telefonia Komórkowa Centertel Sp. z o.o.
+PL,260,04,,not in use
+PL,260,05,,Polska Telefonia Komórkowa Centertel Sp. z o.o.
+PL,260,06,Play,P4 Sp. z o.o.
+PL,260,07,Netia,Netia S.A.
+PL,260,08,,E-Telko Sp. z o.o.
+PL,260,09,,Telekomunikacja Kolejowa Sp. z o.o.
+PL,260,10,Sferia,Sferia S.A.
+PL,260,11,Nordisk Polska,Nordisk Polska Sp. z o.o.
+PL,260,12,Cyfrowy Polsat,Cyfrowy Polsat S.A.
+PL,260,15,CenterNet,CenterNet S.A.
+PL,260,16,Mobyland,Mobyland Sp. z o.o.
+PL,260,17,Aero2,Aero 2 Sp. z o.o.
+PT,268,01,Vodafone,Vodafone Portugal
+PT,268,03,Optimus,"Sonaecom – Serviços de Comunicações, S.A."
+PT,268,06,TMN,Telecomunicações Móveis Nacionais
+PT,268,21,Zapp,Zapp Portugal
+PR,330,110,Claro,Puerto Rico Telephone Company
+PR,330,00,Open Mobile,PR Wireless
+QA,427,01,Qtel,Qtel
+QA,427,02,Vodafone,Vodafone Qatar
+QA,427,05,Ministry of Interior,Ministry of Interior
+RE,647,00,Orange,Orange La Réunion
+RE,647,02,Outremer,Outremer Telecom
+RE,647,10,SFR Reunion,Societe Reunionnaise de Radiotelephone
+RO,226,01,Vodafone,Vodafone România
+RO,226,02,Romtelecom,Romtelecom
+RO,226,03,Cosmote,Cosmote România
+RO,226,04,Cosmote,Cosmote România
+RO,226,05,Digi.Mobil,RCS&RDS
+RO,226,06,Cosmote,Cosmote România
+RO,226,10,Orange,Orange România
+RO,226,11,Enigma-System,Enigma-System
+RU,250,01,MTS,Mobile TeleSystems
+RU,250,02,MegaFon,MegaFon OJSC - previously known as North-West GSM
+RU,250,03,NCC,Nizhegorodskaya Cellular Communications
+RU,250,04,Sibchallenge,Sibchallenge
+RU,250,05,ETK,Yeniseytelecom
+RU,250,06,Skylink [10],CJSC Saratov System of Cellular Communications
+RU,250,07,SMARTS,Zao SMARTS
+RU,250,09,Skylink,Khabarovsky Cellular Phone
+RU,250,10,DTC,Dontelekom
+RU,250,11,,Orensot
+RU,250,12,Baykalwestcom,Baykal Westcom / New Telephone Company / Far Eastern Cellular
+RU,250,12,Akos,
+RU,250,13,KUGSM,Kuban GSM
+RU,250,15,SMARTS,"SMARTS Ufa, SMARTS Uljanovsk"
+RU,250,16,NTC,New Telephone Company
+RU,250,17,Utel,JSC Uralsvyazinform
+RU,250,19,INDIGO,INDIGO
+RU,250,20,Tele2,Tele2
+RU,250,23,Mobicom - Novosibirsk,Mobicom - Novosibirsk
+RU,250,28,Beeline,Beeline
+RU,250,35,MOTIV,MOTIV
+RU,250,38,Tambov GSM,Central Telecommunication Company
+RU,250,39,Utel,Uralsvyazinform
+RU,250,44,,Stavtelesot / North Caucasian GSM
+RU,250,92,,Primtelefon
+RU,250,93,,Telecom XXI
+RU,250,99,Beeline,OJSC Vimpel-Communications
+RW,635,10,MTN,MTN Rwandacell SARL
+RW,635,12,Rwandatel,Rwandatel S.A.
+RW,635,13,Tigo,TIGO RWANDA S.A
+SKN,356,050,Digicel,
+SKN,356,110,,LIME
+SKN,356,070,Chippie,UTS
+LC,358,050,Digicel[citation needed],
+LC,358,110,,Cable & Wireless
+PM,308,01,Ameris,St. Pierre-et-Miquelon Télécom
+VC,360,070,Digicel,
+VC,360,100,Cingular Wireless,
+VC,360,110,Cable & Wireless,Cable & Wireless
+WS,549,01,Digicel,Digicel Pacific Ltd.
+WS,549,27,SamoaTel,SamoaTel Ltd
+SM,292,01,PRIMA,San Marino Telecom
+ST,626,01,CSTmovel,Companhia Santomese de Telecomunicaçôe
+SA,420,01,Al Jawal,Saudi Telecom Company
+SA,420,03,Mobily,Etihad Etisalat Company
+SA,420,04,Zain SA,Zain Saudi Arabia
+SN,608,01,Orange,Sonatel
+SN,608,02,Tigo,Millicom International Cellular S.A.
+SN,608,03,Expresso,Sudatel
+RS,220,01,Telenor,Telenor Serbia
+RS,220,02,Telenor,Telenor Montenegro
+RS,220,03,mt:s,Telekom Srbija
+RS,220,05,VIP,VIP Mobile
+SC,633,01,Cable & Wireless,Cable & Wireless Seychelles
+SC,633,02,Mediatech International,Mediatech International
+SC,633,10,Airtel,Telecom Seychelles Ltd
+SL,619,01,Airtel,Bharti Airtel Limited
+SL,619,02,Tigo,Millicom (SL) Limited
+SL,619,03,Africell,Lintel Sierra Leone Limited
+SL,619,04,Comium,Comium Sierra leone INC
+SL,619,05,Africell,Lintel Sierra Leone Limited
+SL,619,25,Mobitel,Mobitel
+SG,525,01,SingTel,Singapore Telecom
+SG,525,02,SingTel-G18,Singapore Telecom
+SG,525,03,M1,MobileOne Asia
+SG,525,05,StarHub,StarHub Mobile
+SG,525,12,,Digital Trunked Radio Network
+SK,231,01,Orange,Orange Slovensko
+SK,231,02,T-Mobile,T-Mobile Slovensko
+SK,231,03,,Unient Communications
+SK,231,04,T-Mobile,T-Mobile Slovensko
+SK,231,06,O2,Telefónica O2 Slovakia
+SK,231,99,ŽSR,Železnice Slovenskej Republiky
+SI,293,40,Si.mobil,SI.MOBIL d.d.
+SI,293,41,Mobitel,Mobitel D.D.
+SI,293,64,T-2,T-2 d.o.o.
+SI,293,70,Tušmobil,Tušmobil d.o.o.
+SB,540,01,BREEZE,Solomon Telekom Co Ltd
+SO,637,60,Nationlink Telecom,Nationlink Telecom
+SO,637,01,Telesom,Telesom
+SO,637,04,Somafone,Somafone FZLLC
+SO,637,10,Nationlink,NationLink Telecom
+SO,637,25,Hormuud,Hormuud Telecom Somalia Inc
+SO,637,30,Golis,Golis Telecom Somalia
+SO,637,82,Telcom,Telcom Somalia
+ZA,655,01,Vodacom,Vodacom
+ZA,655,02,Telkom Mobile / 8.ta,Telkom
+ZA,655,06,Sentech,
+ZA,655,07,Cell C,Cell C
+ZA,655,10,MTN,MTN Group
+ZA,655,11,,South African Police Service Gauteng
+ZA,655,13,Neotel,
+ZA,655,21,,Cape Town Metropolitan Council
+ZA,655,30,,Bokamoso Consortium
+ZA,655,31,,Karabo Telecoms (Pty) Ltd.
+ZA,655,32,,Ilizwi Telecommunications
+ZA,655,33,,Thinta Thinta Telecommunications
+__,250,30,Megafon,Ostelecom
+ES,214,01,Vodafone,Vodafone Spain
+ES,214,03,Orange,France Telecom España SA
+ES,214,04,Yoigo,Xfera Moviles SA
+ES,214,05,TME,Telefónica Móviles España
+ES,214,06,Vodafone,Vodafone Spain
+ES,214,07,movistar,Telefónica Móviles España
+ES,214,08,Euskaltel,
+ES,214,09,Orange,France Telecom España SA
+ES,214,15,BT,BT Group España Compañia de Servicios Globales de Telecomunicaciones S.A.U.
+ES,214,16,TeleCable,Telecable de Asturias S.A.U.
+ES,214,17,Móbil R,R Cable y Telecomunicaciones Galicia S.A.
+ES,214,18,ONO,Cableuropa S.A.U.
+ES,214,19,Simyo,E-PLUS Moviles Virtuales España S.L.U.
+ES,214,20,Fonyou,Fonyou Telecom S.L.
+ES,214,21,Jazztel,Jazz Telecom S.A.U.
+ES,214,22,DigiMobil,Best Spain Telecom
+ES,214,23,Barablu,Barablu Móvil España
+ES,214,24,Eroski,Eroski Móvil España
+ES,214,25,LycaMobile,LycaMobile S.L.
+LK,413,01,Mobitel,Sri Lanka Telecom Mobitel
+LK,413,02,Dialog,Dialog Axiata
+LK,413,03,Etisalat,Emirates Telecommunication Corporation
+LK,413,05,Airtel,Bharti Airtel
+LK,413,08,Hutch,Hutchison Telecommunications Lanka
+SD,634,01,Zain SD,Zain Group - Sudan
+SD,634,02,MTN,MTN Sudan
+SD,634,05,Vivacell,Wawat Securities
+SD,634,07,Sudani One,Sudatel Group
+SR,746,02,Telesur,Telecommunications Company Suriname (Telesur)
+SR,746,03,Digicel,Digicel Group Limited
+SR,746,04,Uniqa,Intelsur N.V. / UTS N.V.
+SZ,653,10,,Swazi MTN
+SE,240,01,Telia,SwedenTeliaSonera
+SE,240,02,3,Hutchison 3G
+SE,240,03,Ice.net,Nordisk Mobiltelefon
+SE,240,04,,3G Infrastructure Services
+SE,240,05,Sweden 3G,Svenska UMTS-Nät
+SE,240,06,Telenor,Telenor Sweden
+SE,240,07,Tele2,Tele2 Sweden
+SE,240,08,Telenor,Telenor Sweden
+SE,240,09,djuice,Telenor Sweden
+SE,240,10,Spring Mobil,Tele2
+SE,240,11,,Lindholmen Science Park
+SE,240,12,,Barablu Mobile Scandinavia
+SE,240,13,,Ventelo Sverige
+SE,240,14,,TDC Mobil
+SE,240,15,,Wireless Maingate Nordic
+SE,240,16,,42IT
+SE,240,17,Gotanet,Götalandsnätet
+SE,240,20,,Wireless Maingate Message Services
+SE,240,21,MobiSir,Trafikverket (formerly Banverket)
+SE,240,24,Sweden 2G,Net4Mobility
+SE,240,25,,DigiTelMobile
+SE,240,26,,Beepsend
+SE,240,33,,Mobile Arts AB
+CH,228,01,Swisscom,Swisscom Ltd
+CH,228,02,Sunrise,Sunrise Communications AG
+CH,228,03,Orange,Orange Communications SA
+CH,228,05,,Togewanet AG (Comfone)
+CH,228,06,SBB-CFF-FFS,SBB AG
+CH,228,07,IN&Phone,IN&Phone SA
+CH,228,08,Tele2,Tele2 Telecommunications AG
+CH,228,50,,3G Mobile AG
+CH,228,51,,BebbiCell AG
+SY,417,01,Syriatel,Syriatel Mobile Telecom
+SY,417,02,MTN,MTN Syria
+TW,466,01,FarEasTone,Far EasTone Telecommunications Co Ltd
+TW,466,05,APTG,Asia Pacific Telecom
+TW,466,06,Tuntex,Tuntex Telecom
+TW,466,11,Chunghwa LDM,LDTA/Chungwa Telecom
+TW,466,88,KG Telecom,KG Telecom
+TW,466,89,VIBO,VIBO Telecom
+TW,466,92,Chungwa,Chunghwa
+TW,466,93,MobiTai,Mobitai Communications
+TW,466,97,Taiwan Mobile,Taiwan Mobile Co. Ltd
+TW,466,99,TransAsia,TransAsia Telecoms
+TJ,436,01,Tcell,JV Somoncom
+TJ,436,02,Tcell,Indigo Tajikistan
+TJ,436,03,MLT,TT Mobile
+TJ,436,04,Babilon-M,Babilon-Mobile
+TJ,436,05,Beeline,Vimpelcom
+TJ,436,12,Tcell,Indigo
+TZ,640,02,tiGO,MIC Tanzania Limited
+TZ,640,03,Zantel,Zanzibar Telecom Ltd
+TZ,640,04,Vodacom,Vodacom Tanzania Limited
+TZ,640,05,Airtel,Bharti Airtel
+TZ,640,06,Sasatel,Dovetel Limited
+TZ,640,07,TTCL Mobile,Tanzania Telecommunication Company LTD (TTCL)
+TZ,640,08,Benson Online (BOL),Benson Informatics Limited
+TZ,640,09,Hits,ExcellentCom Tanzania Limited
+TZ,640,11,SmileCom,Smile Telecoms Holdings Ltd.
+TH,520,00,my CAT 3G+,CAT Telecom
+TH,520,01,AIS,Advanced Info Service
+TH,520,02,CAT CDMA,CAT Telecom
+TH,520,10,,WCS IQ
+TH,520,15,TOT 3G,Telephone Organization of Thailand (TOT)
+TH,520,18,dtac,Total Access Communication
+TH,520,23,AIS GSM 1800,Digital Phone (AIS)
+TH,520,99,True Move,True Corporation
+TG,615,01,Togo Cell,Togo Telecom
+TG,615,03,Moov,Moov Togo
+TO,539,01,,Tonga Communications Corporation
+TO,539,43,,Shoreline Communication
+TO,539,88,Digicel,
+TT,374,12,bmobile,TSTT
+TT,374,130,Digicel,Digicel (Trinidad & Tobago) Limited
+TN,605,01,Orange,Orange Tunisie
+TN,605,02,Tunicell,Tunisie Telecom
+TN,605,03,Tunisiana,Orascom Telecom Tunisie
+TR,286,01,Turkcell,Turkcell Iletisim Hizmetleri A.S.
+TR,286,02,Vodafone,Vodafone Turkey
+TR,286,03,Avea,
+TR,286,04,,Aycell
+TM,438,01,MTS,Barash Communication Technologies
+TM,438,02,TM-Cell,Altyn Asyr
+TC,376,350,C&W,Cable & Wireless West Indies Ltd (Turks & Caicos)
+TC,376,352,Islandcom,Islandcom Telecommunications
+TC,338,05,Digicel,Digicel (Turks & Caicos) Limited
+TV,553,01,TTC,Tuvalu Telecom
+UG,641,01,Airtel,Bharti Airtel
+UG,641,10,MTN,MTN Uganda
+UG,641,11,UTL,Uganda Telecom Ltd.
+UG,641,14,Orange,Orange Uganda
+UG,641,22,Warid Telecom,Warid Telecom
+UA,255,01,MTS,Ukrainian Mobile Communications
+UA,255,02,Beeline,Ukrainian Radio Systems
+UA,255,03,Kyivstar,Kyivstar GSM JSC
+UA,255,04,IT,Intertelecom
+UA,255,05,Golden Telecom,Golden Telecom
+UA,255,06,life:),Astelit
+UA,255,07,Ukrtelecom,Ukrtelecom
+UA,255,21,PEOPLEnet,Telesystems of Ukraine
+UA,255,23,CDMA Ukraine,ITC
+AE,424,02,Etisalat,E mirates Telecom Corp
+AE,424,03,du,Emirates Integrated Telecommunications Company
+UK,234,00,BT,BT Group
+UK,234,01,Vectone Mobile,Mundio Mobile Limited
+UK,234,02,O2,Telefónica O2 UK Limited
+UK,234,03,Airtel-Vodafone,Jersey Airtel Limited
+UK,234,04,FMS Solutions Ltd,FMS Solutions Ltd
+UK,234,05,,COLT Mobile Telecommunications Limited
+UK,234,06,,Internet Computer Bureau Limited
+UK,234,07,,Cable & Wireless UK
+UK,234,08,,OnePhone (UK) Ltd
+UK,234,09,,Tismi BV
+UK,234,10,O2,Telefónica O2 UK Limited
+UK,234,11,O2,Telefónica Europe
+UK,234,12,Railtrack,Network Rail Infrastructure Ltd
+UK,234,13,Railtrack,Network Rail Infrastructure Ltd
+UK,234,14,Hay Systems Ltd,Hay Systems Ltd
+UK,234,15,Vodafone,Vodafone United Kingdom
+UK,234,16,Talk Talk,TalkTalk Communications Limited
+UK,234,17,,FleXtel Limited
+UK,234,18,Cloud9,Cloud9
+UK,234,19,Private Mobile Networks PMN,Teleware plc
+UK,234,20,Three,Hutchison 3G UK Ltd
+UK,234,22,RoutoMessaging,Routo Telecommunications Limited
+UK,234,24,Greenfone,Stour Marine
+UK,234,25,Truphone,Software Cellular Network Ltd
+UK,234,30,T-Mobile,Everything Everywhere Limited (TM)
+UK,234,31,Virgin,Virgin Mobile
+UK,234,32,Virgin,Virgin Mobile
+UK,234,33,Orange,Everything Everywhere Limited (TM)
+UK,234,34,Orange,Everything Everywhere Limited (TM)
+UK,234,35,,JSC Ingenium (UK) Limited
+UK,234,36,,Cable and Wireless Isle of Man Limited
+UK,234,37,,Synectiv Ltd
+UK,234,50,JT-Wave,Jersey Telecom
+UK,234,55,,Cable & Wireless Guernsey / Sure Mobile (Jersey)
+UK,234,58,,Manx Telecom
+UK,234,76,BT,BT Group
+UK,234,78,Airwave,Airwave (communications network)[citation needed]
+UK,235,00,,Mundio Mobile Limited
+UK,235,01,,Everything Everywhere Limited (TM)
+UK,235,02,,Everything Everywhere Limited (TM)
+UK,235,77,BT,BT Group
+UK,235,91,,Vodafone United Kingdom
+UK,235,92,,Cable & Wireless UK
+UK,235,94,,Hutchison 3G UK Ltd
+UK,235,95,,Network Rail Infrastructure Limited
+US,310,053,,Virgin Mobile US
+US,310,054,,Alltel US
+US,310,066,,U.S. Cellular
+US,310,004,Verizon,Verizon Wireless
+US,310,005,Verizon,Verizon Wireless
+US,310,010,,MCI
+US,310,012,Verizon,Verizon Wireless
+US,310,013,MobileTel,
+US,310,014,,Testing
+US,310,016,,Cricket Communications
+US,310,017,,North Sight Communications Inc.
+US,310,020,,Union Telephone Company
+US,310,026,T-Mobile,
+US,310,030,Centennial,Centennial Communications
+US,310,034,Airpeak,
+US,310,040,Concho,"Concho Cellular Telephone Co., Inc."
+US,310,046,SIMMETRY,TMP Corp
+US,310,060,,Consolidated Telcom
+US,310,070,,Highland Cellular
+US,310,080,Corr,Corr Wireless Communications LLC
+US,310,090,AT&T,AT&T Mobility
+US,310,100,Plateau Wireless,New Mexico RSA 4 East Ltd. Partnership
+US,310,110,PTI Pacifica,PTI Pacifica Inc.
+US,310,120,Sprint,
+US,310,150,AT&T,AT&T Mobility
+US,310,160,,T-Mobile
+US,310,170,,T-Mobile
+US,310,180,West Central,West Central Wireless
+US,310,190,Dutch Harbor,"Alaska Wireless Communications, LLC"
+US,310,200,,T-Mobile
+US,310,210,,T-Mobile
+US,310,220,,T-Mobile
+US,310,230,,T-Mobile
+US,310,240,,T-Mobile
+US,310,250,,T-Mobile
+US,310,260,,T-Mobile
+US,310,270,,T-Mobile
+US,310,280,,T-Mobile
+US,310,290,,T-Mobile
+US,310,300,iSmart Mobile,Smart Call (Truphone)
+US,310,310,,T-Mobile
+US,310,311,,Farmers Wireless
+US,310,320,Cellular One,"Smith Bagley, Inc."
+US,310,330,T-Mobile,
+US,310,340,Westlink,Westlink Communications
+US,310,350,,Carolina Phone
+US,310,380,AT&T,AT&T Mobility
+US,310,390,Cellular One of East Texas,"TX-11 Acquisition, LLC"
+US,310,400,i CAN_GSM,Wave Runner LLC (Guam)
+US,310,410,AT&T,AT&T Mobility
+US,310,420,Cincinnati Bell,Cincinnati Bell Wireless
+US,310,430,,Alaska Digitel
+US,310,440,Cellular One,
+US,310,450,Viaero,Viaero Wireless
+US,310,460,Simmetry,TMP Corporation
+US,310,470,nTelos,
+US,310,480,,Choice Phone
+US,310,490,T-Mobile,
+US,310,500,Alltel,
+US,310,510,Airtel,Airtel Wireless
+US,310,520,VeriSign,
+US,310,530,,West Virginia Wireless
+US,310,540,Oklahoma Western,Oklahoma Western Telephone Company
+US,310,560,AT&T,AT&T Mobility
+US,310,570,Cellular One,"MTPCS, LLC"
+US,310,580,T-Mobile,
+US,310,590,Alltel,Alltel Communications Inc
+US,310,610,Epic Touch,Elkhart Telephone Co.
+US,310,620,Coleman County Telecom,Coleman County Telecommunications
+US,310,630,AmeriLink PCS,Choice Wireless
+US,310,640,Airadigm,Airadigm Communications
+US,310,650,Jasper,"Jasper Wireless, inc"
+US,310,660,T-Mobile,
+US,310,670,Northstar,
+US,310,680,AT&T,AT&T Mobility
+US,310,690,Conestoga,Conestoga Wireless Company
+US,310,730,SeaMobile,
+US,310,740,Convey,Convey Communications Inc.
+US,310,760,Panhandle,Panhandle Telecommunications Systems Inc.
+US,310,770,i wireless,Iowa Wireless Services
+US,310,780,,Airlink PCS
+US,310,790,PinPoint,PinPoint Communications
+US,310,800,,T-Mobile
+US,310,830,Caprock,Caprock Cellular
+US,310,840,telna Mobile,"Telecom North America Mobile, Inc."
+US,310,850,Aeris,"Aeris Communications, Inc."
+US,310,870,PACE,Kaplan Telephone Company
+US,310,880,Advantage,Advantage Cellular Systems
+US,310,890,Unicel,Rural Cellular Corporation
+US,310,900,Mid-Rivers Wireless,Mid-Rivers Communications
+US,310,910,First Cellular,First Cellular of Southern Illinois
+US,310,940,,Iris Wireless LLC
+US,310,950,XIT Wireless,Texas RSA 1 dba XIT Cellular
+US,310,960,Plateau Wireless,
+US,310,970,Globalstar,
+US,310,980,,AT&T Mobility
+US,310,990,,AT&T Mobility
+US,311,000,,Mid-Tex Cellular
+US,311,010,Chariton Valley,Chariton Valley Communications
+US,311,020,,Missouri RSA 5 Partnership
+US,311,030,,Indigo Wireless
+US,311,040,,Commnet Wireless
+US,311,050,,Wikes Cellular
+US,311,060,Farmers Cellular,Farmers Cellular Telephone
+US,311,070,Easterbrooke,Easterbrooke Cellular Corporation
+US,311,080,Pine Cellular,Pine Telephone Company
+US,311,090,Long Lines Wireless,Long Lines Wireless LLC
+US,311,100,,High Plains Wireless
+US,311,110,,High Plains Wireless
+US,311,120,,Choice Phone
+US,311,130,,Cell One Amarillo
+US,311,140,Sprocket,MBO Wireless
+US,311,150,,Wilkes Cellular
+US,311,160,,Endless Mountains Wireless
+US,311,170,PetroCom,Broadpoint Inc
+US,311,180,,Cingular Wireless
+US,311,190,,Cellular Properties
+US,311,210,,Emery Telcom Wireless
+US,311,220,,U.S. Cellular
+US,311,230,,C Spire Wireless
+US,311,330,Bug Tussel Wireless,Bug Tussel Wireless
+US,311,480,Verizon,Verizon Wireless
+US,311,660,metroPCS,metroPCS
+US,316,010,Nextel,Nextel Communications
+US,316,011,,Southern Communications Services
+UY,748,01,Antel,Compania estatal (ANTEL)
+UY,748,07,Movistar,Telefónica Móviles Uruguay
+UY,748,10,Claro UY,AM Wireless Uruguay S.A.
+UZ,434,01,,Buztel
+UZ,434,02,,Uzmacom
+UZ,434,04,Beeline,Unitel LLC
+UZ,434,05,Ucell,Coscom
+UZ,434,06,,Perfectum Mobile
+UZ,434,07,MTS,Uzdunrobita
+VU,541,01,SMILE,Telecom Vanuatu Ltd
+VE,734,01,Digitel,Corporacion Digitel C.A.
+VE,734,02,Digitel,Corporacion Digitel C.A.
+VE,734,03,Digitel,Corporacion Digitel C.A.
+VE,734,04,movistar,Telefónica Móviles Venezuela
+VE,734,06,Movilnet,Telecomunicaciones Movilnet
+VN,452,01,MobiFone,Vietnam Mobile Telecom Services Company (VMS)
+VN,452,02,Vinaphone,Vietnam Telecom Services Company
+VN,452,03,S-Fone,S-Telecom
+VN,452,04,Viettel Mobile,Viettel Telecom
+VN,452,05,Vietnamobile,Hanoi Telecom
+VN,452,06,EVNTelecom,EVNTelecom - EVN
+VN,452,08,3G EVNTelecom,EVNTelecom - EVN
+VN,452,07,Beeline VN,GTEL Mobile JSC
+YE,421,01,SabaFon,
+YE,421,02,MTN,SpaceTel
+YE,421,03,Yemen Mobile,Yemen Mobile
+YE,421,04,HiTS-UNITEL,Y
+ZM,645,01,Airtel,Bharti Airtel
+ZM,645,02,MTN,MTN Group
+ZM,645,03,ZAMTEL,Zambia Telecommunications Company Ltd
+ZW,648,01,Net*One,Net*One Cellular (Pvt) Ltd
+ZW,648,03,Telecel,Telecel Zimbabwe (PVT) Ltd
+ZW,648,04,Econet,Econet Wireless (Private) Limited
+__,901,01,ICO,ICO Satellite Management
+__,901,02,,Sense Communications International
+__,901,03,Iridium,
+__,901,04,Globalstar,
+__,901,05,,Thuraya RMSS Network
+__,901,06,,Thuraya Satellite Telecommunications Company
+__,901,07,Ellipso,
+__,901,08,,
+__,901,09,,Tele1 Europe
+__,901,10,ACeS,
+__,901,11,Inmarsat,
+__,901,12,Telenor,Maritime Communications Partner AS
+__,901,13,GSM.AQ,Global Networks Switzerland Inc.
+__,901,14,,AeroMobile AS
+__,901,15,,OnAir Switzerland Sarl
+__,901,16,,Jasper Systems
+__,901,17,Navitas,
+__,901,18,Cellular @Sea,AT&T Mobility
+__,901,19,,Vodafone Malta Maritime
+__,901,21,Seanet,Seanet Maritime Communications
+__,901,23,,Beeline
+__,901,24,iNum,Voxbone
+__,901,26,TIM,Telecom Italia
+__,901,29,Telenor,
+__,901,32,Sky High,MegaFon
--- /dev/null
+create table mcc_mnc_oper_list (id integer primary key, country char(3), mcc integer, mnc char(3), oper char(45) );
+BEGIN;
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 1, "01", "TEST");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GE", 289, "67", "Aquafon");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GE", 289, "88", "A-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AF", 412, "01", "AWCC");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AF", 412, "20", "Roshan");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AF", 412, "40", "MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AF", 412, "50", "Etisalat");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AL", 76, "01", "AMC");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AL", 276, "02", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AL", 276, "03", "Eagle Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AL", 276, "04", "Plus Communication");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DZ", 603, "01", "Mobilis");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DZ", 603, "02", "Djezzy");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DZ", 603, "03", "Nedjma");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AS", 44, "11", "Bluesky");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AD", 213, "03", "Mobiland");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AO", 631, "02", "UNITEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AO", 631, "04", "MOVICEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AI", 365, "010", "Weblinks Limited");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AI", 365, "840", "Cable & Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AG", 344, "030", "APUA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AG", 344, "920", "LIME");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AG", 338, "050", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AR", 722, "010", "Movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AR", 722, "020", "Nextel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AR", 722, "070", "Movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AR", 722, "310", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AR", 722, "320", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AR", 722, "330", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AR", 722, "34", "Personal");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AR", 722, "341", "Personal");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AR", 722, "350", "Hutchinson (PORT HABLE)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AR", 722, "36", "Personal");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AM", 283, "01", "Beeline");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AM", 283, "05", "VivaCell-MTS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AM", 283, "10", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AW", 363, "01", "SETAR");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AW", 363, "02", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "01", "Telstra");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "02", "Optus");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "03", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "04", "Department of Defence");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "05", "Ozitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "06", "3");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "08", "One.Tel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "09", "Airnet");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "12", "3");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "13", "Railcorp");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "14", "AAPT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "15", "3GIS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "16", "Victorian Rail Track");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "21", "SOUL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "24", "Advance Communications Technologies Pty. Ltd.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "38", "Crazy John's");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "71", "Telstra");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "72", "Telstra");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "88", "Localstar Holding Pty. Ltd.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "90", "Optus");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AU", 505, "99", "One.Tel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AT", 232, "01", "A1");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AT", 232, "03", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AT", 232, "05", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AT", 232, "07", "tele.ring");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AT", 232, "09", "A1");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AT", 232, "10", "3");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AT", 232, "11", "bob");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AT", 232, "12", "yesss");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AT", 232, "14", "3");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AT", 232, "15", "Barablu");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AT", 232, "91", "GSM-R A");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AZ", 400, "01", "Azercell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AZ", 400, "02", "Bakcell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AZ", 400, "03", "FONEX");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AZ", 400, "04", "Nar Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BS", 364, "390", "BaTelCo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BH", 426, "01", "Batelco");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BH", 426, "02", "zain BH");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BH", 426, "04", "VIVA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BD", 470, "01", "Grameenphone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BD", 470, "02", "Robi");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BD", 470, "03", "Banglalink");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BD", 470, "04", "TeleTalk");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BD", 470, "05", "Citycell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BD", 470, "06", "Airtel formerly Warid Telcom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BB", 342, "600", "LIME");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BB", 342, "750", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BB", 342, "820", "Sunbeach Communications");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BY", 257, "01", "velcom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BY", 257, "02", "MTS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BY", 257, "03", "DIALLOG");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BY", 257, "04", "life:)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BY", 257, "501", "BelCel JV");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BE", 206, "01", "Proximus");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BE", 206, "05", "Telenet");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BE", 206, "10", "Mobistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BE", 206, "20", "BASE");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BZ", 702, "67", "DigiCell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BZ", 702, "99", "Smart");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BJ", 616, "01", "Libercom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BJ", 616, "02", "Moov");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BJ", 616, "03", "MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BJ", 616, "04", "BBCOM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BJ", 616, "05", "Glo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BM", 350, "01", "Digicel Bermuda");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BM", 350, "02", "Mobility");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BM", 338, "050", "Digicel Bermuda");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BM", 310, "59", "Cellular One");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BT", 402, "11", "B-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BT", 402, "77", "TashiCell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BO", 736, "01", "Nuevatel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BO", 736, "02", "Entel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BO", 736, "03", "Tigo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BA", 218, "03", "HT-ERONET");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BA", 218, "05", "m:tel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BA", 218, "90", "BH Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BW", 652, "01", "Mascom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BW", 652, "02", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BW", 652, "04", "BTC Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "00", "Nextel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "02", "TIM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "03", "TIM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "04", "TIM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "05", "Claro BR");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "06", "Vivo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "07", "Sercomtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "10", "Vivo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "11", "Vivo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "15", "CTBC Celular");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "16", "Brasil Telecom GSM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "23", "Vivo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "31", "Oi");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "32", "CTBC Celular");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "33", "CTBC Celular");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "34", "CTBC Celular");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BR", 724, "39", "Nextel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VG", 348, "170", "LIME");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VG", 348, "570", "CCT Boatphone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VG", 348, "770", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BN", 528, "01", "Jabatan Telekom Brunei");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BN", 528, "02", "B-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BN", 528, "11", "DSTCom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BG", 284, "01", "M-Tel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BG", 284, "03", "Vivacom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BG", 284, "04", "Undisclosed");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BG", 284, "05", "GLOBUL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BF", 613, "01", "Telmob");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BF", 613, "02", "Zain");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BF", 613, "03", "Telecel Faso");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BI", 642, "01", "Spacetel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BI", 642, "02", "Africell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BI", 642, "03", "Onatel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BI", 642, "07", "Smart Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BI", 642, "08", "HiTs Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("BI", 642, "82", "U-COM Burundi");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KH", 456, "01", "Mobitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KH", 456, "02", "hello");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KH", 456, "03", "S Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KH", 456, "04", "qb");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KH", 456, "05", "Star-Cell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KH", 456, "06", "Smart Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KH", 456, "18", "Mfone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KH", 456, "11", "Excell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KH", 456, "09", "Beeline");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KH", 456, "08", "Metfone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CM", 624, "01", "MTN Cameroon");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CM", 624, "02", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "220", "Telus");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "221", "Telus");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "270", "unknown");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "290", "Airtel Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "320", "Mobilicity");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "350", "FIRST");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "360", "MiKe");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "361", "Telus");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "370", "Fido");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "380", "DMTS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "490", "WIND Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "500", "Videotron");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "510", "Videotron");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "610", "Bell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "610", "Bell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "620", "ICE Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "640", "Bell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "652", "BC Tel Mobility (Telus)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "653", "Telus");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "655", "MTS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "656", "TBay");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "657", "Telus");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "660", "MTS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "680", "SaskTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "701", "MB Tel Mobility");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "702", "MT&T Mobility (Aliant)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "703", "New Tel Mobility (Aliant)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "710", "Globalstar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "720", "Rogers Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "780", "SaskTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CA", 302, "880", "Bell / Telus / SaskTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CV", 625, "01", "CVMOVEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CV", 625, "02", "T+");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KY", 346, "140", "LIME");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KY", 346, "50", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CF", 623, "01", "CTP");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CF", 623, "02", "TC");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CF", 623, "03", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CF", 623, "04", "Nationlink");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TD", 622, "01", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TD", 622, "02", "Tchad Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TD", 622, "03", "TIGO - Millicom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TD", 622, "04", "Salam");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CL", 730, "01", "entel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CL", 730, "02", "movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CL", 730, "03", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CL", 730, "04", "Nextel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CL", 730, "08", "VTR Móvil");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CL", 730, "09", "Nextel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CL", 730, "10", "entel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CL", 730, "99", "Will");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CN", 460, "00", "China Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CN", 460, "01", "China Unicom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CN", 460, "02", "China Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CN", 460, "03", "China Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CN", 460, "05", "China Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CN", 460, "06", "China Unicom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CN", 460, "07", "China Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CN", 460, "20", "China Tietong");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CO", 732, "001", "Colombia Telecomunicaciones S.A.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CO", 732, "002", "Edatel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CO", 732, "101", "Comcel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CO", 732, "102", "movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CO", 732, "103", "Tigo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CO", 732, "111", "Tigo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CO", 732, "123", "movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KM", 654, "01", "HURI - SNPT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CG", 629, "01", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CG", 629, "10", "Libertis Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CG", 629, "07", "Warid Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CK", 548, "01", "Telecom Cook");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CR", 712, "01", "Kolbi ICE");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CR", 712, "02", "Kolbi ICE");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CR", 712, "03", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CR", 712, "04", "movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HR", 219, "01", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HR", 219, "02", "Tele2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HR", 219, "10", "Vip");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CU", 368, "01", "CUBACEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CY", 280, "01", "Cytamobile-Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CY", 280, "10", "MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CZ", 230, "01", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CZ", 230, "02", "O2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CZ", 230, "03", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CZ", 230, "04", "U:fon");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CZ", 230, "05", "TRAVEL TELEKOMMUNIKATION, s.r.o");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CZ", 230, "06", "OSNO TELECOMUNICATION, s.r.o");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CZ", 230, "98", "Správa železniční dopravní cesty, s.o");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CZ", 230, "99", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CD", 630, "01", "Vodacom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CD", 630, "02", "Zain");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CD", 630, "04", "Cellco");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CD", 630, "05", "Supercell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CD", 630, "10", "Libertis Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CD", 630, "86", "CCT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CD", 630, "89", "SAIT Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DK", 238, "01", "TDC");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DK", 238, "02", "Telenor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DK", 238, "03", "MIGway A/S");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DK", 238, "05", "ApS KBUS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DK", 238, "06", "3");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DK", 238, "07", "Barablu Mobile Ltd.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DK", 238, "09", "Dansk Beredskabskommunikation A/S");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DK", 238, "10", "TDC");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DK", 238, "11", "Dansk Beredskabskommunikation A/S");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DK", 238, "12", "Lycamobile Denmark Ltd");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DK", 238, "20", "Telia");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DK", 238, "30", "Telia");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DK", 238, "40", "Ericsson Danmark A/S");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DK", 238, "77", "Telenor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DJ", 638, "01", "Evatis");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DM", 366, "020", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DM", 366, "110", "Cable & Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DO", 370, "01", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DO", 370, "02", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DO", 370, "03", "Tricom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DO", 370, "04", "Viva");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TL", 514, "02", "Timor Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("EC", 740, "00", "Movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("EC", 740, "01", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("EC", 740, "02", "Alegro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("EG", 602, "01", "Mobinil");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("EG", 602, "02", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("EG", 602, "03", "Etisalat");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SV", 706, "01", "CTE Telecom Personal");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SV", 706, "02", "digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SV", 706, "03", "Tigo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SV", 706, "04", "movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SV", 706, "11", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GQ", 627, "01", "Orange GQ");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GQ", 627, "03", "Hits GQ");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ER", 657, "01", "Eritel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("EE", 248, "01", "EMT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("EE", 248, "02", "Elisa");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("EE", 248, "03", "Tele 2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("EE", 248, "04", "OY Top Connect");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("EE", 248, "05", "AS Bravocom Mobiil");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("EE", 248, "06", "Progroup Holding");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ET", 636, "01", "ETH-MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FO", 288, "01", "Faroese Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FO", 288, "02", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FJ", 542, "01", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FJ", 542, "02", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FI", 244, "03", "DNA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FI", 244, "05", "Elisa");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FI", 244, "07", "Nokia");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FI", 244, "08", "Unknown");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FI", 244, "10", "TDC Oy");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FI", 244, "11", "VIRVE");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FI", 244, "12", "DNA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FI", 244, "14", "AMT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FI", 244, "15", "SAMK");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FI", 244, "21", "Saunalahti");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FI", 244, "29", "Scnl Truphone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FI", 244, "91", "Sonera");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FR", 208, "00", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FR", 208, "01", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FR", 208, "02", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FR", 208, "05", "Globalstar Europe");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FR", 208, "06", "Globalstar Europe");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FR", 208, "07", "Globalstar Europe");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FR", 208, "10", "SFR");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FR", 208, "11", "SFR");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FR", 208, "13", "SFR");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FR", 208, "14", "Free Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FR", 208, "15", "Free Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FR", 208, "20", "Bouygues");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FR", 208, "21", "Bouygues");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FR", 208, "22", "Transatel Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FR", 208, "88", "Bouygues");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PF", 547, "20", "Vini");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GA", 628, "01", "Libertis");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GA", 628, "02", "Moov");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GA", 628, "03", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GA", 628, "04", "Azur");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GM", 607, "01", "Gamcel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GM", 607, "02", "Africel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GM", 607, "03", "Comium");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GM", 607, "04", "QCell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GE", 282, "01", "Geocell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GE", 282, "02", "MagtiCom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GE", 282, "03", "MagtiCom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GE", 282, "04", "Beeline");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GE", 282, "05", "Silknet");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "01", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "02", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "03", "E-Plus");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "04", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "05", "E-Plus");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "06", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "07", "O2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "08", "O2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "09", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "10", "Arcor AG & Co");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "11", "O2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "12", "Dolphin Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "13", "Mobilcom Multimedia");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "14", "Group 3G UMTS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "15", "Airdata");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "16", "Vistream");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "42", "27C3");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "43", "LYCA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "60", "DB Telematik");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "76", "Siemens AG");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "77", "E-Plus");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "92", "Nash Technologies");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("DE", 262, "901", "Debitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GH", 620, "01", "MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GH", 620, "02", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GH", 620, "03", "tiGO");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GH", 620, "04", "Expresso");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GH", 620, "06", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GI", 266, "01", "GibTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GI", 266, "06", "CTS Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GR", 202, "01", "Cosmote");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GR", 202, "05", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GR", 202, "09", "Wind");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GR", 202, "10", "Wind");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GL", 290, "01", "TELE Greenland A/S");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GD", 352, "030", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GD", 352, "110", "Cable & Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GP", 340, "01", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GP", 340, "02", "Outremer");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GP", 340, "03", "Telcell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GP", 340, "08", "Dauphin");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GP", 340, "20", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GU", 310, "032", "IT&E Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GU", 310, "033", "Guam Telephone Authority");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GU", 310, "140", "mPulse");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GU", 310, "370", "docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GU", 311, "250", "i CAN_GSM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GU", 310, "470", "docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GT", 704, "01", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GT", 704, "02", "Comcel / Tigo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GT", 704, "03", "movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GB", 234, "55", "Sure Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GB", 234, "50", "Wave Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GB", 234, "03", "Airtel Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GN", 611, "01", "Orange S.A.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GN", 611, "02", "Sotelgui");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GN", 611, "03", "Telecel Guinee");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GN", 611, "04", "MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GN", 611, "05", "Cellcom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GW", 632, "02", "Areeba");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GW", 632, "03", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GY", 738, "01", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("GY", 738, "02", "GT&T Cellink Plus");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HT", 372, "01", "Voila");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HT", 372, "02", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HT", 372, "03", "NATCOM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HN", 708, "01", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HN", 708, "02", "Tigo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HN", 708, "30", "Hondutel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HN", 708, "40", "DIGICEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "00", "1O1O / One2Free");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "01", "CITIC Telecom 1616");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "02", "CSL Limited");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "03", "3 (3G)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "04", "3 (2G)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "05", "3 (CDMA)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "06", "SmarTone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "07", "China Unicom (Hong Kong) Limited");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "08", "Trident Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "09", "China Motion Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "10", "New World Mobility");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "11", "China-Hong Kong Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "12", "CMCC HK");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "14", "Hutchison Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "15", "SmarTone Mobile Communications Limited");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "16", "PCCW Mobile (2G)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "17", "SmarTone Mobile Communications Limited");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "18", "CSL Limited");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "19", "PCCW Mobile (3G)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HK", 454, "29", "PCCW Mobile (CDMA)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HU", 216, "01", "Telenor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HU", 216, "30", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("HU", 216, "70", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IS", 274, "01", "Síminn");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IS", 274, "02", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IS", 274, "03", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IS", 274, "04", "Viking");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IS", 274, "06", "Núll níu ehf");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IS", 274, "07", "IceCell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IS", 274, "08", "On-waves");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IS", 274, "11", "Nova");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IS", 274, "12", "Tal");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "01", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "02", "AirTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "03", "AirTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "04", "IDEA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "05", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "07", "IDEA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "09", "Reliance");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "10", "AirTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "11", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "12", "IDEA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "13", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "14", "IDEA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "15", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "17", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "19", "IDEA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "20", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "21", "Loop Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "22", "IDEA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "24", "IDEA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "25", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "27", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "28", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "29", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "30", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "31", "AirTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "34", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "36", "Reliance");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "37", "Aircel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "38", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "41", "Aircel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "42", "Aircel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "44", "IDEA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "45", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "46", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "48", "Dishnet Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "49", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "51", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "52", "Reliance");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "53", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "54", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "55", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "71", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "56", "IDEA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "57", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "58", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "59", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "60", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "62", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "64", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "66", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "67", "Reliance GSM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "68", "DOLPHIN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "69", "DOLPHIN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "72", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "74", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "76", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "78", "Idea Cellular Ltd");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "80", "BSNL MOBILE");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "81", "CellOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "82", "Idea");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "83", "Reliance Smart GSM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "84", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "85", "Reliance");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "86", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "87", "Idea");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "88", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "89", "Idea");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "90", "AirTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "91", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "92", "AirTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "93", "AirTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "96", "AirTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "01", "Reliance");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "03", "Reliance");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "04", "Reliance");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "05", "Reliance");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "09", "Reliance");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "10", "Reliance");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "13", "Reliance");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "025", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "026", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "027", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "029", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "030", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "031", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "032", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "033", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "034", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "035", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "036", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "037", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "038", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "039", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "041", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "042", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "043", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "044", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "045", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "046", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "047", "TATA Teleservice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "51", "AirTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "52", "AirTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "54", "AirTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "55", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "56", "AirTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "66", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "70", "IDEA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "750", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "751", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "752", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "753", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "754", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "755", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "756", "Vodafone IN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "799", "IDEA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "800", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "801", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "802", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "803", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "804", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "805", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "806", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "807", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "808", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "809", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "810", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "811", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "812", "AIRCEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "819", "Uninor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "818", "Uninor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "820", "Uninor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "821", "Uninor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "822", "Uninor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "824", "Videocon Datacom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "827", "Videocon Datacom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "834", "Videocon Datacom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "844", "Uninor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "845", "IDEA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "86", "IDEA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "848", "IDEA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "850", "IDEA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "855", "Loop Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "864", "Loop Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "865", "Loop Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "875", "Uninor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "880", "Uninor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "881", "S Tel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "912", "Etisalat DB(cheers)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "913", "Etisalat DB(cheers)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "914", "Etisalat DB(cheers)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "917", "Etisalat DB(cheers)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 404, "927", "Uninor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IN", 405, "929", "Uninor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ID", 510, "00", "PSN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ID", 510, "01", "INDOSAT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ID", 510, "03", "StarOne");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ID", 510, "07", "TelkomFlexi");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ID", 510, "08", "AXIS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ID", 510, "09", "SMART");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ID", 510, "10", "Telkomsel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ID", 510, "11", "XL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ID", 510, "20", "TELKOMMobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ID", 510, "21", "IM3");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ID", 510, "27", "Ceria");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ID", 510, "28", "Fren/Hepi");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ID", 510, "89", "3");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ID", 510, "99", "Esia");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IR", 432, "11", "IR-MCI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IR", 432, "14", "TKC");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IR", 432, "19", "MTCE");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IR", 432, "32", "Taliya");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IR", 432, "35", "Irancell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IR", 432, "70", "TCI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IR", 432, "93", "Iraphone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IQ", 418, "05", "Asia Cell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IQ", 418, "08", "SanaTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IQ", 418, "20", "Zain");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IQ", 418, "30", "Zain");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IQ", 418, "40", "Korek");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IQ", 418, "45", "Mobitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IQ", 418, "92", "Omnnea");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IE", 272, "01", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IE", 272, "02", "O2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IE", 272, "03", "Meteor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IE", 272, "04", "Access Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IE", 272, "05", "3");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IE", 272, "07", "Eircom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IE", 272, "09", "Clever Communications");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IE", 272, "11", "Liffey Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IM", 234, "58", "Pronto GSM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IM", 234, "09", "Sure Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IL", 425, "01", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IL", 425, "02", "Cellcom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IL", 425, "03", "Pelephone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IL", 425, "77", "Mirs");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IT", 222, "01", "TIM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IT", 222, "02", "Elsacom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IT", 222, "07", "Noverca");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IT", 222, "10", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IT", 222, "30", "RFI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IT", 222, "77", "IPSE 2000");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IT", 222, "88", "Wind");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IT", 222, "98", "Blu");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("IT", 222, "99", "3 Italia");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CI", 612, "01", "Cora de Comstar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CI", 612, "02", "Moov");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CI", 612, "03", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CI", 612, "04", "KoZ");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CI", 612, "05", "MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CI", 612, "06", "ORICEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JM", 338, "020", "LIME");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JM", 338, "050", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JM", 338, "070", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JM", 338, "180", "LIME");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "00", "eMobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "01", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "02", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "03", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "04", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "06", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "07", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "08", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "09", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "10", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "11", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "12", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "13", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "14", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "15", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "16", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "17", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "18", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "19", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "20", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "21", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "22", "NTT docomo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "23", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "24", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "25", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "26", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "27", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "28", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "29", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "30", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "31", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "32", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "33", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "34", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "35", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "36", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "37", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "38", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "39", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "40", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "41", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "42", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "43", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "44", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "45", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "46", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "47", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "48", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "49", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "50", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "51", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "52", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "53", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "54", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "55", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "56", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "58", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "60", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "61", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "62", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "63", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "64", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "65", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "66", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "67", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "68", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "69", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "70", "au");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "71", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "72", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "73", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "74", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "75", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "76", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "77", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "78", "Okinawa Cellular Telephone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "79", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "80", "TU-KA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "81", "TU-KA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "82", "TU-KA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "83", "TU-KA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "84", "TU-KA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "85", "TU-KA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "86", "TU-KA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "87", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "88", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "89", "KDDI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "90", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "92", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "93", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "94", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "95", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "96", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "97", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "98", "SoftBank");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JP", 440, "99", "DoCoMo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JE", 234, "50", "JT-Wave");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JE", 234, "55", "Sure Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JE", 234, "03", "Airtel Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JO", 416, "01", "zain JO");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JO", 416, "02", "XPress Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JO", 416, "03", "Umniah");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("JO", 416, "77", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KZ", 401, "01", "Beeline");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KZ", 401, "02", "Kcell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KZ", 401, "07", "Dalacom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KZ", 401, "08", "Kazakhtelecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KZ", 401, "77", "Mobile Telecom Service");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KE", 639, "02", "Safaricom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KE", 639, "03", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KE", 639, "07", "Orange Kenya");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KE", 639, "05", "yu");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KI", 545, "09", "Kiribati Frigate");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KP", 467, "192", "Koryolink");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KP", 467, "193", "SunNet");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KR", 450, "02", "KT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KR", 450, "03", "Power 017");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KR", 450, "04", "KT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KR", 450, "05", "SKT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KR", 450, "06", "LGU+");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KR", 450, "08", "olleh");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RKS", 212, "01", "Vala");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RKS", 293, "41", "IPKO");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RKS", 212, "01", "Z Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KW", 419, "02", "zain KW");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KW", 419, "03", "Wataniya");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KW", 419, "04", "Viva");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KG", 437, "01", "Beeline");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KG", 437, "03", "Fonex");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KG", 437, "05", "MegaCom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("KG", 437, "09", "O!");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LA", 457, "01", "LaoTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LA", 457, "02", "ETL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LA", 457, "03", "Unitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LA", 457, "08", "Tigo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LV", 247, "01", "LMT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LV", 247, "02", "Tele2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LV", 247, "03", "TRIATEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LV", 247, "05", "Bite");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LV", 247, "06", "Rigatta");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LV", 247, "07", "MTS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LV", 247, "08", "IZZI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LV", 247, "09", "Camel Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LB", 415, "01", "Alfa");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LB", 415, "03", "mtc touch");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LB", 415, "05", "Ogero Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LS", 651, "01", "Vodacom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LS", 651, "02", "Econet Ezin-cel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LR", 618, "01", "Lonestar Cell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LR", 618, "02", "Libercell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LR", 618, "04", "Comium");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LR", 618, "07", "Cellcom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LR", 618, "20", "LIBTELCO");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LY", 606, "00", "Libyana");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LY", 606, "01", "Madar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LY", 606, "02", "Al-Jeel Phone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LY", 606, "03", "Libya Phone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LY", 606, "06", "Hatef Libya");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LI", 295, "01", "Swisscom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LI", 295, "02", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LI", 295, "05", "FL1");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LI", 295, "77", "Alpmobil");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LI", 295, "04", "Cubic Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LT", 246, "01", "Omnitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LT", 246, "02", "BITE");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LT", 246, "03", "Tele 2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LT", 246, "05", "LitRail");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LT", 246, "06", "Mediafon");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LU", 270, "01", "LuxGSM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LU", 270, "77", "Tango");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LU", 270, "99", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MO", 455, "00", "SmarTone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MO", 455, "01", "CTM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MO", 455, "02", "China Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MO", 455, "03", "3");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MO", 455, "04", "CTM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MO", 455, "05", "3");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MK", 294, "01", "T-Mobile MK");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MK", 294, "02", "ONE");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MK", 294, "03", "Vip MK");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MG", 646, "01", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MG", 646, "02", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MG", 646, "03", "Sacel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MG", 646, "04", "Telma");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MW", 650, "01", "TNM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MW", 650, "10", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MY", 502, "01", "ATUR 450");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MY", 502, "10", "DiGi Telecommunications");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MY", 502, "11", "TM Homeline");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MY", 502, "12", "Maxis");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MY", 502, "13", "Celcom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MY", 502, "14", "Telekom Malaysia Berhad for PSTN SMS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MY", 502, "16", "DiGi");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MY", 502, "17", "Hotlink");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MY", 502, "18", "U Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MY", 502, "18", "TM Homeline");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MY", 502, "19", "Celcom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MY", 502, "20", "Electcoms Wireless Sdn Bhd");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MY", 502, "150", "Tune Talk");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MY", 502, "151", "Baraka Telecom Sdn Bhd (MVNE)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MY", 502, "152", "Yes");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MV", 472, "01", "Dhiraagu");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MV", 472, "02", "Wataniya");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ML", 610, "01", "Malitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ML", 610, "02", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MT", 278, "01", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MT", 278, "21", "GO");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MT", 278, "77", "Melita");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MQ", 340, "01", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MQ", 340, "02", "Outremer");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MQ", 340, "20", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MR", 609, "01", "Mattel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MR", 609, "02", "Chinguitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MR", 609, "10", "Mauritel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MU", 617, "01", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MU", 617, "02", "MTML");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MU", 617, "10", "Emtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MX", 334, "010", "Nextel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MX", 334, "020", "Telcel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MX", 334, "030", "movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MX", 334, "040", "Iusacell / Unefon");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MX", 334, "050", "Iusacell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("FM", 550, "01", "FSM EMMANUEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MD", 259, "01", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MD", 259, "02", "Moldcell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MD", 259, "03", "IDC");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MD", 259, "03", "Unité");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MD", 259, "04", "Eventis");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MD", 259, "05", "Unité");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MD", 259, "99", "Unité");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MC", 212, "01", "Office des Telephones");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MN", 428, "99", "MobiCom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MN", 428, "88", "Unitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MN", 428, "91", "Skytel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MN", 428, "98", "G.Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ME", 297, "01", "Telenor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ME", 297, "02", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ME", 297, "03", "m:tel CG");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ME", 297, "04", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MA", 604, "00", "Méditel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MA", 604, "01", "IAM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MA", 604, "05", "INWI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MZ", 643, "01", "mCel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MZ", 643, "04", "Vodacom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("MM", 414, "01", "MPT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NA", 649, "01", "MTC");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NA", 649, "02", "switch");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NA", 649, "03", "Leo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NR", 536, "02", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NP", 429, "01", "Namaste / NT Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NP", 429, "02", "Ncell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NP", 429, "04", "SmartCell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NP", 429, "03", "Sky/C-Phone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "01", "VastMobiel B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "02", "Tele2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "03", "Voiceworks B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "04", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "05", "Elephant Talk Communications Premium Rate Services");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "06", "Mundio Mobile (Netherlands) Ltd");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "07", "Teleena (MVNE)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "08", "KPN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "09", "Lycamobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "10", "KPN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "12", "Telfort");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "13", "Unica Installatietechniek B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "14", "6Gmobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "15", "Ziggo B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "16", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "17", "Intercity Mobile Communications B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "18", "UPC Nederland B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "19", "Mixe Communication Solutions B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "20", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "21", "ProRail B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "22", "Ministerie van Defensie");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "23", "ASPIDER Solutions Nederland B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "24", "Private Mobility Nederland B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "25", "CapX B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "26", "SpeakUp B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "27", "Breezz Nederland B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "67", "RadioAccess B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "68", "Unify Group Holding B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NL", 204, "69", "KPN Mobile The Netherlands B.V.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AN", 362, "51", "Telcell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AN", 362, "69", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AN", 362, "91", "UTS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AN", 362, "95", "MIO");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AN", 362, "94", "Bayòs");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NC", 546, "01", "Mobilis");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NZ", 530, "00", "Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NZ", 530, "01", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NZ", 530, "02", "Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NZ", 530, "03", "Woosh");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NZ", 530, "04", "TelstraClear");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NZ", 530, "05", "XT Mobile Network");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NZ", 530, "24", "2degrees");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NI", 710, "21", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NI", 710, "30", "movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NI", 710, "73", "SERCOM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NE", 614, "01", "SahelCom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NE", 614, "02", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NE", 614, "03", "Telecel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NE", 614, "04", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NG", 621, "20", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NG", 621, "30", "MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NG", 621, "40", "M-Tel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NG", 621, "50", "Glo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NG", 621, "60", "Etisalat");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NG", 621, "25", "Visafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NU", 555, "01", "Telecom Niue");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NF", 505, "10", "Norfolk Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NO", 242, "01", "Telenor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NO", 242, "02", "NetCom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NO", 242, "03", "Teletopia");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NO", 242, "04", "Tele2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NO", 242, "05", "Network Norway");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NO", 242, "06", "Ice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NO", 242, "07", "Ventelo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NO", 242, "08", "TDC");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NO", 242, "09", "Com4");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NO", 242, "11", "SystemNet");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NO", 242, "20", "Jernbaneverket AS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("NO", 242, "23", "Lyca");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("OM", 422, "02", "Oman Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("OM", 422, "03", "Nawras");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PK", 410, "01", "Mobilink");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PK", 410, "03", "Ufone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PK", 410, "04", "Zong");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PK", 410, "06", "Telenor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PK", 410, "07", "Warid");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PW", 552, "01", "PNCC");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PW", 552, "80", "Palau Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PS", 425, "05", "Jawwal");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PS", 425, "06", "Wataniya");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PA", 714, "01", "Cable & Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PA", 714, "02", "movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PA", 714, "04", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PA", 714, "03", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PG", 537, "01", "B-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PG", 537, "03", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PY", 744, "01", "VOX");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PY", 744, "02", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PY", 744, "04", "Tigo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PY", 744, "05", "Personal");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PY", 744, "06", "Copaco");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PE", 716, "06", "Movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PE", 716, "07", "NEXTEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PE", 716, "10", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PH", 515, "01", "Islacom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PH", 515, "02", "Globe");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PH", 515, "03", "Smart");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PH", 515, "05", "Sun");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PH", 515, "11", "PLDT via ACeS Philippines");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PH", 515, "18", "Cure");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PH", 515, "88", "Nextel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PL", 260, "01", "Plus");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PL", 260, "02", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PL", 260, "03", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PL", 260, "04", "not in use");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PL", 260, "05", "Polska Telefonia Komórkowa Centertel Sp. z o.o.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PL", 260, "06", "Play");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PL", 260, "07", "Netia");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PL", 260, "08", "E-Telko Sp. z o.o.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PL", 260, "09", "Telekomunikacja Kolejowa Sp. z o.o.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PL", 260, "10", "Sferia");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PL", 260, "11", "Nordisk Polska");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PL", 260, "12", "Cyfrowy Polsat");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PL", 260, "15", "CenterNet");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PL", 260, "16", "Mobyland");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PL", 260, "17", "Aero2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PT", 268, "01", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PT", 268, "03", "Optimus");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PT", 268, "06", "TMN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PT", 268, "21", "Zapp");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PR", 330, "110", "Claro");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PR", 330, "00", "Open Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("QA", 427, "01", "Qtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("QA", 427, "02", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("QA", 427, "05", "Ministry of Interior");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RE", 647, "00", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RE", 647, "02", "Outremer");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RE", 647, "10", "SFR Reunion");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RO", 226, "01", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RO", 226, "02", "Romtelecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RO", 226, "03", "Cosmote");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RO", 226, "04", "Cosmote");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RO", 226, "05", "Digi.Mobil");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RO", 226, "06", "Cosmote");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RO", 226, "10", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RO", 226, "11", "Enigma-System");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "01", "MTS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "02", "MegaFon");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "03", "NCC");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "04", "Sibchallenge");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "05", "ETK");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "06", "Skylink [10]");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "07", "SMARTS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "09", "Skylink");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "10", "DTC");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "11", "Orensot");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "12", "Baykalwestcom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "12", "Akos");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "13", "KUGSM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "15", "SMARTS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "16", "NTC");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "17", "Utel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "19", "INDIGO");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "20", "Tele2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "23", "Mobicom - Novosibirsk");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "28", "Beeline");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "35", "MOTIV");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "38", "Tambov GSM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "39", "Utel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "44", "Stavtelesot / North Caucasian GSM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "92", "Primtelefon");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "93", "Telecom XXI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RU", 250, "99", "Beeline");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RW", 635, "10", "MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RW", 635, "12", "Rwandatel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RW", 635, "13", "Tigo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SKN", 356, "050", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SKN", 356, "110", "LIME");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SKN", 356, "070", "Chippie");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LC", 358, "050", "Digicel[citation needed]");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LC", 358, "110", "Cable & Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("PM", 308, "01", "Ameris");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VC", 360, "070", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VC", 360, "100", "Cingular Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VC", 360, "110", "Cable & Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("WS", 549, "01", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("WS", 549, "27", "SamoaTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SM", 292, "01", "PRIMA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ST", 626, "01", "CSTmovel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SA", 420, "01", "Al Jawal");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SA", 420, "03", "Mobily");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SA", 420, "04", "Zain SA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SN", 608, "01", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SN", 608, "02", "Tigo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SN", 608, "03", "Expresso");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RS", 220, "01", "Telenor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RS", 220, "02", "Telenor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RS", 220, "03", "mt:s");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("RS", 220, "05", "VIP");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SC", 633, "01", "Cable & Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SC", 633, "02", "Mediatech International");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SC", 633, "10", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SL", 619, "01", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SL", 619, "02", "Tigo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SL", 619, "03", "Africell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SL", 619, "04", "Comium");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SL", 619, "05", "Africell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SL", 619, "25", "Mobitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SG", 525, "01", "SingTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SG", 525, "02", "SingTel-G18");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SG", 525, "03", "M1");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SG", 525, "05", "StarHub");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SG", 525, "12", "Digital Trunked Radio Network");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SK", 231, "01", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SK", 231, "02", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SK", 231, "03", "Unient Communications");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SK", 231, "04", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SK", 231, "06", "O2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SK", 231, "99", "ŽSR");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SI", 293, "40", "Si.mobil");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SI", 293, "41", "Mobitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SI", 293, "64", "T-2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SI", 293, "70", "Tušmobil");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SB", 540, "01", "BREEZE");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SO", 637, "60", "Nationlink Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SO", 637, "01", "Telesom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SO", 637, "04", "Somafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SO", 637, "10", "Nationlink");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SO", 637, "25", "Hormuud");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SO", 637, "30", "Golis");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SO", 637, "82", "Telcom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZA", 655, "01", "Vodacom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZA", 655, "02", "Telkom Mobile / 8.ta");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZA", 655, "06", "Sentech");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZA", 655, "07", "Cell C");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZA", 655, "10", "MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZA", 655, "11", "South African Police Service Gauteng");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZA", 655, "13", "Neotel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZA", 655, "21", "Cape Town Metropolitan Council");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZA", 655, "30", "Bokamoso Consortium");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZA", 655, "31", "Karabo Telecoms (Pty) Ltd.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZA", 655, "32", "Ilizwi Telecommunications");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZA", 655, "33", "Thinta Thinta Telecommunications");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 250, "30", "Megafon");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "01", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "03", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "04", "Yoigo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "05", "TME");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "06", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "07", "movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "08", "Euskaltel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "09", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "15", "BT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "16", "TeleCable");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "17", "Móbil R");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "18", "ONO");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "19", "Simyo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "20", "Fonyou");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "21", "Jazztel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "22", "DigiMobil");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "23", "Barablu");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "24", "Eroski");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ES", 214, "25", "LycaMobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LK", 413, "01", "Mobitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LK", 413, "02", "Dialog");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LK", 413, "03", "Etisalat");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LK", 413, "05", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("LK", 413, "08", "Hutch");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SD", 634, "01", "Zain SD");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SD", 634, "02", "MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SD", 634, "05", "Vivacell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SD", 634, "07", "Sudani One");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SR", 746, "02", "Telesur");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SR", 746, "03", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SR", 746, "04", "Uniqa");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SZ", 653, "10", "Swazi MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "01", "Telia");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "02", "3");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "03", "Ice.net");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "04", "3G Infrastructure Services");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "05", "Sweden 3G");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "06", "Telenor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "07", "Tele2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "08", "Telenor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "09", "djuice");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "10", "Spring Mobil");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "11", "Lindholmen Science Park");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "12", "Barablu Mobile Scandinavia");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "13", "Ventelo Sverige");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "14", "TDC Mobil");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "15", "Wireless Maingate Nordic");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "16", "42IT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "17", "Gotanet");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "20", "Wireless Maingate Message Services");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "21", "MobiSir");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "24", "Sweden 2G");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "25", "DigiTelMobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "26", "Beepsend");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SE", 240, "33", "Mobile Arts AB");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CH", 228, "01", "Swisscom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CH", 228, "02", "Sunrise");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CH", 228, "03", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CH", 228, "05", "Togewanet AG (Comfone)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CH", 228, "06", "SBB-CFF-FFS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CH", 228, "07", "IN&Phone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CH", 228, "08", "Tele2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CH", 228, "50", "3G Mobile AG");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("CH", 228, "51", "BebbiCell AG");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SY", 417, "01", "Syriatel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("SY", 417, "02", "MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TW", 466, "01", "FarEasTone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TW", 466, "05", "APTG");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TW", 466, "06", "Tuntex");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TW", 466, "11", "Chunghwa LDM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TW", 466, "88", "KG Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TW", 466, "89", "VIBO");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TW", 466, "92", "Chungwa");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TW", 466, "93", "MobiTai");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TW", 466, "97", "Taiwan Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TW", 466, "99", "TransAsia");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TJ", 436, "01", "Tcell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TJ", 436, "02", "Tcell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TJ", 436, "03", "MLT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TJ", 436, "04", "Babilon-M");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TJ", 436, "05", "Beeline");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TJ", 436, "12", "Tcell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TZ", 640, "02", "tiGO");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TZ", 640, "03", "Zantel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TZ", 640, "04", "Vodacom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TZ", 640, "05", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TZ", 640, "06", "Sasatel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TZ", 640, "07", "TTCL Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TZ", 640, "08", "Benson Online (BOL)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TZ", 640, "09", "Hits");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TZ", 640, "11", "SmileCom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TH", 520, "00", "my CAT 3G+");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TH", 520, "01", "AIS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TH", 520, "02", "CAT CDMA");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TH", 520, "10", "WCS IQ");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TH", 520, "15", "TOT 3G");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TH", 520, "18", "dtac");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TH", 520, "23", "AIS GSM 1800");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TH", 520, "99", "True Move");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TG", 615, "01", "Togo Cell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TG", 615, "03", "Moov");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TO", 539, "01", "Tonga Communications Corporation");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TO", 539, "43", "Shoreline Communication");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TO", 539, "88", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TT", 374, "12", "bmobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TT", 374, "130", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TN", 605, "01", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TN", 605, "02", "Tunicell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TN", 605, "03", "Tunisiana");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TR", 286, "01", "Turkcell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TR", 286, "02", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TR", 286, "03", "Avea");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TR", 286, "04", "Aycell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TM", 438, "01", "MTS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TM", 438, "02", "TM-Cell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TC", 376, "350", "C&W");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TC", 376, "352", "Islandcom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TC", 338, "05", "Digicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("TV", 553, "01", "TTC");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UG", 641, "01", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UG", 641, "10", "MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UG", 641, "11", "UTL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UG", 641, "14", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UG", 641, "22", "Warid Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UA", 255, "01", "MTS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UA", 255, "02", "Beeline");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UA", 255, "03", "Kyivstar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UA", 255, "04", "IT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UA", 255, "05", "Golden Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UA", 255, "06", "life:)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UA", 255, "07", "Ukrtelecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UA", 255, "21", "PEOPLEnet");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UA", 255, "23", "CDMA Ukraine");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AE", 424, "02", "Etisalat");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("AE", 424, "03", "du");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "00", "BT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "01", "Vectone Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "02", "O2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "03", "Airtel-Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "04", "FMS Solutions Ltd");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "05", "COLT Mobile Telecommunications Limited");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "06", "Internet Computer Bureau Limited");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "07", "Cable & Wireless UK");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "08", "OnePhone (UK) Ltd");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "09", "Tismi BV");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "10", "O2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "11", "O2");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "12", "Railtrack");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "13", "Railtrack");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "14", "Hay Systems Ltd");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "15", "Vodafone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "16", "Talk Talk");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "17", "FleXtel Limited");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "18", "Cloud9");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "19", "Private Mobile Networks PMN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "20", "Three");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "22", "RoutoMessaging");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "24", "Greenfone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "25", "Truphone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "30", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "31", "Virgin");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "32", "Virgin");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "33", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "34", "Orange");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "35", "JSC Ingenium (UK) Limited");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "36", "Cable and Wireless Isle of Man Limited");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "37", "Synectiv Ltd");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "50", "JT-Wave");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "55", "Cable & Wireless Guernsey / Sure Mobile (Jersey)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "58", "Manx Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "76", "BT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 234, "78", "Airwave");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 235, "00", "Mundio Mobile Limited");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 235, "01", "Everything Everywhere Limited (TM)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 235, "02", "Everything Everywhere Limited (TM)");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 235, "77", "BT");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 235, "91", "Vodafone United Kingdom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 235, "92", "Cable & Wireless UK");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 235, "94", "Hutchison 3G UK Ltd");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UK", 235, "95", "Network Rail Infrastructure Limited");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "053", "Virgin Mobile US");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "054", "Alltel US");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "066", "U.S. Cellular");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "004", "Verizon");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "005", "Verizon");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "010", "MCI");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "012", "Verizon");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "013", "MobileTel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "014", "Testing");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "016", "Cricket Communications");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "017", "North Sight Communications Inc.");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "020", "Union Telephone Company");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "026", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "030", "Centennial");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "034", "Airpeak");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "040", "Concho");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "046", "SIMMETRY");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "060", "Consolidated Telcom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "070", "Highland Cellular");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "080", "Corr");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "090", "AT&T");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "100", "Plateau Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "110", "PTI Pacifica");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "120", "Sprint");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "150", "AT&T");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "160", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "170", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "180", "West Central");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "190", "Dutch Harbor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "200", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "210", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "220", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "230", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "240", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "250", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "260", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "270", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "280", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "290", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "300", "iSmart Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "310", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "311", "Farmers Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "320", "Cellular One");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "330", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "340", "Westlink");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "350", "Carolina Phone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "380", "AT&T");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "390", "Cellular One of East Texas");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "400", "i CAN_GSM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "410", "AT&T");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "420", "Cincinnati Bell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "430", "Alaska Digitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "440", "Cellular One");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "450", "Viaero");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "460", "Simmetry");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "470", "nTelos");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "480", "Choice Phone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "490", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "500", "Alltel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "510", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "520", "VeriSign");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "530", "West Virginia Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "540", "Oklahoma Western");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "560", "AT&T");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "570", "Cellular One");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "580", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "590", "Alltel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "610", "Epic Touch");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "620", "Coleman County Telecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "630", "AmeriLink PCS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "640", "Airadigm");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "650", "Jasper");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "660", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "670", "Northstar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "680", "AT&T");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "690", "Conestoga");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "730", "SeaMobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "740", "Convey");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "760", "Panhandle");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "770", "i wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "780", "Airlink PCS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "790", "PinPoint");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "800", "T-Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "830", "Caprock");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "840", "telna Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "850", "Aeris");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "870", "PACE");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "880", "Advantage");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "890", "Unicel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "900", "Mid-Rivers Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "910", "First Cellular");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "940", "Iris Wireless LLC");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "950", "XIT Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "960", "Plateau Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "970", "Globalstar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "980", "AT&T Mobility");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 310, "990", "AT&T Mobility");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "000", "Mid-Tex Cellular");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "010", "Chariton Valley");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "020", "Missouri RSA 5 Partnership");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "030", "Indigo Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "040", "Commnet Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "050", "Wikes Cellular");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "060", "Farmers Cellular");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "070", "Easterbrooke");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "080", "Pine Cellular");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "090", "Long Lines Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "100", "High Plains Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "110", "High Plains Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "120", "Choice Phone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "130", "Cell One Amarillo");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "140", "Sprocket");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "150", "Wilkes Cellular");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "160", "Endless Mountains Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "170", "PetroCom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "180", "Cingular Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "190", "Cellular Properties");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "210", "Emery Telcom Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "220", "U.S. Cellular");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "230", "C Spire Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "330", "Bug Tussel Wireless");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "480", "Verizon");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 311, "660", "metroPCS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 316, "010", "Nextel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("US", 316, "011", "Southern Communications Services");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UY", 748, "01", "Antel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UY", 748, "07", "Movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UY", 748, "10", "Claro UY");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UZ", 434, "01", "Buztel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UZ", 434, "02", "Uzmacom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UZ", 434, "04", "Beeline");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UZ", 434, "05", "Ucell");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UZ", 434, "06", "Perfectum Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("UZ", 434, "07", "MTS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VU", 541, "01", "SMILE");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VE", 734, "01", "Digitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VE", 734, "02", "Digitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VE", 734, "03", "Digitel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VE", 734, "04", "movistar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VE", 734, "06", "Movilnet");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VN", 452, "01", "MobiFone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VN", 452, "02", "Vinaphone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VN", 452, "03", "S-Fone");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VN", 452, "04", "Viettel Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VN", 452, "05", "Vietnamobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VN", 452, "06", "EVNTelecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VN", 452, "08", "3G EVNTelecom");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("VN", 452, "07", "Beeline VN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("YE", 421, "01", "SabaFon");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("YE", 421, "02", "MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("YE", 421, "03", "Yemen Mobile");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("YE", 421, "04", "HiTS-UNITEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZM", 645, "01", "Airtel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZM", 645, "02", "MTN");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZM", 645, "03", "ZAMTEL");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZW", 648, "01", "Net*One");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZW", 648, "03", "Telecel");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("ZW", 648, "04", "Econet");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "01", "ICO");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "02", "Sense Communications International");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "03", "Iridium");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "04", "Globalstar");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "05", "Thuraya RMSS Network");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "06", "Thuraya Satellite Telecommunications Company");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "07", "Ellipso");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "08", "");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "09", "Tele1 Europe");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "10", "ACeS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "11", "Inmarsat");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "12", "Telenor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "13", "GSM.AQ");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "14", "AeroMobile AS");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "15", "OnAir Switzerland Sarl");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "16", "Jasper Systems");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "17", "Navitas");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "18", "Cellular @Sea");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "19", "Vodafone Malta Maritime");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "21", "Seanet");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "23", "Beeline");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "24", "iNum");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "26", "TIM");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "29", "Telenor");
+insert into mcc_mnc_oper_list (country, mcc, mnc, oper) values ("__", 901, "32", "Sky High");
+COMMIT;
--- /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", "TRATS2", "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);
+ s_phonebook_init(p, h);
+ s_sap_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: 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 <glib.h>
+
+#include <tcore.h>
+#include <hal.h>
+#include <core_object.h>
+#include <plugin.h>
+#include <queue.h>
+#include <co_call.h>
+#include <user_request.h>
+#include <server.h>
+#include <at.h>
+
+#include "s_common.h"
+#include "s_call.h"
+
+
+#define STATUS_INCOMING 4
+#define STATUS_WAITING 5
+#define STATUS_CONNECTED 7
+#define COMMA 0X2c
+
+static gboolean setsoundpath = FALSE;
+static gboolean soundvolume = FALSE;
+
+// End Cause field - Call state end cause
+
+typedef enum {
+ CALL_END_NO_CAUSE,
+
+ // These definitions are taken from GSM 04.08 Table 10.86
+
+ CC_CAUSE_UNASSIGNED_NUMBER,
+ CC_CAUSE_NO_ROUTE_TO_DEST,
+ CC_CAUSE_CHANNEL_UNACCEPTABLE,
+ CC_CAUSE_OPERATOR_DETERMINED_BARRING,
+ CC_CAUSE_NORMAL_CALL_CLEARING,
+ CC_CAUSE_USER_BUSY,
+ CC_CAUSE_NO_USER_RESPONDING,
+ CC_CAUSE_USER_ALERTING_NO_ANSWER,
+ CC_CAUSE_CALL_REJECTED,
+ CC_CAUSE_NUMBER_CHANGED,
+ CC_CAUSE_NON_SELECTED_USER_CLEARING,
+ CC_CAUSE_DESTINATION_OUT_OF_ORDER,
+ CC_CAUSE_INVALID_NUMBER_FORMAT,
+ CC_CAUSE_FACILITY_REJECTED,
+ CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY,
+ CC_CAUSE_NORMAL_UNSPECIFIED,
+ CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE,
+ CC_CAUSE_NETWORK_OUT_OF_ORDER,
+ CC_CAUSE_TEMPORARY_FAILURE,
+ CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION,
+ CC_CAUSE_ACCESS_INFORMATION_DISCARDED,
+ CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE,
+ CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED,
+ CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE,
+ CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED,
+ CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG,
+ CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED,
+ CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE,
+ CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE,
+ CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED,
+ CC_CAUSE_ACM_GEQ_ACMMAX,
+ CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED,
+ CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE,
+ CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED,
+ CC_CAUSE_INVALID_TRANSACTION_ID_VALUE,
+ CC_CAUSE_USER_NOT_MEMBER_OF_CUG,
+ CC_CAUSE_INCOMPATIBLE_DESTINATION,
+ CC_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION,
+ CC_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE,
+ CC_CAUSE_INVALID_MANDATORY_INFORMATION,
+ CC_CAUSE_MESSAGE_TYPE_NON_EXISTENT,
+ CC_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROT_STATE,
+ CC_CAUSE_IE_NON_EXISTENT_OR_NOT_IMPLEMENTED,
+ CC_CAUSE_CONDITIONAL_IE_ERROR,
+ CC_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE,
+ CC_CAUSE_RECOVERY_ON_TIMER_EXPIRY,
+ CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
+ CC_CAUSE_INTERWORKING_UNSPECIFIED,
+ CC_CAUSE_END = 128,
+
+ // Reject causes
+ REJECT_CAUSE_IMSI_UNKNOWN_IN_HLR,
+ REJECT_CAUSE_ILLEGAL_MS,
+ REJECT_CAUSE_IMSI_UNKNOWN_IN_VLR,
+ REJECT_CAUSE_IMEI_NOT_ACCEPTED,
+ REJECT_CAUSE_ILLEGAL_ME,
+ REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED,
+ REJECT_CAUSE_GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED,
+ REJECT_CAUSE_MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK,
+ REJECT_CAUSE_IMPLICITLY_DETACHED,
+ REJECT_CAUSE_PLMN_NOT_ALLOWED,
+ REJECT_CAUSE_LA_NOT_ALLOWED,
+ REJECT_CAUSE_NATIONAL_ROAMING_NOT_ALLOWED,
+ REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN,
+ REJECT_CAUSE_NO_SUITABLE_CELLS_IN_LA,
+ REJECT_CAUSE_MSC_TEMPORARILY_NOT_REACHABLE,
+ REJECT_CAUSE_NETWORK_FAILURE,
+ REJECT_CAUSE_MAC_FAILURE,
+ REJECT_CAUSE_SYNCH_FAILURE,
+ REJECT_CAUSE_CONGESTTION,
+ REJECT_CAUSE_GSM_AUTH_UNACCEPTED,
+ REJECT_CAUSE_SERVICE_OPTION_NOT_SUPPORTED,
+ REJECT_CAUSE_REQ_SERV_OPT_NOT_SUBSCRIBED,
+ REJECT_CAUSE_SERVICE_OPT__OUT_OF_ORDER,
+ REJECT_CAUSE_CALL_CANNOT_BE_IDENTIFIED,
+ REJECT_CAUSE_NO_PDP_CONTEXT_ACTIVATED,
+ REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MIN_VALUE,
+ REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MAX_VALUE,
+ REJECT_CAUSE_SEMANTICALLY_INCORRECT_MSG,
+ REJECT_CAUSE_INVALID_MANDATORY_INFO,
+ REJECT_CAUSE_MESSAGE_TYPE_NON_EXISTANT,
+ REJECT_CAUSE_MESSAGE_TYPE_NOT_COMP_PRT_ST,
+ REJECT_CAUSE_IE_NON_EXISTANT,
+ REJECT_CAUSE_MSG_NOT_COMPATIBLE_PROTOCOL_STATE,
+
+
+ // Connection Management establishment rejection cause
+ REJECT_CAUSE_REJ_UNSPECIFIED,
+
+ // AS reject causes
+ REJECT_CAUSE_AS_REJ_RR_REL_IND,
+ REJECT_CAUSE_AS_REJ_RR_RANDOM_ACCESS_FAILURE,
+ REJECT_CAUSE_AS_REJ_RRC_REL_IND,
+ REJECT_CAUSE_AS_REJ_RRC_CLOSE_SESSION_IND,
+ REJECT_CAUSE_AS_REJ_RRC_OPEN_SESSION_FAILURE,
+ REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL,
+ REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL_REDIAL_NOT_ALLOWED,
+ REJECT_CAUSE_AS_REJ_LOW_LEVEL_IMMED_RETRY,
+
+ // MM reject causes
+ REJECT_CAUSE_MM_REJ_INVALID_SIM,
+ REJECT_CAUSE_MM_REJ_NO_SERVICE,
+ REJECT_CAUSE_MM_REJ_TIMER_T3230_EXP,
+ REJECT_CAUSE_MM_REJ_NO_CELL_AVAILABLE,
+ REJECT_CAUSE_MM_REJ_WRONG_STATE,
+ REJECT_CAUSE_MM_REJ_ACCESS_CLASS_BLOCKED,
+ // Definitions for release ind causes between MM and CNM
+ REJECT_CAUSE_ABORT_MSG_RECEIVED,
+ REJECT_CAUSE_OTHER_CAUSE,
+
+ // CNM reject causes
+ REJECT_CAUSE_CNM_REJ_TIMER_T303_EXP,
+ REJECT_CAUSE_CNM_REJ_NO_RESOURCES,
+ REJECT_CAUSE_CNM_MM_REL_PENDING,
+ REJECT_CAUSE_CNM_INVALID_USER_DATA,
+ CALL_END_CAUSE_MAX = 255
+} call_end_cause_e_type;
+
+
+struct clcc_call_t {
+ struct call_CLCC_info {
+ int id;
+ enum tcore_call_direction direction;
+ enum tcore_call_status status;
+ enum tcore_call_type type;
+ int mpty;
+ int num_len;
+ int num_type;
+ }
+ info;
+ char number[90];
+};
+
+typedef struct {
+ int network_cause;
+ int tapi_cause;
+} call_end_cause_info;
+
+/**************************************************************************
+ * Local Function Prototypes
+ **************************************************************************/
+/************************* REQUESTS ***************************/
+static void _call_status_idle(TcorePlugin *p, CallObject *co);
+static void _call_status_active(TcorePlugin *p, CallObject *co);
+static void _call_status_dialing(TcorePlugin *p, CallObject *co);
+static void _call_status_alert(TcorePlugin *p, CallObject *co);
+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);
+
+/************************* CONFIRMATION ***************************/
+static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data); // from Kernel
+static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data);
+static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data);
+static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data);
+static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data);
+
+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_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data);
+
+/************************* RESPONSES ***************************/
+static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data);
+
+/************************* NOTIIFICATIONS ***************************/
+static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data);
+static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data);
+static void on_notification_call_status(CoreObject *o, const void *data, void *user_data);
+static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data);
+static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data);
+
+
+/**************************************************************************
+ * Local Utility Function Prototypes
+ **************************************************************************/
+static gboolean _call_request_message(TcorePending *pending, CoreObject *o, UserRequest *ur, void *on_resp, void *user_data);
+static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status);
+static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call);
+
+/**************************************************************************
+ * Local Function Definitions
+ **************************************************************************/
+
+const call_end_cause_info call_end_cause_table[] = // call end cause table to convert Netwotk cause to TAPI cause
+{
+ { 1, CC_CAUSE_UNASSIGNED_NUMBER}, { 3, CC_CAUSE_NO_ROUTE_TO_DEST},
+ { 6, CC_CAUSE_CHANNEL_UNACCEPTABLE}, { 8, CC_CAUSE_OPERATOR_DETERMINED_BARRING},
+ { 16, CC_CAUSE_NORMAL_CALL_CLEARING}, { 17, CC_CAUSE_USER_BUSY},
+ { 18, CC_CAUSE_NO_USER_RESPONDING}, { 19, CC_CAUSE_USER_ALERTING_NO_ANSWER},
+ { 21, CC_CAUSE_CALL_REJECTED}, { 22, CC_CAUSE_NUMBER_CHANGED},
+ { 26, CC_CAUSE_NON_SELECTED_USER_CLEARING}, { 27, CC_CAUSE_DESTINATION_OUT_OF_ORDER},
+ { 28, CC_CAUSE_INVALID_NUMBER_FORMAT}, { 29, CC_CAUSE_FACILITY_REJECTED},
+ { 30, CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY}, { 31, CC_CAUSE_NORMAL_UNSPECIFIED},
+ { 34, CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE}, { 38, CC_CAUSE_NETWORK_OUT_OF_ORDER},
+ { 41, CC_CAUSE_TEMPORARY_FAILURE}, { 42, CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION},
+ { 43, CC_CAUSE_ACCESS_INFORMATION_DISCARDED}, { 44, CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE},
+ { 47, CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED}, { 49, CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE},
+ { 50, CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED}, { 55, CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG},
+ { 57, CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED}, { 58, CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE},
+ { 63, CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE}, { 65, CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED},
+ { 68, CC_CAUSE_ACM_GEQ_ACMMAX}, { 69, CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED},
+ { 70, CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE}, { 79, CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED},
+ { 81, CC_CAUSE_INVALID_TRANSACTION_ID_VALUE}, { 87, CC_CAUSE_USER_NOT_MEMBER_OF_CUG},
+ { 88, CC_CAUSE_INCOMPATIBLE_DESTINATION}, { 91, CC_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION},
+ { 95, CC_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE}, { 96, CC_CAUSE_INVALID_MANDATORY_INFORMATION},
+ { 97, CC_CAUSE_MESSAGE_TYPE_NON_EXISTENT}, { 98, CC_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROT_STATE},
+ { 99, CC_CAUSE_IE_NON_EXISTENT_OR_NOT_IMPLEMENTED}, { 100, CC_CAUSE_CONDITIONAL_IE_ERROR},
+ { 101, CC_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE}, { 102, CC_CAUSE_RECOVERY_ON_TIMER_EXPIRY},
+ { 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");
+
+ switch (status) {
+ case 0:
+ return TCORE_CALL_STATUS_ACTIVE;
+
+ case 1:
+ return TCORE_CALL_STATUS_HELD;
+
+ case 2:
+ return TCORE_CALL_STATUS_DIALING;
+
+ case 3:
+ return TCORE_CALL_STATUS_ALERT;
+
+ case 4:
+ return TCORE_CALL_STATUS_INCOMING;
+
+ case 5:
+ return TCORE_CALL_STATUS_WAITING;
+
+ case 6: // DISCONNECTED state // FALL THROUGH
+ default:
+ return TCORE_CALL_STATUS_IDLE;
+ }
+}
+
+static gboolean _call_is_in_mpty(int mpty)
+{
+ dbg("Entry");
+
+ switch (mpty) {
+ case 0:
+ return FALSE;
+
+ case 1:
+ return TRUE;
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+static enum tcore_call_type call_type(int type)
+{
+ dbg("Entry");
+
+ switch (type) {
+ case 0:
+ return TCORE_CALL_TYPE_VOICE;
+
+ case 1:
+ return TCORE_CALL_TYPE_VIDEO;
+
+ default:
+ break;
+ }
+
+ return TCORE_CALL_TYPE_VOICE;
+}
+
+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);
+ }
+ return CC_CAUSE_NORMAL_CALL_CLEARING;
+ dbg("Exit");
+}
+
+static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data)
+{
+ dbg("Entry");
+
+ // TODO
+
+ return TRUE;
+}
+
+static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data)
+{
+ GSList *tokens = NULL;
+ GSList *lines = NULL;
+ const char *line = NULL;
+ char *stat;
+ int status;
+
+ dbg("Entry");
+
+ lines = (GSList *) data;
+ if (1 != g_slist_length(lines)) {
+ err("Unsolicited message, BUT multiple lines present");
+ goto OUT;
+ }
+
+ line = (char *) (lines->data);
+ tokens = tcore_at_tok_new(line);
+
+ stat = g_slist_nth_data(tokens, 1);
+ if (!stat) {
+ dbg("Stat is missing from %XCALLSTAT indiaction");
+ } else {
+ status = atoi(stat);
+
+ switch (status) {
+ case STATUS_INCOMING:
+ dbg("calling on_notification_call_incoming");
+ on_notification_call_incoming(o, line, user_data);
+ break;
+
+ case STATUS_WAITING:
+ dbg("calling on_notification_call_waiting");
+ on_notification_call_waiting(o, line, user_data);
+ break;
+
+ case STATUS_CONNECTED: /*igonre Connected state. */
+ dbg("Connected state");
+ break;
+
+ default:
+ dbg("calling on_notification_call_status");
+ on_notification_call_status(o, line, user_data);
+ break;
+ }
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+
+OUT:
+ dbg("Exit");
+ return TRUE;
+}
+
+static gboolean _call_request_message(TcorePending *pending,
+ CoreObject *o,
+ UserRequest *ur,
+ void *on_resp,
+ void *user_data)
+{
+ TcoreHal *hal = NULL;
+ TReturn ret;
+
+ dbg("Entry");
+
+ tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
+
+ if (on_resp) {
+ tcore_pending_set_response_callback(pending, on_resp, user_data);
+ }
+ tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
+
+ if (ur) {
+ tcore_pending_link_user_request(pending, ur);
+ } else {
+ err("User Request is NULL, is this internal request??");
+ }
+
+ // 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");
+ return FALSE;
+ }
+
+ dbg("Exit");
+ return TRUE;
+}
+
+static void _call_status_idle(TcorePlugin *p, CallObject *co)
+{
+ CoreObject *core_obj = NULL;
+ char *cmd_str = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req = NULL;
+ gboolean ret = FALSE;
+ UserRequest *ur;
+
+ dbg("Entry");
+ core_obj = tcore_plugin_ref_core_object(p, "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) {
+ // get call end cause.
+ cmd_str = g_strdup_printf("%s", "AT+XCEER");
+ dbg("Request command string: %s", cmd_str);
+
+ // Create new Pending request
+ pending = tcore_pending_new(core_obj, 0);
+
+ // Create new AT-Command request
+ req = tcore_at_request_new(cmd_str, "+XCEER", 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);
+
+ ur = tcore_user_request_new(NULL, NULL);
+ // Send request
+ ret = _call_request_message(pending, core_obj, ur, _on_confirmation_call_end_cause, co);
+
+ if (!ret) {
+ err("Failed to send AT-Command request");
+ // free only UserRequest.
+ if (ur) {
+ tcore_user_request_free(ur);
+ ur = NULL;
+ }
+ return;
+ }
+ } else {
+ err("Call object was not free");
+ tcore_call_object_free(core_obj, co);
+ }
+ dbg("Exit");
+ return;
+}
+
+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) {
+ data.type = tcore_call_object_get_type(co);
+ dbg("data.type : [%d]", data.type);
+
+ data.id = tcore_call_object_get_id(co);
+ dbg("data.id : [%d]", data.id);
+
+ // Set Status
+ tcore_call_object_set_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"),
+ TNOTI_CALL_STATUS_DIALING,
+ sizeof(struct tnoti_call_status_dialing),
+ (void *) &data);
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void _call_status_alert(TcorePlugin *p, CallObject *co)
+{
+ struct tnoti_call_status_alert data;
+
+ dbg("Entry");
+
+ // Alerting has just 1 data 'CALL ID'
+ if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ALERT) {
+ data.type = tcore_call_object_get_type(co);
+ dbg("data.type : [%d]", data.type);
+
+ data.id = tcore_call_object_get_id(co);
+ dbg("data.id : [%d]", data.id);
+
+ // Set Status
+ tcore_call_object_set_status(co, TCORE_CALL_STATUS_ALERT);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(p),
+ tcore_plugin_ref_core_object(p, "call"),
+ TNOTI_CALL_STATUS_ALERT,
+ sizeof(struct tnoti_call_status_alert),
+ (void *) &data);
+ }
+
+ dbg("Exit");
+ return;
+}
+
+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) {
+ data.type = tcore_call_object_get_type(co);
+ dbg("data.type : [%d]", data.type);
+
+ data.id = tcore_call_object_get_id(co);
+ dbg("data.id : [%d]", data.id);
+
+ // Set Status
+ tcore_call_object_set_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"),
+ TNOTI_CALL_STATUS_ACTIVE,
+ sizeof(struct tnoti_call_status_active),
+ (void *) &data);
+ }
+
+ dbg("Exit");
+ return;
+}
+
+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) {
+ data.type = tcore_call_object_get_type(co);
+ dbg("data.type : [%d]", data.type);
+
+ data.id = tcore_call_object_get_id(co);
+ dbg("data.id : [%d]", data.id);
+
+ // Set Status
+ tcore_call_object_set_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"),
+ TNOTI_CALL_STATUS_HELD,
+ sizeof(struct tnoti_call_status_held),
+ (void *) &data);
+ }
+
+ dbg("Exit");
+ return;
+}
+
+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) {
+ tcore_call_object_set_status(co, TCORE_CALL_STATUS_INCOMING);
+
+ data.type = tcore_call_object_get_type(co);
+ dbg("data.type : [%d]", data.type);
+
+ data.id = tcore_call_object_get_id(co);
+ dbg("data.id : [%d]", data.id);
+
+ data.cli.mode = tcore_call_object_get_cli_mode(co);
+ dbg("data.cli.mode : [%d]", data.cli.mode);
+
+ tcore_call_object_get_number(co, data.cli.number);
+ dbg("data.cli.number : [%s]", data.cli.number);
+
+ data.cna.mode = tcore_call_object_get_cna_mode(co);
+ dbg("data.cna.mode : [%d]", data.cna.mode);
+
+ tcore_call_object_get_name(co, data.cna.name);
+ dbg("data.cna.name : [%s]", data.cna.name);
+
+ data.forward = FALSE; // this is tmp code
+
+ data.active_line = tcore_call_object_get_active_line(co);
+ dbg("data.active_line : [%d]", data.active_line);
+
+ // Send notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(p),
+ tcore_plugin_ref_core_object(p, "call"),
+ TNOTI_CALL_STATUS_INCOMING,
+ sizeof(struct tnoti_call_status_incoming),
+ (void *) &data);
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void _call_status_waiting(TcorePlugin *p, CallObject *co)
+{
+ dbg("Entry");
+ _call_status_incoming(p, co);
+
+ dbg("Exit");
+ return;
+}
+
+static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status)
+{
+ dbg("Entry");
+
+ dbg("Call Status is %d", status);
+ switch (status) {
+ case TCORE_CALL_STATUS_IDLE:
+ _call_status_idle(p, co);
+ break;
+
+ case TCORE_CALL_STATUS_ACTIVE:
+ _call_status_active(p, co);
+ break;
+
+ case TCORE_CALL_STATUS_HELD:
+ _call_status_held(p, co);
+ break;
+
+ case TCORE_CALL_STATUS_DIALING:
+ _call_status_dialing(p, co);
+ break;
+
+ case TCORE_CALL_STATUS_ALERT:
+ _call_status_alert(p, co);
+ break;
+
+ case TCORE_CALL_STATUS_INCOMING:
+ _call_status_incoming(p, co);
+ break;
+
+ case TCORE_CALL_STATUS_WAITING:
+ _call_status_waiting(p, co);
+ break;
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static TReturn _call_list_get(CoreObject *o, gboolean *event_flag)
+{
+ UserRequest *ur = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ TcoreATRequest *req = NULL;
+ gboolean ret = FALSE;
+
+ dbg("Entry");
+ if (!o) {
+ err("Core Object is NULL");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ // Create new User Request
+ ur = tcore_user_request_new(NULL, NULL);
+
+ // Command string
+ cmd_str = g_strdup("AT+CLCC");
+
+ // Create new Pending Request
+ pending = tcore_pending_new(o, 0);
+ req = tcore_at_request_new(cmd_str, "+CLCC", TCORE_AT_MULTILINE);
+
+ g_free(cmd_str);
+
+ 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_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;
+ }
+
+ dbg("AT request sent success");
+ return TCORE_RETURN_SUCCESS;
+}
+
+// CONFIRMATION
+static void on_confirmation_call_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 void on_confirmation_call_outgoing(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = data;
+ struct tresp_call_dial resp;
+ 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 = CALL_ERROR_NONE;
+ } else {
+ dbg("RESPONSE NOT OK");
+
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("Unspecified error cause OR string corrupted");
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ // Send Response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_DIAL, sizeof(struct tresp_call_dial), &resp);
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit")
+ return;
+}
+
+static void on_confirmation_call_accept(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = data;
+ struct tresp_call_answer resp;
+ 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 = CALL_ERROR_NONE;
+ } else {
+ dbg("RESPONSE NOT OK");
+
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("Unspecified error cause OR string corrupted");
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+
+ // Send Response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+
+static void on_confirmation_call_reject(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = data;
+ struct tresp_call_answer resp;
+ 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 = CALL_ERROR_NONE;
+ } else {
+ dbg("RESPONSE NOT OK");
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("Unspecified error cause OR string corrupted");
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+ // TODO: CMEE error mapping is required.
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+
+ // Send Response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void on_confirmation_call_replace(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = data;
+ struct tresp_call_answer resp;
+ 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 = CALL_ERROR_NONE;
+ } else {
+ dbg("RESPONSE NOT OK");
+ line = (const char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 1) {
+ err("Unspecified error cause OR string corrupted");
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+ // TODO: CMEE error mapping is required.
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+
+ // Send Response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
+ } else {
+ dbg("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ CoreObject *o = NULL;
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = data;
+ struct tresp_call_answer resp;
+ enum telephony_call_error error;
+
+ dbg("Entry");
+
+ o = tcore_pending_ref_core_object(p);
+ ur = tcore_pending_ref_user_request(p);
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+
+ if (ur) {
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ 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("Unspecified error cause OR string corrupted");
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ // Send response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
+ if (!resp.err) {
+ GSList *list = 0;
+ CallObject *co = NULL;
+
+ // Active Call
+ list = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_ACTIVE);
+ if (!list) {
+ err("Can't find active Call");
+ return;
+ }
+
+ co = (CallObject *) list->data;
+ if (!co) {
+ err("Can't get active Call object");
+ return;
+ }
+
+ // Set Call Status
+ tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
+ dbg("Call status is set to HELD");
+ }
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type)
+{
+ UserRequest *ur = NULL;
+ struct tresp_call_end resp;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ enum telephony_call_error error;
+ const TcoreATResponse *response = data;
+
+ dbg("Entry");
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ 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("Unspecified error cause OR string corrupted");
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+ }
+ tcore_at_tok_free(tokens);
+ }
+
+ resp.type = type;
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("resp.type = %d resp.id= %d", resp.type, resp.id);
+
+ // Send reponse to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+// RESPONSE
+static void on_confirmation_call_endall(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ // skip response handling - actual result will be handled in on_confirmation_call_release_all
+ const TcoreATResponse *response = data;
+
+ dbg("Entry");
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ } else {
+ err("RESPONSE NOT OK");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+
+static void on_confirmation_call_release_all(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ALL);
+
+ return;
+}
+
+
+static void on_confirmation_call_release_specific(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_DEFAULT);
+
+ return;
+}
+
+static void on_confirmation_call_release_all_active(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ACTIVE_ALL);
+
+ return;
+}
+
+static void on_confirmation_call_release_all_held(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_HOLD_ALL);
+
+ return;
+}
+
+static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = NULL;
+ 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 = 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("Unspecified error cause OR string corrupted");
+ error = CALL_ERROR_SERVICE_UNAVAIL;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ error = CALL_ERROR_SERVICE_UNAVAIL;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("Response Call type -%d", type);
+ switch (type) {
+ case TRESP_CALL_HOLD:
+ {
+ struct tresp_call_hold resp;
+
+ resp.err = error;
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("call hold response");
+ // Send reponse to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
+ }
+ break;
+
+ case TRESP_CALL_ACTIVE:
+ {
+ struct tresp_call_active resp;
+
+ resp.err = error;
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("call active response");
+ // Send reponse to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
+ }
+ break;
+
+ case TRESP_CALL_JOIN:
+ {
+ struct tresp_call_join resp;
+
+ resp.err = error;
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("call join response");
+
+ // Send reponse to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_JOIN, sizeof(struct tresp_call_join), &resp);
+ }
+ break;
+
+ case TRESP_CALL_SPLIT:
+ {
+ struct tresp_call_split resp;
+
+ resp.err = error;
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("call split response");
+ // Send reponse to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_SPLIT, sizeof(struct tresp_call_split), &resp);
+ }
+ break;
+
+ case TRESP_CALL_DEFLECT:
+ {
+ struct tresp_call_deflect resp;
+
+ resp.err = error;
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("call deflect response");
+ // Send reponse to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_DEFLECT, sizeof(struct tresp_call_deflect), &resp);
+ }
+
+ break;
+
+ case TRESP_CALL_TRANSFER:
+ {
+ struct tresp_call_transfer resp;
+
+ resp.err = error;
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("call transfer response");
+ // Send reponse to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_TRANSFER, sizeof(struct tresp_call_transfer), &resp);
+ }
+ break;
+
+ case TRESP_CALL_SEND_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);
+ }
+ break;
+
+ default:
+ {
+ dbg("type not supported");
+ return;
+ }
+ }
+
+ if ((type == TRESP_CALL_HOLD) || (type == TRESP_CALL_ACTIVE) || (type == TRESP_CALL_JOIN)
+ || (type == TRESP_CALL_SPLIT)) {
+ if (!error) {
+ CoreObject *core_obj = NULL;
+ gboolean *eflag = g_new0(gboolean, 1);
+
+ core_obj = tcore_pending_ref_core_object(p);
+ *eflag = FALSE;
+
+ dbg("Calling _call_list_get");
+ _call_list_get(core_obj, eflag);
+ }
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_HOLD);
+
+ return;
+}
+
+static void on_confirmation_call_active(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_ACTIVE);
+
+ return;
+}
+
+static void on_confirmation_call_join(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_JOIN);
+
+ return;
+}
+
+static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SPLIT);
+
+ return;
+}
+
+static void on_confirmation_call_deflect(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_DEFLECT);
+
+ return;
+}
+
+static void on_confirmation_call_transfer(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ dbg("Entry");
+ _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_TRANSFER);
+
+ return;
+}
+
+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);
+
+ return;
+}
+
+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;
+ enum telephony_call_error error;
+
+ dbg("Entry");
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ 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 = CALL_ERROR_SERVICE_UNAVAIL;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+ // TODO: CMEE error mapping is required.
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("Set dtmf tone duration response - %d", error);
+ return;
+}
+
+static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ CoreObject *core_obj = NULL;
+ UserRequest *ur = NULL;
+ const TcoreATResponse *response = data;
+ struct tresp_call_swap resp;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+
+ dbg("Entry");
+ core_obj = tcore_pending_ref_core_object(p);
+ ur = tcore_pending_ref_user_request(p);
+
+ if (ur) {
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ 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 = CALL_ERROR_SERVICE_UNAVAIL;
+ } else {
+ resp.err = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ resp.id = tcore_call_object_get_id((CallObject *) user_data);
+ dbg("resp.id = %d", resp.id);
+
+ // Send response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_SWAP, sizeof(struct tresp_call_swap), &resp);
+
+ if (!resp.err) {
+ GSList *active = NULL;
+ GSList *held = NULL;
+ CallObject *co = NULL;
+ gboolean *eflag = NULL;
+
+ held = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_HELD);
+ if (!held) {
+ err("Can't find held Call");
+ return;
+ }
+
+ active = tcore_call_object_find_by_status(core_obj, TCORE_CALL_STATUS_ACTIVE);
+ if (!active) {
+ dbg("Can't find active Call");
+ return;
+ }
+
+ while (held) {
+ co = (CallObject *) held->data;
+ if (!co) {
+ err("Can't get held Call object");
+ return;
+ }
+
+ resp.id = tcore_call_object_get_id(co);
+
+ // Send response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
+
+ held = g_slist_next(held);
+ }
+
+ while (active) {
+ co = (CallObject *) active->data;
+ if (!co) {
+ err("[ error ] can't get active call object");
+ return;
+ }
+
+ resp.id = tcore_call_object_get_id(co);
+
+ // Send response to TAPI
+ tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
+ active = g_slist_next(active);
+ }
+
+ eflag = g_new0(gboolean, 1);
+ *eflag = FALSE;
+
+ dbg("calling _call_list_get");
+ _call_list_get(core_obj, eflag);
+ }
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void on_confirmation_call_set_source_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = data;
+ char *resp_str = NULL;
+ struct tresp_call_sound_set_path resp;
+ gboolean error;
+
+ dbg("Entry");
+ ur = tcore_pending_ref_user_request(p);
+
+ // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
+ 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 = TRUE;
+ goto OUT;
+ }
+
+ if (!g_slist_nth_data(tokens, 1)) {
+ err(" function_id is missing");
+ resp.err = TRUE;
+ 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 = FALSE;
+ } else {
+ resp.err = TRUE;
+ }
+ }
+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 = TRUE;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = TRUE;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ if (ur) {
+ 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);
+ setsoundpath = TRUE;
+ }
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void on_confirmation_call_set_destination_sound_path(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_sound_set_path resp;
+ const TcoreATResponse *response = data;
+ gboolean error;
+
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+ // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
+
+ if (!response) {
+ err("Input data is NULL");
+ return;
+ }
+
+ if (ur) {
+ 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)) {
+ dbg("group_id is missing");
+ resp.err = TRUE;
+ goto OUT;
+ }
+
+ if (!g_slist_nth_data(tokens, 1)) {
+ dbg("function_id is missing");
+ resp.err = TRUE;
+ 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 = FALSE;
+ } else {
+ resp.err = TRUE;
+ }
+ }
+
+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 = TRUE;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+ // TODO: CMEE error mapping is required.
+ resp.err = TRUE;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ if (setsoundpath == TRUE) {
+ 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);
+ }
+ } else {
+ dbg("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void on_confirmation_call_set_source_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ const TcoreATResponse *response = data;
+ char *resp_str = NULL;
+ struct tresp_call_sound_set_volume_level resp;
+ gboolean error;
+
+ ur = tcore_pending_ref_user_request(p);
+ dbg("Entry");
+ // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
+ 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 = TRUE;
+ goto OUT;
+ }
+
+ if (!g_slist_nth_data(tokens, 1)) {
+ err("function_id is missing");
+ resp.err = TRUE;
+ 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 = FALSE;
+ } else {
+ resp.err = TRUE;
+ }
+ }
+
+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 = TRUE;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = TRUE;
+ }
+
+ // Free tokens
+ tcore_at_tok_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);
+ soundvolume = TRUE;
+ }
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+
+static void on_confirmation_call_set_destination_sound_volume_level(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;
+ const TcoreATResponse *response = data;
+ struct tresp_call_sound_set_volume_level resp;
+ gboolean error;
+
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+
+ // +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]\ 3
+ if (!response) {
+ err("Input data is NULL");
+ return;
+ }
+
+ if (ur) {
+ 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 = TRUE;
+ goto OUT;
+ }
+
+ if (!g_slist_nth_data(tokens, 1)) {
+ err("function_id is missing");
+ resp.err = TRUE;
+ 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 = FALSE;
+ } else {
+ resp.err = TRUE;
+ }
+ }
+
+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 = TRUE;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = TRUE;
+ }
+
+ tcore_at_tok_free(tokens);
+ }
+
+ if (soundvolume == TRUE) {
+ 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);
+ }
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+
+static void on_confirmation_call_mute(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;
+ const TcoreATResponse *response = data;
+ gboolean 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 = TRUE;
+ goto OUT;
+ }
+
+ if (!g_slist_nth_data(tokens, 1)) {
+ err(" function_id is missing");
+ resp.err = TRUE;
+ 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 = FALSE;
+ } else {
+ resp.err = TRUE;
+ }
+ }
+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 = TRUE;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = TRUE;
+ }
+
+ // 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;
+ gboolean error;
+
+ dbg("Entry");
+
+ response = (TcoreATResponse *) data;
+ 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 = TRUE;
+ goto OUT;
+ }
+
+ if (!g_slist_nth_data(tokens, 1)) {
+ err(" function_id is missing");
+ resp.err = TRUE;
+ 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 = FALSE;
+ } else {
+ resp.err = TRUE;
+ }
+ }
+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 = TRUE;
+ } else {
+ error = atoi(g_slist_nth_data(tokens, 0));
+
+ // TODO: CMEE error mapping is required.
+ resp.err = TRUE;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_CALL_UNMUTE, sizeof(struct tresp_call_unmute), &resp);
+ } else {
+ err("User Request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+// RESPONSE
+static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ TcorePlugin *plugin = NULL;
+ CoreObject *core_obj = NULL;
+ CallObject *co = NULL;
+ struct clcc_call_t *call_list = NULL;
+ gboolean *event_flag = (gboolean *) user_data;
+ const TcoreATResponse *response = data;
+ GSList *resp_data = NULL;
+ char *line = NULL;
+
+ int cllc_info = 0, countCalls = 0, countValidCalls = 0;
+ int error = 0;
+
+ dbg("Entry");
+
+ plugin = tcore_pending_ref_plugin(p);
+ core_obj = tcore_pending_ref_core_object(p);
+
+ if (response->success > 0) {
+ dbg("RESPONCE OK");
+ if (response->lines) {
+ resp_data = (GSList *) response->lines;
+ countCalls = g_slist_length(resp_data);
+ dbg("Total records : %d", countCalls);
+ }
+
+ if (0 == countCalls) {
+ err("Call count is zero");
+ if (event_flag) {
+ g_free(event_flag);
+ event_flag = NULL;
+ }
+ return;
+ }
+
+ call_list = g_new0(struct clcc_call_t, countCalls);
+
+ for (countValidCalls = 0; resp_data != NULL; resp_data = resp_data->next, countValidCalls++, cllc_info++) {
+ line = (char *) (resp_data->data);
+
+ error = _callFromCLCCLine(line, call_list + countValidCalls);
+ if (0 != error) {
+ continue;
+ }
+
+ co = tcore_call_object_find_by_id(core_obj, call_list[cllc_info].info.id);
+ if (!co) {
+ co = tcore_call_object_new(core_obj, call_list[cllc_info].info.id);
+ if (!co) {
+ err("error : tcore_call_object_new [ id : %d ]", call_list[cllc_info].info.id);
+ continue;
+ }
+ }
+
+ // Call set parameters
+ 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_active_line(co, 0);
+
+ if (*event_flag) {
+ dbg("Call status before calling _call_branch_by_status() : (%d)", call_list[cllc_info].info.status);
+ _call_branch_by_status(plugin, co, call_list[cllc_info].info.status);
+ } else {
+ // Set Status
+ tcore_call_object_set_status(co, call_list[cllc_info].info.status);
+
+ dbg("Call id : (%d)", call_list[cllc_info].info.id);
+ dbg("Call direction : (%d)", call_list[cllc_info].info.direction);
+ dbg("Call type : (%d)", call_list[cllc_info].info.type);
+ dbg("Call mpty : (%d)", call_list[cllc_info].info.mpty);
+ dbg("Call number : (%s)", call_list[cllc_info].number);
+ dbg("Call status : (%d)", call_list[cllc_info].info.status);
+ }
+ }
+
+ // Free Call list
+ g_free(call_list);
+ }
+
+ // Free User data
+ if (event_flag) {
+ g_free(event_flag);
+ event_flag = NULL;
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ TcorePlugin *plugin = NULL;
+ CoreObject *core_obj = NULL;
+ CallObject *co = (CallObject *) user_data;
+ const TcoreATResponse *response = data;
+ const char *line = NULL;
+ struct tnoti_call_status_idle call_status;
+ GSList *tokens = NULL;
+ char *resp_str;
+ int error;
+
+ dbg("Entry");
+ plugin = tcore_pending_ref_plugin(p);
+ core_obj = tcore_pending_ref_core_object(p);
+
+ 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 (!resp_str) {
+ err("call end cause - report value missing");
+ } else {
+ resp_str = g_slist_nth_data(tokens, 1);
+ if (!resp_str) {
+ err("call end cause value missing");
+ }
+ error = atoi(resp_str);
+ dbg("call end cause - %d", error);
+ call_status.cause = _compare_call_end_cause(error);
+ dbg("TAPI call end cause - %d", call_status.cause);
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ } else {
+ err("RESPONSE NOT OK");
+ line = (char *) response->final_response;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ err("err cause not specified or string corrupted");
+ } else {
+ err(" err cause value: %d", atoi(g_slist_nth_data(tokens, 0)));
+ }
+ call_status.cause = CC_CAUSE_NORMAL_CALL_CLEARING;
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ }
+
+ call_status.type = tcore_call_object_get_type(co);
+ dbg("data.type : [%d]", call_status.type);
+
+ call_status.id = tcore_call_object_get_id(co);
+ dbg("data.id : [%d]", call_status.id);
+
+ // Set Status
+ tcore_call_object_set_status(co, TCORE_CALL_STATUS_IDLE);
+
+ // Send Notification to TAPI
+ tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+ core_obj,
+ TNOTI_CALL_STATUS_IDLE,
+ sizeof(struct tnoti_call_status_idle),
+ (void *) &call_status);
+
+ // Free Call object
+ tcore_call_object_free(core_obj, co);
+}
+
+static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call)
+{
+ // +CLCC: 1,0,2,0,0,"18005551212",145
+ // [+CLCC: <id1>, <dir>, <stat>, <mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]
+ int state;
+ int mode;
+ int isMT;
+ char *num = NULL;
+ unsigned int num_type;
+ GSList *tokens = NULL;
+ char *resp = NULL;
+
+ dbg("Entry");
+
+ tokens = tcore_at_tok_new(line);
+ // parse <id>
+ resp = g_slist_nth_data(tokens, 0);
+ if (!resp) {
+ err("InValid ID");
+ goto ERROR;
+ }
+ p_call->info.id = atoi(resp);
+ dbg("id : [%d]\n", p_call->info.id);
+
+ // parse <dir>
+ resp = g_slist_nth_data(tokens, 1);
+ if (!resp) {
+ err("InValid Dir");
+ goto ERROR;
+ }
+ isMT = atoi(resp);
+ if (0 == isMT) {
+ p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;
+ } else {
+ p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;
+ }
+ dbg("Direction : [ %d ]\n", p_call->info.direction);
+
+ // parse <stat>
+ resp = g_slist_nth_data(tokens, 2);
+ if (!resp) {
+ err("InValid Stat");
+ goto ERROR;
+ }
+ state = atoi(resp);
+ dbg("Call state : %d", state);
+ switch (state) {
+ case 0: // active
+ p_call->info.status = TCORE_CALL_STATUS_ACTIVE;
+ break;
+
+ case 1:
+ p_call->info.status = TCORE_CALL_STATUS_HELD;
+ break;
+
+ case 2:
+ p_call->info.status = TCORE_CALL_STATUS_DIALING;
+ break;
+
+ case 3:
+ p_call->info.status = TCORE_CALL_STATUS_ALERT;
+ break;
+
+ case 4:
+ p_call->info.status = TCORE_CALL_STATUS_INCOMING;
+ break;
+
+ case 5:
+ p_call->info.status = TCORE_CALL_STATUS_WAITING;
+ break;
+ }
+ dbg("Status : [%d]\n", p_call->info.status);
+
+ // parse <mode>
+ resp = g_slist_nth_data(tokens, 3);
+ if (!resp) {
+ err("InValid Mode");
+ goto ERROR;
+ }
+ mode = atoi(resp);
+ switch (mode) {
+ case 0:
+ p_call->info.type = TCORE_CALL_TYPE_VOICE;
+ break;
+
+ case 1:
+ p_call->info.type = TCORE_CALL_TYPE_VIDEO;
+ break;
+
+ default: // only Voice/VT call is supported in CS. treat other unknown calls as error
+ dbg("invalid type : [%d]\n", mode);
+ goto ERROR;
+ }
+ dbg("Call type : [%d]\n", p_call->info.type);
+
+ // parse <mpty>
+ resp = g_slist_nth_data(tokens, 4);
+ if (!resp) {
+ err("InValid Mpty");
+ goto ERROR;
+ }
+
+ p_call->info.mpty = atoi(resp);
+ dbg("Mpty : [ %d ]\n", p_call->info.mpty);
+
+ // parse <num>
+ resp = g_slist_nth_data(tokens, 5);
+ dbg("Incoming number - %s and its len - %d", resp, strlen(resp));
+
+ // tolerate null here
+ if (!resp) {
+ err("Number is NULL");
+ goto ERROR;
+ }
+ // 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);
+
+ // parse <num type>
+ resp = g_slist_nth_data(tokens, 6);
+ if (!resp) {
+ dbg("InValid Num type");
+ goto ERROR;
+ }
+ p_call->info.num_type = atoi(resp);
+ dbg("BCD num type: [0x%x]\n", p_call->info.num_type);
+
+ // check number is international or national.
+ num_type = ((p_call->info.num_type) >> 4) & 0x07;
+ dbg("called party's type of number : [0x%x]\n", num_type);
+
+ if (num_type == 1 && num[0] != '+') {
+ // international number
+ p_call->number[0] = '+';
+ memcpy(&(p_call->number[1]), num, strlen(num));
+ } else {
+ memcpy(&(p_call->number), num, strlen(num));
+ }
+ dbg("incoming number - %s", p_call->number);
+
+ g_free(num);
+ num = NULL;
+ // Free tokens
+ tcore_at_tok_free(tokens);
+
+ dbg("Exit");
+ return 0;
+
+ERROR:
+ err("Invalid CLCC line");
+
+ if (num) {
+ g_free(num);
+ num = NULL;
+ }
+
+ // Free tokens
+ tcore_at_tok_free(tokens);
+ err("Exit");
+ return -1;
+}
+
+// NOTIFICATION
+static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data)
+{
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ char *pId;
+ int call_id;
+ gboolean *eflag;
+ GSList *pList = NULL;
+ CallObject *co = NULL, *dupco = NULL;
+
+ dbg("function entrance");
+ // check call with waiting status already exist
+ pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
+
+ if (pList != NULL) {
+ dbg("[error]Waiting call already exist. skip");
+ return;
+ }
+ // check call with incoming status already exist
+ pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
+
+ if (pList != NULL) {
+ dbg("[error]incoming call already exist. skip");
+ return;
+ }
+ line = (char *) data;
+ tokens = tcore_at_tok_new(line);
+
+ pId = g_slist_nth_data(tokens, 0);
+ if (!pId) {
+ dbg("[error]:Call id is missing from +XCALLSTAT indication");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+
+ call_id = atoi(pId);
+ 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;
+ }
+
+ tcore_at_tok_free(tokens);
+
+ eflag = g_new0(gboolean, 1);
+ *eflag = TRUE;
+ dbg("calling _call_list_get");
+ _call_list_get(o, eflag);
+}
+
+static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data)
+{
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ char *pId;
+ int call_id;
+ gboolean *eflag;
+ GSList *pList = NULL;
+ CallObject *co = NULL, *dupco = NULL;
+
+ dbg("function entrance");
+ // check call with incoming status already exist
+ pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
+
+ if (pList != NULL) {
+ dbg("incoming call already exist. skip");
+ return;
+ }
+
+ line = (char *) data;
+ tokens = tcore_at_tok_new(line);
+
+ pId = g_slist_nth_data(tokens, 0);
+ if (!pId) {
+ dbg("Error:Call id is missing from %XCALLSTAT indication");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+
+ call_id = atoi(pId);
+
+ 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")
+ tcore_at_tok_free(tokens);
+
+ eflag = g_new0(gboolean, 1);
+ *eflag = TRUE;
+
+ dbg("calling _call_list_get");
+ _call_list_get(o, eflag);
+}
+
+static void on_notification_call_status(CoreObject *o, const void *data, void *user_data)
+{
+ char *cmd = NULL;
+ TcorePlugin *plugin = NULL;
+ CallObject *co = NULL;
+ int id = -1;
+ int status = 0;
+ int type = 0;
+ char *stat = NULL;
+ char *pCallId = NULL;
+ GSList *tokens = NULL;
+ gboolean *eflag = NULL;
+ enum tcore_call_status co_status;
+
+ dbg("function entrance");
+ plugin = tcore_object_ref_plugin(o);
+ cmd = (char *) data;
+ tokens = tcore_at_tok_new(cmd);
+
+ // parse <Call Id>
+ pCallId = g_slist_nth_data(tokens, 0);
+ if (!pCallId) {
+ dbg("CallId is missing from %XCALLSTAT indication");
+ tcore_at_tok_free(tokens);
+ return;
+ } else {
+ id = atoi(pCallId);
+ dbg("call id = %d", id);
+ // parse <Stat>
+ if ((stat = g_slist_nth_data(tokens, 1))) {
+ status = atoi(stat);
+ }
+ dbg("call status = %d", status);
+ }
+
+ tcore_at_tok_free(tokens);
+ co_status = _call_status(status);
+
+ dbg("co_status = %d", co_status);
+ switch (co_status) {
+ case CALL_STATUS_ACTIVE:
+ {
+ dbg("call(%d) status : [ ACTIVE ]", id);
+ co = tcore_call_object_find_by_id(o, id);
+ if (!co) {
+ dbg("co is NULL");
+ return;
+ }
+ _call_status_active(plugin, co);
+ }
+ break;
+
+ case CALL_STATUS_HELD:
+ dbg("call(%d) status : [ held ]", id);
+ break;
+
+ case CALL_STATUS_DIALING:
+ {
+ dbg("call(%d) status : [ dialing ]", id);
+ co = tcore_call_object_find_by_id(o, id);
+ if (!co) {
+ co = tcore_call_object_new(o, id);
+ if (!co) {
+ dbg("error : tcore_call_object_new [ id : %d ]", id);
+ return;
+ }
+ }
+
+ tcore_call_object_set_type(co, call_type(type));
+ tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_OUTGOING);
+ _call_status_dialing(plugin, co);
+ }
+ break;
+
+ case CALL_STATUS_ALERT:
+ {
+ dbg("call(%d) status : [ alert ]", id);
+ co = tcore_call_object_find_by_id(o, id);
+ if (!co) {
+ dbg("co is NULL");
+ return;
+ }
+ // Store dialed number information into Call object.
+ eflag = g_new0(gboolean, 1);
+ *eflag = TRUE;
+ dbg("calling _call_list_get");
+ _call_list_get(o, eflag);
+ }
+ break;
+
+ case CALL_STATUS_INCOMING:
+ case CALL_STATUS_WAITING:
+ dbg("call(%d) status : [ incoming ]", id);
+ break;
+
+ case CALL_STATUS_IDLE:
+ {
+ dbg("call(%d) status : [ release ]", id);
+
+ co = tcore_call_object_find_by_id(o, id);
+ if (!co) {
+ dbg("co is NULL");
+ return;
+ }
+
+ plugin = tcore_object_ref_plugin(o);
+ if (!plugin) {
+ dbg("plugin is NULL");
+ return;
+ }
+ _call_status_idle(plugin, co);
+ }
+ break;
+
+ default:
+ dbg("invalid call status", id);
+ break;
+ }
+}
+
+static TReturn s_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;
+ TcoreATRequest *req;
+ 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_dial *) tcore_user_request_ref_data(ur, 0);
+ if (data->type == CALL_TYPE_VIDEO) {
+ dbg("invalid call type")
+ return TCORE_RETURN_FAILURE;
+ }
+
+ clir = _get_clir_status(data->number);
+
+ // Compose ATD Cmd string
+ switch (clir) {
+ case TCORE_CALL_CLI_MODE_PRESENT:
+ dbg("CALL_CLI_MODE_PRESENT");
+ cclir = "I";
+ break; // invocation
+
+ case TCORE_CALL_CLI_MODE_RESTRICT:
+ dbg("CALL_CLI_MODE_RESTRICT");
+ cclir = "i";
+ break; // suppression
+
+ case TCORE_CALL_CLI_MODE_DEFAULT:
+ default:
+ cclir = "";
+ dbg("CALL_CLI_MODE_DEFAULT");
+ break; // subscription default
+ }
+
+ dbg("data->number = %s", data->number);
+
+ raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);
+ cmd_str = g_strdup_printf("%s", raw_str);
+
+ dbg("request command : %s", cmd_str);
+
+ pending = tcore_pending_new(o, 0);
+ 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);
+ ret = _call_request_message(pending, o, ur, on_confirmation_call_outgoing, NULL);
+
+ g_free(raw_str);
+ g_free(cmd_str);
+
+ if (!ret) {
+ dbg("AT request(%s) sent failed", req->cmd);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("AT request(%s) sent success", req->cmd);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_answer(CoreObject *o, UserRequest *ur)
+{
+ char *cmd_str = NULL;
+ CallObject *co = NULL;
+ struct treq_call_answer *data = 0;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req;
+ 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_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) {
+ dbg(" request 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);
+ 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_accept, co);
+ g_free(cmd_str);
+
+ if (!ret) {
+ dbg("AT request(%s) sent failed", req->cmd);
+ return TCORE_RETURN_FAILURE;
+ }
+ } else {
+ switch (data->type) {
+ case CALL_ANSWER_TYPE_REJECT:
+ {
+ dbg("call answer reject");
+ tcore_call_control_answer_reject(o, ur, on_confirmation_call_reject, co);
+ }
+ break;
+
+ case CALL_ANSWER_TYPE_REPLACE:
+ {
+ dbg("call answer replace");
+ tcore_call_control_answer_replace(o, ur, on_confirmation_call_replace, co);
+ }
+ break;
+
+ case CALL_ANSWER_TYPE_HOLD_ACCEPT:
+ {
+ dbg("call answer hold and accept");
+ tcore_call_control_answer_hold_and_accept(o, ur, on_confirmation_call_hold_and_accept, co);
+ }
+ break;
+
+ default:
+ dbg("[ error ] wrong answer type [ %d ]", data->type);
+ return TCORE_RETURN_FAILURE;
+ }
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_release(CoreObject *o, UserRequest *ur)
+{
+ CallObject *co = NULL;
+ struct treq_call_end *data = 0;
+ UserRequest *ur_dup = NULL;
+ char *chld0_cmd = NULL;
+ char *chld1_cmd = NULL;
+ TcorePending *pending = NULL, *pending1 = NULL;
+ TcoreATRequest *req, *req1;
+ 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);
+
+ dbg("type of release call = %d", data->type);
+
+ if (data->type == CALL_END_TYPE_ALL) {
+ // releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence
+ chld0_cmd = g_strdup("AT+CHLD=0");
+ chld1_cmd = g_strdup("AT+CHLD=1");
+
+ pending = tcore_pending_new(o, 0);
+ req = tcore_at_request_new(chld0_cmd, NULL, TCORE_AT_NO_RESULT);
+
+ 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));
+
+ tcore_pending_set_request_data(pending, 0, req);
+ ur_dup = tcore_user_request_new(NULL, NULL);
+ ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_endall, NULL);
+ g_free(chld0_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);
+
+ 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));
+
+ tcore_pending_set_request_data(pending1, 0, req1);
+ ret = _call_request_message(pending1, o, ur, on_confirmation_call_release_all, co);
+ g_free(chld1_cmd);
+
+ if (!ret) {
+ dbg("AT request %s has failed ", req->cmd);
+ return TCORE_RETURN_FAILURE;
+ }
+ } else {
+ switch (data->type) {
+ case CALL_END_TYPE_DEFAULT:
+ {
+ int id = 0;
+ id = tcore_call_object_get_id(co);
+
+ dbg("call end call id [%d]", id);
+ tcore_call_control_end_specific(o, ur, id, on_confirmation_call_release_specific, co);
+ }
+ break;
+
+ case CALL_END_TYPE_ACTIVE_ALL:
+ {
+ dbg("call end all active");
+ tcore_call_control_end_all_active(o, ur, on_confirmation_call_release_all_active, co);
+ }
+ break;
+
+ case CALL_END_TYPE_HOLD_ALL:
+ {
+ dbg("call end all held");
+ tcore_call_control_end_all_held(o, ur, on_confirmation_call_release_all_held, co);
+ }
+ break;
+
+ default:
+ dbg("[ error ] wrong end type [ %d ]", data->type);
+ return TCORE_RETURN_FAILURE;
+ }
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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);
+
+ co = tcore_call_object_find_by_id(o, hold->id);
+ tcore_call_control_hold(o, ur, on_confirmation_call_hold, co);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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);
+
+ co = tcore_call_object_find_by_id(o, active->id);
+ tcore_call_control_active(o, ur, on_confirmation_call_active, co);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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);
+
+ co = tcore_call_object_find_by_id(o, swap->id);
+ tcore_call_control_swap(o, ur, on_confirmation_call_swap, co);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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);
+
+ co = tcore_call_object_find_by_id(o, join->id);
+ tcore_call_control_join(o, ur, on_confirmation_call_join, co);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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);
+
+ tcore_call_control_split(o, ur, split->id, on_confirmation_call_split, co);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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);
+
+ tcore_call_control_deflect(o, ur, deflect->number, on_confirmation_call_deflect, co);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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);
+
+ co = tcore_call_object_find_by_id(o, transfer->id);
+ tcore_call_control_transfer(o, ur, on_confirmation_call_transfer, co);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_send_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;
+ char *dtmfstr = NULL, *tmp_dtmf = NULL;
+ unsigned int dtmf_count;
+
+ dbg("Function enter");
+
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ dup = tcore_user_request_new(NULL, NULL);
+ (void) _set_dtmf_tone_duration(o, dup);
+
+ dtmf = (struct treq_call_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;
+ }
+
+ tmp_dtmf = dtmfstr;
+
+ for (dtmf_count = 0; dtmf_count < strlen(dtmf->digits); dtmf_count++) {
+ *tmp_dtmf = dtmf->digits[dtmf_count];
+ tmp_dtmf++;
+
+ *tmp_dtmf = COMMA;
+ tmp_dtmf++;
+ }
+
+ // last digit is having COMMA , overwrite it with '\0' .
+ *(--tmp_dtmf) = '\0';
+ dbg("Input DTMF string(%s)", dtmfstr);
+
+ // AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>
+ cmd_str = g_strdup_printf("AT+VTS=%s", dtmfstr);
+ dbg("request command : %s", cmd_str);
+
+ pending = tcore_pending_new(o, 0);
+ 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);
+ ret = _call_request_message(pending, o, ur, on_confirmation_call_dtmf, NULL);
+ g_free(dtmfstr);
+ g_free(cmd_str);
+
+ if (!ret) {
+ dbg("AT request sent failed")
+ return TCORE_RETURN_FAILURE;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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_sound_set_path *sound_path = 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;
+ }
+ sound_path = (struct treq_call_sound_set_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;
+
+ case CALL_SOUND_PATH_HEADSET_3_5PI:
+ device_type = 3;
+ break;
+
+ case CALL_SOUND_PATH_SPEAKER:
+ device_type = 4;
+ break;
+
+ case CALL_SOUND_PATH_HANDFREE:
+ device_type = 5;
+ break;
+
+ case CALL_SOUND_PATH_HEADSET_HAC:
+ device_type = 6;
+ break;
+
+ 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;
+ }
+
+ 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);
+ 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);
+ 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)
+{
+ UserRequest *src_ur = NULL;
+ UserRequest *dest_ur = NULL;
+ TcorePending *src_pending = NULL;
+ TcorePending *dest_pending = NULL;
+ TcoreATRequest *src_req = NULL;
+ TcoreATRequest *dest_req = NULL;
+ char *cmd_str = NULL, *volume_level = NULL;
+ gboolean ret = FALSE;
+ struct treq_call_sound_set_volume_level *data = NULL;
+
+ 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_sound_set_volume_level *) tcore_user_request_ref_data(ur, 0);
+
+ // Hard-coded values for MIC & Speakers
+ // Source volume
+ dbg("Set Source volume");
+
+ cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,3,88"); // Source type
+ dbg("Request command string: %s", cmd_str);
+
+ // Create new Pending request
+ src_pending = tcore_pending_new(o, 0);
+
+ // Create new AT-Command request
+ src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
+
+ // Free Command string
+ g_free(cmd_str);
+
+ tcore_pending_set_request_data(src_pending, 0, src_req);
+ src_ur = tcore_user_request_ref(ur);
+
+ // Send request
+ ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
+ if (!ret) {
+ err("Failed to send AT-Command request");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ cmd_str = g_strdup_printf("%s", "AT+XDRV=40,7,0,88"); // Destination type
+ dbg("Request command string: %s", cmd_str);
+
+ // Create new Pending request
+ src_pending = tcore_pending_new(o, 0);
+
+ // Create new AT-Command request
+ src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
+
+ // Free Command string
+ g_free(cmd_str);
+
+ tcore_pending_set_request_data(src_pending, 0, src_req);
+
+ src_ur = tcore_user_request_ref(ur);
+
+ // Send request
+ ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
+ if (!ret) {
+ err("Failed to send AT-Command request");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ // Destination volume
+ dbg("Set Source volume");
+
+ cmd_str = g_strdup_printf("%s", "AT+XDRV=40,8,0,88"); // Source type
+ dbg("Request command string: %s", cmd_str);
+
+ // Create new Pending request
+ dest_pending = tcore_pending_new(o, 0);
+
+ // Create new AT-Command request
+ dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
+
+ // Free Command string
+ g_free(cmd_str);
+
+ tcore_pending_set_request_data(dest_pending, 0, dest_req);
+ dest_ur = tcore_user_request_ref(ur);
+
+ // Send request
+ ret = _call_request_message(dest_pending, o, dest_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
+ if (!ret) {
+ err("Failed to send AT-Command request");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("Input volume level - %d", data->volume);
+ switch (data->volume) {
+ case CALL_SOUND_MUTE:
+ volume_level = "0";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_1:
+ volume_level = "40";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_2:
+ volume_level = "46";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_3:
+ volume_level = "52";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_4:
+ volume_level = "58";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_5:
+ volume_level = "64";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_6:
+ volume_level = "70";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_7:
+ volume_level = "76";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_8:
+ volume_level = "82";
+ break;
+
+ case CALL_SOUND_VOLUME_LEVEL_9:
+ default:
+ volume_level = "88";
+ break;
+ }
+ cmd_str = g_strdup_printf("%s%s", "AT+XDRV=40,8,2,", volume_level); // Destination type
+ dbg("Request command string: %s", cmd_str);
+
+ // Create new Pending request
+ dest_pending = tcore_pending_new(o, 0);
+
+ // Create new AT-Command request
+ dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+ dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
+
+ // Free Command string
+ g_free(cmd_str);
+
+ tcore_pending_set_request_data(dest_pending, 0, dest_req);
+
+ // Send request
+ ret = _call_request_message(dest_pending, o, ur, on_confirmation_call_set_destination_sound_volume_level, NULL);
+ if (!ret) {
+ err("Failed to send AT-Command request");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ 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)
+{
+ char *cmd_str = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req = NULL;
+ gboolean ret = FALSE;
+
+ dbg("Entry");
+
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ 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);
+
+ // 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;
+ }
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_call_unmute(CoreObject *o, UserRequest *ur)
+{
+ char *cmd_str = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req = NULL;
+ gboolean ret = FALSE;
+
+ dbg("Entry");
+
+ if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ 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);
+ 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);
+ if (!ret) {
+ err("Failed to send AT-Command request");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+
+static TReturn s_call_get_mute_status(CoreObject *o, UserRequest *ur)
+{
+ dbg("Entry");
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+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.
+ 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, NULL, TCORE_AT_NO_RESULT);
+ 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_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;
+}
+
+// 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,
+ .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)
+{
+ 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_CALL,
+ sizeof(unsigned int),
+ (void *) &id);
+
+ 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)
+{
+ 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;
+}
--- /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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <glib.h>
+
+
+#include "s_common.h"
+
+#include <plugin.h>
+
+#undef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+#undef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+#define bitsize(type) (sizeof(type) * 8)
+
+#define copymask(type) ((0xffffffff) >> (32 - bitsize(type)))
+
+#define MASK(width, offset, data) \
+ (((width) == bitsize(data)) ? (data) : \
+ ((((copymask(data) << (bitsize(data) - ((width) % bitsize(data)))) & copymask(data)) >> (offset)) & (data))) \
+
+
+#define MASK_AND_SHIFT(width, offset, shift, data) \
+ ((((signed) (shift)) < 0) ? \
+ MASK((width), (offset), (data)) << -(shift) : \
+ MASK((width), (offset), (data)) >> (((signed) (shift)))) \
+
+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);
+
+void util_hex_dump(char *pad, int size, const void *data)
+{
+ char buf[255] = {0, };
+ char hex[4] = {0, };
+ int i;
+ unsigned char *p;
+
+ if (size <= 0) {
+ msg("%sno data", pad);
+ return;
+ }
+
+ p = (unsigned char *) data;
+
+ snprintf(buf, 255, "%s%04X: ", pad, 0);
+ for (i = 0; i < size; i++) {
+ snprintf(hex, 4, "%02X ", p[i]);
+ strcat(buf, hex);
+
+ if ((i + 1) % 8 == 0) {
+ if ((i + 1) % 16 == 0) {
+ msg("%s", buf);
+ memset(buf, 0, 255);
+ snprintf(buf, 255, "%s%04X: ", pad, i + 1);
+ } else {
+ strcat(buf, " ");
+ }
+ }
+ }
+
+ 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)
+{
+ 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");
+ 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)
+{
+ int i = 0;
+ UserRequest *ur;
+ struct work_queue_data *wqd;
+
+ if (!queue)
+ 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)
+ return NULL;
+
+ ur = wqd->ur;
+ free(wqd);
+
+ return ur;
+}
+
+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;
+ }
+}
+
+char* util_hexStringToBytes(char *s)
+{
+ char *ret;
+ int i;
+ int sz;
+
+ if (s == NULL)
+ return NULL;
+
+ sz = strlen(s);
+
+ ret = calloc((sz / 2) + 1, 1);
+
+ 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]);
+ }
+
+ return ret;
+}
+
+char _util_unpackb(const char *src, int pos, int len)
+{
+ char result = 0;
+ int rshift = 0;
+
+ src += pos / 8;
+ pos %= 8;
+
+ rshift = MAX(8 - (pos + len), 0);
+
+ if (rshift > 0) {
+ result = MASK_AND_SHIFT(len, pos, rshift, *src);
+ } else {
+ result = MASK(8 - pos, pos, *src);
+ src++;
+ len -= 8 - pos;
+
+ if (len > 0) result = (result << len) | (*src >> (8 - len)); // if any bits left
+ }
+
+ return result;
+}
+
+char _util_convert_byte_hexChar(char val)
+{
+ char hex_char;
+
+ if (val <= 9) {
+ hex_char = (char) (val + '0');
+ } else if (val >= 10 && val <= 15) {
+ hex_char = (char) (val - 10 + 'A');
+ } else {
+ hex_char = '0';
+ }
+
+ return (hex_char);
+}
+
+gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes)
+{
+ int i;
+ char nibble;
+ int buf_pos = 0;
+
+ for (i = 0; i < num_bytes * 2; i++) {
+ nibble = _util_unpackb(byte_pdu, buf_pos, 4);
+ buf_pos += 4;
+ hex_pdu[i] = _util_convert_byte_hexChar(nibble);
+ }
+
+ return TRUE;
+}
+
+char* util_removeQuotes(void *data)
+{
+ char *tmp = NULL;
+ int data_len = 0;
+
+ data_len = strlen((const char *) data);
+ dbg("data_len: %d----%s", data_len, data);
+ if (data_len <= 0) {
+ return NULL;
+ }
+ tmp = calloc(1, data_len - 1);
+ memcpy(tmp, data + 1, data_len - 2);
+ dbg("tmp: %s", tmp);
+
+ return tmp;
+}
--- /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");
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ if (TCORE_RETURN_SUCCESS == res.result) {
+ if (TRUE == req_data->enable)
+ res.result = 1;
+ else
+ res.result = 2;
+ } else {
+ res.result = 3;
+ }
+
+ tcore_user_request_send_response(ur, TRESP_MODEM_SET_FLIGHTMODE, sizeof(struct tresp_modem_set_flightmode), &res);
+
+ 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_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 for ps*/
+ prepare_and_send_pending_request(plugin, "umts_ps", "at+cmee=2", NULL, TCORE_AT_NO_RESULT, on_response_bootup_subscription);
+
+ /*CMEE subscription for sms*/
+ prepare_and_send_pending_request(plugin, "umts_sms", "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);
+
+ /* XBCSTAT subscription */
+ prepare_and_send_pending_request(plugin, "sap", "at+xbcstat=1", 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);
+ 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);
+
+ 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);
+ 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);
+
+ 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);
+ 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);
+
+ 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: 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 <glib.h>
+
+#include <tcore.h>
+#include <hal.h>
+#include <core_object.h>
+#include <plugin.h>
+#include <queue.h>
+#include <co_network.h>
+#include <co_ps.h>
+#include <server.h>
+#include <storage.h>
+#include <util.h>
+#include <at.h>
+
+#include "s_common.h"
+#include "s_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 AT_CREG_STAT_SEARCHING 2 /* not registered, but MT is currently searching a new operator to register to */
+#define AT_CREG_STAT_REG_DENIED 3 /* registration denied */
+#define AT_CREG_STAT_UNKNOWN 4 /* unknown */
+#define AT_CREG_STAT_REG_ROAM 5 /* registered, roaming */
+
+#define AT_COPS_MODE_AUTOMATIC 0 /* automatic (<oper> field is ignored) */
+#define AT_COPS_MODE_MANUAL 1 /* manual (<oper> field shall be present, and <AcT> optionally) */
+#define AT_COPS_MODE_DEREGISTER 2 /* deregister from network */
+#define AT_COPS_MODE_SET_ONLY 3 /* set only <format> */
+#define AT_COPS_MODE_MANUAL_AUTOMATIC 4 /*automatic - manual*/
+
+#define AT_COPS_FORMAT_LONG_ALPHANUMERIC 0 /* long format alphanumeric <oper> */
+#define AT_COPS_FORMAT_SHORT_ALPHANUMERIC 1 /* short format alphanumeric <oper> */
+#define AT_COPS_FORMAT_NUMERIC 2 /* numeric <oper> */
+
+#define AT_COPS_ACT_GSM 0 /* GSM */
+#define AT_COPS_ACT_GSM_COMPACT 1 /* GSM Compact */
+#define AT_COPS_ACT_UTRAN 2 /* UTRAN */
+#define AT_COPS_ACT_GSM_EGPRS 3 /* GSM w/EGPRS */
+#define AT_COPS_ACT_UTRAN_HSDPA 4 /* UTRAN w/HSDPA */
+#define AT_COPS_ACT_UTRAN_HSUPA 5 /* UTRAN w/HSUPA */
+#define AT_COPS_ACT_UTRAN_HSDPA_HSUPA 6 /* UTRAN w/HSDPA and HSUPA */
+#define AT_COPS_ACT_E_UTRAN 7 /* E-UTRAN */
+
+#define AT_GSM_XBANDSEL_AUTOMATIC 0
+#define AT_GSM_XBANDSEL_1800 1800
+#define AT_GSM_XBANDSEL_1900 1900
+#define AT_GSM_XBANDSEL_900 900
+#define AT_GSM_XBANDSEL_850 850
+#define AT_GSM_XBANDSEL_450 450
+#define AT_GSM_XBANDSEL_480 480
+#define AT_GSM_XBANDSEL_750 750
+#define AT_GSM_XBANDSEL_380 380
+#define AT_GSM_XBANDSEL_410 410
+
+#define AT_XRAT_GSM 0
+#define AT_XRAT_DUAL 1
+#define AT_XRAT_UMTS 2
+
+#define MAX_NETWORKS_PREF_PLMN_SUPPORT 150
+#define MAX_NETWORKS_MANUAL_SEARCH_SUPPORT 20
+
+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,
+ [AT_CREG_STAT_SEARCHING] = NETWORK_SERVICE_DOMAIN_STATUS_SEARCH,
+ [AT_CREG_STAT_REG_DENIED] = NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY,
+ [AT_CREG_STAT_UNKNOWN] = NETWORK_SERVICE_DOMAIN_STATUS_NO,
+ [AT_CREG_STAT_REG_ROAM] = NETWORK_SERVICE_DOMAIN_STATUS_FULL,
+};
+
+static unsigned int lookup_tbl_access_technology[] = {
+ [AT_COPS_ACT_GSM] = NETWORK_ACT_GSM,
+ [AT_COPS_ACT_GSM_COMPACT] = NETWORK_ACT_GSM,
+ [AT_COPS_ACT_UTRAN] = NETWORK_ACT_UTRAN,
+ [AT_COPS_ACT_GSM_EGPRS] = NETWORK_ACT_EGPRS,
+ [AT_COPS_ACT_UTRAN_HSDPA] = NETWORK_ACT_UTRAN,
+ [AT_COPS_ACT_UTRAN_HSUPA] = NETWORK_ACT_UTRAN,
+ [AT_COPS_ACT_UTRAN_HSDPA_HSUPA] = NETWORK_ACT_UTRAN,
+ [AT_COPS_ACT_E_UTRAN] = NETWORK_ACT_GSM_UTRAN,
+};
+
+static gboolean get_serving_network(CoreObject *o, UserRequest *ur);
+
+
+static void on_confirmation_network_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 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)
+{
+ 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);
+
+ pending = tcore_pending_new(o, 0);
+ 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, req->cmd);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
+
+ ret = tcore_hal_send_request(hal, pending);
+ return;
+}
+
+
+static void _insert_mcc_mnc_oper_list(TcorePlugin *p, CoreObject *o)
+{
+ Server *s;
+ Storage *strg;
+ void *handle;
+ char query[255] = { 0, };
+ GHashTableIter iter;
+ gpointer key, value;
+ GHashTable *result = NULL, *row = NULL;
+ struct tcore_network_operator_info *noi = NULL;
+ int count = 0;
+
+ s = tcore_plugin_ref_server(p);
+ strg = tcore_server_find_storage(s, "database");
+
+ handle = tcore_storage_create_handle(strg, "/opt/dbspace/.mcc_mnc_oper_list.db");
+ if (!handle) {
+ dbg("fail to create database handle");
+ return;
+ }
+
+ snprintf(query, 255, "select country, mcc, mnc, oper from mcc_mnc_oper_list");
+
+ result = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify) g_hash_table_destroy);
+
+ tcore_storage_read_query_database(strg, handle, query, NULL, result, 4);
+
+ g_hash_table_iter_init(&iter, result);
+ while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ row = value;
+
+ noi = calloc(sizeof(struct tcore_network_operator_info), 1);
+
+ 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);
+
+ count++;
+ }
+
+ dbg("count = %d", count);
+
+ g_hash_table_destroy(result);
+
+ tcore_storage_remove_handle(strg, handle);
+}
+
+static enum telephony_network_service_type _get_service_type(enum telephony_network_service_type prev_type,
+ int domain, int act, int cs_status, int ps_status)
+{
+ enum telephony_network_service_type ret;
+
+ ret = prev_type;
+
+ switch (act) {
+ case NETWORK_ACT_UNKNOWN:
+ ret = NETWORK_SERVICE_TYPE_UNKNOWN;
+ break;
+
+ case NETWORK_ACT_GSM:
+ if (prev_type == NETWORK_SERVICE_TYPE_2_5G_EDGE && domain == NETWORK_SERVICE_DOMAIN_CS)
+ ret = NETWORK_SERVICE_TYPE_2_5G_EDGE;
+ else
+ ret = NETWORK_SERVICE_TYPE_2G;
+ break;
+
+ case NETWORK_ACT_EGPRS:
+ return NETWORK_SERVICE_TYPE_2_5G_EDGE;
+ break;
+
+ case NETWORK_ACT_UMTS:
+ ret = NETWORK_SERVICE_TYPE_3G;
+ break;
+ }
+
+ if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_NO && ps_status == NETWORK_SERVICE_DOMAIN_STATUS_NO) {
+ ret = NETWORK_SERVICE_TYPE_NO_SERVICE;
+ } else if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_SEARCH || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_SEARCH) {
+ if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
+ /* no change */
+ } else {
+ ret = NETWORK_SERVICE_TYPE_SEARCH;
+ }
+ } else if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_EMERGENCY) {
+ if (cs_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL || ps_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL) {
+ /* no change */
+ } else {
+ ret = NETWORK_SERVICE_TYPE_EMERGENCY;
+ }
+ }
+
+ return ret;
+}
+
+static void _ps_set(TcorePlugin *p, int status)
+{
+ GSList *co_list = NULL;
+
+ 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)));
+
+ g_slist_free(co_list);
+}
+
+static void on_timeout_search_network(TcorePending *p, void *user_data)
+{
+ UserRequest *ur;
+ struct tresp_network_search resp;
+
+ dbg("TIMEOUT !!!!! pending=%p", p);
+
+ memset(&resp, 0, sizeof(struct tresp_network_search));
+
+ resp.result = TCORE_RETURN_FAILURE;
+ resp.list_count = 0;
+
+ 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)
+{
+ UserRequest *ur;
+ const TcoreATResponse *atResp = data;
+ // GSList *tokens = NULL;
+ // char * line = NULL;
+ struct tresp_network_set_plmn_selection_mode resp = {0};
+
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+ resp.result = TCORE_RETURN_SUCCESS;
+ } else {
+ dbg("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_PLMN_SELECTION_MODE, sizeof(struct tresp_network_set_plmn_selection_mode), &resp);
+ }
+}
+
+static void on_response_get_plmn_selection_mode(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur;
+ struct tresp_network_get_plmn_selection_mode resp = {0};
+ const TcoreATResponse *atResp = data;
+ GSList *tokens = NULL;
+ char *line = NULL;
+ int mode = 0;
+
+ resp.result = TCORE_RETURN_FAILURE;
+
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+ /* Format of output
+ +COPS: <mode>[,<format>,<oper>[,< AcT>]]
+ */
+
+ if (atResp->lines) {
+ line = (char *) atResp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ msg("invalid message");
+ goto OUT;
+ }
+ mode = atoi(tcore_at_tok_nth(tokens, 0));
+ dbg("mode = %d", mode);
+
+ switch (mode) {
+ case AT_COPS_MODE_AUTOMATIC:
+ resp.mode = NETWORK_SELECT_MODE_AUTOMATIC;
+ break;
+
+ case AT_COPS_MODE_MANUAL:
+ case AT_COPS_MODE_MANUAL_AUTOMATIC:
+ resp.mode = NETWORK_SELECT_MODE_MANUAL;
+ break;
+
+ case AT_COPS_MODE_DEREGISTER:
+ case AT_COPS_MODE_SET_ONLY:
+ resp.result = TCORE_RETURN_FAILURE;
+ goto OUT;
+ }
+ resp.result = TCORE_RETURN_SUCCESS;
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ resp.result = TCORE_RETURN_FAILURE;
+ }
+
+OUT:
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_PLMN_SELECTION_MODE, sizeof(struct tresp_network_get_plmn_selection_mode), &resp);
+ }
+
+ if (tokens != NULL)
+ tcore_at_tok_free(tokens);
+
+ return;
+}
+
+static void on_response_search_network(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur;
+ struct tresp_network_search resp;
+ int i = 0;
+ char *line = NULL;
+ const TcoreATResponse *atResp = data;
+ GSList *tokens = NULL;
+ GSList *network_token = NULL;
+ int AcT = 0;
+ char *temp_plmn_info = NULL;
+ char *pResp = NULL;
+ int num_network_avail = 0;
+
+ memset(&resp, 0, sizeof(struct tresp_network_search));
+ resp.result = TCORE_RETURN_FAILURE;
+ resp.list_count = 0;
+
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+ if (atResp->lines) {
+ line = (char *) atResp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ num_network_avail = g_slist_length(tokens);
+ dbg(" length of tokens is %d\n", num_network_avail);
+ if (num_network_avail < 1) {
+ msg("invalid message");
+ goto OUT;
+ }
+ }
+
+ 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)]
+ */
+
+ for (i = 0; ((i < num_network_avail) && (i < MAX_NETWORKS_MANUAL_SEARCH_SUPPORT)); i++) {
+ network_token = tcore_at_tok_new(g_slist_nth_data(tokens, i));
+
+ pResp = (tcore_at_tok_nth(network_token, 0));
+ if (pResp != NULL) {
+ dbg("status : %s", pResp);
+ 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 (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);
+ }
+
+ /* PLMN ID */
+ pResp = tcore_at_tok_nth(network_token, 3);
+ if (pResp != NULL) {
+ dbg("PLMN ID : %s", pResp);
+ temp_plmn_info = util_removeQuotes(pResp);
+ }
+
+ 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 (strlen(pResp) > 0) {
+ AcT = atoi(pResp);
+
+ if (0 == AcT)
+ resp.list[i].act = NETWORK_ACT_GSM;
+ else if (2 == AcT)
+ resp.list[i].act = NETWORK_ACT_UMTS;
+ }
+ }
+
+ dbg("Operator [%d] :: stat = %d, Name =%s, plmnId = %s, AcT=%d\n", resp.list_count, resp.list[i].status, resp.list[i].name, resp.list[i].plmn, resp.list[i].act);
+ resp.list_count++;
+
+ tcore_at_tok_free(network_token);
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ resp.result = TCORE_RETURN_FAILURE;
+ }
+
+OUT:
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ 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;
+}
+
+static void on_response_set_umts_band(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *atResp = data;
+
+ dbg("On Response Set UMTS Band");
+
+ if (atResp->success > 0) {
+ dbg("Response OK");
+ } else {
+ dbg("Response NOK");
+ }
+
+ dbg("Wait for response of XRAT before sending final band setting response to AP");
+ return;
+}
+
+
+static void on_response_set_gsm_band(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *atResp = data;
+
+ dbg("On Response Set GSM Band");
+ if (atResp->success > 0) {
+ dbg("Response OK");
+ } else {
+ dbg("Response NOK");
+ }
+
+ dbg("Wait for response of XRAT before sending final band setting response to AP");
+ return;
+}
+
+static void on_response_get_umts_band(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *atResp = data;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ int total_umts_bands = 0;
+ int i = 0;
+ char *band_token = NULL;
+ char umts_band[20] = {0};
+ char umts_band_1 = 0;
+ char umts_band_2 = 0;
+ char umts_band_5 = 0;
+ UserRequest *ur = NULL;
+ struct tresp_network_get_band resp = {0};
+
+ dbg("Entry on_response_get_umts_band");
+
+ resp.mode = NETWORK_BAND_MODE_PREFERRED;
+ resp.result = TCORE_RETURN_SUCCESS;
+
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+ if (atResp->lines) {
+ line = (char *) atResp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ total_umts_bands = g_slist_length(tokens);
+ dbg("Total UMTS bands enabled are : %d\n", total_umts_bands);
+ if (total_umts_bands < 1) {
+ goto OUT;
+ }
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ goto OUT;
+ }
+
+ for (i = 0; i < total_umts_bands; i++) {
+ band_token = tcore_at_tok_nth(tokens, i);
+
+ if (band_token == NULL)
+ continue;
+
+ memset(umts_band, 0x00, sizeof(umts_band));
+
+ if (atoi(band_token) == 0) { /* 0 means UMTS automatic */
+ umts_band_1 = umts_band_2 = umts_band_5 = TRUE;
+ break;
+ }
+
+ /* Strip off starting quotes & ending quotes */
+ strncpy(umts_band, band_token + 1, strlen(band_token) - 2);
+
+ if (!strcmp(umts_band, "UMTS_BAND_I")) {
+ umts_band_1 = TRUE;
+ } else if (!strcmp(umts_band, "UMTS_BAND_II")) {
+ umts_band_2 = TRUE;
+ } else if (!strcmp(umts_band, "UMTS_BAND_II")) {
+ umts_band_5 = TRUE;
+ } else {
+ /* Telephony is not interest */
+ dbg("Telephony is not interested in %s band", umts_band);
+ }
+ }
+
+OUT:
+ if ((umts_band_1) && (umts_band_2) && (umts_band_5)) {
+ resp.band = NETWORK_BAND_TYPE_WCDMA;
+ } else if (umts_band_1) {
+ resp.band = NETWORK_BAND_TYPE_WCDMA2100;
+ } else if (umts_band_2) {
+ resp.band = NETWORK_BAND_TYPE_WCDMA1900;
+ } else if (umts_band_5) {
+ resp.band = NETWORK_BAND_TYPE_WCDMA850;
+ } else {
+ resp.result = TCORE_RETURN_FAILURE;
+ }
+
+ dbg("Final resp.band sent to TS = %d", resp.band);
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
+ }
+
+ if (tokens != NULL)
+ tcore_at_tok_free(tokens);
+
+ dbg("Exit on_response_get_umts_band");
+ return;
+}
+
+static void on_response_get_gsm_band(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ struct tresp_network_get_band resp = {0};
+ const TcoreATResponse *atResp = data;
+ GSList *tokens = NULL;
+ int total_gsm_bands = 0;
+ const char *line = NULL;
+ int i = 0;
+ char *band_token = NULL;
+ UserRequest *ur = NULL;
+ int gsm_850 = 0;
+ int gsm_900 = 0;
+ int gsm_1800 = 0;
+ int gsm_1900 = 0;
+
+ dbg("Entry on_response_get_gsm_band");
+
+ resp.mode = NETWORK_BAND_MODE_PREFERRED;
+ resp.result = TCORE_RETURN_SUCCESS;
+
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+ if (atResp->lines) {
+ line = (char *) atResp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ total_gsm_bands = g_slist_length(tokens);
+ dbg("Total GSM bands enabled are : %d\n", total_gsm_bands);
+ if (total_gsm_bands < 1)
+ goto OUT;
+ }
+ }
+
+ for (i = 0; i < total_gsm_bands; i++) {
+ band_token = tcore_at_tok_nth(tokens, i);
+
+ if (band_token == NULL)
+ continue;
+
+ if (atoi(band_token) == 0) { /* 0 means GSM automatic */
+ gsm_850 = gsm_900 = gsm_1800 = gsm_1900 = TRUE;
+ break;
+ }
+
+ switch (atoi(band_token)) {
+ case AT_GSM_XBANDSEL_850:
+ gsm_850 = TRUE;
+ break;
+
+ case AT_GSM_XBANDSEL_900:
+ gsm_900 = TRUE;
+ break;
+
+ case AT_GSM_XBANDSEL_1800:
+ gsm_1800 = TRUE;
+ break;
+
+ case AT_GSM_XBANDSEL_1900:
+ gsm_1900 = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+OUT:
+
+ if (gsm_850 && gsm_900 && gsm_1800 && gsm_1900) {
+ resp.band = NETWORK_BAND_TYPE_GSM;
+ } else if (gsm_850 && gsm_1900) {
+ resp.band = NETWORK_BAND_TYPE_GSM_850_1900;
+ } else if (gsm_900 && gsm_1800) {
+ resp.band = NETWORK_BAND_TYPE_GSM_900_1800;
+ } else if (gsm_1900) {
+ resp.band = NETWORK_BAND_TYPE_GSM1900;
+ } else if (gsm_850) {
+ resp.band = NETWORK_BAND_TYPE_GSM850;
+ } else if (gsm_1800) {
+ resp.band = NETWORK_BAND_TYPE_GSM1800;
+ } else if (gsm_900) {
+ resp.band = NETWORK_BAND_TYPE_GSM900;
+ } else {
+ resp.result = TCORE_RETURN_FAILURE;
+ }
+
+ dbg("Final resp.band sent to TS = %d", resp.band);
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
+ }
+
+ if (tokens != NULL)
+ tcore_at_tok_free(tokens);
+
+ dbg("Exit on_response_get_gsm_band");
+ return;
+}
+
+
+static void on_response_get_xrat(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ TcoreHal *h = NULL;
+ UserRequest *ur = NULL;
+
+ TcoreATRequest *atreq;
+ char *cmd_str = NULL;
+ UserRequest *dup_ur = NULL;
+ const TcoreATResponse *atResp = data;
+ const char *line = NULL;
+ char *pResp = NULL;
+ GSList *tokens = NULL;
+ TcorePending *pending = NULL;
+ CoreObject *o = NULL;
+ int cp_xrat = 0;
+ struct tresp_network_get_band resp = {0};
+
+ dbg("Enter on_response_get_xrat !!");
+
+ resp.mode = NETWORK_BAND_MODE_PREFERRED;
+
+ ur = tcore_pending_ref_user_request(p);
+ h = tcore_object_get_hal(tcore_pending_ref_core_object(p));
+ o = tcore_pending_ref_core_object(p);
+
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+ if (atResp->lines) {
+ line = (char *) atResp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ msg("invalid message");
+ goto OUT;
+ }
+ }
+
+ if ((pResp = tcore_at_tok_nth(tokens, 0))) {
+ cp_xrat = atoi(pResp);
+
+ if ((cp_xrat == AT_XRAT_DUAL)) { /* mode is Dual, send reply to Telephony */
+ resp.result = TCORE_RETURN_SUCCESS;
+ resp.band = NETWORK_BAND_TYPE_ANY;
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
+ }
+ goto OUT;
+ } else if ((cp_xrat == AT_XRAT_UMTS)) {
+ /* Get UMTS Band Information */
+ 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);
+ 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_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);
+ } else if ((cp_xrat == AT_XRAT_UMTS)) {
+ /* Get GSM Band Information */
+ dup_ur = tcore_user_request_ref(ur); /* duplicate user request for AT+XBANDSEL */
+ cmd_str = g_strdup_printf("AT+XBANDSEL?");
+ atreq = tcore_at_request_new(cmd_str, "+XBANDSEL", TCORE_AT_SINGLELINE);
+ pending = tcore_pending_new(o, 0);
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_response_callback(pending, on_response_get_gsm_band, NULL);
+ tcore_pending_link_user_request(pending, dup_ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_network_message_send, NULL);
+ tcore_hal_send_request(h, pending);
+ g_free(cmd_str);
+ }
+ }
+ } else {
+ dbg("RESPONSE NOK");
+
+ resp.result = TCORE_RETURN_FAILURE;
+ resp.band = NETWORK_BAND_TYPE_ANY;
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_BAND, sizeof(struct tresp_network_get_band), &resp);
+ }
+ }
+OUT:
+
+ if (tokens != NULL)
+ tcore_at_tok_free(tokens);
+
+ dbg("Exit on_response_get_xrat !!");
+
+ return;
+}
+
+
+static void on_response_set_xrat(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ struct tresp_network_set_band resp = {0};
+ const TcoreATResponse *atResp = data;
+
+ dbg("On Response Set XRAT");
+
+ if (atResp->success > 0) {
+ dbg("Response OK");
+ resp.result = TCORE_RETURN_SUCCESS;
+ } else {
+ dbg("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_BAND, sizeof(struct tresp_network_set_band), &resp);
+ }
+
+ return;
+}
+
+static void on_response_set_preferred_plmn(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ struct tresp_network_set_preferred_plmn resp = {0};
+ const TcoreATResponse *atResp = data;
+
+ dbg("ENTER on_response_set_preferred_plmn");
+
+ if (atResp->success > 0) {
+ dbg("Response OK");
+ resp.result = TCORE_RETURN_SUCCESS;
+ } else {
+ dbg("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_PREFERRED_PLMN, sizeof(struct tresp_network_set_preferred_plmn), &resp);
+ }
+
+ dbg("Exit on_response_set_preferred_plmn");
+ return;
+}
+
+static void on_response_get_nitz_name(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *atResp = data;
+ GSList *tokens = NULL;
+ const char *line = NULL;
+ CoreObject *o = NULL;
+ struct tnoti_network_identity noti;
+ int nol = 0;
+ int count = 0;
+ int net_name_type = 0;
+ char *pResp = NULL;
+
+ dbg("Entry on_response_get_nitz_name (+XCOPS)");
+ o = tcore_pending_ref_core_object(p);
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+
+ if (atResp->lines) {
+ nol = g_slist_length(atResp->lines);
+ if (nol > 3) {
+ msg("invalid message");
+ goto OUT;
+ }
+
+ for (count = 0; count < nol; count++) {
+ // parse each line
+ line = g_slist_nth_data(atResp->lines, count);
+ tokens = tcore_at_tok_new(line);
+ dbg("line %d start---------------", count);
+
+ if ((pResp = tcore_at_tok_nth(tokens, 0))) {
+ net_name_type = atoi(pResp);
+ dbg("Net name type : %d", net_name_type);
+
+ switch (net_name_type) {
+ 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 */
+ }
+ break;
+
+ case 5: /* Short Nitz name*/
+ if ((pResp = tcore_at_tok_nth(tokens, 1))) {
+ strncpy(noti.short_name, pResp + 1, strlen(pResp) - 2); /* skip quotes (") while copying */
+ }
+ break;
+
+ case 6: /* Full Nitz name */
+ if ((pResp = tcore_at_tok_nth(tokens, 1))) {
+ strncpy(noti.full_name, pResp + 1, strlen(pResp) - 2); /* skip quotes (") while copying */
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ if (tokens != NULL)
+ tcore_at_tok_free(tokens);
+ }
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_IDENTITY,
+ sizeof(struct tnoti_network_identity), ¬i);
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ }
+
+OUT:
+ dbg("Exit on_response_get_nitz_name");
+}
+
+static void on_response_get_preferred_plmn(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur;
+ int i = 0;
+ char *line = NULL;
+ const TcoreATResponse *atResp = data;
+ GSList *tokens = NULL;
+ char temp_plmn_info[17] = {0};
+ char *pResp = NULL;
+ int plmn_format = 0;
+
+ struct tresp_network_get_preferred_plmn resp = {0};
+ int total_lines = 0;
+ int GSM_AcT2 = 0, GSM_Compact_AcT2 = 0, UTRAN_AcT2 = 0;
+
+ dbg("Entry on_response_get_preferred_plmn");
+
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+ if (atResp->lines) {
+ total_lines = g_slist_length(atResp->lines);
+ dbg("Total number of network present in Preferred PLMN list is %d\n", total_lines);
+
+ if (total_lines < 1) {
+ msg("invalid message");
+ goto OUT;
+ }
+
+ if (total_lines >= MAX_NETWORKS_PREF_PLMN_SUPPORT)
+ total_lines = MAX_NETWORKS_PREF_PLMN_SUPPORT;
+
+/*
++COPL: <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++) {
+ /* Take each line response at a time & parse it */
+ line = tcore_at_tok_nth(atResp->lines, i);
+ tokens = tcore_at_tok_new(line);
+
+ /* <index2>,<format>,<oper2>[,<GSM_AcT2>,<GSM_Compact_AcT2>,<UTRAN_AcT2>,<E-UTRAN_AcT2>] */
+
+ /* EF Index */
+ if ((pResp = tcore_at_tok_nth(tokens, 0))) {
+ dbg("Index : %s", pResp);
+ resp.list[i].ef_index = atoi(pResp);
+ }
+ /* Format */
+ if ((pResp = tcore_at_tok_nth(tokens, 1))) {
+ dbg("format : %s", pResp);
+ plmn_format = atoi(pResp);
+ }
+
+ /* Operator PLMN ID */
+ if ((pResp = tcore_at_tok_nth(tokens, 2))) {
+ dbg("plmn ID : %s", pResp);
+
+ if (strlen(pResp) > 0) {
+ strncpy(temp_plmn_info, pResp + 1, (strlen(pResp)) - 2);
+
+ // 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);
+ }
+ }
+ }
+
+ if ((pResp = tcore_at_tok_nth(tokens, 3))) {
+ dbg("GSM_AcT2 : %s", pResp);
+ GSM_AcT2 = atoi(pResp);
+ }
+
+ if ((pResp = tcore_at_tok_nth(tokens, 4))) {
+ dbg("GSM_Compact AcT2 : %s", pResp);
+ GSM_Compact_AcT2 = atoi(pResp);
+ }
+
+ if ((pResp = tcore_at_tok_nth(tokens, 5))) {
+ dbg("UTRAN_AcT2 : %s", pResp);
+ UTRAN_AcT2 = atoi(pResp);
+ }
+
+ if (UTRAN_AcT2 && (GSM_AcT2 || GSM_Compact_AcT2))
+ resp.list[i].act = NETWORK_ACT_GSM_UTRAN;
+ else if (UTRAN_AcT2)
+ resp.list[i].act = NETWORK_ACT_UMTS;
+ else if (GSM_AcT2 || GSM_Compact_AcT2)
+ resp.list[i].act = NETWORK_ACT_GPRS;
+
+ (resp.list_count)++;
+
+ tcore_at_tok_free(tokens);
+ }
+ }
+ }
+OUT:
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_PREFERRED_PLMN, sizeof(struct tresp_network_get_preferred_plmn), &resp);
+ }
+ dbg("Exit");
+ return;
+}
+
+static void on_response_get_serving_network(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ 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;
+ CoreObject *o;
+ GSList *tokens = NULL;
+ const char *line;
+ int network_mode = -1;
+ int plmn_format = -1;
+ int AcT = -1;
+ struct tnoti_network_identity noti;
+ char *pResp = NULL;
+ int nol, count = 0;
+
+ o = tcore_pending_ref_core_object(p);
+
+ if (resp->success <= 0) {
+ dbg("RESPONSE NOK");
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ Tresp.result = TCORE_RETURN_FAILURE;
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_SERVING_NETWORK, sizeof(struct tresp_network_get_serving_network), &Tresp);
+ }
+
+ return;
+ } else {
+ dbg("RESPONSE OK");
+ nol = g_slist_length(resp->lines);
+ dbg("nol : %d", nol);
+
+ for (count = 0; count < nol; count++) {
+ // parse each line
+ line = g_slist_nth_data(resp->lines, count);
+ tokens = tcore_at_tok_new(line);
+ dbg("line %d start---------------", count);
+ // mode
+ if ((pResp = tcore_at_tok_nth(tokens, 0))) {
+ dbg("mode : %s", pResp);
+ network_mode = atoi(pResp);
+ }
+
+ // format (optional)
+ if ((pResp = tcore_at_tok_nth(tokens, 1))) {
+ dbg("format : %s", pResp);
+ if (strlen(pResp) > 0)
+ plmn_format = atoi(pResp);
+ }
+
+ // plmn
+ switch (plmn_format) {
+ case AT_COPS_FORMAT_LONG_ALPHANUMERIC:
+ if ((pResp = tcore_at_tok_nth(tokens, 2))) {
+ dbg("long PLMN : %s", pResp);
+ if (strlen(pResp) > 0) {
+ long_plmn_name = util_removeQuotes(pResp);
+
+ // set network name into po
+ tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_FULL, long_plmn_name);
+ }
+ }
+ break;
+
+ case AT_COPS_FORMAT_SHORT_ALPHANUMERIC:
+ if ((pResp = tcore_at_tok_nth(tokens, 2))) {
+ dbg("short PLMN : %s", pResp);
+ if (strlen(pResp) > 0) {
+ short_plmn_name = util_removeQuotes(pResp);
+
+ // set network name into po
+ tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_SHORT, short_plmn_name);
+ }
+ }
+ break;
+
+ case AT_COPS_FORMAT_NUMERIC:
+ if ((pResp = tcore_at_tok_nth(tokens, 2))) {
+ dbg("numeric : %s", pResp);
+ if (strlen(pResp) > 0) {
+ memset(plmn, 0, 7);
+
+ /* Strip off starting quotes & ending quotes */
+ strncpy(plmn, pResp + 1, strlen(pResp) - 2);
+ tcore_network_set_plmn(o, plmn);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // act
+ if ((pResp = tcore_at_tok_nth(tokens, 3))) {
+ dbg("AcT : %s", pResp);
+ if (strlen(pResp) > 0) {
+ AcT = atoi(pResp);
+ tcore_network_set_access_technology(o, lookup_tbl_access_technology[AcT]);
+ }
+ }
+
+ tcore_at_tok_free(tokens);
+ }
+
+ memcpy(Tresp.plmn, plmn, 7);
+ tcore_network_get_access_technology(o, &(Tresp.act));
+ tcore_network_get_lac(o, &(Tresp.gsm.lac));
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur) {
+ Tresp.result = TCORE_RETURN_SUCCESS;
+ tcore_user_request_send_response(ur, TRESP_NETWORK_GET_SERVING_NETWORK, sizeof(struct tresp_network_get_serving_network), &Tresp);
+ } else {
+ /* Network change noti */
+ struct tnoti_network_change network_change;
+
+ memset(&network_change, 0, sizeof(struct tnoti_network_change));
+ memcpy(network_change.plmn, plmn, 7);
+ 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);
+ 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));
+ if (long_plmn_name)
+ memcpy(noti.full_name, long_plmn_name, MIN(33, 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);
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
+ 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);
+ }
+ return;
+}
+
+static gboolean on_event_ps_network_regist(CoreObject *o, const void *data, void *user_data)
+{
+ struct tnoti_network_registration_status regist_status;
+ enum telephony_network_service_domain_status cs_status;
+ enum telephony_network_service_domain_status ps_status;
+ enum telephony_network_service_type service_type;
+ enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
+ struct tnoti_network_location_cellinfo net_lac_cell_info = {0};
+ struct tnoti_ps_protocol_status noti = {0};
+ unsigned char svc_domain = NETWORK_SERVICE_DOMAIN_PS;
+ int stat = 0, AcT = 0;
+ unsigned int lac = 0xffff, ci = 0xffff;
+ unsigned int rac = 0xffff;
+ GSList *tokens = NULL;
+ char *pResp;
+ char *line = NULL;
+ GSList *lines = NULL;
+
+ lines = (GSList *) data;
+ if (1 != g_slist_length(lines)) {
+ dbg("unsolicited msg but multiple line");
+ goto OUT;
+ }
+ line = (char *) (lines->data);
+ dbg("+CGREG NOTI RECEIVED");
+
+/*
++CREG: <stat> [[,<lac>,<ci>[AcT]]
+
+Possible values of <stat> can be
+0 Not registered, ME is not currently searching a new operator to register to
+1 Registered, home network
+2 Not registered, but ME is currently searching a new operator to register
+3 Registration denied
+4 Unknown
+5 Registered, in roaming
+
+<lac>
+string type; two byte location area code in hexadecimal format (e.g. 00C3)
+
+<ci>
+string type; four byte cell ID in hexadecimal format (e.g. 0000A13F)
+
+<ACT>
+0 GSM
+2 UTRAN
+3 GSM w/EGPRS
+4 UTRAN w/HSDPA
+5 UTRAN w/HSUPA
+6 UTRAN w/HSDPA and HSUPA
+Note: <Act> is supporting from R7 and above Protocol Stack.
+
+<rac>: is R7 and above feature, string type; one byte routing area code in hexadecimal format.
+*/
+ if (line != NULL) {
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ msg("invalid message");
+ goto OUT;
+ }
+
+ if (!(pResp = g_slist_nth_data(tokens, 0))) {
+ dbg("No STAT in +CGREG");
+ goto OUT;
+ } else {
+ stat = atoi(pResp);
+ if ((pResp = g_slist_nth_data(tokens, 1)))
+ lac = atoi(pResp);
+
+ if ((pResp = g_slist_nth_data(tokens, 2)))
+ ci = atoi(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
+ dbg("No rac in +CGREG");
+ }
+
+
+ dbg("stat=%d, lac=0x%lx, ci=0x%lx, Act=%d, rac = 0x%x", stat, lac, ci, AcT, rac);
+
+ ps_status = lookup_tbl_net_status[stat];
+
+ tcore_network_set_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, ps_status);
+ _ps_set(tcore_object_ref_plugin(o), ps_status);
+
+ tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, &cs_status);
+
+ 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);
+ dbg("new_service_type = 0x%x", service_type);
+ tcore_network_set_service_type(o, service_type);
+
+ tcore_network_set_lac(o, lac);
+ tcore_network_set_cell_id(o, ci);
+ tcore_network_set_rac(o, rac);
+
+ net_lac_cell_info.lac = lac;
+ net_lac_cell_info.cell_id = ci;
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_LOCATION_CELLINFO,
+ sizeof(struct tnoti_network_location_cellinfo), &net_lac_cell_info);
+
+ regist_status.cs_domain_status = cs_status;
+ regist_status.ps_domain_status = ps_status;
+ regist_status.service_type = service_type;
+ 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);
+#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);
+
+ /* Get PLMN ID needed to application */
+ // get_serving_network(o, NULL);
+ } else {
+ dbg("Response NOK");
+ }
+
+OUT:
+ if (NULL != tokens)
+ tcore_at_tok_free(tokens);
+ return TRUE;
+}
+
+static gboolean on_event_cs_network_regist(CoreObject *o, const void *event_info, void *user_data)
+{
+ GSList *lines = NULL;
+ char *line = NULL;
+ struct tnoti_network_registration_status regist_status;
+ enum telephony_network_service_domain_status cs_status;
+ enum telephony_network_service_domain_status ps_status;
+ enum telephony_network_service_type service_type;
+ enum telephony_network_access_technology act = NETWORK_ACT_UNKNOWN;
+ struct tnoti_network_location_cellinfo net_lac_cell_info = {0};
+
+
+ unsigned char svc_domain = NETWORK_SERVICE_DOMAIN_CS;
+ int stat = 0, AcT = 0;
+ unsigned int lac = 0xffff, ci = 0xffff;
+ GSList *tokens = NULL;
+ char *pResp;
+
+ lines = (GSList *) event_info;
+ if (1 != g_slist_length(lines)) {
+ dbg("unsolicited msg but multiple line");
+ goto OUT;
+ }
+ line = (char *) (lines->data);
+
+ dbg("+CREG NOTI RECEIVED");
+
+/*
++CREG: <stat> [[,<lac>,<ci>[AcT]]
+
+Possible values of <stat> can be
+0 Not registered, ME is not currently searching a new operator to register to
+1 Registered, home network
+2 Not registered, but ME is currently searching a new operator to register
+3 Registration denied
+4 Unknown
+5 Registered, in roaming
+
+<lac>
+string type; two byte location area code in hexadecimal format (e.g. 00C3)
+
+<ci>
+string type; four byte cell ID in hexadecimal format (e.g. 0000A13F)
+
+<ACT>
+0 GSM
+2 UTRAN
+3 GSM w/EGPRS
+4 UTRAN w/HSDPA
+5 UTRAN w/HSUPA
+6 UTRAN w/HSDPA and HSUPA
+Note: <Act> is supporting from R7 and above Protocol Stack.
+*/
+ if (line != NULL) {
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < 1) {
+ msg("invalid message");
+ goto OUT;
+ }
+
+ if (!(pResp = g_slist_nth_data(tokens, 0))) {
+ dbg("No STAT in +CREG");
+ goto OUT;
+ } else {
+ stat = atoi(pResp);
+ if ((pResp = g_slist_nth_data(tokens, 1)))
+ lac = atoi(pResp);
+
+ if ((pResp = g_slist_nth_data(tokens, 2)))
+ ci = atoi(pResp);
+ else
+ dbg("No ci in +CREG");
+
+ if ((pResp = g_slist_nth_data(tokens, 3)))
+ AcT = atoi(pResp);
+ else
+ dbg("No AcT in +CREG");
+ }
+
+
+ dbg("stat=%d, lac=0x%lx, ci=0x%lx, Act=%d", stat, lac, ci, AcT);
+
+ cs_status = lookup_tbl_net_status[stat];
+ tcore_network_set_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, cs_status);
+
+ // tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, &cs_status);
+ tcore_network_get_service_status(o, TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET, &ps_status);
+
+ 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);
+ dbg("new_service_type = 0x%x", service_type);
+ tcore_network_set_service_type(o, service_type);
+
+ tcore_network_set_lac(o, lac);
+ tcore_network_set_cell_id(o, ci);
+
+ net_lac_cell_info.lac = lac;
+ net_lac_cell_info.cell_id = ci;
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_LOCATION_CELLINFO,
+ sizeof(struct tnoti_network_location_cellinfo), &net_lac_cell_info);
+
+ regist_status.cs_domain_status = cs_status;
+ regist_status.ps_domain_status = ps_status;
+ regist_status.service_type = service_type;
+ 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);
+
+ /* Get PLMN ID needed to application */
+ if ((NETWORK_SERVICE_DOMAIN_STATUS_FULL == cs_status) ||
+ NETWORK_SERVICE_DOMAIN_STATUS_FULL == ps_status)
+ get_serving_network(o, NULL);
+ } else {
+ dbg("Response NOK");
+ }
+
+OUT:
+ if (NULL != tokens)
+ tcore_at_tok_free(tokens);
+ return TRUE;
+}
+
+static gboolean on_event_network_icon_info(CoreObject *o, const void *event_info, void *user_data)
+{
+ struct tnoti_network_icon_info net_icon_info = {0};
+ char *line = NULL;
+ char *rssiToken = NULL;
+ char *batteryToken = NULL;
+ GSList *tokens = NULL;
+ GSList *lines = NULL;
+
+ lines = (GSList *) event_info;
+ if (1 != g_slist_length(lines)) {
+ dbg("unsolicited msg but multiple line");
+ goto OUT;
+ }
+ line = (char *) (lines->data);
+ dbg("+XCIEV Network Icon Info Noti Recieve");
+ memset(&net_icon_info, 0, sizeof(struct tnoti_network_icon_info));
+
+ if (line != NULL) {
+ dbg("Response OK");
+
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) != 2) {
+ msg("invalid message");
+ goto OUT;
+ }
+
+ rssiToken = (char *) g_slist_nth_data(tokens, 0);
+
+ if (strlen(rssiToken) > 0) {
+ net_icon_info.type = NETWORK_ICON_INFO_RSSI;
+ net_icon_info.rssi = atoi(g_slist_nth_data(tokens, 0));
+ dbg("rssi level : %d", net_icon_info.rssi);
+ }
+
+ batteryToken = (char *) g_slist_nth_data(tokens, 1);
+ if (strlen(batteryToken) > 0) {
+ net_icon_info.type = NETWORK_ICON_INFO_BATTERY;
+ net_icon_info.battery = atoi(g_slist_nth_data(tokens, 1));
+ dbg("battery level : %d", net_icon_info.battery);
+ }
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_ICON_INFO,
+ sizeof(struct tnoti_network_icon_info), &net_icon_info);
+ } else {
+ dbg("Response NOK");
+ }
+
+
+OUT:
+ if (NULL != tokens)
+ tcore_at_tok_free(tokens);
+
+ return TRUE;
+}
+
+static gboolean on_event_network_ctzv_time_info(CoreObject *o, const void *event_info, void *user_data)
+{
+ struct tnoti_network_timeinfo net_time_info = {0};
+ char *line = NULL;
+ GSList *tokens = NULL;
+ char *time = NULL;
+ char *time_zone = NULL;
+ GSList *lines = NULL;
+ char ptime_param[20] = {0};
+ UserRequest *ur = NULL;
+ dbg("Enter : on_event_network_ctzv_time_info");
+
+ lines = (GSList *) event_info;
+ if (1 != g_slist_length(lines)) {
+ dbg("unsolicited msg but multiple line");
+ goto OUT;
+ }
+ line = (char *) (lines->data);
+
+/*
++CTZV: <tz>,<time>
+<tz> integer value indicating the time zone (e.g. -22 or +34)
+<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) {
+ dbg("Response OK");
+ dbg("noti line is %s", line);
+
+ tokens = tcore_at_tok_new(line);
+
+ if (g_slist_length(tokens) < 2) {
+ msg("invalid message");
+ goto OUT;
+ }
+
+ if ((time_zone = g_slist_nth_data(tokens, 0))) {
+ 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));
+
+ if ((time = g_slist_nth_data(tokens, 1)) && (strlen(time) > 18)) {
+ strncpy(ptime_param, time + 1, 2); /* skip past initial quote (") */
+ net_time_info.year = atoi(ptime_param);
+
+ strncpy(ptime_param, time + 4, 2); /* skip slash (/) after year param */
+ net_time_info.month = atoi(ptime_param);
+
+ strncpy(ptime_param, time + 7, 2); /* skip past slash (/) after month param */
+ net_time_info.day = atoi(ptime_param);
+
+ strncpy(ptime_param, time + 10, 2); /* skip past comma (,) after day param */
+ net_time_info.hour = atoi(ptime_param);
+
+ strncpy(ptime_param, time + 13, 2); /* skip past colon (:) after hour param */
+ net_time_info.minute = atoi(ptime_param);
+
+ strncpy(ptime_param, time + 16, 2); /* skip past colon (:) after minute param */
+ net_time_info.second = atoi(ptime_param);
+ }
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_NETWORK_TIMEINFO, sizeof(struct tnoti_network_timeinfo), &net_time_info);
+
+ 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);
+ } else {
+ dbg("line is NULL");
+ }
+
+OUT:
+ if (NULL != tokens)
+ tcore_at_tok_free(tokens);
+
+ dbg("Exit: on_event_network_ctzv_time_info");
+ return TRUE;
+}
+
+static void on_sim_resp_hook_get_netname(UserRequest *ur, enum tcore_response_command command, unsigned int data_len,
+ const void *data, void *user_data)
+{
+ const struct tresp_sim_read *resp = data;
+ CoreObject *o = user_data;
+
+ if (command == TRESP_SIM_GET_SPN) {
+ dbg("OK SPN GETTING!!");
+ dbg("resp->result = 0x%x", resp->result);
+ dbg("resp->data.spn.display_condition = 0x%x", resp->data.spn.display_condition);
+ dbg("resp->data.spn.spn = [%s]", resp->data.spn.spn);
+
+ tcore_network_set_network_name(o, TCORE_NETWORK_NAME_TYPE_SPN, (const char *) resp->data.spn.spn);
+
+ /**
+ * display condition
+ * bit[0]: 0 = display of registered PLMN name not required when registered PLMN is either HPLMN or a PLMN in the service provider PLMN list
+ * 1 = display of registered PLMN name required when registered PLMN is either HPLMN or a PLMN in the service provider PLMN list
+ * bit[1]: 0 = display of the service provider name is required when registered PLMN is neither HPLMN nor a PLMN in the service provider PLMN list
+ * 1 = display of the service provider name is not required when registered PLMN is neither HPLMN nor a PLMN in the service provider PLMN list
+ */
+ if (resp->data.spn.display_condition & 0x01) {
+ tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_NETWORK);
+ }
+ if ((resp->data.spn.display_condition & 0x02) == 0) {
+ tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_SPN);
+ }
+ if ((resp->data.spn.display_condition & 0x03) == 0x01) {
+ tcore_network_set_network_name_priority(o, TCORE_NETWORK_NAME_PRIORITY_ANY);
+ }
+ }
+}
+
+static enum tcore_hook_return on_hook_sim_init(Server *s, CoreObject *source, enum tcore_notification_command command,
+ unsigned int data_len, void *data, void *user_data)
+{
+ const struct tnoti_sim_status *sim = data;
+ UserRequest *ur = NULL;
+
+ if (sim->sim_status == SIM_STATUS_INIT_COMPLETED) {
+ ur = tcore_user_request_new(NULL, NULL);
+ tcore_user_request_set_command(ur, TREQ_SIM_GET_SPN);
+ tcore_user_request_set_response_hook(ur, on_sim_resp_hook_get_netname, user_data);
+ tcore_object_dispatch_request(source, ur);
+ }
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static TReturn search_network(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *h = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *atreq = NULL;
+ char *cmd_str = NULL;
+ dbg("search_network - 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;
+ }
+
+ 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, 60);
+ 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);
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn set_plmn_selection_mode(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *h = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *atreq;
+ char *cmd_str = NULL;
+ int format = 0; /* default value for long alphanumeric */
+ int mode = 0;
+ char plmn[7] = {0};
+ int act = 0;
+
+ const struct treq_network_set_plmn_selection_mode *req_data = NULL;
+
+
+ dbg("set_plmn_selection_mode - ENTER!!");
+
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ 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>]]]]
+ /* oper parameter format
+ - 0 <oper> format presentations are set to long alphanumeric. If Network name not available it displays combination of Mcc and MNC in string format.
+ - 1 <oper> format presentation is set to short alphanumeric.
+ - 2 <oper> format presentations set to numeric.
+ */
+
+ if ((req_data->act == NETWORK_ACT_GSM) || (req_data->act == NETWORK_ACT_EGPRS))
+ act = 0;
+ else
+ act = 2;
+
+ switch (req_data->mode) {
+ case NETWORK_SELECT_MODE_MANUAL:
+ {
+ mode = AT_COPS_MODE_MANUAL;
+ format = AT_COPS_FORMAT_NUMERIC;
+
+ memset(plmn, 0, 7);
+ memcpy(plmn, req_data->plmn, 6);
+
+ if (strlen(req_data->plmn) == 6) {
+ if (plmn[5] == '#')
+ plmn[5] = 0;
+ }
+
+ cmd_str = g_strdup_printf("AT+COPS=%d,%d,\"%s\",%d", mode, format, plmn, act);
+ }
+ break;
+
+ case NETWORK_SELECT_MODE_AUTOMATIC:
+ default:
+ cmd_str = g_strdup("AT+COPS=0");
+ break;
+ }
+
+
+ atreq = tcore_at_request_new(cmd_str, "+COPS", TCORE_AT_NO_RESULT);
+
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_response_callback(pending, on_response_set_plmn_selection_mode, 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);
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn get_plmn_selection_mode(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *h = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *atreq;
+ char *cmd_str = NULL;
+
+ dbg("get_plmn_selection_mode - 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;
+ }
+ 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_response_callback(pending, on_response_get_plmn_selection_mode, 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);
+ return TCORE_RETURN_SUCCESS;
+}
+
+
+static TReturn set_band(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *h = NULL;
+ TcorePending *pending = NULL;
+ TcorePending *pending_gsm = NULL;
+ TcorePending *pending_umts = NULL;
+ TcoreATRequest *atreq;
+ char *cmd_str = NULL;
+ const struct treq_network_set_band *req_data;
+ gboolean set_gsm_band = 0;
+ gboolean set_umts_band = 0;
+ int gsm_band = 255;
+ int gsm_band2 = 255;
+ char *umts_band = NULL;
+ UserRequest *dup_ur_gsm = NULL;
+ UserRequest *dup_ur_umts = NULL;
+
+ dbg("set_band - ENTER!!");
+
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ 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);
+
+ switch (req_data->band) {
+ case NETWORK_BAND_TYPE_GSM850:
+ gsm_band = AT_GSM_XBANDSEL_850;
+ set_gsm_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_GSM_900_1800:
+ gsm_band = AT_GSM_XBANDSEL_900;
+ gsm_band2 = AT_GSM_XBANDSEL_1800;
+ set_gsm_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_GSM1900:
+ gsm_band = AT_GSM_XBANDSEL_1900;
+ set_gsm_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_GSM1800:
+ gsm_band = AT_GSM_XBANDSEL_1800;
+ set_gsm_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_GSM_850_1900:
+ gsm_band = AT_GSM_XBANDSEL_850;
+ gsm_band2 = AT_GSM_XBANDSEL_1900;
+ set_gsm_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_ANY:
+ gsm_band = AT_GSM_XBANDSEL_AUTOMATIC;
+ set_umts_band = TRUE;
+ set_gsm_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_WCDMA:
+ set_umts_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_WCDMA2100:
+ umts_band = "UMTS_BAND_I";
+ set_umts_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_WCDMA1900:
+ umts_band = "UMTS_BAND_II";
+ set_umts_band = TRUE;
+ break;
+
+ case NETWORK_BAND_TYPE_WCDMA850:
+ umts_band = "UMTS_BAND_V";
+ set_umts_band = TRUE;
+ break;
+
+ default:
+ break;
+ }
+
+ dbg("set_band > set_umts_band = %d, set_gsm_band = %d", set_umts_band, set_gsm_band);
+
+ if (set_umts_band == TRUE) {
+ if ((req_data->band == NETWORK_BAND_TYPE_WCDMA) || (req_data->band == NETWORK_BAND_TYPE_ANY))
+ cmd_str = g_strdup_printf("AT+XUBANDSEL=0");
+ else
+ cmd_str = g_strdup_printf("AT+XUBANDSEL=%s", umts_band);
+
+ atreq = tcore_at_request_new(cmd_str, "+XUBANDSEL", TCORE_AT_NO_RESULT);
+ pending_umts = tcore_pending_new(o, 0);
+
+ tcore_pending_set_request_data(pending_umts, 0, atreq);
+ tcore_pending_set_priority(pending_umts, TCORE_PENDING_PRIORITY_DEFAULT);
+ tcore_pending_set_response_callback(pending_umts, on_response_set_umts_band, NULL);
+
+ /* duplicate user request for UMTS Band setting AT command for same UR */
+ dup_ur_umts = tcore_user_request_ref(ur);
+ tcore_pending_link_user_request(pending_umts, dup_ur_umts);
+ tcore_pending_set_send_callback(pending_umts, on_confirmation_network_message_send, NULL);
+
+ tcore_hal_send_request(h, pending_umts);
+ g_free(cmd_str);
+ }
+
+ if (set_gsm_band == TRUE) {
+ dbg("Entered set_gsm_band");
+ if (gsm_band2 == 255)
+ cmd_str = g_strdup_printf("AT+XBANDSEL=%d", gsm_band);
+ else
+ cmd_str = g_strdup_printf("AT+XBANDSEL=%d,%d", gsm_band, gsm_band2);
+
+ dbg("Command string: %s", cmd_str);
+ atreq = tcore_at_request_new(cmd_str, "+XBANDSEL", TCORE_AT_NO_RESULT);
+ pending_gsm = tcore_pending_new(o, 0);
+
+ tcore_pending_set_request_data(pending_gsm, 0, atreq);
+ tcore_pending_set_priority(pending_gsm, TCORE_PENDING_PRIORITY_DEFAULT);
+ tcore_pending_set_response_callback(pending_gsm, on_response_set_gsm_band, NULL);
+
+ /* duplicate user request for GSM Band setting AT command for same UR */
+ dup_ur_gsm = tcore_user_request_ref(ur);
+ tcore_pending_link_user_request(pending_gsm, dup_ur_gsm);
+ tcore_pending_set_send_callback(pending_gsm, on_confirmation_network_message_send, NULL);
+
+ tcore_hal_send_request(h, pending_gsm);
+ g_free(cmd_str);
+ }
+
+ /* Lock device to specific RAT as requested by application */
+/*
+AT+XRAT=<Act>[,<PreferredAct>]
+<AcT> indicates the radio access technology and may be
+0 GSM single mode
+1 GSM / UMTS Dual mode
+2 UTRAN (UMTS)
+*/
+ if ((set_umts_band == TRUE) && (set_gsm_band == TRUE)) {
+ cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_DUAL);
+ } else if (set_umts_band == TRUE) {
+ cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_UMTS);
+ } else {
+ cmd_str = g_strdup_printf("AT+XRAT=%d", AT_XRAT_GSM);
+ }
+ atreq = tcore_at_request_new(cmd_str, "+XRAT", TCORE_AT_NO_RESULT);
+ pending = tcore_pending_new(o, 0);
+
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
+ tcore_pending_set_response_callback(pending, on_response_set_xrat, 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);
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn get_band(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *h = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *atreq;
+ char *cmd_str = NULL;
+ dbg("get_band - 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;
+ }
+
+ /* Get RAT Information Information. Based on RAT read response, we will get specific RAT bands only */
+ cmd_str = g_strdup_printf("AT+XRAT?");
+ atreq = tcore_at_request_new(cmd_str, "+XRAT", TCORE_AT_SINGLELINE);
+ pending = tcore_pending_new(o, 0);
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_response_callback(pending, on_response_get_xrat, 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);
+ return TCORE_RETURN_SUCCESS;
+}
+
+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;
+ char *cmd_str = NULL;
+ int format = 2; /* Alway use numeric format, as application gives data in this default format */
+ int gsm_act = 0;
+ int gsm_compact_act = 0;
+ int utran_act = 0;
+
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ p = tcore_object_ref_plugin(o);
+ 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");
+/*
+AT+CPOL=
+[<index>][,<format>[,<oper>[,<GSM_AcT>,
+<GSM_Compact_AcT>,<UTRAN_AcT>]]]
+ */
+
+ if ((req_data->act == NETWORK_ACT_GSM) || (req_data->act == NETWORK_ACT_GPRS) || (req_data->act == NETWORK_ACT_EGPRS))
+ gsm_act = TRUE;
+ else if ((req_data->act == NETWORK_ACT_UMTS) || (req_data->act == NETWORK_ACT_UTRAN))
+ utran_act = TRUE;
+ else if (req_data->act == NETWORK_ACT_GSM_UTRAN)
+ gsm_act = utran_act = TRUE;
+
+ if (strlen(req_data->plmn) > 6) {
+ req_data->plmn[6] = '\0';
+ } else if (strlen(req_data->plmn) == 6) {
+ if (req_data->plmn[5] == '#') {
+ req_data->plmn[5] = '\0';
+ }
+ }
+ cmd_str = g_strdup_printf("AT+CPOL=%d,%d,\"%s\",%d,%d,%d", req_data->ef_index + 1, format, req_data->plmn, gsm_act, gsm_compact_act, utran_act);
+
+ dbg("cmd_str - %s", cmd_str);
+ atreq = tcore_at_request_new(cmd_str, "+CPOL", TCORE_AT_NO_RESULT);
+
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_response_callback(pending, on_response_set_preferred_plmn, 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);
+
+ dbg("Exit set_preferred_plmn");
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn get_preferred_plmn(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *h = NULL;
+ TcorePending *pending = NULL;
+ TcoreATRequest *atreq = NULL;
+
+ char *cmd_str = NULL;
+
+ dbg("get_preferred_plmn - 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;
+ }
+
+ pending = tcore_pending_new(o, 0);
+
+ cmd_str = g_strdup_printf("AT+CPOL?");
+ atreq = tcore_at_request_new(cmd_str, "+CPOL", TCORE_AT_MULTILINE);
+
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_response_callback(pending, on_response_get_preferred_plmn, 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);
+
+ dbg("get_preferred_plmn - EXIT!!");
+
+ 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);
+ return TCORE_RETURN_SUCCESS;
+}
+
+static struct tcore_network_operations network_ops = {
+ .search = search_network,
+ .set_plmn_selection_mode = set_plmn_selection_mode,
+ .get_plmn_selection_mode = get_plmn_selection_mode,
+ .set_service_domain = NULL,
+ .get_service_domain = NULL,
+ .set_band = set_band,
+ .get_band = get_band,
+ .set_preferred_plmn = set_preferred_plmn,
+ .get_preferred_plmn = get_preferred_plmn,
+ .set_order = NULL,
+ .get_order = NULL,
+ .set_power_on_attach = NULL,
+ .get_power_on_attach = NULL,
+ .set_cancel_manual_search = NULL,
+ .get_serving_network = get_serving_network,
+};
+
+gboolean s_network_init(TcorePlugin *p, TcoreHal *h)
+{
+ CoreObject *o = NULL;
+
+ o = tcore_network_new(p, "umts_network", &network_ops, h);
+ if (!o)
+ return FALSE;
+
+ 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);
+
+ /* +CTZV: <tz>,<time> */
+ tcore_object_add_callback(o, "+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);
+
+ _insert_mcc_mnc_oper_list(p, o);
+
+ return TRUE;
+}
+
+void s_network_exit(TcorePlugin *p)
+{
+ CoreObject *o;
+
+ o = tcore_plugin_ref_core_object(p, "umts_network");
+
+ tcore_network_free(o);
+}
--- /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_phonebook.h>
+#include <co_sim.h>
+#include <user_request.h>
+#include <server.h>
+#include <at.h>
+
+#include "s_common.h"
+#include "s_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_NINE 9
+
+/* Type Of Number and Number Plan */
+#define TON_INTERNATIONAL 145
+#define TON_UNKNOWN 129
+#define NUM_PLAN_INTERNATIONAL 0x0070
+#define NUM_PLAN_UNKNOWN 0x0060
+
+enum pb_usim_file_type {
+ PB_USIM_NAME = 0x01, /**< Name */
+ PB_USIM_NUMBER, /**< Number */
+ PB_USIM_ANR, /**< Another number */
+ PB_USIM_EMAIL, /**< Email */
+ PB_USIM_SNE, /**< Second name entry */
+ PB_USIM_GRP, /**< Group file */
+ PB_USIM_PBC, /** <1 byte control info and 1 byte hidden info*/
+ PB_USIM_ANRA, /**< Another number a*/
+ PB_USIM_ANRB, /**< Another number b*/
+ PB_USIM_ANRC, /**< Another number c*/
+ PB_USIM_EMAILA, /**< email a*/
+ PB_USIM_EMAILB, /**< email b*/
+ PB_USIM_EMAILC, /**< email c*/
+};
+
+static TReturn _get_support_list(CoreObject *o);
+static TReturn s_get_count(CoreObject *o, UserRequest *ur);
+static TReturn s_get_info(CoreObject *o, UserRequest *ur);
+static TReturn s_get_usim_info(CoreObject *o, UserRequest *ur);
+static TReturn s_read_record(CoreObject *o, UserRequest *ur);
+static TReturn s_update_record(CoreObject *o, UserRequest *ur);
+static TReturn s_delete_record(CoreObject *o, UserRequest *ur);
+
+static enum tcore_response_command _find_resp_command(UserRequest *ur)
+{
+ switch(tcore_user_request_get_command(ur))
+ {
+ case TREQ_PHONEBOOK_GETCOUNT:
+ return TRESP_PHONEBOOK_GETCOUNT;
+ case TREQ_PHONEBOOK_GETMETAINFO:
+ return TRESP_PHONEBOOK_GETMETAINFO;
+ case TREQ_PHONEBOOK_GETUSIMINFO:
+ return TRESP_PHONEBOOK_GETUSIMINFO;
+ case TREQ_PHONEBOOK_READRECORD:
+ return TRESP_PHONEBOOK_READRECORD;
+ case TREQ_PHONEBOOK_UPDATERECORD:
+ return TRESP_PHONEBOOK_UPDATERECORD;
+ case TREQ_PHONEBOOK_DELETERECORD:
+ return TRESP_PHONEBOOK_DELETERECORD;
+ default:
+ return TRESP_UNKNOWN;
+ }
+}
+
+static enum tel_phonebook_ton _find_num_plan(int number_plan)
+{
+ enum tel_phonebook_ton result;
+ dbg("number_plan : 0x%04x", number_plan);
+
+ if(number_plan & NUM_PLAN_INTERNATIONAL) {
+ result = PB_TON_INTERNATIONAL;
+ }
+ else {
+ result = PB_TON_UNKNOWN;
+ }
+ dbg("result : %d", result);
+ return result;
+}
+
+static void on_confirmation_phonebook_message_send(TcorePending *p, gboolean result, void *user_data)
+{
+ dbg("msg out from queue");
+
+ if (result == FALSE) { /* Fail */
+ dbg("SEND FAIL");
+ }
+ else {
+ dbg("SEND OK");
+ }
+}
+
+static char* _get_phonebook_type(enum tel_phonebook_type pb_type)
+{
+ char *phonebook_type = NULL;
+ dbg(" Function entry ");
+ dbg("pb_type = %d", pb_type);
+
+ phonebook_type = (char*)calloc(sizeof(char), VAL_FIVE);
+ if(NULL == phonebook_type) {
+ err("Memory allcoation failed");
+ return phonebook_type;
+ }
+
+ switch(pb_type)
+ {
+ case PB_TYPE_FDN:
+ phonebook_type = "FD";
+ break;
+ case PB_TYPE_ADN:
+ case PB_TYPE_AAS:
+ case PB_TYPE_GAS:
+ phonebook_type = "SM";
+ break;
+ case PB_TYPE_SDN:
+ phonebook_type = "SN";
+ break;
+ case PB_TYPE_USIM:
+ phonebook_type = "AP";
+ break;
+ default:
+ dbg("Invalid pb_type [%02x]", pb_type);
+ free(phonebook_type);
+ phonebook_type = NULL;
+ break;
+ }
+ dbg(" Function exit");
+ return phonebook_type;
+}
+
+static enum tel_phonebook_type _get_phonebook_enum(const char* pb_type)
+{
+ enum tel_phonebook_type phonebook_type = PB_TYPE_UNKNOWNN;
+ dbg(" Function entry ");
+ dbg("pb_type = %s", pb_type);
+
+ if(strcmp("FD", pb_type) == VAL_ZERO) {
+ phonebook_type = PB_TYPE_FDN;
+ }
+ else if(strcmp("SM", pb_type) == VAL_ZERO) {
+ phonebook_type = PB_TYPE_ADN;
+ }
+ else if(strcmp("SN", pb_type) == VAL_ZERO) {
+ phonebook_type = PB_TYPE_SDN;
+ }
+ else if(strcmp("AP", pb_type) == VAL_ZERO) {
+ phonebook_type = PB_TYPE_USIM;
+ }
+
+ dbg(" Function exit");
+ return phonebook_type;
+}
+
+static gboolean on_event_phonebook_status(CoreObject *o, const void *event_info, void *user_data)
+{
+ dbg("Phonebook init received from modem");
+
+ _get_support_list(o);
+
+ return TRUE;
+}
+
+static void _on_response_select(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ CoreObject *o = NULL;
+ enum tcore_request_command req_cmd = TREQ_UNKNOWN;
+ int *selected_pb = user_data;
+ GQueue *queue = NULL;
+ dbg(" Function entry ");
+
+ o = tcore_pending_ref_core_object(p);
+ ur = tcore_pending_ref_user_request(p);
+ if (!ur){
+ dbg("error - current ur is NULL");
+ return;
+ }
+
+ queue = tcore_object_ref_user_data(o);
+ if(queue) {
+ ur = tcore_user_request_ref(ur);
+ }
+
+ req_cmd = tcore_user_request_get_command(ur);
+ dbg("origin treq command [%x]", req_cmd);
+
+ if(resp->success > VAL_ZERO) {
+ dbg("RESPONSE OK");
+ tcore_phonebook_set_selected_type(o, *selected_pb);
+ switch (req_cmd)
+ {
+ case TREQ_PHONEBOOK_GETCOUNT:
+ s_get_count(o, ur);
+ break;
+ case TREQ_PHONEBOOK_GETMETAINFO:
+ s_get_info(o, ur);
+ break;
+ case TREQ_PHONEBOOK_GETUSIMINFO:
+ s_get_usim_info(o, ur);
+ break;
+ case TREQ_PHONEBOOK_READRECORD:
+ s_read_record(o, ur);
+ break;
+ case TREQ_PHONEBOOK_UPDATERECORD:
+ s_update_record(o, ur);
+ break;
+ case TREQ_PHONEBOOK_DELETERECORD:
+ s_delete_record(o, ur);
+ break;
+ default:
+ dbg("not handled treq cmd[%d]", req_cmd);
+ break;
+ }
+ }
+ else
+ {
+ dbg("RESPONSE NOK");
+ switch (req_cmd)
+ {
+ case TREQ_PHONEBOOK_GETCOUNT:
+ {
+ struct tresp_phonebook_get_count resp_getcount;
+ dbg("error TREQ_PHONEBOOK_GETCOUNT");
+ memset(&resp_getcount, 0x00, sizeof(struct tresp_phonebook_get_count));
+ resp_getcount.result = PB_FAIL;
+ tcore_user_request_send_response(ur, TRESP_PHONEBOOK_GETCOUNT, sizeof(struct tresp_phonebook_get_count), &resp_getcount);
+ }
+ break;
+ case TREQ_PHONEBOOK_GETMETAINFO:
+ {
+ dbg("error TREQ_PHONEBOOK_GETMETAINFO");
+ }
+ break;
+ case TREQ_PHONEBOOK_GETUSIMINFO:
+ {
+ dbg("error TREQ_PHONEBOOK_GETUSIMINFO");
+ }
+ break;
+ case TREQ_PHONEBOOK_READRECORD:
+ {
+ struct tresp_phonebook_read_record resp_readrecord;
+ dbg("error TREQ_PHONEBOOK_READRECORD");
+ memset(&resp_readrecord, 0x00, sizeof(struct tresp_phonebook_read_record));
+ resp_readrecord.result = PB_FAIL;
+ resp_readrecord.phonebook_type = *selected_pb;
+ tcore_user_request_send_response(ur, TRESP_PHONEBOOK_READRECORD, sizeof(struct tresp_phonebook_read_record), &resp_readrecord);
+ }
+ break;
+ case TREQ_PHONEBOOK_UPDATERECORD:
+ {
+ struct tresp_phonebook_update_record resp_updaterecord;
+ dbg("error TREQ_PHONEBOOK_UPDATERECORD");
+ memset(&resp_updaterecord, 0x00, sizeof(struct tresp_phonebook_update_record));
+ resp_updaterecord.result = PB_FAIL;
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_update_record), &resp_updaterecord);
+ }
+ break;
+ case TREQ_PHONEBOOK_DELETERECORD:
+ {
+ struct tresp_phonebook_delete_record resp_deleterecord;
+ dbg("error TREQ_PHONEBOOK_DELETERECORD");
+ memset(&resp_deleterecord, 0x00, sizeof(struct tresp_phonebook_delete_record));
+ resp_deleterecord.result = PB_FAIL;
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_delete_record), &resp_deleterecord);
+ }
+ break;
+ default:
+ dbg("not handled treq cmd[%d]", req_cmd);
+ break;
+ }
+
+ }
+
+ free(selected_pb);
+ selected_pb = NULL;
+ dbg(" Function exit");
+}
+
+static void on_response_get_count(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ GSList *tokens=NULL;
+ const char *temp = NULL;
+ struct tresp_phonebook_get_count res;
+ char *pbtype = NULL;
+ dbg(" Function entry ");
+
+ ur = tcore_pending_ref_user_request(p);
+ if (!ur){
+ dbg("error - current ur is NULL");
+ return;
+ }
+
+ memset(&res, 0x00, sizeof(struct tresp_phonebook_get_count));
+ if(resp->success > VAL_ZERO) {
+ dbg("RESPONSE OK");
+ if(resp->lines) {
+ temp = (const char*)resp->lines->data;
+ tokens = tcore_at_tok_new(temp);
+ if (g_slist_length(tokens) < VAL_ONE) {
+ msg("invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+ res.result = PB_SUCCESS;
+
+ temp = (const char*)g_slist_nth_data(tokens, VAL_ZERO);
+ pbtype = util_removeQuotes((void*)temp);
+ res.type = _get_phonebook_enum(pbtype);
+
+ if(NULL != g_slist_nth_data(tokens, VAL_ONE)){
+ res.used_count = atoi(g_slist_nth_data(tokens, VAL_ONE));
+ }
+
+ if(NULL != g_slist_nth_data(tokens, VAL_TWO)){
+ res.total_count = atoi(g_slist_nth_data(tokens, VAL_TWO));
+ }
+ dbg("used count = %d, total count= %d", res.used_count, res.total_count);
+ free(pbtype);
+ pbtype = NULL;
+ }
+ else{
+ dbg("RESPONSE NOK");
+ res.result = PB_FAIL;
+ }
+
+ tcore_user_request_send_response(ur, TRESP_PHONEBOOK_GETCOUNT, sizeof(struct tresp_phonebook_get_count), &res);
+
+ tcore_at_tok_free(tokens);
+ dbg(" Function exit");
+}
+
+static void on_response_get_info(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ struct tresp_phonebook_get_info res = {0,};
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ GSList *tokens=NULL;
+ const char *line;
+ int *selected_pb = (int*)user_data;
+
+ dbg(" Function entry ");
+
+ ur = tcore_pending_ref_user_request(p);
+ if (!ur){
+ dbg("error - current ur is NULL");
+ return;
+ }
+
+ memset(&res, 0x00, sizeof(struct tresp_phonebook_get_info));
+ res.type = *selected_pb;
+ if(resp->success > VAL_ZERO) {
+ dbg("RESPONSE OK");
+ if(resp->lines) {
+ line = (const char*)resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < VAL_ONE) {
+ msg("invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+ res.result = PB_SUCCESS;
+
+ res.number_length_max = atoi(g_slist_nth_data(tokens, VAL_ZERO));
+ res.text_length_max = atoi(g_slist_nth_data(tokens, VAL_ONE));
+ dbg("number_length_max %d text_length_max %d",res.number_length_max,res.text_length_max);
+ }
+ else{
+ dbg("RESPONSE NOK");
+ res.result = PB_FAIL;
+ }
+
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_get_info), &res);
+
+ tcore_at_tok_free(tokens);
+ free(selected_pb);
+ selected_pb = NULL;
+ dbg(" Function exit");
+}
+
+static void on_response_read_record(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ GSList *tokens=NULL;
+ const char *line;
+ struct tresp_phonebook_read_record res;
+ int num_len = VAL_ZERO;
+ int name_len = VAL_ZERO;
+ int num_plan = VAL_ZERO;
+ char *member = NULL;
+ char *temp = NULL;
+ int *selected_pb = (int*)user_data;
+
+ dbg(" Function entry ");
+
+ ur = tcore_pending_ref_user_request(p);
+ if (!ur){
+ dbg("error - current ur is NULL");
+ return;
+ }
+
+ memset(&res, 0x00, sizeof(struct tresp_phonebook_read_record));
+ res.phonebook_type = *selected_pb;
+
+ if(resp->success > VAL_ZERO) {
+ dbg("RESPONSE OK");
+ if(resp->lines) {
+ line = (const char*)resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < VAL_ONE) {
+ msg("invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+ res.result = PB_SUCCESS;
+
+ res.index = atoi(g_slist_nth_data(tokens, VAL_ZERO));
+ res.next_index = (res.index + VAL_ONE);
+ num_plan = atoi(g_slist_nth_data(tokens, VAL_TWO));
+ res.ton = _find_num_plan(num_plan);
+
+ temp = g_slist_nth_data(tokens, VAL_ONE);
+ member = util_removeQuotes((void*)temp);
+ dbg("number %s - %d", member, (num_len-VAL_TWO));
+ memcpy(res.number, member, strlen(member));
+ free(member);
+ member = NULL;
+
+ temp = g_slist_nth_data(tokens, VAL_THREE);
+ member = util_removeQuotes((void*)temp);
+ dbg("name %s - %d", member, strlen(member));
+ memcpy(res.name, member, strlen(member));
+ free(member);
+ member = NULL;
+
+ if(NULL != g_slist_nth_data(tokens, VAL_FOUR)) {
+ if(atoi(g_slist_nth_data(tokens, VAL_FOUR)) == VAL_ZERO) {
+ dbg("phonebook entry not hidden");
+ }
+ else{
+ dbg("phonebook entry hidden");
+ }
+ }
+
+ if(NULL != g_slist_nth_data(tokens, VAL_SIX)){
+ num_len = strlen(g_slist_nth_data(tokens, VAL_SIX));
+ snprintf((char *)res.anr1, num_len+1, "%s", (char*)g_slist_nth_data(tokens, VAL_SIX));
+ }
+
+ if(NULL != g_slist_nth_data(tokens, VAL_SEVEN)){
+ num_plan = atoi(g_slist_nth_data(tokens, VAL_SEVEN));
+ res.anr1_ton = _find_num_plan(num_plan);
+ }
+
+ if(NULL != g_slist_nth_data(tokens, VAL_NINE)){
+ name_len = strlen(g_slist_nth_data(tokens, VAL_NINE));
+ memcpy(res.email1, g_slist_nth_data(tokens, VAL_NINE), name_len);
+ }
+ }
+ else{
+ dbg("RESPONSE NOK");
+ res.result = PB_FAIL;
+ }
+
+ tcore_user_request_send_response(ur, TRESP_PHONEBOOK_READRECORD, sizeof(struct tresp_phonebook_read_record), &res);
+
+ tcore_at_tok_free(tokens);
+ free(selected_pb);
+ selected_pb = NULL;
+ dbg(" Function exit");
+}
+
+static void on_response_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 res;
+ dbg(" Function entry ");
+
+ if(resp->success > VAL_ZERO) {
+ dbg("RESPONSE OK");
+ res.result = PB_SUCCESS;
+ }
+ else{
+ dbg("RESPONSE NOK");
+ res.result = PB_FAIL;
+ }
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur){
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_update_record),
+ &res);
+ }
+ else{
+ dbg("error - current ur is NULL");
+ }
+
+}
+
+static void on_response_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 res;
+
+ if(resp->success > VAL_ZERO) {
+ dbg("RESPONSE OK");
+ res.result = PB_SUCCESS;
+ }
+ else{
+ dbg("RESPONSE NOK");
+ res.result = PB_FAIL;
+ }
+
+ ur = tcore_pending_ref_user_request(p);
+ if (ur){
+ tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_delete_record), &res);
+ }
+ else{
+ dbg("error - current ur is NULL");
+ }
+}
+
+static void _response_get_support_list(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ CoreObject*o = NULL;
+ GSList *tokens=NULL;
+ const char *line;
+ char *temp = NULL;
+ char *pbtype = NULL;
+ struct tnoti_phonebook_status noti_data = {0,};
+
+ dbg(" Function entry ");
+
+ o = tcore_pending_ref_core_object(p);
+ if(!o){
+ dbg("error - core object is null");
+ return;
+ }
+
+ if(resp->success > VAL_ZERO) {
+ dbg("RESPONSE OK");
+ if(resp->lines) {
+ line = (const char*)resp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) < VAL_ONE) {
+ msg("invalid message");
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ }
+
+ temp = (char*)g_slist_nth_data(tokens, VAL_ZERO);
+ pbtype = strtok(temp, "(,)");
+ while(pbtype != NULL) {
+ temp = util_removeQuotes((void*)pbtype);
+ dbg("pbtype %s", temp);
+ if (VAL_ZERO == strcmp(temp, "FD")) {
+ dbg("SIM fixed-dialing phonebook");
+ noti_data.support_list.b_fdn = VAL_ONE;
+ }
+ else if (VAL_ZERO == strcmp(temp, "SN")) {
+ dbg("Service Dialing Number");
+ noti_data.support_list.b_sdn = VAL_ONE;
+ }
+ else if (VAL_ZERO == strcmp(temp, "SM")) {
+ dbg("2G SIM ADN phonebook");
+ noti_data.support_list.b_adn = VAL_ONE;
+ }
+ else if (VAL_ZERO == strcmp(temp, "LD")) {
+ dbg("SIM/UICC last-dialling-phonebook");
+ }
+ else if (VAL_ZERO == strcmp(temp, "ON")) {
+ dbg("SIM (or MT) own numbers (MSISDNs) list");
+ }
+ else if (VAL_ZERO == strcmp(temp, "BL")) {
+ dbg("Blacklist phonebook");
+ }
+ else if (VAL_ZERO == strcmp(temp, "EC")) {
+ dbg("SIM emergency-call-codes phonebook");
+ }
+ else if (VAL_ZERO == strcmp(temp, "AP")) {
+ dbg("Selected application phonebook");
+ }
+ else if (VAL_ZERO == strcmp(temp, "BN")) {
+ dbg("SIM barred-dialling-number");
+ }
+ pbtype = strtok (NULL, "(,)");
+ g_free(temp);
+ }
+
+ noti_data.b_init = TRUE;
+ tcore_phonebook_set_support_list(o, ¬i_data.support_list);
+ tcore_phonebook_set_status(o, noti_data.b_init);
+ tcore_at_tok_free(tokens);
+ }
+ else{
+ dbg("RESPONSE NOK");
+ noti_data.b_init = FALSE;
+ tcore_phonebook_set_status(o, noti_data.b_init);
+ }
+
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_PHONEBOOK_STATUS,
+ sizeof(struct tnoti_phonebook_status), ¬i_data);
+}
+
+static TReturn _get_support_list(CoreObject *o)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+
+ dbg(" Function entry ");
+
+ if (!o){
+ return TCORE_RETURN_EINVAL;
+ }
+
+ hal = tcore_object_get_hal(o);
+ pending = tcore_pending_new(o, VAL_ZERO);
+
+ cmd_str = g_strdup_printf("AT+CPBS=?");
+ req = tcore_at_request_new(cmd_str, "+CPBS:", 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, VAL_ZERO, req);
+ tcore_pending_set_response_callback(pending, _response_get_support_list, NULL);
+ tcore_pending_set_send_callback(pending, on_confirmation_phonebook_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn _select(CoreObject *o, UserRequest *ur, enum tel_phonebook_type pbt)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_phonebook_get_count *req_data;
+ int *pb_type = NULL;
+ char *phonebook_type = NULL;
+
+ dbg(" Function entry ");
+
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+
+ phonebook_type = (char*)_get_phonebook_type(req_data->phonebook_type);
+ if(NULL == phonebook_type){
+ err("phonebook_type is NULL");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ pb_type = calloc(sizeof(enum tel_phonebook_type),VAL_ONE);
+ if(pb_type == NULL) {
+ err("Failed to allocate memory");
+ return TCORE_RETURN_FAILURE;
+ }
+ *pb_type = pbt;
+
+ cmd_str = g_strdup_printf("AT+CPBS=\"%s\"", phonebook_type);
+ 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));
+
+ hal = tcore_object_get_hal(o);
+ pending = tcore_pending_new(o, VAL_ZERO);
+ tcore_pending_set_request_data(pending, VAL_ZERO, req);
+ tcore_pending_set_response_callback(pending, _on_response_select, (void*)pb_type);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_phonebook_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ free(phonebook_type);
+ g_free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_get_count(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_phonebook_get_count *req_data = NULL;
+ enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
+
+ dbg("Function Entry");
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+ pbt = tcore_phonebook_get_selected_type(o);
+ if (req_data->phonebook_type != pbt) {
+ dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
+ _select(o, ur, req_data->phonebook_type);
+ return TCORE_RETURN_SUCCESS;
+ }
+
+ cmd_str = g_strdup_printf("AT+CPBS?");
+ req = tcore_at_request_new(cmd_str, "+CPBS:", TCORE_AT_SINGLELINE);
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ hal = tcore_object_get_hal(o);
+ pending = tcore_pending_new(o, VAL_ZERO);
+
+ tcore_pending_set_request_data(pending, VAL_ZERO, req);
+ tcore_pending_set_response_callback(pending, on_response_get_count, hal);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_phonebook_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+ dbg("Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_get_info(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_phonebook_get_info *req_data = NULL;
+ enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
+ int *pb_type = NULL;
+
+ dbg(" Function entry ");
+
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+ pbt = tcore_phonebook_get_selected_type(o);
+ if (req_data->phonebook_type != pbt) {
+ dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
+ _select(o, ur, req_data->phonebook_type);
+ return TCORE_RETURN_SUCCESS;
+ }
+
+ pb_type = calloc(sizeof(enum tel_phonebook_type),VAL_ONE);
+ if(pb_type == NULL) {
+ err("Failed to allocate memory");
+ return TCORE_RETURN_FAILURE;
+ }
+ *pb_type = pbt;
+ dbg("pb_type %d", *pb_type);
+
+ cmd_str = g_strdup_printf("AT+CPBF=?");
+ req = tcore_at_request_new(cmd_str, "+CPBF:", TCORE_AT_SINGLELINE);
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ hal = tcore_object_get_hal(o);
+ pending = tcore_pending_new(o, VAL_ZERO);
+
+ tcore_pending_set_request_data(pending, VAL_ZERO, req);
+ tcore_pending_set_response_callback(pending, on_response_get_info, (void*)pb_type);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_phonebook_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+
+}
+
+static TReturn s_get_usim_info(CoreObject *o, UserRequest *ur)
+{
+ dbg("NOT IMPLEMENTED");
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_read_record(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal*hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_phonebook_read_record *req_data = NULL;
+ enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
+ int *pb_type = NULL;
+
+ dbg(" Function entry ");
+
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+ pbt = tcore_phonebook_get_selected_type(o);
+ if (req_data->phonebook_type != pbt) {
+ dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
+ _select(o, ur, req_data->phonebook_type);
+ return TCORE_RETURN_SUCCESS;
+ }
+
+ pb_type = calloc(sizeof(enum tel_phonebook_type),VAL_ONE);
+ if(pb_type == NULL) {
+ err("Failed to allocate memory");
+ return TCORE_RETURN_FAILURE;
+ }
+ *pb_type = pbt;
+ dbg("pb_type %d", *pb_type);
+
+ cmd_str = g_strdup_printf("AT+CPBR=%d,%d", req_data->index, req_data->index);
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ hal = tcore_object_get_hal(o);
+ pending = tcore_pending_new(o, VAL_ZERO);
+
+ tcore_pending_set_request_data(pending, VAL_ZERO, req);
+ tcore_pending_set_response_callback(pending, on_response_read_record, (void*)pb_type);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_phonebook_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_update_record(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_phonebook_update_record *req_data = NULL;
+ enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
+
+ dbg(" Function entry ");
+
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+ pbt = tcore_phonebook_get_selected_type(o);
+ if (req_data->phonebook_type != pbt) {
+ dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
+ _select(o, ur, req_data->phonebook_type);
+ return TCORE_RETURN_SUCCESS;
+ }
+
+ cmd_str = g_strdup_printf("AT+CPBW=,\"%s\",%d,\"%s\"", req_data->number, ((PB_TON_INTERNATIONAL == req_data->ton) ? TON_INTERNATIONAL: TON_UNKNOWN), req_data->name);
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ hal = tcore_object_get_hal(o);
+ pending = tcore_pending_new(o, VAL_ZERO);
+
+ tcore_pending_set_request_data(pending, VAL_ZERO, req);
+ tcore_pending_set_response_callback(pending, on_response_update_record, hal);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_phonebook_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_delete_record(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_phonebook_delete_record *req_data;
+ enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
+
+ dbg(" Function entry ");
+
+ if (!o || !ur)
+ return TCORE_RETURN_EINVAL;
+
+ req_data = tcore_user_request_ref_data(ur, NULL);
+ pbt = tcore_phonebook_get_selected_type(o);
+ if (req_data->phonebook_type != pbt) {
+ dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
+ _select(o, ur, req_data->phonebook_type);
+ return TCORE_RETURN_SUCCESS;
+ }
+
+ cmd_str = g_strdup_printf("AT+CPBW=%d", req_data->index);
+ req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
+ dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+ hal = tcore_object_get_hal(o);
+ pending = tcore_pending_new(o, VAL_ZERO);
+
+ tcore_pending_set_request_data(pending, VAL_ZERO, req);
+ tcore_pending_set_response_callback(pending, on_response_delete_record, hal);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_phonebook_message_send, NULL);
+
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static struct tcore_phonebook_operations phonebook_ops = {
+ .get_count = s_get_count,
+ .get_info = s_get_info,
+ .get_usim_info = s_get_usim_info,
+ .read_record = s_read_record,
+ .update_record = s_update_record,
+ .delete_record = s_delete_record,
+};
+
+gboolean s_phonebook_init(TcorePlugin *p, TcoreHal *h)
+{
+ CoreObject *o = NULL;
+
+ dbg("Entry");
+ o = tcore_phonebook_new(p, "phonebook", &phonebook_ops, h);
+ if (!o)
+ return FALSE;
+
+ tcore_object_add_callback(o, "+PBREADY", on_event_phonebook_status, NULL);
+ dbg("Exit");
+ return TRUE;
+}
+
+void s_phonebook_exit(TcorePlugin *p)
+{
+ CoreObject *o = NULL;
+ o = tcore_plugin_ref_core_object(p, "phonebook");
+ if (!o)
+ return;
+
+ tcore_phonebook_free(o);
+}
--- /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);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ (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 TReturn activate_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
+{
+ dbg("Entered");
+ return send_pdp_activate_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("Entered");
+
+ 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 = 0;
+ noti.result = 0;
+ } else {
+ dbg("Response NOK");
+ noti.context_id = cid;
+ noti.state = 3;
+ noti.result = 0;
+ /*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[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)) {
+ return TCORE_RETURN_SUCCESS;
+ }
+ _unable_to_get_pending(co_ps, ps_context);
+ return TCORE_RETURN_FAILURE;
+}
+
+static TReturn define_ps_context(CoreObject *co_ps, CoreObject *ps_context, void *user_data)
+{
+ dbg("Entered");
+
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(co_ps))){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+ return send_define_pdp_context_cmd(co_ps, ps_context);
+}
+
+
+static struct tcore_ps_operations ps_ops = {
+ .define_context = define_ps_context,
+ .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) 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 "s_common.h"
+#include "s_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 s_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));
+ *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);
+
+ 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);
+
+ free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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);
+
+ 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);
+
+ free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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);
+
+ 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 s_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);
+
+ 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 s_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);
+
+ 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);
+
+ free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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);
+
+ 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);
+
+ free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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);
+
+ 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);
+
+ free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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);
+
+ 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);
+
+ free(cmd_str);
+ dbg(" Function exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static struct tcore_sap_operations sap_ops =
+{
+ .connect = s_connect,
+ .disconnect = s_disconnect,
+ .req_status = s_req_status,
+ .set_transport_protocol = s_set_transport_protocol,
+ .set_power = s_set_power,
+ .get_atr = s_get_atr,
+ .transfer_apdu = s_transfer_apdu,
+ .get_cardreader_status = s_get_cardreader_status,
+};
+
+
+gboolean s_sap_init(TcorePlugin *p, TcoreHal *h)
+{
+ CoreObject *o = NULL;
+
+ dbg("Entry");
+ o = tcore_sap_new(p, "sap", &sap_ops, h);
+ if (!o)
+ return FALSE;
+
+ tcore_object_add_callback(o,"+XBCSTAT", on_event_sap_status, NULL);
+ //tcore_object_add_callback(o, "NULL", on_event_sap_disconnect, NULL); //ToDo - Indication not present
+ dbg("Exit");
+ return TRUE;
+}
+
+void s_sap_exit(TcorePlugin *p)
+{
+ CoreObject *o;
+ o = tcore_plugin_ref_core_object(p, "sap");
+ if (!o)
+ return;
+
+ tcore_sap_free(o);
+}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Chandan Swarup Patra <chandan.sp@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 <server.h>
+#include <co_sat.h>
+#include <user_request.h>
+#include <at.h>
+
+#include "s_common.h"
+#include "s_sat.h"
+#define ENVELOPE_CMD_LEN 256
+
+static TReturn s_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)
+{
+ dbg("on_confirmation_modem_message_send - msg out from queue.\n");
+
+ if (result == FALSE) {
+ /* Fail */
+ dbg("SEND FAIL");
+ } else {
+ dbg("SEND OK");
+ }
+}
+
+static gboolean on_response_terminal_response_confirm(CoreObject *o, const void *event_info, void *user_data)
+{
+ dbg("Function Entry");
+ return TRUE;
+ dbg("Function Exit");
+}
+
+static gboolean on_event_sat_proactive_command(CoreObject *o, const void *event_info, void *user_data)
+{
+ struct tcore_sat_proactive_command decoded_data;
+ struct tnoti_sat_proactive_ind proactive_noti;
+ int len_proactive_cmd = 0;
+ GSList *lines = NULL;
+ GSList *tokens = NULL;
+ char *line = NULL;
+ char *hexData = NULL;
+ char *tmp = NULL;
+ char *recordData = NULL;
+
+ dbg("Function Entry");
+
+ memset(&proactive_noti, 0x00, sizeof(struct tnoti_sat_proactive_ind));
+ memset(&decoded_data, 0x00, sizeof(struct tcore_sat_proactive_command));
+ lines = (GSList *) event_info;
+ line = (char *) lines->data;
+ tokens = tcore_at_tok_new(line);
+ if (g_slist_length(tokens) != 1) {
+ dbg("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));
+
+ tmp = util_removeQuotes(hexData);
+ recordData = util_hexStringToBytes(tmp);
+ dbg("recordData: %x", recordData);
+ 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);
+
+ proactive_noti.cmd_number = decoded_data.cmd_num;
+ proactive_noti.cmd_type = decoded_data.cmd_type;
+
+ switch (decoded_data.cmd_type) {
+ case SAT_PROATV_CMD_DISPLAY_TEXT:
+ dbg("decoded command is display text!!");
+ memcpy(&proactive_noti.proactive_ind_data.display_text, &decoded_data.data.display_text, sizeof(struct tel_sat_display_text_tlv));
+ break;
+
+ case SAT_PROATV_CMD_GET_INKEY:
+ dbg("decoded command is get inkey!!");
+ memcpy(&proactive_noti.proactive_ind_data.get_inkey, &decoded_data.data.get_inkey, sizeof(struct tel_sat_get_inkey_tlv));
+ break;
+
+ case SAT_PROATV_CMD_GET_INPUT:
+ dbg("decoded command is get input!!");
+ memcpy(&proactive_noti.proactive_ind_data.get_input, &decoded_data.data.get_input, sizeof(struct tel_sat_get_input_tlv));
+ break;
+
+ case SAT_PROATV_CMD_MORE_TIME:
+ dbg("decoded command is more time!!");
+ memcpy(&proactive_noti.proactive_ind_data.more_time, &decoded_data.data.more_time, sizeof(struct tel_sat_more_time_tlv));
+ break;
+
+ case SAT_PROATV_CMD_PLAY_TONE:
+ dbg("decoded command is play tone!!");
+ memcpy(&proactive_noti.proactive_ind_data.play_tone, &decoded_data.data.play_tone, sizeof(struct tel_sat_play_tone_tlv));
+ break;
+
+ case SAT_PROATV_CMD_SETUP_MENU:
+ dbg("decoded command is SETUP MENU!!");
+ memcpy(&proactive_noti.proactive_ind_data.setup_menu, &decoded_data.data.setup_menu, sizeof(struct tel_sat_setup_menu_tlv));
+ break;
+
+ case SAT_PROATV_CMD_SELECT_ITEM:
+ dbg("decoded command is select item!!");
+ memcpy(&proactive_noti.proactive_ind_data.select_item, &decoded_data.data.select_item, sizeof(struct tel_sat_select_item_tlv));
+ break;
+
+ case SAT_PROATV_CMD_SEND_SMS:
+ dbg("decoded command is send sms!!");
+ memcpy(&proactive_noti.proactive_ind_data.send_sms, &decoded_data.data.send_sms, sizeof(struct tel_sat_send_sms_tlv));
+ break;
+
+ case SAT_PROATV_CMD_SEND_SS:
+ dbg("decoded command is send ss!!");
+ memcpy(&proactive_noti.proactive_ind_data.send_ss, &decoded_data.data.send_ss, sizeof(struct tel_sat_send_ss_tlv));
+ break;
+
+ case SAT_PROATV_CMD_SEND_USSD:
+ dbg("decoded command is send ussd!!");
+ memcpy(&proactive_noti.proactive_ind_data.send_ussd, &decoded_data.data.send_ussd, sizeof(struct tel_sat_send_ussd_tlv));
+ break;
+
+ case SAT_PROATV_CMD_SETUP_CALL:
+ dbg("decoded command is setup call!!");
+ memcpy(&proactive_noti.proactive_ind_data.setup_call, &decoded_data.data.setup_call, sizeof(struct tel_sat_setup_call_tlv));
+ break;
+
+ case SAT_PROATV_CMD_REFRESH:
+ dbg("decoded command is refresh");
+ memcpy(&proactive_noti.proactive_ind_data.refresh, &decoded_data.data.refresh, sizeof(struct tel_sat_refresh_tlv));
+ break;
+
+ case SAT_PROATV_CMD_PROVIDE_LOCAL_INFO:
+ dbg("decoded command is provide local info");
+ memcpy(&proactive_noti.proactive_ind_data.provide_local_info, &decoded_data.data.provide_local_info, sizeof(struct tel_sat_provide_local_info_tlv));
+ break;
+
+ case SAT_PROATV_CMD_SETUP_EVENT_LIST:
+ dbg("decoded command is setup event list!!");
+ memcpy(&proactive_noti.proactive_ind_data.setup_event_list, &decoded_data.data.setup_event_list, sizeof(struct tel_sat_setup_event_list_tlv));
+ // setup_event_rsp_get(o, &decoded_data.data.setup_event_list);
+ break;
+
+ case SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT:
+ dbg("decoded command is setup idle mode text");
+ memcpy(&proactive_noti.proactive_ind_data.setup_idle_mode_text, &decoded_data.data.setup_idle_mode_text, sizeof(struct tel_sat_setup_idle_mode_text_tlv));
+ break;
+
+ case SAT_PROATV_CMD_SEND_DTMF:
+ dbg("decoded command is send dtmf");
+ memcpy(&proactive_noti.proactive_ind_data.send_dtmf, &decoded_data.data.send_dtmf, sizeof(struct tel_sat_send_dtmf_tlv));
+ break;
+
+ case SAT_PROATV_CMD_LANGUAGE_NOTIFICATION:
+ dbg("decoded command is language notification");
+ memcpy(&proactive_noti.proactive_ind_data.language_notification, &decoded_data.data.language_notification, sizeof(struct tel_sat_language_notification_tlv));
+ break;
+
+ case SAT_PROATV_CMD_LAUNCH_BROWSER:
+ dbg("decoded command is launch browser");
+ memcpy(&proactive_noti.proactive_ind_data.launch_browser, &decoded_data.data.launch_browser, sizeof(struct tel_sat_launch_browser_tlv));
+ break;
+
+ case SAT_PROATV_CMD_OPEN_CHANNEL:
+ dbg("decoded command is open channel!!");
+ memcpy(&proactive_noti.proactive_ind_data.open_channel, &decoded_data.data.open_channel, sizeof(struct tel_sat_open_channel_tlv));
+ break;
+
+ case SAT_PROATV_CMD_CLOSE_CHANNEL:
+ dbg("decoded command is close channel!!");
+ memcpy(&proactive_noti.proactive_ind_data.close_channel, &decoded_data.data.close_channel, sizeof(struct tel_sat_close_channel_tlv));
+ break;
+
+ case SAT_PROATV_CMD_RECEIVE_DATA:
+ dbg("decoded command is receive data!!");
+ memcpy(&proactive_noti.proactive_ind_data.receive_data, &decoded_data.data.receive_data, sizeof(struct tel_sat_receive_channel_tlv));
+ break;
+
+ case SAT_PROATV_CMD_SEND_DATA:
+ dbg("decoded command is send data!!");
+ memcpy(&proactive_noti.proactive_ind_data.send_data, &decoded_data.data.send_data, sizeof(struct tel_sat_send_channel_tlv));
+ break;
+
+ case SAT_PROATV_CMD_GET_CHANNEL_STATUS:
+ dbg("decoded command is get channel status!!");
+ memcpy(&proactive_noti.proactive_ind_data.get_channel_status, &decoded_data.data.get_channel_status, sizeof(struct tel_sat_get_channel_status_tlv));
+ break;
+
+ default:
+ dbg("wrong input");
+ break;
+ }
+ if ((decoded_data.cmd_type == SAT_PROATV_CMD_REFRESH) || (decoded_data.cmd_type == SAT_PROATV_CMD_SETUP_EVENT_LIST)) {
+ /*Not supported*/
+ dbg("Not suported Proactive command");
+ return FALSE;
+ }
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAT_PROACTIVE_CMD,
+ sizeof(struct tnoti_sat_proactive_ind), &proactive_noti);
+ tcore_at_tok_free(tokens);
+ dbg("Function Exit");
+ return TRUE;
+}
+
+static void on_response_envelop_cmd(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *resp = data;
+ UserRequest *ur = NULL;
+ CoreObject *o = NULL;
+ const struct treq_sat_envelop_cmd_data *req_data = NULL;
+ GSList *tokens = NULL;
+ struct tresp_sat_envelop_data res;
+ const char *line = NULL;
+ const char *env_res = NULL;
+ int sw2 = -1;
+
+ ur = tcore_pending_ref_user_request(p);
+ req_data = tcore_user_request_ref_data(ur, NULL);
+ o = tcore_pending_ref_core_object(p);
+
+ if (!req_data) {
+ dbg("request data is NULL");
+ return;
+ }
+ memset(&res, 0, sizeof(struct tresp_sat_envelop_data));
+
+ res.sub_cmd = req_data->sub_cmd;
+
+ 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;
+ }
+ }
+ env_res = g_slist_nth_data(tokens, 0);
+ res.result = 0x8000;
+ res.envelop_resp = ENVELOPE_SUCCESS;
+ dbg("RESPONSE OK 3");
+ if (NULL != g_slist_nth_data(tokens, 1)) {
+ sw2 = atoi(g_slist_nth_data(tokens, 1));
+ dbg("RESPONSE OK 4");
+ if (sw2 == 0) {
+ dbg("RESPONSE OK 5");
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAT_SESSION_END, 0, NULL);
+ }
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ res.result = -1;
+ res.envelop_resp = ENVELOPE_FAILED;
+ }
+
+ if (ur) {
+ tcore_user_request_send_response(ur, TRESP_SAT_REQ_ENVELOPE, sizeof(struct tresp_sat_envelop_data), &res);
+ }
+ tcore_at_tok_free(tokens);
+ dbg(" Function exit");
+}
+
+
+static void on_response_terminal_response(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = NULL;
+ CoreObject *o = NULL;
+ const TcoreATResponse *resp = data;
+ gpointer tmp = NULL;
+
+ dbg("Function Entry");
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ dbg(" resp->success = %d", resp->success);
+ ur = tcore_pending_ref_user_request(p);
+ tmp = (gpointer) tcore_user_request_ref_communicator(ur);
+ if (!ur || !tmp) {
+ dbg("error - current ur is NULL");
+ return;
+ }
+
+ o = tcore_pending_ref_core_object(p);
+ if (!o)
+ dbg("error - current sat core is NULL");
+ tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_SAT_SESSION_END, 0, NULL);
+ }
+ dbg("Function Exit");
+}
+
+static TReturn s_envelope(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_sat_envelop_cmd_data *req_data = NULL;
+ int envelope_cmd_len = 0;
+ char envelope_cmd[ENVELOPE_CMD_LEN];
+ int count = 0;
+ char envelope_cmdhex[ENVELOPE_CMD_LEN * 2];
+ char *pbuffer = NULL;
+
+ dbg("Function Entry");
+ memset(&envelope_cmdhex, 0x00, sizeof(envelope_cmdhex));
+ 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);
+
+ envelope_cmd_len = tcore_sat_encode_envelop_cmd(req_data, (char *) envelope_cmd);
+
+ dbg("envelope_cmd_len %d", envelope_cmd_len);
+ if (envelope_cmd_len == 0) {
+ 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]);
+ 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);
+ 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_envelop_cmd, hal);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_sat_message_send, NULL);
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+ dbg("Function Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_terminal_response(CoreObject *o, UserRequest *ur)
+{
+ TcoreHal *hal = NULL;
+ TcoreATRequest *req = NULL;
+ TcorePending *pending = NULL;
+ char *cmd_str = NULL;
+ const struct treq_sat_terminal_rsp_data *req_data = 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);
+
+ proactive_resp_len = tcore_sat_encode_terminal_response(req_data, (char *) proactive_resp);
+ dbg("proactive_resp %s", proactive_resp);
+ dbg("proactive_resp length %d", strlen(proactive_resp));
+ if (proactive_resp_len == 0) {
+ return TCORE_RETURN_EINVAL;
+ }
+ hexString = calloc((proactive_resp_len * 2) + 1, 1);
+
+ for (i = 0; i < proactive_resp_len * 2; i += 2) {
+ char value = 0;
+ value = (proactive_resp[i / 2] & 0xf0) >> 4;
+ if (value < 0xA)
+ hexString[i] = ((proactive_resp[i / 2] & 0xf0) >> 4) + '0';
+ else
+ hexString[i] = ((proactive_resp[i / 2] & 0xf0) >> 4) + 'A' - 10;
+
+ value = proactive_resp[i / 2] & 0x0f;
+ if (value < 0xA)
+ hexString[i + 1] = (proactive_resp[i / 2] & 0x0f) + '0';
+ else
+ hexString[i + 1] = (proactive_resp[i / 2] & 0x0f) + 'A' - 10;
+ }
+
+ dbg("hexString %s", hexString);
+ cmd_str = g_strdup_printf("AT+SATR=\"%s\"", hexString);
+
+ 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_terminal_response, hal);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_sat_message_send, NULL);
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+ dbg("Function Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static struct tcore_sat_operations sat_ops = {
+ .envelope = s_envelope,
+ .terminal_response = s_terminal_response,
+};
+
+gboolean s_sat_init(TcorePlugin *p, TcoreHal *h)
+{
+ 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);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void s_sat_exit(TcorePlugin *p)
+{
+ CoreObject *o = NULL;
+ o = tcore_plugin_ref_core_object(p, "sat");
+ if (!o)
+ return;
+ tcore_sat_free(o);
+}
--- /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 tel_sim_mbi_list mbi_list;
+ struct tel_sim_mb_number mb_list[SIM_MSP_CNT_MAX*5];
+ 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!");
+ tcore_at_tok_free(tokens);
+ 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);
+ 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);
+ tcore_at_tok_free(tokens);
+ 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);
+ 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);
+ 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 = NULL;
+ struct tel_sim_service_table *svct = NULL;
+ struct tel_sim_ecc *ecc = NULL;
+ struct tel_sim_msisdn *msisdn = NULL;
+ struct tel_sim_opl *opl = NULL;
+ struct tel_sim_pnn *pnn = NULL;
+ struct tel_sim_cfis *cf = NULL;
+ struct tel_sim_mbi *mbi = NULL;
+ struct tel_sim_mw *mw = NULL;
+ 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);
+ imsi = calloc(sizeof(struct tel_sim_imsi),1);
+ 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);
+ }
+ if(imsi)
+ free(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_SST: //EF UST has same address
+ svct = calloc(sizeof(struct tel_sim_service_table),1);
+ if(tcore_sim_get_type(co_sim) == SIM_TYPE_GSM) {
+ dr = tcore_sim_decode_sst(&svct->sst , (unsigned char *) res, res_len);
+ }else if(tcore_sim_get_type(co_sim) == SIM_TYPE_USIM) {
+ dr = tcore_sim_decode_ust(&svct->ust , (unsigned char *) res, res_len);
+ } else {
+ dbg("err not handled tcore_sim_get_type(o)[%d] in here",tcore_sim_get_type(co_sim));
+ }
+ if (dr == FALSE) {
+ dbg("SST/UST decoding failed");
+ } else {
+ tcore_sim_set_service_table(co_sim, svct);
+ }
+ if(svct)
+ free(svct);
+ 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) {
+ ecc = calloc(sizeof(struct tel_sim_ecc),1);
+ dbg("decode w/ index [%d]", file_meta->current_index);
+ 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++;
+ }
+ if(ecc)
+ free(ecc);
+ } 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);
+ msisdn = calloc(sizeof(struct tel_sim_msisdn),1);
+ 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++;
+ }
+ if(msisdn)
+ free(msisdn);
+ break;
+
+ case SIM_EF_OPL:
+ dbg("decode w/ index [%d]", file_meta->current_index);
+ opl = calloc(sizeof(struct tel_sim_opl),1);
+ 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);
+ pnn = calloc(sizeof(struct tel_sim_pnn),1);
+ 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], pnn, sizeof(struct tel_sim_pnn));
+ file_meta->files.data.pnn.pnn_count++;
+ }
+ if(pnn)
+ free(pnn);
+ 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_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
+ mbi = calloc(sizeof(struct tel_sim_mbi),1);
+ dr = tcore_sim_decode_mbi(mbi, (unsigned char *) res, res_len);
+ if (dr == TRUE) {
+ memcpy( &file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count], mbi, sizeof(struct tel_sim_mbi) );
+ file_meta->mbi_list.profile_count++;
+ dbg("mbi count[%d]", file_meta->mbi_list.profile_count);
+ dbg("voice_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].voice_index);
+ dbg("fax_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].fax_index);
+ dbg("email_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].email_index);
+ dbg("other_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].other_index);
+ dbg("video_index[%d]", file_meta->mbi_list.mbi[file_meta->mbi_list.profile_count -1].video_index);
+ }
+ if(mbi)
+ free(mbi);
+ break;
+
+ case SIM_EF_CPHS_MAILBOX_NUMBERS: // linear type
+ case SIM_EF_MBDN: //linear type
+ dr = tcore_sim_decode_xdn(&file_meta->mb_list[file_meta->current_index-1].number_info, (unsigned char *) res, res_len);
+ file_meta->mb_list[file_meta->current_index-1].rec_index = file_meta->current_index;
+ break;
+
+ case SIM_EF_CPHS_VOICE_MSG_WAITING: // transparent type
+ dr = tcore_sim_decode_vmwf(&file_meta->files.data.mw.cphs_mw, (unsigned char *) res, res_len);
+ break;
+
+ case SIM_EF_USIM_MWIS: //linear type
+ mw = calloc(sizeof(struct tel_sim_mw),1);
+ dr = tcore_sim_decode_mwis(mw, (unsigned char *) res, res_len);
+ if (dr == TRUE) {
+ memcpy( &file_meta->files.data.mw.mw_list.mw[file_meta->files.data.mw.mw_list.profile_count], mw, sizeof(struct tel_sim_mw) );
+ file_meta->files.data.mw.mw_list.mw[file_meta->files.data.mw.mw_list.profile_count].rec_index = file_meta->current_index;
+ file_meta->files.data.mw.mw_list.profile_count++;
+ }
+ if(mw)
+ free(mw);
+ break;
+
+ case SIM_EF_CPHS_CALL_FORWARD_FLAGS: //transparent type
+ dr = tcore_sim_decode_cff(&file_meta->files.data.cf.cphs_cf, (unsigned char *) res, res_len);
+ break;
+
+ case SIM_EF_USIM_CFIS: //linear type
+ cf = calloc(sizeof(struct tel_sim_cfis),1);
+ dr = tcore_sim_decode_cfis(cf, (unsigned char *) res, res_len);
+ if (dr == TRUE) {
+ memcpy( &file_meta->files.data.cf.cf_list.cf[file_meta->files.data.cf.cf_list.profile_count], cf, sizeof(struct tel_sim_cfis) );
+ file_meta->files.data.cf.cf_list.cf[file_meta->files.data.cf.cf_list.profile_count].rec_index = file_meta->current_index;
+ file_meta->files.data.cf.cf_list.profile_count++;
+ }
+ if(cf)
+ 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*)&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_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(&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;
+
+ 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]", file_meta->file_id);
+ dr = 0;
+ break;
+ }
+ } else {
+ rt = _decode_status_word(sw1, sw2);
+ file_meta->files.result = rt;
+ }
+ free(tmp);
+ free(res);
+ 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;
+ TReturn ret = TCORE_RETURN_FAILURE;
+ 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);
+
+ 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);
+ ret = tcore_hal_send_request(hal, pending);
+ if (TCORE_RETURN_SUCCESS != ret) {
+ tcore_user_request_free(ur);
+ }
+ 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_data resp_cf = {0, };
+ struct tresp_sim_set_data 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_data), &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_data), &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) {
+ 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);
+ return;
+ }
+ res.apdu_resp_length = atoi(g_slist_nth_data(tokens, 0)) / 2;
+
+ tmp = util_removeQuotes(g_slist_nth_data(tokens, 1));
+ decoded_data = util_hexStringToBytes(tmp);
+
+ memcpy((char *) res.apdu_resp, decoded_data, res.apdu_resp_length);
+ free(tmp);
+ free(decoded_data);
+ }
+ } 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);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ 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);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ 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);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ 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);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ 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);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ 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);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ 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);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+ 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;
+
+ if(FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))){
+ dbg("cp not ready/n");
+ 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;
+
+ 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);
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ 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_cphs_cf*)&cf->cphs_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_cfis*)&cf->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 apdu_len = 0;
+ int result = 0;
+ const struct treq_sim_transmit_apdu *req_data;
+
+ dbg(" Function entry ");
+
+ 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 (!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);
+ apdu_len = strlen(apdu);
+ cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", apdu_len, 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,
+ .get_atr = NULL,
+ .req_authentication = NULL,
+};
+
+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);
+}
--- /dev/null
+/*
+ * tel-plugin-imc
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Madhavi Akella <madhavi.a@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 <stdint.h>
+
+#include <glib.h>
+
+#include <tcore.h>
+#include <hal.h>
+#include <core_object.h>
+#include <plugin.h>
+#include <queue.h>
+#include <co_sms.h>
+#include <co_sim.h>
+#include <user_request.h>
+#include <storage.h>
+#include <server.h>
+#include <at.h>
+#include <plugin.h>
+
+#include "common/TelErr.h"
+#include "s_common.h"
+#include "s_sms.h"
+
+/*=============================================================
+ 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
+
+/*=============================================================
+ 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 */
+
+/*=============================================================
+ CBMI Selection
+==============================================================*/
+#define SMS_CBMI_SELECTED_SOME 0x02 /* Some CBMIs are selected */
+#define SMS_CBMI_SELECTED_ALL 0x01 /* All CBMIs are selected */
+
+/*=============================================================
+ 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 */
+
+/*=============================================================
+ Memory Status
+==============================================================*/
+#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
+
+/*=============================================================
+ String Preprocessor
+==============================================================*/
+#define CR '\r' /* Carriage Return */
+
+/*=============================================================
+ Developer
+==============================================================*/
+#define SMS_SWAPBYTES16(x) (((x) & 0xffff0000) | (((x) & 0x0000ff00) >> 8) | (((x) & 0x000000ff) << 8))
+
+void print_glib_list_elem(gpointer data, gpointer user_data);
+
+static void on_response_class2_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data);
+
+
+gboolean util_byte_to_hex(const char *byte_pdu, char *hex_pdu, int num_bytes);
+
+void print_glib_list_elem(gpointer data, gpointer user_data)
+{
+ char *item = (char *)data;
+
+ dbg("item: [%s]", item);
+}
+
+/*=============================================================
+ Send Callback
+==============================================================*/
+static void on_confirmation_sms_message_send(TcorePending *p, gboolean result, void *user_data)
+{
+ dbg("Entered Function. Request message out from queue");
+
+ dbg("TcorePending: [%p]", p);
+ dbg("result: [%02x]", result);
+ dbg("user_data: [%p]", user_data);
+
+ if (result == TRUE) {
+ dbg("SEND OK");
+ } else { /* Failed */
+ dbg("SEND NOK");
+ }
+
+ dbg("Exiting Function. Nothing to return");
+}
+
+/*=============================================================
+ Utilities
+==============================================================*/
+static void util_sms_free_memory(void *sms_ptr)
+{
+ dbg("Entry");
+
+ if (NULL != sms_ptr) {
+ dbg("Freeing memory location: [%p]", sms_ptr);
+ free(sms_ptr);
+ sms_ptr = NULL;
+ } else {
+ err("Invalid memory location. Nothing to do.");
+ }
+
+ dbg("Exit");
+}
+
+
+static int util_sms_decode_smsParameters(unsigned char *incoming, unsigned int length, struct telephony_sms_Params *params)
+{
+ int alpha_id_len = 0;
+ int i = 0;
+ int nOffset = 0;
+
+ dbg(" RecordLen = %d", length);
+
+ if(incoming == NULL || params == NULL)
+ return FALSE;
+
+ alpha_id_len = length -SMS_SMSP_PARAMS_MAX_LEN;
+
+ if (alpha_id_len > 0) {
+ if (alpha_id_len > SMS_SMSP_ALPHA_ID_LEN_MAX) {
+ alpha_id_len = SMS_SMSP_ALPHA_ID_LEN_MAX;
+ }
+
+ for (i = 0; i < alpha_id_len; i++) {
+ if (0xff == incoming[i]) {
+ dbg(" found");
+ break;
+ }
+ }
+
+ memcpy(params->szAlphaId, incoming, i);
+
+ params->alphaIdLen = i;
+
+ dbg(" Alpha id length = %d", i);
+ } else {
+ params->alphaIdLen = 0;
+ dbg(" Alpha id length is zero");
+ }
+
+ params->paramIndicator = incoming[alpha_id_len];
+
+ dbg(" Param Indicator = %02x", params->paramIndicator);
+
+ if ((params->paramIndicator & SMSPValidDestAddr) == 0) {
+ nOffset = nDestAddrOffset;
+
+ if (0x00 == incoming[alpha_id_len + nOffset] || 0xff == incoming[alpha_id_len + nOffset]) {
+ params->tpDestAddr.dialNumLen = 0;
+
+ dbg("DestAddr Length is 0");
+ } else {
+ if (0 < (int) incoming[alpha_id_len + nOffset]) {
+ params->tpDestAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
+
+ if (params->tpDestAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
+ params->tpDestAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
+ } else {
+ params->tpDestAddr.dialNumLen = 0;
+ }
+
+ params->tpDestAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
+ params->tpDestAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
+
+ memcpy(params->tpDestAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpDestAddr.dialNumLen));
+
+ dbg("Dest TON is %d", params->tpDestAddr.typeOfNum);
+ dbg("Dest NPI is %d", params->tpDestAddr.numPlanId);
+ dbg("Dest Length = %d", params->tpDestAddr.dialNumLen);
+ dbg("Dest Addr = %s", params->tpDestAddr.diallingNum);
+ }
+ } else {
+ params->tpDestAddr.dialNumLen = 0;
+ }
+
+ if ((params->paramIndicator & SMSPValidSvcAddr) == 0) {
+ nOffset = nSCAAddrOffset;
+
+ if (0x00 == (int) incoming[alpha_id_len + nOffset] || 0xff == (int) incoming[alpha_id_len + nOffset]) {
+ params->tpSvcCntrAddr.dialNumLen = 0;
+
+ dbg(" SCAddr Length is 0");
+ } else {
+ if (0 < (int) incoming[alpha_id_len + nOffset]) {
+ params->tpSvcCntrAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
+
+ if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
+ params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
+
+ params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
+ params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
+
+ memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpSvcCntrAddr.dialNumLen));
+
+ dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
+ dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
+ dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
+
+ for (i = 0; i < (int) params->tpSvcCntrAddr.dialNumLen; i++)
+ dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
+ } else {
+ params->tpSvcCntrAddr.dialNumLen = 0;
+ }
+ }
+ } else if ((0x00 < (int) incoming[alpha_id_len + nSCAAddrOffset] && (int) incoming[alpha_id_len + nSCAAddrOffset] <= 12)
+ || 0xff != (int) incoming[alpha_id_len + nSCAAddrOffset]) {
+ nOffset = nSCAAddrOffset;
+
+ if (0x00 == (int) incoming[alpha_id_len + nOffset] || 0xff == (int) incoming[alpha_id_len + nOffset]) {
+ params->tpSvcCntrAddr.dialNumLen = 0;
+ dbg("SCAddr Length is 0");
+ } else {
+ if (0 < (int) incoming[alpha_id_len + nOffset]) {
+ params->tpSvcCntrAddr.dialNumLen = (int) (incoming[alpha_id_len + nOffset] - 1);
+
+ params->tpSvcCntrAddr.dialNumLen = incoming[alpha_id_len + nOffset] - 1;
+
+ if (params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN)
+ params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN;
+
+ params->tpSvcCntrAddr.numPlanId = incoming[alpha_id_len + (++nOffset)] & 0x0f;
+ params->tpSvcCntrAddr.typeOfNum = (incoming[alpha_id_len + nOffset] & 0x70) >> 4;
+
+ memcpy(params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)],
+ (params->tpSvcCntrAddr.dialNumLen));
+
+ dbg("SCAddr Length = %d ", params->tpSvcCntrAddr.dialNumLen);
+ dbg("SCAddr TON is %d", params->tpSvcCntrAddr.typeOfNum);
+ dbg("SCAddr NPI is %d", params->tpSvcCntrAddr.numPlanId);
+
+ for (i = 0; i < (int) params->tpSvcCntrAddr.dialNumLen; i++)
+ dbg("SCAddr = %d [%02x]", i, params->tpSvcCntrAddr.diallingNum[i]);
+ } else {
+ params->tpSvcCntrAddr.dialNumLen = 0;
+ }
+ }
+ } else {
+ params->tpSvcCntrAddr.dialNumLen = 0;
+ }
+
+ if ((params->paramIndicator & SMSPValidPID) == 0 && (alpha_id_len + nPIDOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
+ params->tpProtocolId = incoming[alpha_id_len + nPIDOffset];
+ }
+ if ((params->paramIndicator & SMSPValidDCS) == 0 && (alpha_id_len + nDCSOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
+ params->tpDataCodingScheme = incoming[alpha_id_len + nDCSOffset];
+ }
+ if ((params->paramIndicator & SMSPValidVP) == 0 && (alpha_id_len + nVPOffset) < MAX_GSM_SMS_PARAM_RECORD_SIZE) {
+ params->tpValidityPeriod = incoming[alpha_id_len + nVPOffset];
+ }
+
+ dbg(" Alpha Id(Len) = %d", (int) params->alphaIdLen);
+
+ 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);
+
+ return TRUE;
+}
+
+
+/*=============================================================
+ Notifications
+==============================================================*/
+static gboolean on_event_sms_ready_status(CoreObject *o, 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;
+
+ 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;
+ char *line = NULL, *cmd_str = NULL;
+ int index = 0, mem_type = 0;
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+ TcorePending *pending = NULL;
+
+ dbg("Entered Function");
+
+ lines = (GSList *)event_info;
+ line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
+
+ dbg("Line 1: [%s]", line);
+
+ if (!line) {
+ err("Line 1 is invalid");
+ return FALSE;
+ }
+
+ tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
+ mem_type = atoi(g_slist_nth_data(tokens, 0)); // Type of Memory stored
+ index = atoi((char *) g_slist_nth_data(tokens, 1));
+
+ hal = tcore_object_get_hal(obj);
+ if (NULL == hal) {
+ err("NULL input. Unable to proceed");
+ dbg("readMsg: hal: [%p]", hal);
+
+ dbg("Exit");
+ return TCORE_RETURN_EINVAL;
+ }
+
+ 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);
+ 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;
+ }
+
+ 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_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)
+ 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);
+
+ int rtn = -1;
+ GSList *tokens = NULL;
+ GSList *lines = NULL;
+ char *line = NULL;
+ int pdu_len = 0, no_of_tokens = 0;
+ unsigned char *bytePDU = NULL;
+ struct tnoti_sms_umts_msg gsmMsgInfo;
+ int sca_length = 0;
+
+ dbg("Entered Function");
+
+ lines = (GSList *)event_info;
+ memset(&gsmMsgInfo, 0x00, sizeof(struct tnoti_sms_umts_msg));
+
+ if (2 != g_slist_length(lines)) {
+ err("Invalid number of lines for +CMT. Must be 2");
+ return FALSE;
+ }
+
+ line = (char *)g_slist_nth_data(lines, 0); /* Fetch Line 1 */
+
+ dbg("Line 1: [%s]", line);
+
+ if (!line) {
+ err("Line 1 is invalid");
+ return FALSE;
+ }
+
+ tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
+
+ no_of_tokens = g_slist_length(tokens);
+
+ 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 */
+ } 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 */
+ }
+
+ line = (char *)g_slist_nth_data(lines, 1); /* Fetch Line 2 */
+
+ dbg("Line 2: [%s]", line);
+
+ if (!line) {
+ err("Line 2 is invalid");
+ return FALSE;
+ }
+
+ /* Convert to Bytes */
+ bytePDU = (unsigned char *)util_hexStringToBytes(line);
+
+ sca_length = bytePDU[0];
+
+ dbg("SCA length = %d", sca_length);
+
+ 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);
+ }
+
+ util_hex_dump(" ", strlen(line)/2, bytePDU);
+ util_hex_dump(" ", sca_length, gsmMsgInfo.msgInfo.sca);
+ 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);
+
+ if(tokens)
+ tcore_at_tok_free(tokens);
+
+ 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,};
+
+ int rtn = -1 ,memoryStatus = -1;
+ GSList *tokens=NULL;
+ GSList *lines=NULL;
+ char *line = NULL , *pResp = NULL;
+
+ dbg(" Entry");
+
+ lines = (GSList *)event_info;
+ if (1 != g_slist_length(lines)) {
+ dbg("unsolicited msg but multiple line");
+ }
+
+ line = (char*)(lines->data);
+
+ if (line) {
+ dbg("Response OK");
+ tokens = tcore_at_tok_new(line);
+ pResp = g_slist_nth_data(tokens, 0);
+
+ if (pResp) {
+ memoryStatus = atoi(pResp);
+ 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);
+ }
+ tcore_at_tok_free(tokens);
+ }else {
+ dbg("Response NOK");
+ }
+
+ dbg(" Exit ");
+ return TRUE;
+}
+
+static gboolean on_event_sms_cb_incom_msg(CoreObject *o, const void *event_info, void *user_data)
+{
+ //+CBM: <length><CR><LF><pdu>
+
+ struct tnoti_sms_cellBroadcast_msg cbMsgInfo;
+
+ 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;
+
+ memset(&cbMsgInfo, 0, sizeof(struct tnoti_sms_cellBroadcast_msg));
+
+ line = (char *)(lines->data);
+
+ if (line != NULL) {
+ dbg("Response OK");
+ dbg("Noti line is %s",line);
+ tokens = tcore_at_tok_new(line); /* Split Line 1 into tokens */
+
+ pResp = g_slist_nth_data(tokens, 0);
+ if (pResp) {
+ length = atoi(pResp);
+ } else {
+ dbg("token 0 is null");
+ }
+
+ pdu = g_slist_nth_data(lines, 1);
+ if (pdu != NULL) {
+ cbMsgInfo.cbMsg.length = length;
+ 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)) {
+ 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);
+ } else {
+ dbg("Invalid Message Length");
+ }
+ } else {
+ dbg("Recieved NULL pdu");
+ }
+ } else {
+ dbg("Response NOK");
+ }
+
+ dbg(" Return value [%d]",rtn);
+
+ if(tokens)
+ tcore_at_tok_free(tokens);
+
+ return TRUE;
+}
+
+
+/*=============================================================
+ 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,};
+ UserRequest *ur = NULL;
+ const TcoreATResponse *atResp = data;
+
+ int rtn = -1;
+ int index = (int) user_data;
+
+ dbg(" Func Entrance");
+
+ ur = tcore_pending_ref_user_request(p);
+ if (atResp->success) {
+ dbg("Response OK");
+ delMsgInfo.index = index;
+ delMsgInfo.result = SMS_SENDSMS_SUCCESS;
+ } else {
+ dbg("Response NOK");
+ delMsgInfo.index = index;
+ delMsgInfo.result = SMS_DEVICE_FAILURE;
+ }
+
+ rtn = 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,};
+ UserRequest *ur = NULL;
+ const TcoreATResponse *atResp = data;
+ GSList *tokens = NULL;
+ char *line = NULL;
+ char *pResp = NULL;
+ int rtn = -1;
+
+ ur = tcore_pending_ref_user_request(p);
+ if (atResp->success) {
+ dbg("Response OK");
+ if (atResp->lines) {
+ 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.result = SMS_SENDSMS_SUCCESS;
+ } else {
+ dbg("No Tokens");
+ saveMsgInfo.index = -1;
+ saveMsgInfo.result = SMS_DEVICE_FAILURE;
+ }
+ tcore_at_tok_free(tokens);
+ }
+ } else {
+ dbg("Response NOK");
+ saveMsgInfo.index = -1;
+ saveMsgInfo.result = SMS_DEVICE_FAILURE;
+ }
+
+ rtn = tcore_user_request_send_response(ur, TRESP_SMS_SAVE_MSG, sizeof(struct tresp_sms_save_msg), &saveMsgInfo);
+ dbg("Return value [%d]", rtn);
+ return;
+}
+
+static void on_response_send_umts_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *at_response = data;
+ struct tresp_sms_send_umts_msg resp_umts;
+ UserRequest *user_req = NULL;
+
+ int msg_ref = 0;
+ GSList *tokens = NULL;
+ char *gslist_line = NULL, *line_token = NULL;
+
+ dbg("Entry");
+
+ user_req = tcore_pending_ref_user_request(pending);
+
+ if (NULL == user_req) {
+ err("No user request");
+
+ dbg("Exit");
+ return;
+ }
+
+ memset(&resp_umts, 0x00, sizeof(resp_umts));
+ resp_umts.result = SMS_DEVICE_FAILURE;
+
+ 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;
+ dbg("gslist_line: [%s]", gslist_line);
+
+ tokens = tcore_at_tok_new(gslist_line); //extract tokens
+
+ line_token = g_slist_nth_data(tokens, 0);
+ if (line_token != NULL) {
+ msg_ref = atoi(line_token);
+ dbg("Message Reference: [%d]", msg_ref);
+
+ resp_umts.result = SMS_SENDSMS_SUCCESS;
+ } else {
+ dbg("No Message Reference received");
+ }
+ tcore_at_tok_free(tokens);
+ } else { // no lines in at_response
+ dbg("No lines");
+ }
+ } else { // failure
+ dbg("Response NOK");
+ }
+
+ tcore_user_request_send_response(user_req, TRESP_SMS_SEND_UMTS_MSG, sizeof(resp_umts), &resp_umts);
+
+ dbg("Exit");
+ return;
+}
+
+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;
+ char *gslist_line = NULL, *line_token = NULL, *hex_pdu = NULL;
+ int pdu_len = 0, rtn = 0;
+ unsigned char *bytePDU = NULL;
+ struct tnoti_sms_umts_msg gsmMsgInfo;
+ 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
+
+ if (at_response->success > 0) {
+ dbg("Response OK");
+ if (at_response->lines) {
+ //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
+
+ 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;
+
+ dbg("gslist_line: [%s]", gslist_line);
+
+ //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
+
+ hex_pdu = g_slist_nth_data(tokens, 0); //Fetch SMS PDU
+
+ //free the consumed token
+ tcore_at_tok_free(tokens);
+ } else {
+ dbg("No lines");
+ }
+ } else {
+ err("Response NOK");
+ }
+
+ /* Convert to Bytes */
+ bytePDU = (unsigned char *)util_hexStringToBytes(hex_pdu);
+
+ sca_length = bytePDU[0];
+
+ dbg("SCA length = %d", sca_length);
+
+ 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);
+ }
+
+ 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);
+
+ 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);
+
+ free(bytePDU);
+
+ dbg("Exit");
+ return;
+}
+
+static void on_response_read_msg(TcorePending *pending, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *at_response = data;
+ struct tresp_sms_read_msg resp_read_msg;
+ UserRequest *user_req = 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;
+
+ dbg("Entry");
+ dbg("index: [%d]", index);
+ 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) {
+ err("No user request");
+
+ dbg("Exit");
+ return;
+ }
+
+ memset(&resp_read_msg, 0x00, sizeof(resp_read_msg));
+ resp_read_msg.result = SMS_PHONE_FAILURE;
+
+ if (at_response->success > 0) {
+ dbg("Response OK");
+ if (at_response->lines) {
+ //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
+
+ 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);
+ 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;
+ }
+ }
+
+ 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
+ if (line_token != NULL) {
+ pdu_len = atoi(line_token);
+ dbg("Length: [%d]", pdu_len);
+ }
+
+ //fetch second line
+ hex_pdu = (char *) at_response->lines->next->data;
+
+ dbg("EF-SMS PDU: [%s]", hex_pdu);
+
+ //free the consumed token
+ tcore_at_tok_free(tokens);
+
+ if (NULL != hex_pdu) {
+ util_hex_dump(" ", sizeof(hex_pdu), (void *)hex_pdu);
+
+ byte_pdu = util_hexStringToBytes(hex_pdu);
+
+ sca_length = (int)byte_pdu[0];
+
+ 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 ((resp_read_msg.dataInfo.smsData.msgLength > 0)
+ && (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);
+
+ resp_read_msg.result = SMS_SUCCESS;
+ } else {
+ 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);
+
+ 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);
+
+ resp_read_msg.result = SMS_SUCCESS;
+ } else {
+ dbg("Invalid Message Length");
+ resp_read_msg.result = SMS_INVALID_PARAMETER_FORMAT;
+ }
+ }
+ free(byte_pdu);
+ }else {
+ dbg("NULL PDU");
+ }
+ }else {
+ dbg("No lines");
+ }
+ } else {
+ err("Response NOK");
+ }
+
+ tcore_user_request_send_response(user_req, TRESP_SMS_READ_MSG, sizeof(resp_read_msg), &resp_read_msg);
+
+ dbg("Exit");
+ return;
+}
+
+static void on_response_get_msg_indices(TcorePending *pending, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *at_response = data;
+ struct tresp_sms_get_storedMsgCnt resp_stored_msg_cnt;
+ UserRequest *user_req = NULL;
+ struct tresp_sms_get_storedMsgCnt *resp_stored_msg_cnt_prev = NULL;
+
+ GSList *tokens = NULL;
+ char *gslist_line = NULL, *line_token = NULL;
+ int gslist_line_count = 0, ctr_loop = 0;
+
+ dbg("Entry");
+
+ 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));
+ resp_stored_msg_cnt.result = SMS_DEVICE_FAILURE;
+
+ if (at_response->success) {
+ dbg("Response OK");
+ if (at_response->lines) {
+ gslist_line_count = g_slist_length(at_response->lines);
+
+ if (gslist_line_count > SMS_GSM_SMS_MSG_NUM_MAX)
+ 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
+
+ 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 */
+
+ 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
+
+ line_token = g_slist_nth_data(tokens, 0);
+ if (NULL != line_token) {
+ resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop] = atoi(line_token);
+ resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
+ } else {
+ dbg("line_token of gslist_line [%d] is NULL", ctr_loop);
+ continue;
+ }
+ tcore_at_tok_free(tokens);
+ } else {
+ 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
+ resp_stored_msg_cnt.result = SMS_SENDSMS_SUCCESS;
+ }
+ }
+ } else {
+ dbg("Respnose NOK");
+ }
+
+ resp_stored_msg_cnt.storedMsgCnt.totalCount = resp_stored_msg_cnt_prev->storedMsgCnt.totalCount;
+ resp_stored_msg_cnt.storedMsgCnt.usedCount = resp_stored_msg_cnt_prev->storedMsgCnt.usedCount;
+
+ util_sms_free_memory(resp_stored_msg_cnt_prev);
+
+ dbg("total: [%d], used: [%d], result: [%d]", resp_stored_msg_cnt.storedMsgCnt.totalCount, resp_stored_msg_cnt.storedMsgCnt.usedCount, resp_stored_msg_cnt.result);
+ for (ctr_loop = 0; ctr_loop < gslist_line_count; ctr_loop++) {
+ dbg("index: [%d]", resp_stored_msg_cnt.storedMsgCnt.indexList[ctr_loop]);
+ }
+
+ tcore_user_request_send_response(user_req, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(resp_stored_msg_cnt), &resp_stored_msg_cnt);
+
+ dbg("Exit");
+ return;
+}
+
+static void on_response_get_stored_msg_cnt(TcorePending *pending, int data_len, const void *data, void *user_data)
+{
+ 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;
+ TcoreATRequest *atReq = NULL;
+ int usedCnt = 0, totalCnt = 0, result = 0;
+
+ TcorePending *pending_new = NULL;
+ CoreObject *o = NULL;
+
+ dbg("Entered");
+
+ respStoredMsgCnt = malloc(sizeof(struct tresp_sms_get_storedMsgCnt));
+ result = SMS_DEVICE_FAILURE;
+
+ ur = tcore_pending_ref_user_request(pending);
+ ur_dup = tcore_user_request_ref(ur);
+ o = tcore_pending_ref_core_object(pending);
+
+ if (atResp->success > 0) {
+ dbg("Response OK");
+ if (NULL != atResp->lines) {
+ 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);
+ }
+
+ pResp = g_slist_nth_data(tokens, 1);
+ if (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);
+
+ pending_new = tcore_pending_new(o, 0);
+ //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);
+
+ 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_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
+ tcore_at_tok_free(tokens);
+
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return;
+ }
+ //free the consumed token
+ if (tokens)
+ tcore_at_tok_free(tokens);
+ } else {
+ dbg("No data");
+ }
+ } else {
+ err("Response NOK");
+ }
+ respStoredMsgCnt->result = result;
+ tcore_user_request_send_response(ur, TRESP_SMS_GET_STORED_MSG_COUNT, sizeof(struct tresp_sms_get_storedMsgCnt), &respStoredMsgCnt);
+
+
+ dbg("Exit");
+ return;
+}
+
+static void on_response_get_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
+{
+ const TcoreATResponse *at_response = data;
+ struct tresp_sms_get_sca respGetSca;
+ UserRequest *user_req = NULL;
+
+ GSList *tokens = NULL;
+ char *gslist_line = NULL, *sca_addr = NULL, *sca_toa = NULL;
+
+ dbg("Entry");
+
+ memset(&respGetSca, 0, sizeof(respGetSca));
+ respGetSca.result = SMS_DEVICE_FAILURE;
+
+ user_req = tcore_pending_ref_user_request(pending);
+
+ if (at_response->success) {
+ dbg("Response OK");
+ if (at_response->lines) {
+ gslist_line = (char *)at_response->lines->data;
+
+ tokens = tcore_at_tok_new(gslist_line);
+ sca_addr = g_slist_nth_data(tokens, 0);
+ sca_toa = g_slist_nth_data(tokens, 1);
+
+ if ((NULL != sca_addr)
+ && (NULL != sca_toa)) {
+ dbg("sca_addr: [%s]. sca_toa: [%s]", sca_addr, sca_toa);
+
+ respGetSca.scaAddress.dialNumLen = strlen(sca_addr);
+
+ if (145 == atoi(sca_toa)) {
+ respGetSca.scaAddress.typeOfNum = SIM_TON_INTERNATIONAL;
+ } else {
+ respGetSca.scaAddress.typeOfNum = SIM_TON_NATIONAL;
+ }
+
+ respGetSca.scaAddress.numPlanId = 0;
+
+ memcpy(respGetSca.scaAddress.diallingNum, sca_addr, strlen(sca_addr));
+
+ dbg("len [%d], sca_addr [%s], TON [%d], NPI [%d]", respGetSca.scaAddress.dialNumLen, respGetSca.scaAddress.diallingNum, respGetSca.scaAddress.typeOfNum, respGetSca.scaAddress.numPlanId);
+
+ respGetSca.result = SMS_SENDSMS_SUCCESS;
+ } else {
+ err("sca_addr OR sca_toa NULL");
+ }
+ } else {
+ dbg("NO Lines");
+ }
+ } else {
+ dbg("Response NOK");
+ }
+
+ tcore_user_request_send_response(user_req, TRESP_SMS_GET_SCA, sizeof(respGetSca), &respGetSca);
+
+ if(tokens)
+ tcore_at_tok_free(tokens);
+
+ dbg("Exit");
+ return;
+}
+
+static void on_response_set_sca(TcorePending *pending, int data_len, const void *data, void *user_data)
+{
+ /*
+ Response is expected in this format
+ OK
+ or
+ +CMS ERROR: <err>
+ */
+ UserRequest *ur;
+ //copies the AT response data to resp
+ const TcoreATResponse *atResp = data;
+ struct tresp_sms_set_sca respSetSca;
+
+ memset(&respSetSca, 0, sizeof(struct tresp_sms_set_sca));
+
+ ur = tcore_pending_ref_user_request(pending);
+ if (!ur) {
+ dbg("no user_request");
+ return;
+ }
+
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+ respSetSca.result = SMS_SUCCESS;
+ } else {
+ dbg("RESPONSE NOK");
+ respSetSca.result = SMS_DEVICE_FAILURE;
+ }
+
+ tcore_user_request_send_response(ur, TRESP_SMS_SET_SCA, sizeof(struct tresp_sms_set_sca), &respSetSca);
+
+ return;
+}
+
+static void on_response_get_cb_config(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur;
+ struct tresp_sms_get_cb_config respGetCbConfig;
+ const TcoreATResponse *atResp = data;
+ GSList *tokens=NULL;
+ int i = 0, mode =0;
+ char *pResp = NULL, *line = NULL;
+ char delim[] = "-";
+
+ memset(&respGetCbConfig, 0, sizeof(struct tresp_sms_get_cb_config));
+ respGetCbConfig.result = SMS_DEVICE_FAILURE;
+
+ ur = tcore_pending_ref_user_request(p);
+ if (!ur) {
+ dbg("no user_request");
+ return;
+ }
+
+ respGetCbConfig.cbConfig.net3gppType = SMS_NETTYPE_3GPP;
+
+ if (atResp->success) {
+ dbg("Response OK");
+ if (atResp->lines) {
+ line = (char*)atResp->lines->data;
+ if (line != NULL) {
+ dbg("line is %s",line);
+ tokens = tcore_at_tok_new(line);
+ pResp = g_slist_nth_data(tokens, 0);
+ if (pResp) {
+ mode = atoi(pResp);
+ respGetCbConfig.cbConfig.cbEnabled = mode;
+
+ pResp = g_slist_nth_data(tokens, 1);
+ if (pResp) {
+ 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;
+
+ // 0,1,5,320-478,922
+ cb_mid_str = util_removeQuotes(pResp);
+ cb_tokens = tcore_at_tok_new((const char *) 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;
+ }
+ }
+
+ 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(mid_tok, delim);
+ second_tok = strtok(NULL, delim);
+
+ 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 {
+ if (mode == 1) {
+ 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 {
+ respGetCbConfig.cbConfig.msgIdRangeCount = 0;
+ respGetCbConfig.cbConfig.msgIDs[0].net3gpp.selected = FALSE;
+ respGetCbConfig.result = SMS_SENDSMS_SUCCESS;
+ }
+ }
+ } else {
+ dbg("line is NULL");
+ }
+ } else {
+ dbg("atresp->lines is NULL");
+ }
+ } 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)
+ tcore_at_tok_free(tokens);
+
+ return;
+}
+
+static void on_response_set_cb_config(TcorePending *pending, int data_len, const void *data, void *user_data)
+{
+ /*
+ Response is expected in this format
+ OK
+ or
+ +CMS ERROR: <err>
+ */
+
+ UserRequest *ur;
+ const TcoreATResponse *resp = data;
+ int response = 0;
+ const char *line = NULL;
+ GSList *tokens=NULL;
+
+ struct tresp_sms_set_cb_config respSetCbConfig = {0,};
+
+ memset(&respSetCbConfig, 0, sizeof(struct tresp_sms_set_cb_config));
+
+ ur = tcore_pending_ref_user_request(pending);
+ respSetCbConfig.result = SMS_SENDSMS_SUCCESS;
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ } 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");
+ respSetCbConfig.result = SMS_DEVICE_FAILURE;
+ } else {
+ response = atoi(g_slist_nth_data(tokens, 0));
+ /* TODO: CMEE error mapping is required. */
+ respSetCbConfig.result = SMS_DEVICE_FAILURE;
+ }
+ }
+ if (!ur) {
+ dbg("no user_request");
+ return;
+ }
+
+ tcore_user_request_send_response(ur, TRESP_SMS_SET_CB_CONFIG, sizeof(struct tresp_sms_set_cb_config), &respSetCbConfig);
+
+ 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,};
+ const TcoreATResponse *resp = data;
+
+ memset(&respSetMemStatus, 0, sizeof(struct tresp_sms_set_mem_status));
+
+ if (resp->success > 0) {
+ dbg("RESPONSE OK");
+ respSetMemStatus.result = SMS_SENDSMS_SUCCESS;
+ } else {
+ dbg("RESPONSE NOK");
+ respSetMemStatus.result = SMS_DEVICE_FAILURE;
+ }
+
+ ur = tcore_pending_ref_user_request(p);
+ if (!ur) {
+ dbg("no user_request");
+ return;
+ }
+
+ tcore_user_request_send_response(ur, TRESP_SMS_SET_MEM_STATUS, sizeof(struct tresp_sms_set_mem_status), &respSetMemStatus);
+
+ return;
+}
+
+static void on_response_set_msg_status(TcorePending *pending, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur;
+ struct tresp_sms_set_msg_status respMsgStatus = {0, };
+ const TcoreATResponse *atResp = data;
+ int response = 0, sw1 = 0, sw2 = 0;
+ const char *line = NULL;
+ char *pResp = NULL;
+ GSList *tokens = NULL;
+
+ dbg("Entry");
+
+ memset(&respMsgStatus, 0, sizeof(struct tresp_sms_set_msg_status));
+ respMsgStatus.result = SMS_DEVICE_FAILURE;
+
+ ur = tcore_pending_ref_user_request(pending);
+
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+
+ if (atResp->lines) {
+ line = (const char *) atResp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ pResp = g_slist_nth_data(tokens, 0);
+ if (pResp != NULL) {
+ sw1 = atoi(pResp);
+ } else {
+ dbg("sw1 is NULL");
+ }
+ pResp = g_slist_nth_data(tokens, 1);
+ if (pResp != NULL) {
+ sw2 = atoi(pResp);
+ if ((sw1 == AT_SW1_SUCCESS) && (sw2 == 0)) {
+ respMsgStatus.result = SMS_SENDSMS_SUCCESS;
+ }
+ } else {
+ dbg("sw2 is NULL");
+ }
+ pResp = g_slist_nth_data(tokens, 3);
+
+ if (pResp != NULL) {
+ response = atoi(pResp);
+ dbg("response is %s", response);
+ }
+ } else {
+ dbg("No lines");
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ }
+
+ tcore_user_request_send_response(ur, TRESP_SMS_SET_MSG_STATUS , sizeof(struct tresp_sms_set_msg_status), &respMsgStatus);
+
+ if(tokens)
+ tcore_at_tok_free(tokens);
+
+ dbg("Exit");
+ return;
+}
+
+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 ;
+ 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;
+
+ memset(&respGetParams, 0, sizeof(struct tresp_sms_get_params));
+ respGetParams.result = SMS_DEVICE_FAILURE;
+
+ ur = tcore_pending_ref_user_request(pending);
+
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+
+ if (atResp->lines) {
+ line = (const char *) atResp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ pResp = g_slist_nth_data(tokens, 0);
+ if (pResp != NULL) {
+ sw1 = atoi(pResp);
+ dbg("sw1 is %d", sw1);
+ } else {
+ dbg("sw1 is NULL");
+ }
+ pResp = g_slist_nth_data(tokens, 1);
+ if (pResp != NULL) {
+ sw2 = atoi(pResp);
+ dbg("sw2 is %d", sw2);
+ if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
+ respGetParams.result = SMS_SENDSMS_SUCCESS;
+ }
+ } else {
+ dbg("sw2 is NULL");
+ }
+ pResp = g_slist_nth_data(tokens, 2);
+ if (pResp != NULL) {
+ hexData = util_removeQuotes(pResp);
+
+ recordData = util_hexStringToBytes(hexData);
+ util_hex_dump(" ", strlen(hexData) / 2, recordData);
+
+ respGetParams.paramsInfo.recordLen = strlen(hexData) / 2;
+
+ 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]);
+
+ free(recordData);
+ free(hexData);
+ } else {
+ dbg("No response");
+ }
+ tcore_at_tok_free(tokens);
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ }
+
+ tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMS, sizeof(struct tresp_sms_get_params), &respGetParams);
+
+ dbg("Exit");
+ return;
+}
+
+static void on_response_set_sms_params(TcorePending *pending, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur;
+ struct tresp_sms_set_params respSetParams = {0, };
+ const TcoreATResponse *atResp = data;
+ int sw1 =0 , sw2 = 0;
+ const char *line = NULL;
+ char *pResp = NULL;
+ GSList *tokens=NULL;
+
+
+ memset(&respSetParams, 0, sizeof(struct tresp_sms_set_params));
+ ur = tcore_pending_ref_user_request(pending);
+
+ respSetParams.result = SMS_DEVICE_FAILURE;
+
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+
+ if (atResp->lines) {
+ line = (const char *) atResp->lines->data;
+ tokens = tcore_at_tok_new(line);
+ pResp = g_slist_nth_data(tokens, 0);
+ if (pResp != NULL) {
+ sw1 = atoi(pResp);
+ } else {
+ dbg("sw1 is NULL");
+ }
+
+ pResp = g_slist_nth_data(tokens, 1);
+ if (pResp != NULL) {
+ sw2 = atoi(pResp);
+ if (((sw1 == AT_SW1_SUCCESS) && (sw2 == AT_SW2_SUCCESS)) || (sw1 == 0x91)) {
+ respSetParams.result = SMS_SENDSMS_SUCCESS;
+ }
+ } else {
+ dbg("sw2 is NULL");
+ }
+ } else {
+ dbg("No lines");
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ }
+
+ tcore_user_request_send_response(ur, TRESP_SMS_SET_PARAMS , sizeof(struct tresp_sms_set_params), &respSetParams);
+
+ if(tokens)
+ tcore_at_tok_free(tokens);
+
+ dbg("Exit");
+ return;
+}
+
+static void on_response_get_paramcnt(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ 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;
+ int sim_type = 0;
+ GSList *tokens=NULL;
+ CoreObject *co_sim = NULL; //need this to get the sim type GSM/USIM
+ TcorePlugin *plugin = NULL;
+
+ dbg("Entry");
+
+ ur = tcore_pending_ref_user_request(p);
+ respGetParamCnt.result = SMS_DEVICE_FAILURE;
+
+ if (atResp->success > 0) {
+ dbg("RESPONSE OK");
+
+ if (atResp->lines) {
+ 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 != NULL) {
+ sw1 = atoi(pResp);
+ } else {
+ dbg("sw1 is NULL");
+ }
+ pResp = g_slist_nth_data(tokens, 1);
+ if (pResp != NULL) {
+ sw2 = atoi(pResp);
+ if ((sw1 == 144) && (sw2 == 0)) {
+ respGetParamCnt.result = SMS_SENDSMS_SUCCESS;
+ }
+ } else {
+ dbg("sw2 is NULL");
+ }
+ pResp = g_slist_nth_data(tokens, 2);
+ if (pResp != NULL) {
+ char *hexData = NULL;
+ char *recordData = NULL;
+ hexData = util_removeQuotes(pResp);
+
+ /*1. SIM access success case*/
+ if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
+ unsigned char tag_len = 0; /* 1 or 2 bytes ??? */
+ int 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;
+
+ recordData = util_hexStringToBytes(hexData);
+ util_hex_dump(" ", strlen(hexData)/2, recordData);
+
+ ptr_data = (unsigned char *)recordData;
+
+ co_sim = tcore_plugin_ref_core_object(tcore_pending_ref_plugin(p), "sim");
+ sim_type = tcore_sim_get_type(co_sim);
+ dbg("sim type is %d",sim_type);
+
+ 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)
+ */
+
+ /* 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++;
+ /* 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++;
+
+ case 0x1:
+ dbg("Getting FileType: [Transparent file type]");
+ /* increment to next byte */
+ ptr_data++;
+ file_type = 0x01; //SIM_FTYPE_TRANSPARENT
+ /* data coding byte - value 21 */
+ 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 */
+ record_len = SMS_SWAPBYTES16(record_len);
+ 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
+ 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 */
+ record_len = SMS_SWAPBYTES16(record_len);
+ ptr_data = ptr_data + 2;
+ num_of_records = *ptr_data++;
+ file_type = 0x04; //SIM_FTYPE_CYCLIC
+ break;
+
+ default:
+ dbg("not handled file type [0x%x]", *ptr_data);
+ break;
+ }
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ free(hexData);
+ free(recordData);
+ tcore_at_tok_free(tokens);
+ 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++;
+ memcpy(&file_id, ptr_data, file_id_len);
+ /* swap bytes */
+ file_id = SMS_SWAPBYTES16(file_id);
+ ptr_data = ptr_data + 2;
+ dbg("Getting FileID=[0x%x]", file_id);
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ free(hexData);
+ free(recordData);
+ tcore_at_tok_free(tokens);
+ return;
+ }
+
+ /* proprietary information */
+ if (*ptr_data == 0xA5) {
+ unsigned short prop_len;
+ /* increment to next byte */
+ ptr_data++;
+ /* length */
+ prop_len = *ptr_data;
+ /* 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("<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;
+ }
+ }
+
+ /* 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 */
+ arr_file_id = SMS_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(hexData);
+ free(recordData);
+ tcore_at_tok_free(tokens);
+ 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 */
+ file_size = SMS_SWAPBYTES16(file_size);
+ ptr_data = ptr_data + 2;
+ } else {
+ dbg("INVALID FCP received - DEbug!");
+ free(hexData);
+ free(recordData);
+ tcore_at_tok_free(tokens);
+ 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(hexData);
+ free(recordData);
+ tcore_at_tok_free(tokens);
+ return;
+ }
+ } else if (sim_type == 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 */
+ file_size = SMS_SWAPBYTES16(file_size);
+ /* parsed file size */
+ ptr_data = ptr_data + 2;
+ /* file id */
+ memcpy(&file_id, ptr_data, 2);
+ file_id = SMS_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) ? 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++;
+ /* 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]", sim_type);
+ }
+
+ dbg("EF[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]", file_id, file_size, file_type, num_of_records, record_len);
+
+ respGetParamCnt.recordCount = num_of_records;
+ respGetParamCnt.result = SMS_SUCCESS;
+
+ //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);
+ } else {
+ /*2. SIM access fail case*/
+ dbg("SIM access fail");
+ respGetParamCnt.result = SMS_UNKNOWN;
+ }
+ } else {
+ dbg("presp is NULL");
+ }
+ } else {
+ dbg("line is blank");
+ }
+ } else {
+ dbg("RESPONSE NOK");
+ }
+
+ tcore_user_request_send_response(ur, TRESP_SMS_GET_PARAMCNT, sizeof(struct tresp_sms_get_paramcnt), &respGetParamCnt);
+
+ if(tokens)
+ tcore_at_tok_free(tokens);
+
+ dbg("Exit");
+ return;
+}
+
+static void _response_get_efsms_data(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ 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 ;
+
+ const TcoreATResponse *resp = data;
+ char *encoded_data = NULL;
+ char msg_status = 0;
+ char *pResp = NULL;
+ GSList *tokens=NULL;
+ const char *line = NULL;
+ int sw1 = 0;
+ int sw2 = 0;
+
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+ TcorePending *pending = NULL;
+ gchar *cmd_str = NULL;
+
+ ur = tcore_pending_ref_user_request(p);
+
+ req_msg_status = tcore_user_request_ref_data(ur, NULL);
+
+ resp_msg_status.result = SMS_DEVICE_FAILURE;
+
+ hal = tcore_object_get_hal(tcore_pending_ref_core_object(pending));
+ dbg("msgStatus: [%x], index [%x]", req_msg_status->msgStatus, req_msg_status->index);
+
+ if (resp->success <= 0) {
+ goto OUT;
+ }
+
+ {
+ 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");
+ goto OUT;
+ }
+ }
+ sw1 = atoi(g_slist_nth_data(tokens, 0));
+ sw2 = atoi(g_slist_nth_data(tokens, 1));
+ pResp = g_slist_nth_data(tokens, 2);
+
+ if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
+ switch (req_msg_status->msgStatus) {
+ case SMS_STATUS_READ:
+ msg_status = 0x01;
+ break;
+
+ case SMS_STATUS_UNREAD:
+ msg_status = 0x03;
+ break;
+
+ case SMS_STATUS_UNSENT:
+ msg_status = 0x07;
+ break;
+
+ case SMS_STATUS_SENT:
+ msg_status = 0x05;
+ break;
+
+ case SMS_STATUS_DELIVERED:
+ msg_status = 0x1D;
+ break;
+
+ case SMS_STATUS_DELIVERY_UNCONFIRMED:
+ msg_status = 0xD;
+ break;
+
+ case SMS_STATUS_MESSAGE_REPLACED:
+ case SMS_STATUS_RESERVED:
+ default:
+ msg_status = 0x03;
+ break;
+ }
+
+ encoded_data = util_removeQuotes(pResp);
+
+ //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);
+ 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
+ g_free(cmd_str);
+ free(encoded_data);
+ util_sms_free_memory(atreq);
+ util_sms_free_memory(pending);
+
+ goto OUT;
+ }
+
+ util_hex_dump(" ", strlen(cmd_str), (void *)cmd_str);
+
+ dup_ur = tcore_user_request_ref(ur);
+
+ tcore_pending_set_request_data(pending, 0, atreq);
+ tcore_pending_set_response_callback(pending, on_response_set_msg_status, NULL);
+ tcore_pending_link_user_request(pending, dup_ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+ free(encoded_data);
+ }
+ }
+
+OUT:
+ 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);
+
+ dbg("Exit");
+
+ return;
+}
+
+/*=============================================================
+ Requests
+==============================================================*/
+static TReturn send_umts_msg(CoreObject *obj, 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;
+
+ dbg("Entry");
+
+ 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);
+
+ dbg("Exit");
+ return TCORE_RETURN_EINVAL;
+ }
+
+ if(FALSE == tcore_hal_get_power_state(hal)){
+ dbg("cp not ready/n");
+ return TCORE_RETURN_ENOSYS;
+ }
+
+ 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];
+
+ dbg("ScLength: [%d]", ScLength);
+
+ if ((sendUmtsMsg->msgDataPackage.msgLength > 0)
+ && (sendUmtsMsg->msgDataPackage.msgLength <= SMS_SMDATA_SIZE_MAX)
+ && (ScLength <= SMS_SCADDRESS_LEN_MAX)) {
+ 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;
+ }
+
+ util_byte_to_hex((const char *)sendUmtsMsg->msgDataPackage.tpduData, (char *)&buf[pdu_len], sendUmtsMsg->msgDataPackage.msgLength);
+
+ pdu_len = pdu_len + 2*sendUmtsMsg->msgDataPackage.msgLength;
+
+ buf[pdu_len] = '\0'; //Ensure termination
+
+ 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;
+ }
+
+ 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_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);
+
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+ }
+
+ err("Invalid Data len");
+ dbg("Exit");
+ return TCORE_RETURN_SMS_INVALID_DATA_LEN;
+}
+
+static TReturn read_msg(CoreObject *obj, UserRequest *ur)
+{
+ gchar *cmd_str = NULL;
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+ TcorePending *pending = NULL;
+ const struct treq_sms_read_msg *readMsg = NULL;
+
+ dbg("Entry");
+
+ readMsg = tcore_user_request_ref_data(ur, NULL);
+ hal = tcore_object_get_hal(obj);
+ if (NULL == readMsg || NULL == hal) {
+ err("NULL input. Unable to proceed");
+ dbg("readMsg: [%p], hal: [%p]", readMsg, hal);
+
+ dbg("Exit");
+ 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);
+ 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;
+ }
+
+ 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_link_user_request(pending, ur);
+ tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn save_msg(CoreObject *obj, UserRequest *ur)
+{
+ gchar *cmd_str = NULL;
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+ 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 *hex_pdu = NULL;
+
+ dbg("Entry");
+
+ saveMsg = tcore_user_request_ref_data(ur, NULL);
+ hal = tcore_object_get_hal(obj);
+ if (NULL == saveMsg || NULL == hal) {
+ err("NULL input. Unable to proceed");
+ dbg("saveMsg: [%p], hal: [%p]", saveMsg, hal);
+
+ 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);
+
+ switch (saveMsg->msgStatus) {
+ case SMS_STATUS_READ:
+ stat = AT_REC_READ;
+ break;
+
+ case SMS_STATUS_UNREAD:
+ stat = AT_REC_UNREAD;
+ break;
+
+ case SMS_STATUS_SENT:
+ stat = AT_STO_SENT;
+ break;
+
+ case SMS_STATUS_UNSENT:
+ stat = AT_STO_UNSENT;
+ break;
+
+ 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];
+
+ buf[0] = ScLength;
+ dbg("ScLength = %d", ScLength);
+
+ if(ScLength == 0) {
+ buf[0] = 0;
+ } else {
+ memcpy(&buf[1], saveMsg->msgDataPackage.sca, ScLength);
+ }
+
+ memcpy(&buf[ScLength+1], saveMsg->msgDataPackage.tpduData, saveMsg->msgDataPackage.msgLength);
+
+ 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);
+
+ memset (hex_pdu, 0x00, pdu_len * 2 + 1);
+
+ util_byte_to_hex((const char *)buf, (char *)hex_pdu, pdu_len);
+
+ //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);
+
+ 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);
+ util_sms_free_memory(hex_pdu);
+
+ dbg("Exit");
+ return TCORE_RETURN_ENOMEM;
+ }
+
+ 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);
+ 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);
+
+ g_free(cmd_str);
+ free(hex_pdu);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+ }
+
+ err("Invalid Data len");
+ dbg("Exit");
+ return TCORE_RETURN_SMS_INVALID_DATA_LEN;
+}
+
+static TReturn delete_msg(CoreObject *obj, UserRequest *ur)
+{
+ gchar *cmd_str = NULL;
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+ TcorePending *pending = NULL;
+ const struct treq_sms_delete_msg *delete_msg = NULL;
+
+ dbg("Entry");
+
+ delete_msg = tcore_user_request_ref_data(ur, NULL);
+ hal = tcore_object_get_hal(obj);
+ if (NULL == delete_msg || NULL == hal) {
+ err("NULL input. Unable to proceed");
+ dbg("deleteMsg: [%p], hal: [%p]", delete_msg, hal);
+
+ dbg("Exit");
+ 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) {
+ cmd_str = g_strdup_printf("AT+CMGD=0,4"); // Delete All Messages
+ } else {
+ cmd_str = g_strdup_printf("AT+CMGD=%d,0", delete_msg->index + 1); // Delete specified index
+ }
+
+ 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) {
+ 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;
+ }
+
+ 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
+ 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);
+
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn get_storedMsgCnt(CoreObject *obj, UserRequest *ur)
+{
+ gchar *cmd_str = NULL;
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+ TcorePending *pending = NULL;
+
+ dbg("Entry");
+
+ hal = tcore_object_get_hal(obj);
+ if (NULL == hal) {
+ err("NULL HAL. Unable to proceed");
+
+ 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+CPMS=\"SM\"");
+ pending = tcore_pending_new(obj, 0);
+ 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
+ g_free(cmd_str);
+ util_sms_free_memory(atreq);
+ util_sms_free_memory(pending);
+
+ dbg("Exit");
+ return TCORE_RETURN_ENOMEM;
+ }
+
+ 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);
+ 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);
+
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn get_sca(CoreObject *obj, UserRequest *ur)
+{
+ gchar * cmd_str = NULL;
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+ TcorePending *pending = NULL;
+
+ dbg("Entry");
+
+ hal = tcore_object_get_hal(obj);
+ if (NULL == hal) {
+ err("HAL NULL. Unable to proceed");
+
+ 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);
+
+ 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;
+ }
+
+ 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);
+ 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);
+
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn set_sca(CoreObject *obj, UserRequest *ur)
+{
+ gchar *cmd_str = NULL;
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+ TcorePending *pending = NULL;
+ const struct treq_sms_set_sca *setSca = NULL;
+ int addrType = 0;
+
+ dbg("Entry");
+
+ setSca = tcore_user_request_ref_data(ur, NULL);
+ hal = tcore_object_get_hal(obj);
+ if (NULL == setSca || NULL == hal) {
+ err("NULL input. Unable to proceed");
+ dbg("setSca: [%p], hal: [%p]", setSca, hal);
+
+ 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);
+
+ 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);
+
+ 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;
+ }
+
+ 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);
+ 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);
+
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn get_cb_config(CoreObject *obj, UserRequest *ur)
+{
+ gchar *cmd_str = NULL;
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+ TcorePending *pending = NULL;
+
+ dbg("Entry");
+
+ hal = tcore_object_get_hal(obj);
+ if (NULL == hal) {
+ err("NULL HAL. Unable to proceed");
+
+ 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);
+ 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;
+ }
+
+ 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);
+ tcore_pending_set_send_callback(pending, on_confirmation_sms_message_send, NULL);
+ tcore_pending_link_user_request(pending, ur);
+ tcore_hal_send_request(hal, pending);
+
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn set_cb_config(CoreObject *obj, UserRequest *ur)
+{
+ gchar *cmd_str = NULL;
+ gchar *mids_str = NULL;
+ GString *mids_GString = NULL;
+
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+ TcorePending *pending = NULL;
+ const struct treq_sms_set_cb_config *setCbConfig = NULL;
+ int ctr1= 0, ctr2 =0;
+ unsigned short appendMsgId = 0;
+
+ dbg("Entry");
+
+ setCbConfig = tcore_user_request_ref_data(ur, NULL);
+ hal = tcore_object_get_hal(obj);
+ if (NULL == setCbConfig || NULL == hal) {
+ err("NULL input. Unable to proceed");
+ dbg("setCbConfig: [%p], hal: [%p]", setCbConfig, hal);
+
+ 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, msgIdCount: %d", setCbConfig->cbEnabled, setCbConfig->msgIdRangeCount);
+
+ 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
+ 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 )
+ continue;
+
+ if( SMS_GSM_SMS_CBMI_LIST_SIZE_MAX <= (setCbConfig->msgIDs[ctr1].net3gpp.toMsgId - setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId) ) {
+ 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));
+
+ if (ctr2 == ((setCbConfig->msgIDs[ctr1].net3gpp.toMsgId) - (setCbConfig->msgIDs[ctr1].net3gpp.fromMsgId))) {
+ mids_GString = g_string_append(mids_GString, "\""); //Mids string termination
+ } else {
+ mids_GString = g_string_append(mids_GString, ",");
+ }
+
+ appendMsgId++;
+ }
+ }
+ mids_str = g_string_free(mids_GString, FALSE);
+ 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) {
+ 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;
+ }
+
+ 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);
+ 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);
+
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn set_mem_status(CoreObject *obj, UserRequest *ur)
+{
+ gchar *cmd_str = NULL;
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+ TcorePending *pending = NULL;
+ const struct treq_sms_set_mem_status *setMemStatus = NULL;
+ int memoryStatus = 0;
+
+ dbg("Entry");
+
+ setMemStatus = tcore_user_request_ref_data(ur, NULL);
+ hal = tcore_object_get_hal(obj);
+ if (NULL == setMemStatus || NULL == hal) {
+ err("NULL input. Unable to proceed");
+ dbg("setMemStatus: [%p], hal: [%p]", setMemStatus, hal);
+
+ 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
+ || setMemStatus->memory_status > SMS_PDA_MEMORY_STATUS_FULL) {
+ err("Invalid memory_status");
+
+ dbg("Exit");
+ return TCORE_RETURN_EINVAL;
+ }
+
+ switch (setMemStatus->memory_status) {
+ case SMS_PDA_MEMORY_STATUS_AVAILABLE:
+ memoryStatus = AT_MEMORY_AVAILABLE;
+ break;
+
+ case SMS_PDA_MEMORY_STATUS_FULL:
+ memoryStatus = AT_MEMORY_FULL;
+ break;
+
+ 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);
+
+ 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;
+ }
+
+ 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);
+ 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);
+
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn set_delivery_report(CoreObject *obj, UserRequest *ur)
+{
+ 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.");
+
+ tcore_user_request_send_response(ur, TRESP_SMS_SET_DELIVERY_REPORT, sizeof(struct tresp_sms_set_delivery_report), &respSetDeliveryReport);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn set_msg_status(CoreObject *obj, UserRequest *ur)
+{
+ gchar *cmd_str = NULL;
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+ TcorePending *pending = NULL;
+ 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);
+ 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;
+ }
+
+ 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);
+ 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);
+
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn get_sms_params(CoreObject *obj, UserRequest *ur)
+{
+ gchar *cmd_str = NULL;
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+ TcorePending *pending = NULL;
+ const struct treq_sms_get_params *getSmsParams = NULL;
+ int record_len = 0 , *smsp_record_len = NULL;
+
+ dbg("Entry");
+
+ getSmsParams = tcore_user_request_ref_data(ur, NULL);
+ hal = tcore_object_get_hal(obj);
+ if (NULL == getSmsParams || NULL == hal) {
+ err("NULL input. Unable to proceed");
+ dbg("getSmsParams: [%p], hal: [%p]", getSmsParams, hal);
+
+ 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>]]]]
+ cmd_str = g_strdup_printf("AT+CRSM=178,28482,%d,4,%d", (getSmsParams->index + 1), record_len);
+
+ dbg("cmd_str is %s",cmd_str);
+
+ 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
+ g_free(cmd_str);
+ util_sms_free_memory(atreq);
+ util_sms_free_memory(pending);
+
+ dbg("Exit");
+ return TCORE_RETURN_ENOMEM;
+ }
+
+ 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);
+ 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);
+
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn set_sms_params(CoreObject *obj, UserRequest *ur)
+{
+ gchar *cmd_str = NULL;
+ char *encoded_data = NULL;
+ unsigned char *temp_data = NULL;
+ int SMSPRecordLen = 0;
+
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+ TcorePending *pending = NULL;
+ const struct treq_sms_set_params *setSmsParams = NULL;
+ int encoded_data_len = 0;
+
+ dbg("Entry");
+
+ setSmsParams = tcore_user_request_ref_data(ur, NULL);
+ hal = tcore_object_get_hal(obj);
+ if (NULL == setSmsParams || NULL == hal) {
+ err("NULL input. Unable to proceed");
+ 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);
+
+ _tcore_util_sms_encode_smsParameters(&(setSmsParams->params), temp_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("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
+ g_free(cmd_str);
+ util_sms_free_memory(atreq);
+ util_sms_free_memory(pending);
+
+ util_sms_free_memory(temp_data);
+ util_sms_free_memory(encoded_data);
+
+ dbg("Exit");
+ return TCORE_RETURN_ENOMEM;
+ }
+
+ 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_sms_params, 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);
+
+ g_free(cmd_str);
+ util_sms_free_memory(temp_data);
+ util_sms_free_memory(encoded_data);
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn get_paramcnt(CoreObject *obj, UserRequest *ur)
+{
+ gchar *cmd_str = NULL;
+ TcoreHal *hal = NULL;
+ TcoreATRequest *atreq = NULL;
+ TcorePending *pending = NULL;
+
+ dbg("Entry");
+
+ hal = tcore_object_get_hal(obj);
+ if (NULL == hal) {
+ err("NULL HAL. Unable to proceed");
+
+ 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>]]]]
+ cmd_str = g_strdup_printf("AT+CRSM=192,28482");
+ 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
+ g_free(cmd_str);
+ util_sms_free_memory(atreq);
+ util_sms_free_memory(pending);
+
+ dbg("Exit");
+ return TCORE_RETURN_FAILURE;
+ }
+
+ 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);
+ 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);
+
+ g_free(cmd_str);
+
+ dbg("Exit");
+ return TCORE_RETURN_SUCCESS;
+}
+
+static struct tcore_sms_operations sms_ops = {
+ .send_umts_msg = send_umts_msg,
+ .read_msg = read_msg,
+ .save_msg = save_msg,
+ .delete_msg = delete_msg,
+ .get_storedMsgCnt = get_storedMsgCnt,
+ .get_sca = get_sca,
+ .set_sca = set_sca,
+ .get_cb_config = get_cb_config,
+ .set_cb_config = set_cb_config,
+ .set_mem_status = set_mem_status,
+ .get_pref_brearer = NULL,
+ .set_pref_brearer = NULL,
+ .set_delivery_report = set_delivery_report,
+ .set_msg_status = set_msg_status,
+ .get_sms_params = get_sms_params,
+ .set_sms_params = set_sms_params,
+ .get_paramcnt = get_paramcnt,
+};
+
+gboolean s_sms_init(TcorePlugin *plugin, TcoreHal *hal)
+{
+ CoreObject *obj = NULL;
+ struct property_sms_info *data = NULL;
+ GQueue *work_queue = NULL;
+ int *smsp_record_len = NULL;
+
+ 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;
+ }
+
+ work_queue = g_queue_new();
+ tcore_object_link_user_data(obj, work_queue);
+
+ //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(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(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);
+
+ dbg("Exit");
+ return TRUE;
+}
+
+void s_sms_exit(TcorePlugin *plugin)
+{
+ CoreObject *obj = NULL;
+ struct property_sms_info *data = NULL;
+
+ dbg("Entry");
+ dbg("plugin: [%p]", plugin);
+
+ 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);
+
+ dbg("Exit");
+ return;
+}
--- /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 <glib.h>
+
+#include <tcore.h>
+#include <hal.h>
+#include <core_object.h>
+#include <plugin.h>
+#include <queue.h>
+#include <co_call.h>
+#include <co_ss.h>
+#include <user_request.h>
+#include <util.h>
+#include <server.h>
+#include <at.h>
+
+#include "s_common.h"
+#include "s_ss.h"
+
+#define NUM_TYPE_INTERNATIONAL 0x01
+#define NUM_PLAN_ISDN 0x01
+
+// To avoid sending multiple response to application
+static gboolean UssdResp = FALSE;
+
+enum telephony_ss_opcode {
+ SS_OPCO_REG = 0x01, /* 0x01 : Registration */
+ SS_OPCO_DEREG, /* 0x02 : De-registration(erase) */
+ SS_OPCO_ACTIVATE, /* 0x03 : Activation */
+ SS_OPCO_DEACTIVATE, /* 0x04 : De-activation */
+ SS_OPCO_MAX
+};
+
+struct ss_confirm_info {
+ enum telephony_ss_class class;
+ int flavor_type;
+ enum tcore_response_command resp;
+ void *data;
+ int data_len;
+};
+
+static gboolean _ss_request_message(TcorePending *pending, CoreObject *o, UserRequest *ur, void *on_resp, void *user_data);
+
+static TReturn _ss_barring_get(CoreObject *o, UserRequest *ur, enum telephony_ss_class class, enum telephony_ss_barring_mode type, enum tcore_response_command resp);
+
+static TReturn _ss_forwarding_get(CoreObject *o, UserRequest *ur, enum telephony_ss_class class, enum telephony_ss_forwarding_mode type, enum tcore_response_command resp);
+
+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 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 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 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 s_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 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 void on_confirmation_ss_message_send(TcorePending *p, gboolean result, void *user_data);
+
+static void _ss_ussd_response(UserRequest *ur, const char *ussd_str, enum telephony_ss_ussd_type type, enum telephony_ss_ussd_status status);
+static void _ss_ussd_notification(TcorePlugin *p, const char *ussd_str, enum telephony_ss_ussd_status status);
+
+static gboolean on_notification_ss_info(CoreObject *o, const void *data, void *user_data);
+static gboolean on_notification_ss_ussd(CoreObject *o, const void *data, void *user_data);
+
+
+static gboolean _ss_request_message(TcorePending *pending,
+ CoreObject *o,
+ UserRequest *ur,
+ void *on_resp,
+ void *user_data)
+{
+ TcoreHal *hal = NULL;
+ TReturn ret;
+ dbg("Entry");
+
+ if (on_resp) {
+ tcore_pending_set_response_callback(pending, on_resp, user_data);
+ }
+ tcore_pending_set_send_callback(pending, on_confirmation_ss_message_send, NULL);
+ if (ur) {
+ tcore_pending_link_user_request(pending, ur);
+ } else {
+ err("User Request is NULL, is this internal request??");
+ }
+
+ 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");
+ return FALSE;
+ }
+
+ dbg("Exit");
+ return TRUE;
+}
+
+static void _ss_ussd_response(UserRequest *ur, const char *ussd_str, enum telephony_ss_ussd_type type, enum telephony_ss_ussd_status status)
+{
+ struct tresp_ss_ussd resp;
+ dbg("Entry");
+
+ if (ur) {
+ memset(&resp, 0x0, sizeof(struct tresp_ss_ussd));
+ resp.type = type;
+ resp.status = status;
+ resp.err = SS_ERROR_NONE;
+ dbg("ussd_str = %s resp.type - %d resp.status - %d", ussd_str, resp.type, resp.status);
+
+ if (ussd_str) {
+ int len = strlen(ussd_str);
+ if (len < MAX_SS_USSD_LEN) {
+ memcpy(resp.str, ussd_str, len);
+ resp.str[len] = '\0';
+ } else {
+ memcpy(resp.str, ussd_str, MAX_SS_USSD_LEN);
+ resp.str[MAX_SS_USSD_LEN - 1] = '\0';
+ }
+ dbg("Response string: %s", resp.str);
+ } else {
+ dbg("USSD string is not present");
+ memset(resp.str, '\0', MAX_SS_USSD_LEN);
+ }
+ UssdResp = TRUE;
+ // Send response to TAPI
+ tcore_user_request_send_response(ur, TRESP_SS_SEND_USSD, sizeof(struct tresp_ss_ussd), &resp);
+ } else {
+ err("User request is NULL");
+ }
+
+ dbg("Exit");
+ return;
+}
+
+static void _ss_ussd_notification(TcorePlugin *p, const char *ussd_str, enum telephony_ss_ussd_status status)
+{
+ CoreObject *core_obj = 0;
+ struct tnoti_ss_ussd noti;
+
+ dbg("function enter");
+ if (!p) {
+ dbg("[ error ] p : (NULL)");
+ return;
+ }
+ noti.status = status;
+ if (ussd_str) {
+ int len = strlen(ussd_str);
+ if (len < MAX_SS_USSD_LEN) {
+ memcpy(noti.str, ussd_str, len);
+ noti.str[len] = '\0';
+ } else {
+ memcpy(noti.str, ussd_str, MAX_SS_USSD_LEN);
+ noti.str[MAX_SS_USSD_LEN - 1] = '\0';
+ }
+ } else {
+ memset(noti.str, '\0', MAX_SS_USSD_LEN);
+ }
+ dbg("noti.str - %s", noti.str);
+
+ core_obj = tcore_plugin_ref_core_object(p, "ss");
+ tcore_server_send_notification(tcore_plugin_ref_server(p),
+ core_obj,
+ TNOTI_SS_USSD,
+ sizeof(struct tnoti_ss_ussd),
+ (void *) ¬i);
+}
+
+static gboolean on_notification_ss_ussd(CoreObject *o, const void *data, void *user_data)
+{
+ enum telephony_ss_ussd_status status;
+ UssdSession *ussd_session = 0;
+ char *ussd_str = 0, *cmd = 0;
+ TcorePlugin *plugin = 0;
+ int m = -1, dcs = 0;
+ char *ussdnoti = NULL, *str = NULL, *dcs_str = NULL;
+ GSList *tokens = NULL;
+ GSList *lines = NULL;
+ char *ussd_string = NULL;
+ unsigned int len;
+
+ plugin = tcore_object_ref_plugin(o);
+ ussd_session = tcore_ss_ussd_get_session(o);
+
+ dbg("function enter");
+ lines = (GSList *) data;
+ if (1 != g_slist_length(lines)) {
+ dbg("unsolicited msg but multiple line");
+ return TRUE;
+ }
+ cmd = (char *) (lines->data);
+ // parse ussd status
+ tokens = tcore_at_tok_new(cmd);
+
+ // parse <m>
+ ussdnoti = g_slist_nth_data(tokens, 0);
+ if (!ussdnoti) {
+ dbg("+CUSD<m> is missing from %CUSD Notification");
+ } else {
+ m = atoi(ussdnoti);
+ dbg("USSD status %d", m);
+ // parse [ <str>, <dcs>]
+ ussd_string = g_slist_nth_data(tokens, 1);
+ if (ussd_string) {
+ /* Strike off starting & ending quotes. 1 extra character for NULL termination */
+ str = malloc(strlen(ussd_string) - 1);
+ dbg("length of Ussd Stirng - %d", strlen(ussd_string));
+ if (str) {
+ memset(str, 0x00, strlen(ussd_string) - 1);
+ } else {
+ dbg("malloc failed")
+ if (NULL != tokens) {
+ tcore_at_tok_free(tokens);
+ }
+ return FALSE;
+ }
+ len = strlen(ussd_string) - 1;
+ ++ussd_string;
+ strncpy(str, ussd_string, len);
+
+ dbg("USSD String - %s len = %d", str, strlen(str));
+ }
+ if ((dcs_str = g_slist_nth_data(tokens, 2))) {
+ dcs = atoi(dcs_str);
+ dbg("USSD dcs %d", dcs);
+ }
+ }
+
+ switch (m) {
+ case 0:
+ status = SS_USSD_NO_ACTION_REQUIRE;
+ break;
+
+ case 1:
+ status = SS_USSD_ACTION_REQUIRE;
+ break;
+
+ case 2:
+ status = SS_USSD_TERMINATED_BY_NET;
+ break;
+
+ case 3:
+ status = SS_USSD_OTHER_CLIENT;
+ break;
+
+ case 4:
+ status = SS_USSD_NOT_SUPPORT;
+ break;
+
+ case 5:
+ status = SS_USSD_TIME_OUT;
+ break;
+
+ default:
+ dbg("unsupported m : %d", m);
+ status = SS_USSD_MAX;
+ break;
+ }
+
+ switch (tcore_util_get_cbs_coding_scheme(dcs)) {
+ case TCORE_DCS_TYPE_7_BIT:
+ case TCORE_DCS_TYPE_UNSPECIFIED:
+ // ussd_str = tcore_util_unpack_gsm7bit(str, strlen(str));
+ // break;
+
+ case TCORE_DCS_TYPE_UCS2:
+ case TCORE_DCS_TYPE_8_BIT:
+ if ((str != NULL) && (strlen(str) > 0)) {
+ ussd_str = g_new0(char, strlen(str) + 1);
+ if (ussd_str != NULL) {
+ memcpy(ussd_str, str, strlen(str));
+ ussd_str[strlen(str)] = '\0';
+ }
+ }
+ break;
+
+ default:
+ dbg("[ error ] unknown dcs type. ussd_session : %x", ussd_session);
+ if (ussd_session) {
+ UserRequest *ur = 0;
+ enum telephony_ss_ussd_type type;
+
+ tcore_ss_ussd_get_session_data(ussd_session, (void **) &ur);
+ if (!ur) {
+ dbg("[ error ] ur : (0)");
+ goto CATCH;
+ }
+
+ type = (enum telephony_ss_ussd_type) tcore_ss_ussd_get_session_type(ussd_session);
+ dbg("ussd type - %d", type);
+
+ _ss_ussd_response(ur, ussd_str, type, status);
+ }
+
+CATCH:
+ if (NULL != tokens) {
+ tcore_at_tok_free(tokens);
+ }
+
+ if (NULL != str) {
+ free(str);
+ }
+ return FALSE;
+ }
+
+ switch (status) {
+ case SS_USSD_NO_ACTION_REQUIRE:
+ case SS_USSD_ACTION_REQUIRE:
+ case SS_USSD_OTHER_CLIENT:
+ case SS_USSD_NOT_SUPPORT:
+ case SS_USSD_TIME_OUT:
+ {
+ if (ussd_session) {
+ UserRequest *ur = 0;
+ enum telephony_ss_ussd_type type;
+
+ 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);
+ dbg("ussd type - %d", type);
+ _ss_ussd_response(ur, (const char *) ussd_str, type, status);
+ if (ussd_str)
+ g_free(ussd_str);
+ } else {
+ tcore_ss_ussd_create_session(o, TCORE_SS_USSD_TYPE_NETWORK_INITIATED, 0, 0);
+ _ss_ussd_notification(plugin, (const char *) ussd_str, status);
+
+ if (ussd_str)
+ g_free(ussd_str);
+ }
+ }
+ break;
+
+ case SS_USSD_TERMINATED_BY_NET:
+ {
+ if (ussd_session) {
+ UserRequest *ur = 0;
+ tcore_ss_ussd_get_session_data(ussd_session, (void **) &ur);
+ if (ur) {
+ tcore_user_request_unref(ur);
+ }
+ tcore_ss_ussd_destroy_session(ussd_session);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (NULL != tokens) {
+ tcore_at_tok_free(tokens);
+ }
+
+ 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;
+ CoreObject *co = 0;
+ char *cmd = 0, *number = 0, *pos;
+ int code1 = -1, code2 = -1, index = 0, ton = 0;
+ char *str_code1, *str_code2, *str_ton, *str_index;
+ GSList *tokens = NULL;
+ char *buf;
+ gboolean cssu = FALSE, cssi = FALSE;
+ GSList *lines = NULL;
+ char *resp = NULL;
+ dbg("function enter");
+
+ plugin = tcore_object_ref_plugin(o);
+ co = tcore_plugin_ref_core_object(plugin, "call");
+ if (!co) {
+ dbg("[ error ] plugin_ref_core_object : call");
+ return FALSE;
+ }
+
+ lines = (GSList *) data;
+ if (1 != g_slist_length(lines)) {
+ dbg("unsolicited msg but multiple line");
+ goto OUT;
+ }
+
+ cmd = (char *) (lines->data);
+ pos = strchr(cmd, ':');
+ if (!pos) {
+ dbg("[ error ] not valid SS- notification ");
+ return TRUE;
+ }
+ buf = calloc(pos - cmd + 2, 1);
+ memcpy(buf, cmd, pos - cmd);
+ dbg("buf is %s", buf);
+
+ if (!strcmp(buf, "+CSSU")) {
+ dbg("SS - +CSSU indication");
+ cssu = TRUE;
+ } else if (!strcmp(buf, "+CSSI")) {
+ dbg("SS - +CSSI indication");
+ cssi = TRUE;
+ }
+ free(buf);
+
+ // handle %CSSU notification
+ if (cssu) {
+ tokens = tcore_at_tok_new(cmd);
+ // parse <code2>
+ str_code2 = g_slist_nth_data(tokens, 0);
+ if (!str_code2) {
+ dbg("Code2 is missing from %CSSU indiaction");
+ } else {
+ code2 = atoi(str_code2);
+ // parse [ <index>, <number> <type>]
+ if ((str_index = g_slist_nth_data(tokens, 1))) {
+ index = atoi(str_index);
+ }
+
+ if ((resp = g_slist_nth_data(tokens, 2))) {
+ // Strike off double quotes
+ number = util_removeQuotes(resp);
+ str_ton = g_slist_nth_data(tokens, 3);
+
+ if (str_ton) {
+ ton = atoi(str_ton);
+ }
+ }
+ }
+
+ dbg("CSSU - code2 = %d index = %d number = %s type = %d", code2, index, number, ton);
+ switch (code2) {
+ case 0: // this is a forwarded call (MT call setup)
+ tcore_call_information_mt_forwarded_call(co, number);
+ break;
+
+ case 2: // call has been put on hold (during a voice call)
+ tcore_call_information_held(co, number);
+ break;
+
+ case 3: // call has been retrieved (during a voice call)
+ tcore_call_information_active(co, number);
+ break;
+
+ case 4: // multiparty call entered (during a voice call)
+ tcore_call_information_joined(co, number);
+ break;
+
+ case 5: // call on hold has been released
+ tcore_call_information_released_on_hold(co, number);
+ break;
+
+ case 6: // forward check SS message received (can be received whenever)
+ tcore_call_information_cf_check_ss_message(co, number);
+ break;
+
+ case 7: // call is being connected (alerting) with the remote party in alerting state in explicit call transfer operation (during a voice call)
+ tcore_call_information_transfer_alert(co, number);
+ break;
+
+ case 8: // call has been connected with the other remote party in explicit call transfer operation (also number and subaddress parameters may be present) (during a voice call or MT call setup)
+ tcore_call_information_transfered(co, number);
+ break;
+
+ case 9: // this is a deflected call (MT call setup):
+ tcore_call_information_mt_deflected_call(co, number);
+ break;
+
+ default:
+ dbg("CSSU - unsupported code2 : %d", code2);
+ break;
+ }
+ }
+ // handle %CSSI notification
+
+ if (cssi) {
+ tokens = tcore_at_tok_new(cmd);
+ // parse <code1>
+ str_code1 = g_slist_nth_data(tokens, 0);
+ if (!str_code1) {
+ dbg("Code1 is missing from %CSSI indiaction");
+ } else {
+ code1 = atoi(str_code1);
+ // parse [ <index> ]
+ if ((str_index = g_slist_nth_data(tokens, 1))) {
+ index = atoi(str_index);
+ }
+ }
+
+ dbg("CSSI - code1 - %d index - %d ", code1, index);
+
+ switch (code1) {
+ case 0: // Unconditional CF is active
+ tcore_call_information_mo_cfu(co);
+ break;
+
+ case 1: // some of the conditional call forwarding are active
+ tcore_call_information_mo_cfc(co);
+ break;
+
+ case 2: // outgoing call is forwarded
+ tcore_call_information_mo_forwarded(co);
+ break;
+
+ case 3: // this call is waiting
+ tcore_call_information_mo_waiting(co);
+ break;
+
+ case 5: // outgoing call is barred
+ tcore_call_information_mo_barred_outgoing(co);
+ break;
+
+ case 6: // incoming call is barred
+ tcore_call_information_mo_barred_incoming(co);
+ break;
+
+ case 7: // CLIR suppression rejected
+ tcore_call_information_mo_clir_suppression_reject(co);
+ break;
+
+ case 8: // outgoing call is deflected
+ tcore_call_information_mo_deflected(co);
+ break;
+
+ default:
+ dbg("unsupported cmd : %d", code1);
+ break;
+ }
+ }
+OUT:
+ if (NULL != tokens) {
+ tcore_at_tok_free(tokens);
+ }
+
+ if (NULL != number) {
+ g_free(number);
+ }
+ return TRUE;
+}
+
+static void on_confirmation_ss_message_send(TcorePending *p, gboolean result, void *user_data)
+{
+ dbg("");
+
+ if (result == FALSE) {
+ // Fail
+ dbg("FAIL");
+ } else {
+ dbg("SEND OK");
+ }
+}
+
+static void on_response_ss_barring_set(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ struct ss_confirm_info *info = 0;
+ enum telephony_ss_class class;
+ CoreObject *o = 0;
+ UserRequest *ur;
+ struct tresp_ss_barring resp;
+ UserRequest *ur_dup = 0;
+ GSList *tokens = NULL;
+ const char *line;
+ int err;
+ const TcoreATResponse *response;
+
+ dbg("function enter");
+ response = data;
+ o = tcore_pending_ref_core_object(p);
+ ur = tcore_pending_ref_user_request(p);
+
+ info = (struct ss_confirm_info *) user_data;
+ class = info->class;
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ resp.err = SS_ERROR_NONE;
+ resp.record = 0;
+ } else {
+ dbg("RESPONSE NOT OK");
+ resp.record = 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 = SS_ERROR_SYSTEMFAILURE;
+ } else {
+ err = atoi(g_slist_nth_data(tokens, 0));
+ // TODO: CMEE error mapping is required.
+ resp.err = SS_ERROR_SYSTEMFAILURE;
+ }
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("on_response_ss_barring_set - rsp.err : %d, ur : %x flavor_type = %d", resp.err, ur, info->flavor_type);
+ dbg("[ check ] class : 0x%x", info->class);
+
+ if (response->success > 0) {
+ if (info->class == SS_CLASS_VOICE) {
+ class = SS_CLASS_ALL_TELE_BEARER;
+ }
+
+ ur_dup = tcore_user_request_ref(ur);
+
+ if (info->flavor_type == SS_BARR_MODE_AB || info->flavor_type == SS_BARR_MODE_AOB) {
+ _ss_barring_get(o, ur_dup, class, SS_BARR_MODE_BAOC, info->resp);
+ } else if (info->flavor_type == SS_BARR_MODE_AIB) {
+ _ss_barring_get(o, ur_dup, class, SS_BARR_MODE_BAIC, info->resp);
+ } else {
+ _ss_barring_get(o, ur_dup, class, info->flavor_type, info->resp);
+ }
+ } else {
+ if (ur) {
+ 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)
+{
+ const TcoreATResponse *response = data;
+ struct ss_confirm_info *info = 0;
+ UserRequest *ur;
+ struct tresp_ss_barring resp;
+ int err;
+ GSList *tokens = NULL;
+ const char *line;
+
+ dbg("function enter");
+ ur = tcore_pending_ref_user_request(p);
+ info = (struct ss_confirm_info *) user_data;
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ resp.err = SS_ERROR_NONE;
+ } else {
+ dbg("RESPONSE NOT OK");
+
+ 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 = SS_ERROR_SYSTEMFAILURE;
+ } else {
+ err = atoi(g_slist_nth_data(tokens, 0));
+ // TODO: CMEE error mapping is required.
+ resp.err = SS_ERROR_SYSTEMFAILURE;
+ }
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("on_response_ss_barring_change_pwd: rsp.err : %d, usr : %x", resp.err, ur);
+ if (ur) {
+ 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_forwarding_set(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ CoreObject *o = 0;
+ UserRequest *ur = 0, *dup_ur = 0;
+ struct ss_confirm_info *info = 0;
+ struct tresp_ss_forwarding resp;
+ GSList *tokens = NULL;
+ const char *line;
+ int err;
+ const TcoreATResponse *response;
+
+ dbg("function enter");
+
+ response = data;
+ o = tcore_pending_ref_core_object(p);
+ ur = tcore_pending_ref_user_request(p);
+
+ info = (struct ss_confirm_info *) user_data;
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ resp.err = SS_ERROR_NONE;
+ resp.record = 0;
+ } else {
+ dbg("RESPONSE NOT OK");
+ resp.record = 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 = SS_ERROR_SYSTEMFAILURE;
+ } else {
+ err = atoi(g_slist_nth_data(tokens, 0));
+ // / TODO: CMEE error mapping is required.
+ resp.err = SS_ERROR_SYSTEMFAILURE;
+ }
+
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("[ check ] class : 0x%x", info->class);
+ dbg("[ check ] flavor_type : 0x%x", info->flavor_type);
+
+ dbg("on_response_ss_forwarding_set - rsp.err : %d, ur : %x", resp.err, ur);
+
+ if (response->success > 0) {
+ 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_forwarding), &resp);
+ } else {
+ dbg("[ error ] ur is 0");
+ }
+ } else {
+ dup_ur = tcore_user_request_ref(ur);
+ _ss_forwarding_get(o, dup_ur, info->class, info->flavor_type, info->resp);
+ }
+ } else {
+ if (ur) {
+ tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
+ } else {
+ dbg("[ error ] ur is 0");
+ }
+ }
+ g_free(user_data);
+}
+
+static void on_response_ss_waiting_set(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ CoreObject *core_obj = 0;
+ UserRequest *ur = 0;
+ UserRequest *ur_dup = 0;
+ struct ss_confirm_info *info = 0;
+ struct tresp_ss_waiting resp;
+ GSList *tokens = NULL;
+ const char *line;
+ int err;
+ const TcoreATResponse *response;
+
+ dbg("function enter");
+ response = data;
+ core_obj = tcore_pending_ref_core_object(p);
+ ur = tcore_pending_ref_user_request(p);
+
+ info = (struct ss_confirm_info *) user_data;
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ resp.err = SS_ERROR_NONE;
+ resp.record = 0;
+ } else {
+ dbg("RESPONSE NOT OK");
+ resp.record = 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 = SS_ERROR_SYSTEMFAILURE;
+ } else {
+ err = atoi(g_slist_nth_data(tokens, 0));
+ // / TODO: CMEE error mapping is required.
+ resp.err = SS_ERROR_SYSTEMFAILURE;
+ }
+ 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 == SS_ERROR_NONE) {
+ ur_dup = tcore_user_request_ref(ur);
+ dbg("Get waiting call 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_waiting), &resp);
+ } else {
+ dbg("[ error ] ur is 0");
+ }
+ }
+ g_free(user_data);
+}
+
+
+static void on_confirmation_ss_ussd(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ CoreObject *core_obj = 0;
+ struct ss_confirm_info *info = 0;
+ struct tresp_ss_ussd resp;
+ UserRequest *ur = NULL, *ussd_ur = NULL;
+ GSList *tokens = NULL;
+ const char *line;
+ int err;
+ UssdSession *ussd_s = NULL;
+ enum tcore_ss_ussd_type type = TCORE_SS_USSD_TYPE_MAX;
+ const TcoreATResponse *response;
+
+ dbg("function enter");
+ response = data;
+ ur = tcore_pending_ref_user_request(p);
+ info = (struct ss_confirm_info *) user_data;
+
+ memset(resp.str, 0x00, MAX_SS_USSD_LEN);
+
+ core_obj = tcore_pending_ref_core_object(p);
+ ussd_s = tcore_ss_ussd_get_session(core_obj);
+
+ if (ussd_s)
+ type = tcore_ss_ussd_get_session_type(ussd_s);
+ else
+ dbg("[ error ] ussd_s : (0)");
+
+ resp.type = (enum telephony_ss_ussd_type) type;
+ resp.status = SS_USSD_MAX; // hardcoded value.
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ resp.err = SS_ERROR_NONE;
+ } else {
+ dbg("RESPONSE NOT OK");
+
+ 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 = SS_ERROR_SYSTEMFAILURE;
+ } else {
+ err = atoi(g_slist_nth_data(tokens, 0));
+ // TODO: CMEE error mapping is required.
+ resp.err = SS_ERROR_SYSTEMFAILURE;
+ }
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("on_confirmation_ss_ussd - rsp.err : %d, ur : %x", resp.err, ur);
+
+ if (response->success > 0) {
+ if (type == TCORE_SS_USSD_TYPE_USER_INITIATED) {
+ dbg("ussd type %d", resp.type);
+
+ if (ussd_s) {
+ tcore_ss_ussd_get_session_data(ussd_s, (void **) &ussd_ur);
+ if (ussd_ur)
+ tcore_user_request_free(ussd_ur);
+ }
+ }
+ }
+
+ if (ussd_s)
+ tcore_ss_ussd_destroy_session(ussd_s);
+
+ if (ur) {
+ if (UssdResp == FALSE) { // to avoid sending multiple response to application.
+ tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_ussd), &resp);
+ }
+ UssdResp = FALSE;
+ } else
+ dbg("[ error ] ur : (0)");
+
+ g_free(user_data);
+}
+
+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;
+ GSList *respdata;
+ struct ss_confirm_info *info = 0;
+ struct tresp_ss_barring resp;
+ int countRecords = 0, countValidRecords = 0;
+ GSList *tokens = NULL;
+ const char *line;
+ char *classx_str;
+ char *stat = NULL;
+ const TcoreATResponse *response;
+
+ dbg("function enter");
+
+ response = data;
+ ur = tcore_pending_ref_user_request(p);
+ info = (struct ss_confirm_info *) user_data;
+
+ if (response->lines) {
+ respdata = (GSList *) response->lines;
+ countRecords = g_slist_length(respdata);
+ dbg("total records : %d", countRecords);
+ } else {
+ countRecords = 0;
+ 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) {
+ line = (const char *) (respdata->data);
+ tokens = tcore_at_tok_new(line);
+
+ // parse <status>
+ stat = g_slist_nth_data(tokens, 0);
+ if (!stat) {
+ dbg("Stat is missing");
+ goto error;
+ }
+
+ status = atoi(stat);
+ if (status == 1) {
+ resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
+ } else {
+ resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
+ }
+ dbg("call barring status - %d", status);
+
+ // Parse <class>
+ classx_str = g_slist_nth_data(tokens, 1);
+
+ if (!classx_str) {
+ dbg("class error. classx not exist - set to requested one : %d", info->class);
+ switch (info->class) {
+ case SS_CLASS_ALL_TELE:
+ classx = 7;
+ break;
+
+ case SS_CLASS_VOICE:
+ classx = 1;
+ break;
+
+ case SS_CLASS_ALL_DATA_TELE:
+ classx = 2;
+ break;
+
+ case SS_CLASS_FAX:
+ classx = 4;
+ break;
+
+ case SS_CLASS_SMS:
+ classx = 8;
+ break;
+
+ case SS_CLASS_ALL_CS_SYNC:
+ classx = 16;
+ break;
+
+ default:
+ classx = 7;
+ dbg("unsupported class %d. set to default : 7", info->class);
+ break;
+ }
+ } else {
+ classx = atoi(classx_str);
+ dbg("call barring classx - %d", classx);
+ }
+
+ switch (classx) {
+ case 1:
+ resp.record[countValidRecords].class = SS_CLASS_VOICE;
+ break;
+
+ case 2:
+ resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
+ break;
+
+ case 4:
+ resp.record[countValidRecords].class = SS_CLASS_FAX;
+ break;
+
+ case 7:
+ resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
+ break;
+
+ case 8:
+ resp.record[countValidRecords].class = SS_CLASS_SMS;
+ break;
+
+ case 16:
+ resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
+ break;
+
+ case 32:
+ resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
+ break;
+
+ default:
+ dbg("unspoorted class : [%d]\n", classx);
+ goto error;
+ break;
+ }
+ resp.record[countValidRecords].mode = (enum telephony_ss_barring_mode) (info->flavor_type);
+ countValidRecords++;
+ tcore_at_tok_free(tokens);
+ continue;
+
+error:
+ dbg("invalid field found. coutinue");
+ tcore_at_tok_free(tokens);
+ continue;
+ }
+
+ dbg("valid count :%d", countValidRecords);
+ resp.record_num = countValidRecords;
+ resp.err = SS_ERROR_NONE;
+ } else {
+ dbg("no active status - return to user")
+ }
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ 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 = SS_ERROR_SYSTEMFAILURE;
+ } else {
+ err = atoi(g_slist_nth_data(tokens, 0));
+ // TODO: CMEE error mapping is required.
+ resp.err = SS_ERROR_SYSTEMFAILURE;
+ }
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("on_response_ss_barring_get- rsp.err : %d, ur : %x", resp.err, ur);
+
+ if (ur)
+ tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_barring), &resp);
+ else
+ dbg("[ error ] ur is 0");
+
+ if (resp.record) {
+ g_free(resp.record);
+ resp.record = NULL;
+ }
+
+ g_free(user_data);
+}
+
+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;
+ char *num;
+ struct ss_confirm_info *info = 0;
+ struct tresp_ss_forwarding resp;
+ int countRecords = 0, countValidRecords = 0;
+
+ GSList *respdata = NULL, *tokens = NULL;
+ const char *line;
+ char *classx_str, *status, *ton, *time_str;
+ const TcoreATResponse *response;
+
+ dbg("function enter");
+ response = data;
+
+ ur = tcore_pending_ref_user_request(p);
+ info = (struct ss_confirm_info *) user_data;
+ if (response->lines) {
+ respdata = (GSList *) response->lines;
+ countRecords = g_slist_length(respdata);
+ dbg("total records : %d", countRecords);
+ } else {
+ countRecords = 0;
+ 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);
+
+ for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
+ line = (const char *) (respdata->data);
+ tokens = tcore_at_tok_new(line);
+
+ // parse <status>
+ status = g_slist_nth_data(tokens, 0);
+ if (!status) {
+ dbg("start line error. skip this line");
+ goto error;
+ } else {
+ if (atoi(status) == 1) {
+ resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
+ } else {
+ resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
+ }
+ }
+
+ // Parse <class>
+ classx_str = g_slist_nth_data(tokens, 1);
+ if (!classx_str) {
+ dbg("class error. skip this line");
+ goto error;
+ } else {
+ switch (atoi(classx_str)) {
+ case 1:
+ resp.record[countValidRecords].class = SS_CLASS_VOICE;
+ break;
+
+ case 2:
+ resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
+ break;
+
+ case 4:
+ resp.record[countValidRecords].class = SS_CLASS_FAX;
+ break;
+
+ case 7:
+ resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
+ break;
+
+ case 8:
+ resp.record[countValidRecords].class = SS_CLASS_SMS;
+ break;
+
+ case 16:
+ resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
+ break;
+
+ case 32:
+ resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
+ break;
+
+ default:
+ dbg("unspoorted class : [%d]\n", classx);
+ goto error;
+ break;
+ }
+ }
+
+ // parse <numer> <type>
+ num = g_slist_nth_data(tokens, 2);
+ if (num) {
+ dbg("number - %s", num);
+ memcpy((resp.record[countValidRecords].number), num, strlen(num));
+ resp.record[countValidRecords].number_present = TRUE;
+
+ 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);
+ }
+ }
+
+ // skip <subaddr> <satype>
+ // parse <time>
+ time_str = g_slist_nth_data(tokens, 6);
+ if (time_str) {
+ time = atoi(time_str);
+ resp.record[countValidRecords].time = (enum telephony_ss_forwarding_no_reply_time) time;
+ dbg("time - %d", time);
+ }
+
+ resp.record[countValidRecords].mode = (enum telephony_ss_forwarding_mode) (info->flavor_type);
+ dbg("flavor_type - %d", (enum telephony_ss_forwarding_mode) (info->flavor_type));
+
+ countValidRecords++;
+ tcore_at_tok_free(tokens);
+ continue;
+error:
+ dbg("invalid field found. coutinue");
+ tcore_at_tok_free(tokens);
+ continue;
+ }
+ dbg("valid count :%d", countValidRecords);
+ resp.record_num = countValidRecords;
+ resp.err = SS_ERROR_NONE;
+ } else {
+ dbg("no active status - return to user")
+ }
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ 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 = SS_ERROR_SYSTEMFAILURE;
+ } else {
+ err = atoi(g_slist_nth_data(tokens, 0));
+ /* TODO: CMEE error mapping is required. */
+ resp.err = SS_ERROR_SYSTEMFAILURE;
+ }
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("on_response_ss_forwarding_get- rsp.err : %d, ur : %x", resp.err, ur);
+ if (ur)
+ tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_forwarding), &resp);
+ else
+ dbg("[ error ] ur is 0");
+
+ if (resp.record) {
+ g_free(resp.record);
+ resp.record = NULL;
+ }
+ g_free(user_data);
+}
+
+static void on_response_ss_waiting_get(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = 0;
+ GSList *respdata, *tokens = NULL;
+ int classx = 0, err = 0;
+ struct ss_confirm_info *info = 0;
+ struct tresp_ss_waiting resp;
+ int countRecords = 0, countValidRecords = 0;
+ const char *line;
+ char *classx_str, *status;
+ const TcoreATResponse *response;
+
+ dbg("function enter")
+ response = data;
+ ur = tcore_pending_ref_user_request(p);
+ info = (struct ss_confirm_info *) user_data;
+
+ if (response->lines) {
+ respdata = (GSList *) response->lines;
+ countRecords = g_slist_length(respdata);
+ dbg("total records : %d", countRecords);
+ } else {
+ countRecords = 0;
+ 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);
+
+ for (countValidRecords = 0; respdata != NULL; respdata = respdata->next) {
+ line = (const char *) (respdata->data);
+ tokens = tcore_at_tok_new(line);
+
+ // parse <status>
+ status = g_slist_nth_data(tokens, 0);
+ if (!status) {
+ dbg("Missing stat in responce ");
+ goto error;
+ } else {
+ if (atoi(status) == 1) {
+ resp.record[countValidRecords].status = SS_STATUS_ACTIVATE;
+ } else {
+ resp.record[countValidRecords].status = SS_STATUS_DEACTIVATE;
+ }
+ }
+ dbg("status = %d", resp.record[countValidRecords].status);
+
+ // Parse <class>
+ classx_str = g_slist_nth_data(tokens, 1);
+ if (!classx_str) {
+ dbg("error - class is missing");
+ goto error;
+ } else {
+ switch (atoi(classx_str)) {
+ case 1:
+ resp.record[countValidRecords].class = SS_CLASS_VOICE;
+ break;
+
+ case 2:
+ resp.record[countValidRecords].class = SS_CLASS_ALL_DATA_TELE;
+ break;
+
+ case 4:
+ resp.record[countValidRecords].class = SS_CLASS_FAX;
+ break;
+
+ case 7:
+ resp.record[countValidRecords].class = SS_CLASS_ALL_TELE;
+ break;
+
+ case 8:
+ resp.record[countValidRecords].class = SS_CLASS_SMS;
+ break;
+
+ case 16:
+ resp.record[countValidRecords].class = SS_CLASS_ALL_CS_SYNC;
+ break;
+
+ case 32:
+ resp.record[countValidRecords].class = SS_CLASS_ALL_CS_ASYNC;
+ break;
+
+ default:
+ dbg("unspoorted class : [%d]\n", classx);
+ goto error;
+ break;
+ }
+ dbg("class info %d", resp.record[countValidRecords].class);
+ }
+
+ countValidRecords++;
+ tcore_at_tok_free(tokens);
+ continue;
+error:
+ dbg("invalid field found. coutinue");
+ tcore_at_tok_free(tokens);
+ continue;
+ }
+
+ dbg("valid count :%d", countValidRecords);
+ resp.record_num = countValidRecords;
+ resp.err = SS_ERROR_NONE;
+ } else {
+ dbg("no active status - return to user")
+ }
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ 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 = SS_ERROR_SYSTEMFAILURE;
+ } else {
+ err = atoi(g_slist_nth_data(tokens, 0));
+ // TODO: CMEE error mapping is required.
+ resp.err = SS_ERROR_SYSTEMFAILURE;
+ }
+ tcore_at_tok_free(tokens);
+ }
+
+ dbg("on_response_ss_waiting_get - rsp.err : %d, ur : %x", resp.err, ur);
+ if (ur)
+ tcore_user_request_send_response(ur, info->resp, sizeof(struct tresp_ss_waiting), &resp);
+ else
+ dbg("[ error ] ur is 0");
+
+ if (resp.record) {
+ g_free(resp.record);
+ resp.record = NULL;
+ }
+ g_free(user_data);
+}
+
+
+static void on_response_ss_cli_get(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+ UserRequest *ur = 0;
+ struct tresp_ss_cli resp;
+ enum telephony_ss_cli_type *p_type = NULL;
+ char *line = NULL, *status;
+ int err = FALSE;
+ int cli_adj, stat;
+ GSList *tokens = NULL;
+ const TcoreATResponse *response;
+
+ dbg("function enter")
+ response = data;
+ ur = tcore_pending_ref_user_request(p);
+ p_type = (enum telephony_ss_cli_type *) (user_data);
+
+ if (response->success > 0) {
+ line = (char *) (((GSList *) response->lines)->data);
+ tokens = tcore_at_tok_new(line);
+
+ if (*p_type == SS_CLI_TYPE_CLIR) {
+ // +CLIR: <n> <m>
+ dbg("CLI type is CLIR")
+ // parse <n>
+ status = g_slist_nth_data(tokens, 0);
+
+ if (!status) {
+ dbg("Call line identification adjustment missing <n>");
+ } else {
+ cli_adj = atoi(status);
+ dbg("CLIR response value of <n> - %d", cli_adj);
+
+ if (cli_adj == 0) {
+ // parse <m>
+ status = g_slist_nth_data(tokens, 1);
+ if (!status) {
+ dbg("status is missing<m>");
+ }
+ stat = atoi(status);
+ dbg("CLIR response value of <m> - %d", stat);
+
+ if (stat == 1 || stat == 3) {
+ resp.status = TRUE;
+ } else {
+ resp.status = FALSE;
+ }
+ } else if (cli_adj == 1) {
+ resp.status = TRUE;
+ } else {
+ resp.status = FALSE;
+ }
+ dbg("resp.status - %d", resp.status);
+ }
+ tcore_at_tok_free(tokens);
+ } else {
+ // parse <n>
+ status = g_slist_nth_data(tokens, 0);
+ if (!status) {
+ dbg("Stat is missing");
+ } else {
+ stat = atoi(status);
+ if (stat == 1)
+ resp.status = TRUE;
+ else
+ resp.status = FALSE;
+
+ dbg("resp.status - %d", resp.status);
+ }
+ tcore_at_tok_free(tokens);
+ }
+ }
+
+ if (response->success > 0) {
+ dbg("RESPONSE OK");
+ resp.err = SS_ERROR_NONE;
+ } else {
+ dbg("RESPONSE NOT OK");
+
+ line = (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 = SS_ERROR_SYSTEMFAILURE;
+ } else {
+ err = atoi(g_slist_nth_data(tokens, 0));
+ // TODO: CMEE error mapping is required.
+ resp.err = SS_ERROR_SYSTEMFAILURE;
+ }
+ tcore_at_tok_free(tokens);
+ }
+
+ resp.type = *p_type;
+ dbg("check - resp.type = %d ", resp.type);
+ if (ur)
+ tcore_user_request_send_response(ur, TRESP_SS_CLI_GET_STATUS, sizeof(struct tresp_ss_cli), &resp);
+ else
+ dbg("[ error ] ur : (0)");
+
+ g_free(user_data);
+}
+
+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,
+};
+
+
+static TReturn _ss_barring_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op)
+{
+ 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];
+ int opco;
+ int classx;
+ char *facility = NULL;
+ gboolean ret = FALSE;
+
+ dbg("function enter");
+ barring = (struct treq_ss_barring *) tcore_user_request_ref_data(ur, 0);
+
+ switch (op) {
+ case SS_OPCO_ACTIVATE:
+ opco = 1;
+ break;
+
+ case SS_OPCO_DEACTIVATE:
+ opco = 0;
+ break;
+
+ default:
+ dbg("unsupported opco : %d", op);
+ return TCORE_RETURN_FAILURE;
+ }
+ dbg("opco - %d", opco);
+
+ switch (barring->mode) {
+ case SS_BARR_MODE_BAOC:
+ facility = "AO";
+ break;
+
+ case SS_BARR_MODE_BOIC:
+ facility = "OI";
+ break;
+
+ case SS_BARR_MODE_BOIC_NOT_HC:
+ facility = "OX";
+ break;
+
+ case SS_BARR_MODE_BAIC:
+ facility = "AI";
+ break;
+
+ case SS_BARR_MODE_BIC_ROAM:
+ facility = "IR";
+ 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:
+ // facility = "NS";
+ default:
+ dbg("unspported mode %d", barring->mode);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("facility - %s", facility);
+
+ switch (barring->class) {
+ case SS_CLASS_ALL_TELE:
+ classx = 7;
+ break;
+
+ case SS_CLASS_VOICE:
+ classx = 1;
+ break;
+
+ case SS_CLASS_ALL_DATA_TELE:
+ classx = 2;
+ break;
+
+ case SS_CLASS_FAX:
+ classx = 4;
+ break;
+
+ case SS_CLASS_SMS:
+ classx = 8;
+ break;
+
+ case SS_CLASS_ALL_CS_SYNC:
+ classx = 16;
+ break;
+
+ default:
+ classx = 7;
+ dbg("unsupported class %d. set to default : 7", barring->class);
+ break;
+ }
+
+ dbg("classx - %d", classx);
+
+ // 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);
+ 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);
+ return TCORE_RETURN_FAILURE;
+ }
+ user_data->flavor_type = (int) (barring->mode);
+ user_data->class = barring->class;
+
+ ret = _ss_request_message(pending, o, ur, on_response_ss_barring_set, user_data);
+ g_free(cmd_str);
+
+ if (!ret) {
+ dbg("AT request sent failed ")
+ if (user_data != NULL) {
+ g_free(user_data);
+ }
+ return TCORE_RETURN_FAILURE;
+ }
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn _ss_barring_get(CoreObject *o,
+ UserRequest *ur,
+ enum telephony_ss_class class,
+ enum telephony_ss_barring_mode mode,
+ enum tcore_response_command resp)
+{
+ struct ss_confirm_info *user_data = 0;
+ gboolean ret = FALSE;
+ char *cmd_str = NULL;
+ int opco, classx;
+ char *facility = NULL;
+ TcoreHal *hal;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req;
+
+ dbg("function enter");
+
+ // query status - opco is fixed to 2
+ opco = 2;
+ // barring mode
+ switch (mode) {
+ case SS_BARR_MODE_BAOC:
+ facility = "AO";
+ break;
+
+ case SS_BARR_MODE_BOIC:
+ facility = "OI";
+ break;
+
+ case SS_BARR_MODE_BOIC_NOT_HC:
+ facility = "OX";
+ break;
+
+ case SS_BARR_MODE_BAIC:
+ facility = "AI";
+ break;
+
+ case SS_BARR_MODE_BIC_ROAM:
+ facility = "IR";
+ break;
+
+ case SS_BARR_MODE_AB:
+ case SS_BARR_MODE_AOB:
+ case SS_BARR_MODE_AIB:
+ case SS_BARR_MODE_BIC_NOT_SIM:
+ default:
+ dbg("unsupported mode %d", mode);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("facility - %s", facility);
+
+ switch (class) {
+ case SS_CLASS_ALL_TELE:
+ classx = 7;
+ break;
+
+ case SS_CLASS_VOICE:
+ classx = 1;
+ break;
+
+ case SS_CLASS_ALL_DATA_TELE:
+ classx = 2;
+ break;
+
+ case SS_CLASS_FAX:
+ classx = 4;
+ break;
+
+ case SS_CLASS_SMS:
+ classx = 8;
+ break;
+
+ case SS_CLASS_ALL_CS_SYNC:
+ classx = 16;
+ break;
+
+ default:
+ classx = 7;
+ dbg("unsupported class %d. set to default : 7", class);
+ break;
+ }
+ dbg("class - %d", classx);
+
+ if (classx == 7)
+ cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d", facility, opco);
+ else
+ cmd_str = g_strdup_printf("AT+CLCK=\"%s\",%d,,%d", facility, opco, classx);
+
+ 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);
+ 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;
+
+ ret = _ss_request_message(pending, o, ur, on_response_ss_barring_get, user_data);
+ g_free(cmd_str);
+
+ if (!ret) {
+ dbg("AT request sent failed ")
+ if (user_data != NULL) {
+ g_free(user_data);
+ }
+ return TCORE_RETURN_FAILURE;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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)
+{
+ 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)
+{
+ TcoreHal *hal;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req;
+ struct treq_ss_barring_change_password *barring = 0;
+ struct ss_confirm_info *user_data = 0;
+ char *cmd_str = NULL;
+ gboolean ret = FALSE;
+ char old_password[MAX_SS_BARRING_PASSWORD_LEN + 1];
+ char new_password[MAX_SS_BARRING_PASSWORD_LEN + 1];
+
+ dbg("function enter");
+
+ 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);
+
+ if (barring->password_old == NULL || barring->password_new == NULL) {
+ dbg("[error]password is null");
+ return TCORE_RETURN_FAILURE;
+ }
+ 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';
+
+ 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);
+ 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 ")
+ if (user_data != NULL) {
+ g_free(user_data);
+ }
+ return TCORE_RETURN_FAILURE;
+ }
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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);
+}
+
+static TReturn _ss_forwarding_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode op)
+{
+ struct treq_ss_forwarding *forwarding = 0;
+ struct ss_confirm_info *user_data = 0;
+ gboolean ret = FALSE;
+ int len = 0;
+ 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;
+
+ dbg("_ss_forwarding_set with opco %d ", op);
+
+ forwarding = (struct treq_ss_forwarding *) tcore_user_request_ref_data(ur, 0);
+ switch (forwarding->mode) {
+ case SS_CF_MODE_CFU:
+ reason = 0;
+ break;
+
+ case SS_CF_MODE_CFB:
+ reason = 1;
+ break;
+
+ case SS_CF_MODE_CFNRy:
+ reason = 2;
+ break;
+
+ case SS_CF_MODE_CFNRc:
+ reason = 3;
+ break;
+
+ case SS_CF_MODE_CF_ALL:
+ reason = 4;
+ break;
+
+ case SS_CF_MODE_CFC:
+ reason = 5;
+ break;
+
+ default:
+ dbg("unsupported reason : %d");
+ return TCORE_RETURN_FAILURE;
+ break;
+ }
+
+ dbg("reason = %d", reason);
+ switch (op) {
+ case SS_OPCO_DEACTIVATE:
+ mode = 0;
+ break;
+
+ case SS_OPCO_ACTIVATE:
+ mode = 1;
+ break;
+
+ case SS_OPCO_REG:
+ mode = 3;
+ break;
+
+ case SS_OPCO_DEREG:
+ mode = 4;
+ break;
+
+ default:
+ dbg("unsupported opco : %d", op);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ dbg("mode = %d", mode);
+
+ // class
+ switch (forwarding->class) {
+ case SS_CLASS_ALL_TELE:
+ classx = 7;
+ break;
+
+ case SS_CLASS_VOICE:
+ classx = 1;
+ break;
+
+ case SS_CLASS_ALL_DATA_TELE:
+ classx = 2;
+ break;
+
+ case SS_CLASS_FAX:
+ classx = 4;
+ break;
+
+ case SS_CLASS_SMS:
+ classx = 8;
+ break;
+
+ case SS_CLASS_ALL_CS_SYNC:
+ classx = 16;
+ break;
+
+ default:
+ classx = 7;
+ dbg("unsupported class %d. set to default : 7", forwarding->class);
+ break;
+ }
+ dbg("classx = %d", classx);
+
+ // 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
+ num_type = 0;
+ }
+ dbg("number = %s", forwarding->number);
+
+ user_data = g_new0(struct ss_confirm_info, 1);
+
+ switch (op) {
+ case SS_OPCO_REG:
+ user_data->resp = TRESP_SS_FORWARDING_REGISTER;
+ break;
+
+ case SS_OPCO_DEREG:
+ user_data->resp = TRESP_SS_FORWARDING_DEREGISTER;
+ break;
+
+ case SS_OPCO_ACTIVATE:
+ user_data->resp = TRESP_SS_FORWARDING_ACTIVATE;
+ break;
+
+ case SS_OPCO_DEACTIVATE:
+ user_data->resp = TRESP_SS_FORWARDING_DEACTIVATE;
+ break;
+
+ default:
+ dbg("[ error ] unknown op (0x%x)", op);
+ break;
+ }
+
+ if (forwarding->number[0] == '+')
+ num_type = 145;
+ else
+ num_type = 129;
+
+ if (op == SS_OPCO_REG)
+ tmp_str = g_strdup_printf("AT+CCFC=%d,%d,\"%s\",%d,%d", reason, mode, forwarding->number, num_type, classx);
+ else // other opcode does not need num field
+ tmp_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
+
+ if (forwarding->mode == SS_CF_MODE_CFNRy) {
+ // add time info to 'no reply' case
+ time = (int) (forwarding->time);
+ cmd_str = g_strdup_printf("%s,,,%d", tmp_str, time);
+ } else {
+ cmd_str = g_strdup_printf("%s", tmp_str);
+ }
+
+ 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);
+ 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->flavor_type = forwarding->mode;
+ user_data->class = forwarding->class;
+
+ ret = _ss_request_message(pending, o, ur, on_response_ss_forwarding_set, user_data);
+
+ g_free(tmp_str);
+ g_free(cmd_str);
+
+ if (!ret) {
+ dbg("AT request sent failed ")
+ if (user_data != NULL) {
+ g_free(user_data);
+ }
+ return TCORE_RETURN_FAILURE;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn _ss_forwarding_get(CoreObject *o,
+ UserRequest *ur,
+ enum telephony_ss_class class,
+ enum telephony_ss_forwarding_mode type,
+ enum tcore_response_command resp)
+{
+ struct ss_confirm_info *user_data = 0;
+ gboolean ret = FALSE;
+ char *cmd_str = NULL;
+ int reason = 0, mode = 0, classx = 0;
+ TcoreHal *hal;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req;
+
+ dbg("function enter");
+
+ switch (type) {
+ case SS_CF_MODE_CFU:
+ reason = 0;
+ break;
+
+ case SS_CF_MODE_CFB:
+ reason = 1;
+ break;
+
+ case SS_CF_MODE_CFNRy:
+ reason = 2;
+ break;
+
+ case SS_CF_MODE_CFNRc:
+ reason = 3;
+ break;
+
+ case SS_CF_MODE_CF_ALL:
+ reason = 4;
+ break;
+
+ case SS_CF_MODE_CFC:
+ reason = 5;
+ break;
+
+ default:
+ dbg("unsupported reason : %d");
+ break;
+ }
+ dbg("reason = %d", reason);
+
+ switch (class) {
+ case SS_CLASS_ALL_TELE:
+ classx = 7;
+ break;
+
+ case SS_CLASS_VOICE:
+ classx = 1;
+ break;
+
+ case SS_CLASS_ALL_DATA_TELE:
+ classx = 2;
+ break;
+
+ case SS_CLASS_FAX:
+ classx = 4;
+ break;
+
+ case SS_CLASS_SMS:
+ classx = 8;
+ break;
+
+ case SS_CLASS_ALL_CS_SYNC:
+ classx = 16;
+ break;
+
+ default:
+ classx = 7;
+ dbg("unsupported class %d. set to default : 7", class);
+ break;
+ }
+
+ dbg("classx = %d", classx);
+
+ // query status - mode set to 2
+ mode = 2;
+ user_data = g_new0(struct ss_confirm_info, 1);
+ user_data->resp = resp;
+ user_data->class = class;
+ user_data->flavor_type = type;
+
+ if (classx == 7)
+ cmd_str = g_strdup_printf("AT+CCFC=%d,%d", reason, mode);
+ else
+ cmd_str = g_strdup_printf("AT+CCFC=%d,%d,,,%d", reason, mode, classx);
+
+ 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);
+ 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_forwarding_get, user_data);
+ g_free(cmd_str);
+
+ if (!ret) {
+ dbg("AT request sent failed ")
+ if (user_data != NULL) {
+ g_free(user_data);
+ }
+ return TCORE_RETURN_FAILURE;
+ }
+
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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)
+{
+ 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)
+{
+ 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)
+{
+ 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)
+{
+ 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);
+}
+
+
+static TReturn _ss_waiting_set(CoreObject *o, UserRequest *ur, enum telephony_ss_opcode opco)
+{
+ struct treq_ss_waiting *waiting = 0;
+ struct ss_confirm_info *user_data = 0;
+ 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 (opco == SS_OPCO_ACTIVATE) {
+ user_data->resp = TRESP_SS_WAITING_ACTIVATE;
+ mode = 1; // enable
+ } else if (opco == SS_OPCO_DEACTIVATE) {
+ user_data->resp = TRESP_SS_WAITING_DEACTIVATE;
+ mode = 0; // disable
+ } else
+ dbg("[ error ] unknown ss mode (0x%x)", opco);
+
+ switch (waiting->class) {
+ case SS_CLASS_ALL_TELE:
+ classx = 7;
+ break;
+
+ case SS_CLASS_VOICE:
+ classx = 1;
+ break;
+
+ case SS_CLASS_ALL_DATA_TELE:
+ classx = 2;
+ break;
+
+ case SS_CLASS_FAX:
+ classx = 4;
+ break;
+
+ case SS_CLASS_SMS:
+ classx = 8;
+ break;
+
+ default:
+ classx = 1;
+ dbg("unsupported class %d. set to default : 1", waiting->class);
+ break;
+ }
+ dbg("mode = %d classxx- %d", mode, classx);
+
+ user_data->class = waiting->class;
+ user_data->flavor_type = (int) opco;
+
+ 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);
+ 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 ")
+ if (user_data != NULL) {
+ g_free(user_data);
+ }
+ return TCORE_RETURN_FAILURE;
+ }
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn _ss_waiting_get(CoreObject *o,
+ UserRequest *ur,
+ enum telephony_ss_class class,
+ enum tcore_response_command resp)
+{
+ struct ss_confirm_info *user_data = 0;
+ gboolean ret = FALSE;
+ int classx; // mode,
+ char *cmd_str;
+ TcoreHal *hal;
+ TcorePending *pending = NULL;
+ TcoreATRequest *req;
+
+ dbg("function enter")
+ switch (class) {
+ case SS_CLASS_ALL_TELE:
+ classx = 7;
+ break;
+
+ case SS_CLASS_VOICE:
+ classx = 1;
+ break;
+
+ case SS_CLASS_ALL_DATA_TELE:
+ classx = 2;
+ break;
+
+ case SS_CLASS_FAX:
+ classx = 4;
+ break;
+
+ case SS_CLASS_SMS:
+ classx = 8;
+ break;
+
+ default:
+ classx = 7;
+ dbg("unsupported class %d. set to default : 7", class);
+ break;
+ }
+ dbg("classx - %d", classx);
+
+ dbg("allocating user data");
+ user_data = g_new0(struct ss_confirm_info, 1);
+ 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);
+ 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 ")
+ if (user_data != NULL) {
+ g_free(user_data);
+ }
+ return TCORE_RETURN_FAILURE;
+ }
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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)
+{
+ 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)
+{
+ 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)
+{
+ 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)
+{
+ 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)
+{
+ 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:
+ cmd_prefix = "+CLIP";
+ rsp_prefix = "+CLIP";
+ break;
+
+ case SS_CLI_TYPE_CLIR:
+ cmd_prefix = "+CLIR";
+ rsp_prefix = "+CLIR";
+ break;
+
+ case SS_CLI_TYPE_COLP:
+ cmd_prefix = "+COLP";
+ rsp_prefix = "+COLP";
+ break;
+
+ case SS_CLI_TYPE_COLR:
+ cmd_prefix = "+COLR";
+ rsp_prefix = "+COLR";
+ break;
+
+ case SS_CLI_TYPE_CNAP:
+ cmd_prefix = "+CNAP";
+ rsp_prefix = "+CNAP";
+ break;
+
+ case SS_CLI_TYPE_CDIP:
+ default:
+ dbg("unsupported cli_type : %d", cli->type);
+ return TCORE_RETURN_FAILURE;
+ break;
+ }
+ dbg("cmd_prefix : %s", cmd_prefix);
+
+ cmd_str = g_strdup_printf("AT%s?", cmd_prefix);
+ dbg("request cmd : %s", cmd_str);
+
+ user_data = g_new0(enum telephony_ss_cli_type, 1);
+ *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);
+ 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 ")
+ if (user_data != NULL) {
+ g_free(user_data);
+ }
+ return TCORE_RETURN_FAILURE;
+ }
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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);
+ user_data->resp = TRESP_SS_SEND_USSD;
+ ussd_s = tcore_ss_ussd_get_session(o);
+ if (!ussd_s) {
+ dbg("USSD session does not exist");
+ tcore_ss_ussd_create_session(o, (enum tcore_ss_ussd_type) ussd->type, (void *) tcore_user_request_ref(ur), 0);
+ } else {
+ if (ussd->type == SS_USSD_TYPE_USER_INITIATED) {
+ dbg("[ error ] ussd session is already exist");
+ g_free(user_data);
+ return TCORE_RETURN_FAILURE;
+ }
+
+ tcore_ss_ussd_set_session_type(ussd_s, (enum tcore_ss_ussd_type) ussd->type);
+ }
+
+ hal = tcore_object_get_hal(o);
+ pending = tcore_pending_new(o, 0);
+ 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);
+
+ ret = _ss_request_message(pending, o, ur, on_confirmation_ss_ussd, user_data);
+ g_free(cmd_str);
+
+ if (!ret) {
+ dbg("AT request sent failed ")
+ if (user_data != NULL) {
+ g_free(user_data);
+ }
+ return TCORE_RETURN_FAILURE;
+ }
+ return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn s_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)
+{
+ 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,
+};
+
+static TReturn s_ss_manage_call_send(CoreObject *o, UserRequest *ur, const char *cmd, ConfirmCallback cb, void *user_data)
+{
+ TcorePending *pending = NULL;
+ TcoreATRequest *req;
+ gboolean ret = FALSE;
+
+ pending = tcore_pending_new(o, 0);
+ req = tcore_at_request_new(cmd, 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);
+
+ ret = _ss_request_message(pending, o, ur, (TcorePendingResponseCallback) cb, user_data);
+ if (!ret) {
+ 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)
+{
+ char *cmd_str = NULL;
+ gboolean ret = FALSE;
+
+ dbg("function enter");
+ 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);
+ g_free(cmd_str);
+ return ret;
+}
+
+static TReturn s_ss_manage_call_1_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=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);
+ 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)
+{
+ char *cmd_str = NULL;
+ gboolean ret = FALSE;
+
+ dbg("function enter");
+ 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);
+ g_free(cmd_str);
+ return ret;
+}
+
+static TReturn s_ss_manage_call_2_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=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);
+ 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)
+{
+ char *cmd_str = NULL;
+ gboolean ret = FALSE;
+
+ dbg("function enter");
+ 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);
+ g_free(cmd_str);
+ return ret;
+}
+
+static TReturn s_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);
+ g_free(cmd_str);
+ return ret;
+}
+
+
+static TReturn s_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);
+ 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)
+{
+ 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);
+ g_free(cmd_str);
+
+ return ret;
+}
+
+gboolean s_ss_init(TcorePlugin *p, TcoreHal *h)
+{
+ CoreObject *so = 0, *co = 0;
+ struct property_call_info *data = 0;
+
+ so = tcore_ss_new(p, "ss", &ss_ops, h);
+ if (!so) {
+ dbg("[ error ] ss_new()");
+ return FALSE;
+ }
+
+ co = tcore_plugin_ref_core_object(p, "call");
+ if (!co) {
+ dbg("[ error ] plugin_ref_core_object");
+ return FALSE;
+ }
+
+ tcore_call_control_set_operations(co, &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);
+
+ return TRUE;
+}
+
+void s_ss_exit(TcorePlugin *p)
+{
+ 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);
+}
--- /dev/null
+<manifest>
+ <request>
+ <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>