From d8efd719c9a636c7add49d039f110434dd8db124 Mon Sep 17 00:00:00 2001 From: "jk7744.park" Date: Tue, 8 Sep 2015 22:40:30 +0900 Subject: [PATCH] tizen 2.3.1 release --- CMakeLists.txt | 13 +- LICENSE | 204 +++++++++++++ debian/changelog | 7 - debian/compat | 1 - debian/control | 21 -- debian/copyright | 7 - debian/dirs | 2 - debian/docs | 0 debian/rules | 118 -------- debian/tel-plugin-imcmodem.install.in | 1 - include/config.h | 35 +++ include/imcmodem.h | 41 +++ include/vnet.h | 19 +- packaging/tel-plugin-imcmodem.spec | 45 +-- src/config.c | 430 ++++++++++++++++++++++++++ src/desc-imcmodem.c | 380 ++--------------------- src/imcmodem.c | 554 ++++++++++++++++++++++++++++++++++ src/vnet.c | 87 ++++-- tel-plugin-imcmodem.manifest | 5 + 19 files changed, 1386 insertions(+), 584 deletions(-) mode change 100755 => 100644 CMakeLists.txt create mode 100644 LICENSE delete mode 100755 debian/changelog delete mode 100755 debian/compat delete mode 100755 debian/control delete mode 100755 debian/copyright delete mode 100755 debian/dirs delete mode 100755 debian/docs delete mode 100755 debian/rules delete mode 100755 debian/tel-plugin-imcmodem.install.in create mode 100644 include/config.h create mode 100644 include/imcmodem.h mode change 100755 => 100644 include/vnet.h create mode 100644 src/config.c mode change 100755 => 100644 src/desc-imcmodem.c create mode 100644 src/imcmodem.c mode change 100755 => 100644 src/vnet.c create mode 100644 tel-plugin-imcmodem.manifest diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100755 new mode 100644 index 3e7b83b..b92cb25 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(EXEC_PREFIX "\${prefix}") SET(LIBDIR "\${prefix}/lib") SET(INCLUDEDIR "\${prefix}/include") -SET(PKGCONFIGDIR "${PREFIX}/lib/pkgconfig" CACHE PATH PKGCONFIGDIR) +SET(PKGCONFIGDIR "${PREFIX}/${LIB_INSTALL_DIR}/pkgconfig" CACHE PATH PKGCONFIGDIR) SET(CMAKE_INSTALL_PREFIX "${PREFIX}") # Set required packages @@ -23,15 +23,17 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include/) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wdeclaration-after-statement -Wmissing-declarations -Wredundant-decls -Wcast-align") -ADD_DEFINITIONS("-DFEATURE_DLOG_DEBUG") +ADD_DEFINITIONS("-DFEATURE_TLOG_DEBUG") ADD_DEFINITIONS("-DTCORE_LOG_TAG=\"IMCMODEM\"") MESSAGE(${CMAKE_C_FLAGS}) MESSAGE(${CMAKE_EXE_LINKER_FLAGS}) SET(SRCS - src/desc-imcmodem.c - src/vnet.c + src/desc-imcmodem.c + src/imcmodem.c + src/vnet.c + src/config.c ) @@ -44,4 +46,5 @@ SET_TARGET_PROPERTIES(imcmodem-plugin PROPERTIES PREFIX "" OUTPUT_NAME imcmodem- # install INSTALL(TARGETS imcmodem-plugin - LIBRARY DESTINATION lib/telephony/plugins) + LIBRARY DESTINATION ${LIB_INSTALL_DIR}/telephony/plugins) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION /usr/share/license RENAME tel-plugin-imcmodem) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bae7f54 --- /dev/null +++ b/LICENSE @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + diff --git a/debian/changelog b/debian/changelog deleted file mode 100755 index e9c50bb..0000000 --- a/debian/changelog +++ /dev/null @@ -1,7 +0,0 @@ -tel-plugin-imcmodem (0.1.0) unstable; urgency=low - - * Initial - * Git: slp/pkgs/t/tel-plugin-imcmodem - * Tag: tel-plugin-imcmodem_0.1.0 - - -- Kyoungyoup Park Mon, 06 August 2012 22:37:29 +0900 diff --git a/debian/compat b/debian/compat deleted file mode 100755 index 7ed6ff8..0000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -5 diff --git a/debian/control b/debian/control deleted file mode 100755 index cd3fb6f..0000000 --- a/debian/control +++ /dev/null @@ -1,21 +0,0 @@ -Source: tel-plugin-imcmodem -Section: libs -Priority: extra -Maintainer: Jongman Park -Uploaders: Jayoung Gu , Kyeongchul Kim , Youngman Park , Inho Oh , DongHoo Park -Build-Depends: debhelper (>= 5), - libglib2.0-dev, libtcore-dev, dlog-dev -Standards-Version: 0.0.0 - -Package: tel-plugin-imcmodem -Section: libs -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, -Description: telephony plugin library for AT communication with IMC modem (Shared Object) - -Package: tel-plugin-imcmodem-dbg -Section: debug -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, tel-plugin-imcmodem (= ${Source-Version}) -Description: telephony plugin library for AT communication with IMC modem (dbg package) - diff --git a/debian/copyright b/debian/copyright deleted file mode 100755 index d5a0cca..0000000 --- a/debian/copyright +++ /dev/null @@ -1,7 +0,0 @@ -Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License version 2.1. - -The full text of the LGPL 2.1 can be found in -/usr/share/common-licenses. diff --git a/debian/dirs b/debian/dirs deleted file mode 100755 index ca882bb..0000000 --- a/debian/dirs +++ /dev/null @@ -1,2 +0,0 @@ -usr/bin -usr/sbin diff --git a/debian/docs b/debian/docs deleted file mode 100755 index e69de29..0000000 diff --git a/debian/rules b/debian/rules deleted file mode 100755 index ab30b7c..0000000 --- a/debian/rules +++ /dev/null @@ -1,118 +0,0 @@ -#!/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-imcmodem-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 diff --git a/debian/tel-plugin-imcmodem.install.in b/debian/tel-plugin-imcmodem.install.in deleted file mode 100755 index f5b1d25..0000000 --- a/debian/tel-plugin-imcmodem.install.in +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/* diff --git a/include/config.h b/include/config.h new file mode 100644 index 0000000..fb0c534 --- /dev/null +++ b/include/config.h @@ -0,0 +1,35 @@ +/* + * tel-plugin-imcmodem + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Kyoungyoup Park + * + * 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 _CONFIG_H_ +#define _CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void config_check_cp_power(TcoreHal *hal); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _CONFIG_H_ */ diff --git a/include/imcmodem.h b/include/imcmodem.h new file mode 100644 index 0000000..391d977 --- /dev/null +++ b/include/imcmodem.h @@ -0,0 +1,41 @@ +/* + * tel-plugin-imcmodem + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Kyoungyoup Park + * + * 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 __IMCMODEM_H__ +#define __IMCMODEM_H__ + +typedef struct vnet_channel { + int fd; + guint watch_id; + gboolean on; +} ImcmodemVnetChannel; + +typedef struct custom_data { + TcoreModem *modem; + ImcmodemVnetChannel ipc0; +} ImcmodemCustomData; + +/* Initialize */ +gboolean imcmodem_init(TcorePlugin *plugin); + +/* De-initialize */ +void imcmodem_deinit(TcorePlugin *plugin); + +#endif /* __IMCMODEM_H__ */ diff --git a/include/vnet.h b/include/vnet.h old mode 100755 new mode 100644 index 5689f76..5c81e6c --- a/include/vnet.h +++ b/include/vnet.h @@ -18,17 +18,17 @@ * limitations under the License. */ - #ifndef _VNET_H_ #define _VNET_H_ - #ifdef __cplusplus extern "C" { #endif +/* CP states */ enum vnet_cp_state { - VNET_CP_STATE_OFFLINE, + VNET_CP_STATE_UNKNOWN = -1, + VNET_CP_STATE_OFFLINE = 0, VNET_CP_STATE_CRASH_RESET, VNET_CP_STATE_CRASH_EXIT, VNET_CP_STATE_BOOTING, @@ -37,18 +37,17 @@ enum vnet_cp_state { VNET_CP_STATE_LOADER_DONE, }; -void vnet_start_cp_ramdump( void ); -void vnet_start_cp_reset( void ); -int vnet_get_cp_state( int fd ); +void vnet_start_cp_ramdump( void ); +void vnet_start_cp_reset( void ); -int vnet_rfs0_open( void ); -int vnet_ipc0_open( void ); +enum vnet_cp_state vnet_get_cp_state( int fd ); +int vnet_rfs0_open( void ); +int vnet_ipc0_open( void ); #ifdef __cplusplus } #endif /* __cplusplus */ -#endif - +#endif /* _VNET_H_ */ diff --git a/packaging/tel-plugin-imcmodem.spec b/packaging/tel-plugin-imcmodem.spec index 008db59..d316be4 100755 --- a/packaging/tel-plugin-imcmodem.spec +++ b/packaging/tel-plugin-imcmodem.spec @@ -1,17 +1,26 @@ -#sbs-git:slp/pkgs/t/tel-plugin-imcmodem -Name: tel-plugin-imcmodem -Summary: telephony plugin library for AT communication with IMC modem -Version: 0.1.2 -Release: 1 -Group: System/Libraries -License: Apache -Source0: tel-plugin-imcmodem-%{version}.tar.gz -Requires(post): /sbin/ldconfig +%define major 0 +%define minor 1 +%define patchlevel 11 + +Name: tel-plugin-imcmodem +Version: %{major}.%{minor}.%{patchlevel} +Release: 1 +License: Apache-2.0 +Summary: telephony plugin library for AT communication with IMC modem +Group: System/Libraries +Source0: tel-plugin-imcmodem-%{version}.tar.gz + +%if "%{?tizen_profile_name}" == "mobile" && "%{_repository}" == "target" +%else +ExcludeArch: %{arm} %ix86 x86_64 +%endif + +BuildRequires: cmake +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(tcore) +Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig -BuildRequires: cmake -BuildRequires: pkgconfig(glib-2.0) -BuildRequires: pkgconfig(dlog) -BuildRequires: pkgconfig(tcore) %description imcmodem plugin for telephony @@ -20,8 +29,8 @@ imcmodem plugin for telephony %setup -q %build -cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -make %{?jobs:-j%jobs} +%cmake . +make %{?_smp_mflags} %post /sbin/ldconfig @@ -29,10 +38,12 @@ make %{?jobs:-j%jobs} %postun -p /sbin/ldconfig %install -rm -rf %{buildroot} %make_install +mkdir -p %{buildroot}/usr/share/license +cp LICENSE %{buildroot}/usr/share/license/%{name} %files +%manifest tel-plugin-imcmodem.manifest %defattr(-,root,root,-) -#%doc COPYING %{_libdir}/telephony/plugins/* +/usr/share/license/%{name} diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..1c0a2ff --- /dev/null +++ b/src/config.c @@ -0,0 +1,430 @@ +/* + * tel-plugin-imcmodem + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Kyoungyoup Park + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "imcmodem.h" +#include "config.h" + +#define IMC_MODEM_PLUGIN_NAME "imc-plugin.so" + +#define IMC_CMUX_MAX_CHANNELS 7 +#define IMC_CMUX_MAX_BUFFER_SIZE 2048 + +/* CP States */ +#define IMC_AT_CPAS_RESULT_READY 0 +#define IMC_AT_CPAS_RESULT_UNAVAIL 1 +#define IMC_AT_CPAS_RESULT_UNKNOWN 2 +#define IMC_AT_CPAS_RESULT_RINGING 3 +#define IMC_AT_CPAS_RESULT_CALL_PROGRESS 4 +#define IMC_AT_CPAS_RESULT_ASLEEP 5 + +/* Maximum Core objects per Logical HAL (indirectly per Channel) */ +#define MAX_CORE_OBJECTS_PER_CHANNEL 3 + +#define IMCMODEM_AT_CMD_XTRACE_ENABLE "at+xsystrace=1,\"digrf=1;bb_sw=1;3g_sw=1\",\"digrf=0x84\",\"oct=4\";+xsystrace=11;+trace=1" + +/* + * List of supported Core Object types + * + * CMUX Channels [0-7] - + * Channel 0 - Control Channel for CMUX + * Channel 1 - CALL & SS + * Channel 2 - SIM & PHONEBOOK + * Channel 3 - SAT & SAP + * Channel 4 - SMS + * Channel 5 - PS + * Channel 6 - NETWORK & GPS + * Channel 7 - MODEM & PS + */ +unsigned int + supported_modules[IMC_CMUX_MAX_CHANNELS+1][MAX_CORE_OBJECTS_PER_CHANNEL] = +{ + /* + * Channel 0 - CMUX Control Channel + * No Core Objects would be assigned to this channel + */ + {0, 0, 0}, + /* Channel 1 */ + {CORE_OBJECT_TYPE_CALL, CORE_OBJECT_TYPE_SS, 0}, + /* Channel 2 */ + {CORE_OBJECT_TYPE_SIM, CORE_OBJECT_TYPE_PHONEBOOK, 0}, + /* Channel 3 */ + {CORE_OBJECT_TYPE_SAT, CORE_OBJECT_TYPE_SAP, 0}, + /* Channel 4 */ + {CORE_OBJECT_TYPE_SMS, 0, 0}, + /* Channel 5 */ + {CORE_OBJECT_TYPE_PS, 0, 0}, + /* Channel 6 */ + {CORE_OBJECT_TYPE_NETWORK, CORE_OBJECT_TYPE_GPS, 0}, + /* Channel 7 */ + {CORE_OBJECT_TYPE_MODEM, 0, 0}, +}; + +static gboolean _check_cp_poweron(TcoreHal *hal); +static void _send_enable_logging_command(TcoreHal *hal); + +static void _on_confirmation_send_message(TcorePending *pending, + gboolean result, void *user_data) +{ + dbg("Message send confirmation"); + + if (result == FALSE) { /* Fail */ + dbg("SEND FAIL"); + } else { + dbg("SEND OK"); + } +} +static void _assign_objects_to_hal(int channel_id, TcoreHal *hal, TcoreHal *phy_hal) +{ + ImcmodemCustomData *custom_data; + TcoreModem *modem; + gboolean ret; + int i; + + if (hal == NULL) { + err("HAL is NULL"); + return; + } + + if (phy_hal == NULL) { + err("Physical HAL is NULL"); + return; + } + + custom_data = tcore_hal_ref_user_data(phy_hal); + if (custom_data == NULL) { + err("custom_data is NULL"); + return; + } + + modem = custom_data->modem; + + for (i = 0 ; i < MAX_CORE_OBJECTS_PER_CHANNEL ; i++) { + if (supported_modules[channel_id][i] == 0) + continue; + + /* Add Core Object type for specific 'hal' */ + ret = tcore_server_add_cp_mapping_tbl_entry(modem, + supported_modules[channel_id][i], hal); + if (ret == TRUE) { + dbg("Core Object Type: [0x%x] - Success"); + } else { + err("Core Object Type: [0x%x] - Fail"); + } + } +} + +static void _on_cmux_setup_complete(gpointer user_data) +{ + Server *s; + TcoreHal *hal = user_data; + ImcmodemCustomData *custom_data; + unsigned int slot_cnt = 1; + + dbg("MUX Setup - COMPLETE"); + + if (hal == NULL) { + err("HAL is NULL"); + return; + } + + custom_data = tcore_hal_ref_user_data(hal); + if (custom_data == NULL) { + err("custom_data is NULL"); + return; + } + + s = tcore_plugin_ref_server(tcore_hal_ref_plugin(hal)); + + /* Load Modem Plug-in */ + tcore_server_load_modem_plugin(s, + custom_data->modem, IMC_MODEM_PLUGIN_NAME); + dbg("Modem plug-in loaded"); + + tcore_server_send_notification(s, NULL, + TNOTI_SERVER_ADDED_MODEM_PLUGIN_COMPLETED, + sizeof(slot_cnt), &slot_cnt); +} + +static void _on_cmux_channel_setup(int channel_id, + TcoreHal *hal, gpointer user_data) +{ + TcorePlugin *plugin; + TcoreHal *phy_hal; + if ((hal == NULL) || (user_data == NULL)) + return; + + if ((channel_id == 0) || (channel_id > IMC_CMUX_MAX_CHANNELS)) { + err("Control Channel"); + return; + } + + phy_hal = user_data; + plugin = tcore_hal_ref_plugin(hal); + + dbg("Channel ID: [%d] Logical HAL: [0x%x]", channel_id, hal); + + /* Assign specifc Core Object types to the Logical HAL (CMUX Channel) */ + _assign_objects_to_hal(channel_id, hal, phy_hal); + + /* Set HAL state to Power ON (TRUE) */ + tcore_hal_set_power_state(hal, TRUE); + dbg("HAL Power State: Power ON"); +} + +static void _on_response_cmux_init(TcorePending *p, int data_len, + const void *data, void *user_data) +{ + const TcoreATResponse *resp = data; + TcoreHal *hal = user_data; + + if ((resp != NULL) && resp->success) { + TReturn ret; + dbg("Initialize CMUX - [OK]"); + + /* Setup Internal CMUX */ + ret = tcore_cmux_setup_internal_mux(CMUX_MODE_BASIC, + IMC_CMUX_MAX_CHANNELS, + IMC_CMUX_MAX_BUFFER_SIZE, hal, + _on_cmux_channel_setup, hal, + _on_cmux_setup_complete, hal); + } else { + err("Initialize CMUX - [NOK]"); + } +} + +static void _on_response_enable_logging(TcorePending *p, + int data_len, const void *data, void *user_data) +{ + const TcoreATResponse *resp = data; + TcoreHal *hal = user_data; + TReturn ret; + + if ((resp != NULL) && resp->success) { + dbg("Enable CP logging - [OK]"); + } else { + err("Enable CP logging - [NOK]"); + } + + /* Initialize Internal MUX (CMUX) */ + ret = tcore_cmux_init(hal, 0, _on_response_cmux_init, hal); + if (ret != TCORE_RETURN_SUCCESS) { + err("Failed to initialize CMUX - Error: [0x%x]", ret); + } else { + dbg("Successfully sent CMUX init to CP"); + } +} + +static void _on_timeout_check_cp_poweron(TcorePending *p, void *user_data) +{ + TcoreHal *hal = user_data; + unsigned int data_len = 0; + char *data = "AT+CPAS"; + + data_len = sizeof(data); + + dbg("Resending Command: [%s] Command Length: [%d]", data, data_len); + + /* + * Retransmit 1st AT command (AT+CPAS) directly via HAL without disturbing + * pending queue. + * HAL was passed as user_data, re-using it + */ + tcore_hal_send_data(hal, data_len, (void *)data); +} + +static void _on_response_check_cp_poweron(TcorePending *pending, + int data_len, const void *data, void *user_data) +{ + const TcoreATResponse *resp = data; + TcoreHal *hal = user_data; + + GSList *tokens = NULL; + const char *line; + gboolean bpoweron = FALSE; + int response = 0; + + if ((resp != NULL) + && resp->success) { + dbg("Check CP POWER - [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) { + err("Invalid message"); + goto ERROR; + } + } + + response = atoi(g_slist_nth_data(tokens, 0)); + dbg("CPAS State: [%d]", response); + + switch (response) { + case IMC_AT_CPAS_RESULT_READY: + case IMC_AT_CPAS_RESULT_RINGING: + case IMC_AT_CPAS_RESULT_CALL_PROGRESS: + case IMC_AT_CPAS_RESULT_ASLEEP: + dbg("CP Power ON!!!"); + bpoweron = TRUE; + break; + + case IMC_AT_CPAS_RESULT_UNAVAIL: + case IMC_AT_CPAS_RESULT_UNKNOWN: + default: + err("Value is Unvailable/Unknown - but CP responded - proceed with Power ON!!!"); + bpoweron = TRUE; + break; + } + } else { + dbg("Check CP POWER - [NOK]"); + } + +ERROR: + /* Free tokens */ + tcore_at_tok_free(tokens); + + if (bpoweron == TRUE) { + dbg("CP Power ON received"); + + /* Enable Logging */ + _send_enable_logging_command(hal); + } else { + err("CP is not ready, send CPAS again"); + _check_cp_poweron(hal); + } + return; +} + +static void _send_enable_logging_command(TcoreHal *hal) +{ + TcoreATRequest *at_req = NULL; + TcorePending *pending = NULL; + + dbg("Sending Trace enabling command for CP logging"); + + /* Create Pending request */ + pending = tcore_pending_new(NULL, 0); + + /* Create AT Request */ + at_req = tcore_at_request_new(IMCMODEM_AT_CMD_XTRACE_ENABLE, + NULL, TCORE_AT_NO_RESULT); + + if (at_req == NULL) { + tcore_pending_free(pending); + return; + } + + dbg("AT-Command: [%s] Prefix(if any): [%s] Command length: [%d]", + at_req->cmd, at_req->prefix, strlen(at_req->cmd)); + + /* Set request data and register Response and Send callbacks */ + tcore_pending_set_request_data(pending, 0, at_req); + tcore_pending_set_response_callback(pending, _on_response_enable_logging, hal); + tcore_pending_set_send_callback(pending, _on_confirmation_send_message, NULL); + + /* Send command to CP */ + if (tcore_hal_send_request(hal, pending) != TCORE_RETURN_SUCCESS) { + tcore_pending_free(pending); + tcore_at_free(at_req); + + err("Failed to send Trace logging command"); + } else { + dbg("Successfully sent Trace logging command"); + } +} + +static gboolean _check_cp_poweron(TcoreHal *hal) +{ + TcoreATRequest *at_req; + TcorePending *pending = NULL; + + /* Create Pending request */ + pending = tcore_pending_new(NULL, 0); + + /* Create AT Request */ + at_req = tcore_at_request_new("AT+CPAS", "+CPAS:", TCORE_AT_SINGLELINE); + + if (at_req == NULL) { + tcore_pending_free(pending); + return FALSE; + } + + dbg("AT-Command: [%s] Prefix(if any): [%s] Command length: [%d]", + at_req->cmd, at_req->prefix, strlen(at_req->cmd)); + + tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT); + + /* Set timeout value and timeout callback */ + tcore_pending_set_timeout(pending, 10); + tcore_pending_set_timeout_callback(pending, _on_timeout_check_cp_poweron, hal); + + /* Set request data and register Response and Send callbacks */ + tcore_pending_set_request_data(pending, 0, at_req); + tcore_pending_set_response_callback(pending, _on_response_check_cp_poweron, hal); + tcore_pending_set_send_callback(pending, _on_confirmation_send_message, NULL); + + /* Send command to CP */ + if (tcore_hal_send_request(hal, pending) != TCORE_RETURN_SUCCESS) { + tcore_pending_free(pending); + tcore_at_free(at_req); + + err("Failed to send CPAS"); + return FALSE; + } else { + dbg("Successfully sent CPAS"); + return TRUE; + } +} + +void config_check_cp_power(TcoreHal *hal) +{ + gboolean ret; + dbg("Entry"); + + if (hal == NULL) + return; + + ret = _check_cp_poweron(hal); + if (ret == TRUE) { + dbg("Successfully sent check CP Power ON command"); + } else { + err("Failed to send check CP Power ON command"); + } +} diff --git a/src/desc-imcmodem.c b/src/desc-imcmodem.c old mode 100755 new mode 100644 index 48f6961..5039dbe --- a/src/desc-imcmodem.c +++ b/src/desc-imcmodem.c @@ -20,393 +20,49 @@ #include #include -#include -#include -#include -#include -#include #include #include #include #include -#include -#include -#include -#include "vnet.h" +#include "imcmodem.h" -struct vnet_channel { - int fd; - guint watch_id; - gboolean on; -}; - -struct custom_data { - struct vnet_channel ipc0; -}; - -typedef gboolean(*cb_func)(GIOChannel *channel, GIOCondition condition, gpointer data); - -static gboolean on_recv_ipc_message(GIOChannel *channel, GIOCondition condition, gpointer data); - -static guint register_gio_watch(TcoreHal *p, int fd, void *callback); - -static TReturn hal_power(TcoreHal *h, gboolean flag); - -static void 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; ifd ) { - g_source_remove( ch->watch_id ); - close( ch->fd ); - } - - ch->fd = vnet_ipc0_open(); - if ( ch->fd < 0 ) { - dbg("[ error ] vnet_ipc0_open()"); - return FALSE; - } - - ch->watch_id = register_gio_watch(h, ch->fd, recv_message); - - ch->on = TRUE; - - return ch->on; -} - -static void _ipc0_deinit( struct vnet_channel *ch ) -{ - g_source_remove( ch->watch_id ); - close( ch->fd ); - - ch->watch_id = 0; - ch->fd = 0; - ch->on = FALSE; -} - - -static gboolean _silent_reset( TcoreHal *h ) -{ - dbg("[ error ] cp crash : strat silent reset"); - tcore_hal_set_power_state(h, FALSE); - - dbg("[ error ] do nothing."); -#if 0 // this is not applicable code, now silent reset is not guaranteed ( 2012, 04, 19 ) - - vnet_start_cp_reset(); - - if ( !hal_power( h, TRUE ) ) { - dbg("[ check ] cp crash : silent reset done"); - return TRUE; - } - -#endif - - return FALSE; -} - -static gboolean _do_exception_operation( TcoreHal *h, int fd, GIOCondition con ) -{ - int state = -1; - struct custom_data *user_data = tcore_hal_ref_user_data( h ); - - dbg("entrance"); - - switch ( con ) { - case G_IO_HUP: { - state = vnet_get_cp_state( fd ); - if ( state < 0 ) { - dbg("[ error ] vnet_get_cp_state()"); - break; - } - - switch ( (enum vnet_cp_state)state ) { - case VNET_CP_STATE_CRASH_EXIT: { - dbg("[ error ] cp crash : strat ramdump"); - _ipc0_deinit( &user_data->ipc0 ); - vnet_start_cp_ramdump(); - - state = VNET_CP_STATE_CRASH_RESET; - - - } break; - - case VNET_CP_STATE_CRASH_RESET: { - - _ipc0_deinit( &user_data->ipc0 ); - - if (tcore_hal_get_power_state( h )) { - - state = VNET_CP_STATE_CRASH_RESET; - - if ( !_silent_reset( h ) ) { - dbg("[ error ] _silent_reset()"); - break; - } - } - - /* - * if current hal power state is FALSE, 'cp_reset' mean normal power off - * ( it's because of kernel concept ) - */ - state = VNET_CP_STATE_OFFLINE; - - } break; - - default: - dbg("useless state, state : (0x%x)", state); - return TRUE; - } - - } break; - - case G_IO_IN: - case G_IO_OUT: - case G_IO_PRI: - case G_IO_ERR: - case G_IO_NVAL: - dbg("[ error ] unknown problem, con : (0x%x)", con); - break; - - } - - tcore_hal_emit_recv_callback(h, sizeof(int), &state); - - dbg("done"); - - return TRUE; -} - -static gboolean _power_on( gpointer data ) -{ - struct custom_data *user_data = 0; - TcoreHal *h = (TcoreHal*)data; - gboolean ret = 0; - static int count = 0; - - user_data = tcore_hal_ref_user_data(h); - if (!user_data) { - dbg("[ error ] tcore_hal_ref_user_data()"); - return TRUE; - } - - count++; - - ret = _ipc0_init( h, &user_data->ipc0, on_recv_ipc_message ); - if ( !ret ) { - dbg("[ error ] _ipc0_init()"); - - if ( count > 20 ) { - dbg("[ error ] _ipc0_init() timeout"); - return FALSE; - } - - return TRUE; - } - - tcore_hal_set_power_state(h, TRUE); - - return FALSE; -} - -static TReturn hal_power(TcoreHal *h, gboolean flag) -{ - if (flag == FALSE) { - /* power off not support */ - return TCORE_RETURN_FAILURE; - } - - g_timeout_add_full( G_PRIORITY_HIGH, 500, _power_on, h, 0 ); - - return TCORE_RETURN_SUCCESS; -} - -static TReturn hal_send(TcoreHal *h, unsigned int data_len, void *data) -{ - int ret; - struct custom_data *user_data; - - if (tcore_hal_get_power_state(h) == FALSE) - return TCORE_RETURN_FAILURE; - - user_data = tcore_hal_ref_user_data(h); - if (!user_data) - return TCORE_RETURN_FAILURE; - - dbg("write (fd=%d, len=%d)", user_data->ipc0.fd, data_len); - - ret = write( user_data->ipc0.fd, (guchar *) data, data_len ); - if (ret < 0) - return TCORE_RETURN_FAILURE; - - return TCORE_RETURN_SUCCESS;; -} - -static struct tcore_hal_operations hops = -{ - .power = hal_power, - .send = hal_send, -}; - -static gboolean on_recv_ipc_message(GIOChannel *channel, GIOCondition condition, gpointer data) +static gboolean on_load() { - TcoreHal *h = data; - struct custom_data *custom; - - #define BUF_LEN_MAX 4096 - char buf[BUF_LEN_MAX]; - int n = 0; - - custom = tcore_hal_ref_user_data(h); - - if ( condition != G_IO_IN ) { - dbg("[ error ] svnet has a problem"); - return _do_exception_operation( h, custom->ipc0.fd, condition ); - } - - memset(buf, 0, BUF_LEN_MAX); - - n = read(custom->ipc0.fd, (guchar *) buf, BUF_LEN_MAX); - if (n < 0) { - err("read error. return_valute = %d", n); - return TRUE; - } - - msg("--[RECV]-------------------------"); - dbg("recv (len = %d)", n); - - tcore_hal_emit_recv_callback(h, n, buf); - msg("--[RECV FINISH]------------------\n"); - - /* Notice: Mode of any HAL is TCORE_HAL_MODE_AT as default. */ - tcore_hal_dispatch_response_data(h, 0, n, buf); + dbg("Load!!!"); return TRUE; } -static guint register_gio_watch(TcoreHal *h, int fd, void *callback) -{ - GIOChannel *channel = NULL; - guint source; - - if (fd < 0 || !callback) - return 0; - - channel = g_io_channel_unix_new(fd); - source = g_io_add_watch(channel, G_IO_IN | G_IO_HUP, (GIOFunc) callback, h); - g_io_channel_unref(channel); - channel = NULL; - - return source; -} - -static gboolean on_load() +static gboolean on_init(TcorePlugin *plugin) { - struct utsname u; - char *vnet_models[] = { "SMDK4410", "SMDK4212", "SLP_PQ", "SLP_PQ_LTE", "SLP_NAPLES", "REDWOOD", "TRATS", NULL }; - int i = 0; - - memset(&u, 0, sizeof(struct utsname)); - uname(&u); - - dbg("u.nodename: [%s]", u.nodename); + dbg("Init!!!"); - for (i = 0; vnet_models[i]; i++ ) { - if (!g_strcmp0(u.nodename, vnet_models[i])) { - return TRUE; - } + if (plugin == NULL) { + err("'plugin' is NULL"); + return FALSE; } - /* - * Not supported model - * - unload this plugin. - */ - - return FALSE; + return imcmodem_init(plugin); } -static gboolean on_init(TcorePlugin *p) +static void on_unload(TcorePlugin *plugin) { - TcoreHal *h; - struct custom_data *data; - - if (!p) - return FALSE; - - dbg("i'm init!"); - - data = calloc(sizeof(struct custom_data), 1); - memset(data, 0, sizeof(struct custom_data)); + dbg("Unload!!!"); - - /* - * HAL init - */ - h = tcore_hal_new(p, "6262", &hops, TCORE_HAL_MODE_AT); - - tcore_hal_set_power_state(h, FALSE); - tcore_hal_link_user_data(h, data); - - return TRUE; -} - -static void on_unload(TcorePlugin *p) -{ - if (!p) + if (plugin == NULL) { + err("Modem Interface Plug-in is NULL"); return; + } - dbg("i'm unload"); + imcmodem_deinit(plugin); + dbg("Unloaded MODEM Interface Plug-in"); } -struct tcore_plugin_define_desc plugin_define_desc = -{ +/* Modem Interface Plug-in descriptor - IMC modem */ +struct tcore_plugin_define_desc plugin_define_desc = { .name = "imcmodem", .priority = TCORE_PLUGIN_PRIORITY_HIGH, .version = 1, diff --git a/src/imcmodem.c b/src/imcmodem.c new file mode 100644 index 0000000..3862e55 --- /dev/null +++ b/src/imcmodem.c @@ -0,0 +1,554 @@ +/* + * tel-plugin-imcmodem + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Kyoungyoup Park + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "imcmodem.h" +#include "vnet.h" +#include "config.h" + +#define IMC_HAL_NAME "imcmodem" +#define IMC_BUFFER_LEN_MAX 4096 + +#define IMC_CP_POWER_ON_TIMEOUT 500 + +#define IMC_MAX_CP_POWER_ON_RETRIES 20 + +#define IMC_DEVICE_NAME_LEN_MAX 16 +#define IMC_DEVICE_NAME_PREFIX "pdp" + +#define VNET_CH_PATH_BOOT0 "/dev/umts_boot0" +#define IOCTL_CG_DATA_SEND _IO('o', 0x37) + +static gboolean _on_recv_ipc_message(GIOChannel *channel, GIOCondition condition, gpointer data); + +static guint _register_gio_watch(TcoreHal *hal, int fd, GIOFunc callback); +static void _deregister_gio_watch(guint watch_id); + + +static guint _register_gio_watch(TcoreHal *hal, int fd, GIOFunc callback) +{ + GIOChannel *channel = NULL; + guint source; + + if ((fd < 0) || (callback == NULL)) + return 0; + + /* Create Unix Watch channel */ + channel = g_io_channel_unix_new(fd); + + /* Add to Watch list for IO and HUP events */ + source = g_io_add_watch(channel, G_IO_IN | G_IO_HUP, (GIOFunc) callback, hal); + g_io_channel_unref(channel); + channel = NULL; + + return source; +} + +static void _deregister_gio_watch(guint watch_id) +{ + dbg("[IMCMODEM] Deregister Watch ID: [%d]", watch_id); + + /* Remove source */ + g_source_remove(watch_id); +} + +static gboolean _ipc0_init(TcoreHal *hal, ImcmodemVnetChannel *ch, GIOFunc recv_message) +{ + dbg("Entry"); + + /* Remove and close the Watch ID and 'fd' if they already exist */ + if (ch->fd >= 0) { + _deregister_gio_watch(ch->watch_id); + close(ch->fd); + } + + /* Open new 'fd' to communicate to CP */ + ch->fd = vnet_ipc0_open(); + if (ch->fd < 0) { + err("Failed to Open Communiation Channel to CP: [%d]", ch->fd); + return FALSE; + } + dbg("AP-CP Communication channel opened - fd: [%d]", ch->fd); + + /* Register Channel for IO */ + ch->watch_id = _register_gio_watch(hal, ch->fd, recv_message); + + ch->on = TRUE; + + return ch->on; +} + +static void _ipc0_deinit(ImcmodemVnetChannel *ch) +{ + /* Remove and close the Watch ID and 'fd' */ + dbg("Watch ID: [%d]", ch->watch_id); + if (ch->watch_id > 0) + _deregister_gio_watch(ch->watch_id); + + dbg("fd: [%d]", ch->fd); + if (ch->fd > 0) + close(ch->fd); + + ch->watch_id = 0; + ch->fd = 0; + + ch->on = FALSE; +} + +static gboolean _silent_reset(TcoreHal *hal) +{ + dbg("[ERROR] Silent Reset"); + + /* Set HAL Poer State to OFF (FALSE) */ + tcore_hal_set_power_state(hal, FALSE); + + /* TODO: Need to handle Silent Reset */ + + return FALSE; +} + +static gboolean _do_exception_operation(TcoreHal *hal, int fd, GIOCondition cond) +{ + enum vnet_cp_state state = VNET_CP_STATE_UNKNOWN; + ImcmodemCustomData *custom_data = tcore_hal_ref_user_data(hal); + dbg("Entry"); + + switch (cond) { + case G_IO_HUP: { + state = vnet_get_cp_state(fd); + if (state == VNET_CP_STATE_UNKNOWN) { + dbg("[ error ] vnet_get_cp_state()"); + break; + } + + switch (state) { + case VNET_CP_STATE_CRASH_EXIT: { + err("CP Crash: Start ramdump"); + + _ipc0_deinit(&(custom_data->ipc0)); + vnet_start_cp_ramdump(); + + state = VNET_CP_STATE_CRASH_RESET; + } + break; + + case VNET_CP_STATE_CRASH_RESET: { + err("CP Crash Reset"); + + _ipc0_deinit(&(custom_data->ipc0)); + + if (tcore_hal_get_power_state(hal) == TRUE) { + state = VNET_CP_STATE_CRASH_RESET; + + if (_silent_reset(hal) == FALSE) { + err("Silent Reset failed!!!"); + break; + } + } + + /* + * if current hal power state is FALSE, 'cp_reset' mean normal power off + * (it's because of kernel concept) + */ + state = VNET_CP_STATE_OFFLINE; + + } + break; + + default: + err("Unwanted State: [0x%x]", state); + return TRUE; + } + } + break; + + case G_IO_IN: + case G_IO_OUT: + case G_IO_PRI: + case G_IO_ERR: + case G_IO_NVAL: + dbg("Unknown/Undefined problem - condition: [0x%x]", cond); + break; + } + + /* Emit receive callback */ + tcore_hal_emit_recv_callback(hal, sizeof(int), &state); + return TRUE; +} + +static gboolean imcmodem_power_on(gpointer data) +{ + ImcmodemCustomData *custom_data; + TcoreHal *hal; + gboolean ret; + + static int count = 0; + dbg("Entry"); + + hal = (TcoreHal*)data; + + custom_data = tcore_hal_ref_user_data(hal); + if (custom_data == NULL) { + err("HAL Custom data is NULL"); + return TRUE; + } + + /* Increment the 'count' */ + count++; + + /* Create and Open interface to CP */ + ret = _ipc0_init(hal, &custom_data->ipc0, _on_recv_ipc_message); + if (ret == FALSE) { + err("Failed to Create/Open CP interface - Try count: [%d]", count); + + if (count > IMC_MAX_CP_POWER_ON_RETRIES) { + TcorePlugin *plugin = tcore_hal_ref_plugin(hal); + Server *server = tcore_plugin_ref_server(plugin); + struct tnoti_modem_power modem_power; + + err("Maximum timeout reached: [%d]", count); + + modem_power.state = MODEM_STATE_ERROR; + + /* Notify server a modem error occured */ + tcore_server_send_notification(server, NULL, + TNOTI_MODEM_POWER, + sizeof(struct tnoti_modem_power), &modem_power); + + tcore_hal_free(hal); + g_free(custom_data); + + return FALSE; + } + + return TRUE; + } + dbg("Created AP-CP interface"); + + /* Set HAL Power State ON (TRUE) */ + tcore_hal_set_power_state(hal, TRUE); + dbg("HAL Power State: Power ON"); + + /* CP is ONLINE, send AT+CPAS */ + config_check_cp_power(hal); + + /* To stop the cycle need to return FALSE */ + return FALSE; +} + +static void _on_cmux_channel_close(TcoreHal *hal, gpointer user_data) +{ + ImcmodemCustomData *custom_data; + + if (hal == NULL) { + err("HAL is NULL"); + return; + } + + custom_data = tcore_hal_ref_user_data(hal); + if (custom_data == NULL) { + err("custom_data is NULL"); + return; + } + + /* Remove mapping Table */ + tcore_server_remove_cp_mapping_tbl_entry(custom_data->modem, hal); +} + +static enum tcore_hook_return imcmodem_on_hal_send(TcoreHal *hal, + unsigned int data_len, void *data, void *user_data) +{ + msg("\n====== TX data DUMP ======\n"); + tcore_util_hex_dump(" ", data_len, data); + msg("\n====== TX data DUMP ======\n"); + + return TCORE_HOOK_RETURN_CONTINUE; +} + +static void imcmodem_on_hal_recv(TcoreHal *hal, + unsigned int data_len, const void *data, void *user_data) +{ + msg("\n====== RX data DUMP ======\n"); + tcore_util_hex_dump(" ", data_len, data); + msg("\n====== RX data DUMP ======\n"); +} + +static gboolean _on_recv_ipc_message(GIOChannel *channel, + GIOCondition condition, gpointer data) +{ + TcoreHal *hal = data; + ImcmodemCustomData *custom_data; + char recv_buffer[IMC_BUFFER_LEN_MAX]; + int recv_len = 0; + TReturn ret; + char buf[256]; + const char * str = NULL; + + custom_data = tcore_hal_ref_user_data(hal); + if (custom_data == NULL) { + err("custom_data is NULL"); + return TRUE; + } + + /* If the received input is NOT IO, then we need to handle the exception */ + if (condition != G_IO_IN) { + err("[ERROR] Not IO input"); + return _do_exception_operation(hal, custom_data->ipc0.fd, condition); + } + + memset(recv_buffer, 0x0, IMC_BUFFER_LEN_MAX); + + /* Receive data from device */ + recv_len = read(custom_data->ipc0.fd, (guchar *)recv_buffer, IMC_BUFFER_LEN_MAX); + if (recv_len < 0) { + str = strerror_r(errno, buf, 256); + err("[READ] recv_len: [%d] Error: [%s]", recv_len, str); + return TRUE; + } + + msg("\n---------- [RECV] Length of received data: [%d] ----------\n", recv_len); + + /* Emit response callback */ + tcore_hal_emit_recv_callback(hal, recv_len, recv_buffer); + + /* Dispatch received data to response handler */ + ret = tcore_hal_dispatch_response_data(hal, 0, recv_len, recv_buffer); + msg("\n---------- [RECV FINISH] Receive processing: [%d] ----------\n", ret); + + return TRUE; +} + +static TReturn imcmodem_hal_send(TcoreHal *hal, unsigned int data_len, void *data) +{ + int ret; + ImcmodemCustomData *custom_data; + + if (tcore_hal_get_power_state(hal) == FALSE) + return TCORE_RETURN_FAILURE; + + custom_data = tcore_hal_ref_user_data(hal); + if (custom_data == NULL) { + err("custom_data is NULL"); + return TCORE_RETURN_FAILURE; + } + + dbg("write (fd=%d, len=%d)", custom_data->ipc0.fd, data_len); + + ret = write(custom_data->ipc0.fd, (guchar *) data, data_len); + if (ret < 0) + return TCORE_RETURN_FAILURE; + + return TCORE_RETURN_SUCCESS;; +} + +static TReturn imcmodem_hal_setup_netif(CoreObject *co, + TcoreHalSetupNetifCallback func, void *user_data, + unsigned int cid, gboolean enable) +{ + if (enable == TRUE) { + int fd; + char ifname[IMC_DEVICE_NAME_LEN_MAX]; + int ret = -1; + char buf[256]; + const char * str = NULL; + + dbg("ACTIVATE"); + + /* Open device to send IOCTL command */ + fd = open(VNET_CH_PATH_BOOT0, O_RDWR); + if (fd < 0) { + str = strerror_r(errno, buf, 256); + err("Failed to Open [%s] Error: [%s]", VNET_CH_PATH_BOOT0, str); + return TCORE_RETURN_FAILURE; + } + + /* + * Send IOCTL to change the Channel to Data mode + * + * Presently only 2 Contexts are suported + */ + switch (cid) { + case 1: { + dbg("Send IOCTL: arg 0x05 (0101) HSIC1, cid: [%d]", cid); + ret = ioctl(fd, IOCTL_CG_DATA_SEND, 0x05); + } + break; + + case 2: { + dbg("Send IOCTL: arg 0x0A (1010) HSIC2, cid: [%d]", cid); + ret = ioctl(fd, IOCTL_CG_DATA_SEND, 0xA); + } + break; + + default: { + err("More than 2 Contexts are not supported right now!!! cid: [%d]", cid); + } + } + + /* Close 'fd' */ + close(fd); + + /* TODO - Need to handle Failure case */ + if (ret < 0) { + err("[ERROR] IOCTL_CG_DATA_SEND - FAIL [0x%x]", IOCTL_CG_DATA_SEND); + + /* Invoke callback function */ + if (func) + func(co, ret, NULL, user_data); + + return TCORE_RETURN_FAILURE; + } else { + dbg("[OK] IOCTL_CG_DATA_SEND - PASS [0x%x]", IOCTL_CG_DATA_SEND); + + /* Device name */ + snprintf(ifname, IMC_DEVICE_NAME_LEN_MAX, "%s%d", IMC_DEVICE_NAME_PREFIX, (cid - 1)); + dbg("Interface Name: [%s]", ifname); + + /* Invoke callback function */ + if (func) + func(co, ret, ifname, user_data); + + return TCORE_RETURN_SUCCESS; + } + } else { + dbg("DEACTIVATE"); + return TCORE_RETURN_SUCCESS; + } +} + +/* HAL Operations */ +static struct tcore_hal_operations hal_ops = { + .power = NULL, + .send = imcmodem_hal_send, + .setup_netif = imcmodem_hal_setup_netif, +}; + +/* Initialize */ +gboolean imcmodem_init(TcorePlugin *plugin) +{ + TcoreHal *hal; + ImcmodemCustomData *custom_data; + + /* Custom data for Modem Interface Plug-in */ + custom_data = g_try_new0(ImcmodemCustomData, 1); + if (custom_data == NULL) { + err("Failed to allocate memory for Custom data"); + return FALSE; + } + dbg("Created custom data memory"); + + /* Register to Server */ + custom_data->modem = tcore_server_register_modem(tcore_plugin_ref_server(plugin), plugin); + if (custom_data->modem == NULL) { + err("Failed to Register modem"); + g_free(custom_data); + return FALSE; + } + + /* Create Physical HAL */ + hal = tcore_hal_new(plugin, IMC_HAL_NAME, &hal_ops, TCORE_HAL_MODE_AT); + if (hal == NULL) { + err("Failed to Create Physical HAL"); + g_free(custom_data); + return FALSE; + } + dbg("HAL [0x%x] created", hal); + + /* Set HAL as Modem Interface Plug-in's User data */ + tcore_plugin_link_user_data(plugin, hal); + + /* Link Custom data to HAL's 'user_data' */ + tcore_hal_link_user_data(hal, custom_data); + + /* Add callbacks for Send/Receive Hooks */ + tcore_hal_add_send_hook(hal, imcmodem_on_hal_send, NULL); + tcore_hal_add_recv_callback(hal, imcmodem_on_hal_recv, NULL); + dbg("Added Send hook and Receive callback"); + + /* Set HAL state to Power OFF (FALSE) */ + tcore_hal_set_power_state(hal, FALSE); + dbg("HAL Power State: Power OFF"); + + /* Check CP Power ON */ + g_timeout_add_full(G_PRIORITY_HIGH, IMC_CP_POWER_ON_TIMEOUT, imcmodem_power_on, hal, 0); + + return TRUE; +} + +/* De-initialize */ +void imcmodem_deinit(TcorePlugin *plugin) +{ + Server *s; + TcoreHal *hal; + ImcmodemCustomData *custom_data; + + s = tcore_plugin_ref_server(plugin); + + /* Unload Modem Plug-in */ + tcore_server_unload_modem_plugin(s, plugin); + dbg("Unloaded modem plug-in"); + + /* HAL cleanup */ + hal = tcore_plugin_ref_user_data(plugin); + if (hal == NULL) { + err("HAL is NULL"); + return; + } + + custom_data = tcore_hal_ref_user_data(hal); + if (custom_data != NULL) { + /* Unregister Modem Interface Plug-in from Server */ + tcore_server_unregister_modem(s, custom_data->modem); + dbg("Unregistered from Server"); + + /* Deinitialize the Physical Channel */ + _ipc0_deinit(&custom_data->ipc0); + dbg("Deinitialized the Channel"); + + /* Free custom data */ + g_free(custom_data); + } + + /* Close CMUX and CMUX channels */ + tcore_cmux_close(hal, _on_cmux_channel_close, NULL); + dbg("CMUX is closed"); + + + /* Free HAL */ + tcore_hal_free(hal); + dbg("Freed HAL"); +} diff --git a/src/vnet.c b/src/vnet.c old mode 100755 new mode 100644 index 5178b90..d05f8fd --- a/src/vnet.c +++ b/src/vnet.c @@ -46,13 +46,17 @@ #ifndef __USE_GNU #define __USE_GNU #endif - - -#define MODEM_IMAGE_PATH "/boot/modem.bin" +#define MODEM_IMAGE_PATH "/opt/modem/modem.bin" #define NV_DIR_PATH "/csa/nv" #define NV_FILE_PATH NV_DIR_PATH"/nvdata.bin" -#define VNET_CH_PATH_BOOT0 "/dev/umts_boot0" +/* + * AP-CP comunication devices + */ +/* To track CP bootup */ +#define VNET_CH_PATH_BOOT0 "/dev/umts_boot0" + +/* Control communication channel */ #define VNET_CH_PATH_IPC0 "/dev/umts_ipc0" #define IOCTL_MODEM_STATUS _IO('o', 0x27) @@ -61,79 +65,96 @@ void vnet_start_cp_ramdump() { int ret; ret = system("/usr/bin/xmm6262-boot -o u &"); - dbg("system(/usr/bin/xmm6262-boot -o u &) ret[%d]",ret) + dbg("system(/usr/bin/xmm6262-boot -o u &) ret[%d]", ret); } void vnet_start_cp_reset() { int ret; ret = system("/usr/bin/xmm6262-boot &"); - dbg("system(/usr/bin/xmm6262-boot &) ret[%d]",ret) + dbg("system(/usr/bin/xmm6262-boot &) ret[%d]", ret); } -int vnet_get_cp_state( int fd ) +enum vnet_cp_state vnet_get_cp_state(int fd) { - enum vnet_cp_state state = VNET_CP_STATE_ONLINE; + enum vnet_cp_state state = VNET_CP_STATE_UNKNOWN; + dbg("Entry"); - state = ioctl( fd, IOCTL_MODEM_STATUS ); + /* Get CP state */ + state = ioctl(fd, IOCTL_MODEM_STATUS); - switch ( state ) { + switch (state) { case VNET_CP_STATE_OFFLINE: - dbg("cp state : offline"); + dbg("CP State: OFFLINE"); break; case VNET_CP_STATE_CRASH_RESET: - dbg("cp state : crash_reset"); + dbg("CP State: CRASH RESET"); break; case VNET_CP_STATE_CRASH_EXIT: - dbg("cp state : crash_exit"); + dbg("CP State: CRASH EXIT"); break; case VNET_CP_STATE_BOOTING: - dbg("cp state : boot"); + dbg("CP State: BOOT"); break; case VNET_CP_STATE_ONLINE: - dbg("cp state : online"); + dbg("CP State: ONLINE"); break; case VNET_CP_STATE_NV_REBUILDING: - dbg("cp state : nv rebuild"); + dbg("CP State: NV REBUILD"); break; case VNET_CP_STATE_LOADER_DONE: - dbg("cp state : loader done"); + dbg("CP State: LOADER DONE"); break; + case VNET_CP_STATE_UNKNOWN: default: - dbg("cp state : unknown state"); - return -1; + dbg("CP State: UNKNOWN State - [%d]", state); + break; } - return (int)state; + return state; } int vnet_ipc0_open() { - int state; - int fd = 0, cnt = 0; + enum vnet_cp_state state; + int fd; + char buf[256]; + const char * str = NULL; + + dbg("Entry"); + + /* Opening device to track CP state */ + fd = open(VNET_CH_PATH_BOOT0, O_RDWR); + if (fd < 0) { + str = strerror_r(errno, buf, 256); + err("Failed to Open [%s] Error: [%s]", VNET_CH_PATH_BOOT0, str); + return -1; + } - fd = open ( VNET_CH_PATH_BOOT0, O_RDWR ); - if ( fd < 0 ) { - dbg("error : open [ %s ] [ %s ]", VNET_CH_PATH_BOOT0, strerror(errno)); + /* Track the state of CP */ + state = vnet_get_cp_state(fd); + close (fd); + + dbg("CP State: [%d]", state); + if (state != VNET_CP_STATE_ONLINE) { + err("CP is NOT yet Online!!!"); return -1; } - state = vnet_get_cp_state( fd ); - if ( (enum vnet_cp_state)state != VNET_CP_STATE_ONLINE ) { + /* Opening AP-CP Control communication device */ + fd = open(VNET_CH_PATH_IPC0, O_RDWR); + if (fd < 0) { + str = strerror_r(errno, buf, 256); + err("Failed to Open [%s] Error: [%s]", VNET_CH_PATH_IPC0, str); return -1; - } else { - fd = open ( VNET_CH_PATH_IPC0, O_RDWR ); - if ( fd < 0 ) { - dbg("error : open [ %s ] [ %s ]", VNET_CH_PATH_IPC0, strerror(errno)); - return -1; - } } + return fd; } diff --git a/tel-plugin-imcmodem.manifest b/tel-plugin-imcmodem.manifest new file mode 100644 index 0000000..573257c --- /dev/null +++ b/tel-plugin-imcmodem.manifest @@ -0,0 +1,5 @@ + + + + + -- 2.7.4