From cb6b79a9ca43e01c5fbd2af174ab8dc201a7dfd4 Mon Sep 17 00:00:00 2001 From: Dongchul Lim Date: Tue, 17 Mar 2015 13:51:48 +0900 Subject: [PATCH] Code Sync up from tizen_2.4 Change-Id: Ie23eb42dd4ab36c8cadbecd1ed3da807924b2b12 --- .gitignore | 100 -- AUTHORS | 7 + CMakeLists.txt | 49 +- LICENSE | 408 ++--- include/s_indi_log.h | 59 + include/s_indi_main.h | 25 + include/s_indi_util.h | 111 ++ packaging/tel-plugin-indicator.spec | 43 +- src/desc-indicator.c | 515 ------ src/desc.c | 66 + src/s_indi_log.c | 43 + src/s_indi_main.c | 1456 +++++++++++++++++ ....manifest => tel-plugin-indicator.manifest | 2 +- 13 files changed, 2029 insertions(+), 855 deletions(-) delete mode 100644 .gitignore create mode 100644 AUTHORS mode change 100644 => 100755 CMakeLists.txt create mode 100644 include/s_indi_log.h create mode 100644 include/s_indi_main.h create mode 100644 include/s_indi_util.h delete mode 100755 src/desc-indicator.c create mode 100644 src/desc.c create mode 100644 src/s_indi_log.c create mode 100644 src/s_indi_main.c rename packaging/tel-plugin-indicator.manifest => tel-plugin-indicator.manifest (66%) diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 63619be..0000000 --- a/.gitignore +++ /dev/null @@ -1,100 +0,0 @@ -#Copyright (c) 2013 GitHub, Inc. -# -#Permission is hereby granted, free of charge, to any person obtaining a -#copy of this software and associated documentation files (the "Software"), -#to deal in the Software without restriction, including without limitation -#the rights to use, copy, modify, merge, publish, distribute, sublicense, -#and/or sell copies of the Software, and to permit persons to whom the -#Software is furnished to do so, subject to the following conditions: -# -#The above copyright notice and this permission notice shall be included in -#all copies or substantial portions of the Software. -# -#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -#FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -#DEALINGS IN THE SOFTWARE. -# -# https://github.com/github/gitignore - -# Object files -*.o - -# Libraries -*.lib -*.a - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app - -# CMake -CMakeCache.txt -CMakeFiles -Makefile -cmake_install.cmake -install_manifest.txt - -# Emacs -*~ -\#*\# -/.emacs.desktop -/.emacs.desktop.lock -.elc -auto-save-list -tramp -.\#* - -# Org-mode -.org-id-locations -*_archive - -# Linux -.* -!.gitignore -*~ - -# Vim -*.s[a-w][a-z] -*.un~ -Session.vim -.netrwhist -*~ - -# Eclipse -*.pydevproject -.project -.metadata -bin/** -tmp/** -tmp/**/* -*.tmp -*.bak -*.swp -*~.nib -local.properties -.classpath -.settings/ -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Locally stored "Eclipse launch configurations" -*.launch - -# CDT-specific -.cproject - -# PDT-specific -.buildpath diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..0051a87 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,7 @@ +Jongman Park +Ja-young Gu +DongHoo Park +Youngman Park +Inho Oh +Gaurav Kalra +Manjunath V diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100644 new mode 100755 index 1129a8e..be7e833 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,40 +1,55 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(indicator-plugin C) -#INCLUDE(FindPkgConfig) - -SET(PREFIX ${CMAKE_INSTALL_PREFIX}) -SET(EXEC_PREFIX "\${prefix}") -SET(LIBDIR "\${prefix}/lib") -SET(INCLUDEDIR "\${prefix}/include") - -# Set required packages +### Set required packages ### INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED glib-2.0 tcore tel-headers) +pkg_check_modules(pkgs REQUIRED glib-2.0 dlog deviced tcore vconf) FOREACH(flag ${pkgs_CFLAGS}) - SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include/) +### Plugin name/destination ### +SET(PLUGIN_NAME "indicator-plugin") +SET(PLUGIN_DEST "${LIB_INSTALL_DIR}/telephony/plugins") -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") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -O2 -Werror -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wdeclaration-after-statement -Wmissing-declarations -Wredundant-decls -Wcast-align -Wall -Wno-array-bounds -Wno-empty-body -Wno-ignored-qualifiers -Wswitch-default -Wno-unused-but-set-parameter -Wno-unused-but-set-variable") +### Common definitions ### ADD_DEFINITIONS("-DFEATURE_TLOG_DEBUG") +#ADD_DEFINITIONS("-DFEATURE_LOG_MODE_VERBOSE") ADD_DEFINITIONS("-DTCORE_LOG_TAG=\"INDICATOR\"") +ADD_DEFINITIONS("-DPLUGIN_VERSION=${VERSION}") +ADD_DEFINITIONS("-DEXPORT_API=__attribute__((visibility(\"default\")))") + +INCLUDE_DIRECTORIES( + ${CMAKE_SOURCE_DIR}/include +) MESSAGE(${CMAKE_C_FLAGS}) -MESSAGE(${CMAKE_EXE_LINKER_FLAGS}) +MESSAGE(${pkgs_LDFLAGS}) -SET(SRCS - src/desc-indicator.c +SET(PROFILE_DEFINITIONS + #ENABLE_AT_FACTORY_IPC + FEATURE_LOG_TX_RX_DATA +) + +SET(SRCS + src/desc.c + src/s_indi_main.c + src/s_indi_log.c ) # library build ADD_LIBRARY(indicator-plugin SHARED ${SRCS}) TARGET_LINK_LIBRARIES(indicator-plugin ${pkgs_LDFLAGS}) -SET_TARGET_PROPERTIES(indicator-plugin PROPERTIES PREFIX "" OUTPUT_NAME indicator-plugin) - +SET_TARGET_PROPERTIES(indicator-plugin + PROPERTIES PREFIX "" + OUTPUT_NAME indicator-plugin + LINKER_LANGUAGE C + COMPILE_DEFINITIONS "${PROFILE_DEFINITIONS}") # install +INSTALL(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION ${PLUGIN_DEST}) INSTALL(TARGETS indicator-plugin LIBRARY DESTINATION ${LIB_INSTALL_DIR}/telephony/plugins) INSTALL(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION /usr/share/license RENAME tel-plugin-indicator) diff --git a/LICENSE b/LICENSE index bae7f54..3d69259 100644 --- a/LICENSE +++ b/LICENSE @@ -1,204 +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. - +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/include/s_indi_log.h b/include/s_indi_log.h new file mode 100644 index 0000000..8fc92f4 --- /dev/null +++ b/include/s_indi_log.h @@ -0,0 +1,59 @@ +/* + * tel-plugin-indicator + * + * Copyright (c) 2014 Samsung Electronics Co. Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +enum { + MODEM_ID_PRIMARY, + MODEM_ID_SECONDARY +}; + +#define MODEM_ID_FIRST MODEM_ID_PRIMARY +#define MODEM_ID_LAST MODEM_ID_SECONDARY + +#ifdef FEATURE_LOG_MODE_VERBOSE +#define s_indi_log_v(...) dbg(__VA_ARGS__) +#else +#define s_indi_log_v(...) \ + do { \ + } while (0); +#endif + +#ifdef FEATURE_LOG_TX_RX_DATA +#define s_indi_log_txrx(id,...) \ + do { \ + const char *tag = s_indi_get_log_tag_with_id(id); \ + info_ex(tag, __VA_ARGS__); \ + } while (0); +#else +#define s_indi_log_txrx(id,...) \ + do { \ + } while (0); +#endif + +#define s_indi_log_ex(name,...) \ + do { \ + gchar *tag = s_indi_get_log_tag_with_cp_name(name); \ + dbg_ex(tag, __VA_ARGS__); \ + g_free(tag); \ + } while (0); + +inline const char *s_indi_get_log_tag_with_id(unsigned int modem_id); +inline char *s_indi_get_log_tag_with_cp_name(const char *cp_name); diff --git a/include/s_indi_main.h b/include/s_indi_main.h new file mode 100644 index 0000000..b13ca82 --- /dev/null +++ b/include/s_indi_main.h @@ -0,0 +1,25 @@ +/* + * tel-plugin-indicator + * + * Copyright (c) 2014 Samsung Electronics Co. Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +gboolean s_indi_init(TcorePlugin *plugin); +void s_indi_deinit(TcorePlugin *plugin); diff --git a/include/s_indi_util.h b/include/s_indi_util.h new file mode 100644 index 0000000..f6646f9 --- /dev/null +++ b/include/s_indi_util.h @@ -0,0 +1,111 @@ +/* + * tel-plugin-indicator + * + * Copyright (c) 2014 Samsung Electronics Co. Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#define s_indi_assert(cond) g_assert(cond) +#define s_indi_assert_not_reached() g_assert_not_reached() +#define s_indi_malloc0(sz) g_malloc0(sz) +#define s_indi_free_func g_free +#define s_indi_free(p) s_indi_free_func(p) +#define s_indi_strdup(str) g_strdup(str) +#define s_indi_str_has_suffix(str, pre) g_str_has_suffix(str, pre) + +#define S_INDI_ZERO (0) +#define S_INDI_ONE (1) +#define S_INDI_FIVE (5) +#define S_INDI_SIPC_ITER_START S_INDI_ONE +#define S_INDI_SIPC_ITER_END (255) +#define S_INDI_MINUS_ONE (-1) +#define S_INDI_NOT_USED(var) ((var) = (var)) +#define S_INDI_SIPC_MSG_ID(hdr) ((hdr).main_cmd << 8 | (hdr).sub_cmd) + +typedef enum { + S_INDI_CELLULAR_UNKNOWN = -1, + S_INDI_CELLULAR_OFF = 0x00, + S_INDI_CELLULAR_CONNECTED = 0x01, + S_INDI_CELLULAR_MMS_CONNECTED = 0x02, + S_INDI_CELLULAR_USING = 0x03, +} s_indi_cellular_state; + +typedef enum { + S_INDI_TRANSFER_UNKNOWN = -1, + S_INDI_TRANSFER_NORMAL = 0x00, + S_INDI_TRANSFER_RX = 0x01, + S_INDI_TRANSFER_TX = 0x02, + S_INDI_TRANSFER_RXTX = 0x03, +} s_indi_transfer_state; + +typedef enum { + S_INDI_LCD_UNKNOWN = -1, + S_INDI_LCD_ON = 0x01, + S_INDI_LCD_DIM = 0x02, + S_INDI_LCD_OFF = 0x03 +} s_indi_lcd_state; + +typedef enum { + S_INDI_PS_CALL_OK = 0x00, + S_INDI_PS_CALL_CONNECT = 0x01, + S_INDI_PS_CALL_NO_CARRIER = 0x03, +} s_indi_ps_call_state; + +struct global_data { + unsigned int id_current; + unsigned int id_start; + unsigned int id_end; +}; + +typedef struct s_indi_cp_state_info_type_struct s_indi_cp_state_info_type; +typedef struct { + gchar *mccmnc; + gboolean b_vconf_checker; + s_indi_lcd_state lcd_state; + int lcd_on_timeout; + int lcd_off_timeout; + int dormant_cnt; + gboolean is_dormant; + gboolean is_dormant_set; + s_indi_cp_state_info_type *parent; +} s_indi_dormancy_info_type; + +struct s_indi_cp_state_info_type_struct{ + CoreObject *co_ps; + GSource *src; + GHashTable *device_info; /* HashTable of s_indi_dev_state_info_type with key = dev_name */ + s_indi_dormancy_info_type dormant_info; + s_indi_cellular_state ps_state; + s_indi_transfer_state cp_trans_state; + unsigned long long rx_total; + unsigned long long tx_total; + int no_rx_pckt; /* Last time since packed was received in seconds */ + gboolean roaming_status; + int curr_timer_cp; + gboolean curr_fdy_state_cp; +}; + +typedef struct { + CoreObject *ps_context; + s_indi_cp_state_info_type *parent; + unsigned long prev_rx; + unsigned long prev_tx; + unsigned long curr_rx; + unsigned long curr_tx; +} s_indi_dev_state_info_type; diff --git a/packaging/tel-plugin-indicator.spec b/packaging/tel-plugin-indicator.spec index aada3ac..33b46db 100755 --- a/packaging/tel-plugin-indicator.spec +++ b/packaging/tel-plugin-indicator.spec @@ -1,36 +1,43 @@ -%define major 3 -%define minor 0 -%define patchlevel 1 +%define major 0 +%define minor 1 +%define patchlevel 62 -Name: tel-plugin-indicator -Summary: Telephony Indicator plugin +Name: tel-plugin-indicator Version: %{major}.%{minor}.%{patchlevel} -Release: 1 -Group: System/Libraries -License: Apache-2.0 -Source0: tel-plugin-indicator-%{version}.tar.gz -Source1001: tel-plugin-indicator.manifest -Requires(post): /sbin/ldconfig -Requires(postun): /sbin/ldconfig +Release: 5 +License: Apache-2.0 +Summary: Telephony Indicator plugin +Group: System/Libraries +Source0: tel-plugin-indicator-%{version}.tar.gz BuildRequires: cmake +BuildRequires: pkgconfig(deviced) +BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(tcore) -BuildRequires: pkgconfig(tel-headers) +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig %description Telephony Indicator plugin %prep %setup -q -cp %{SOURCE1001} . %build -%cmake . -make %{?jobs:-j%jobs} +versionint=$[%{major} * 1000000 + %{minor} * 1000 + %{patchlevel}] -%post +%cmake . -DVERSION=$versionint \ + +make %{?_smp_mflags} + +%post /sbin/ldconfig +##setting vconf key## +vconftool set -t bool memory/testmode/fast_dormancy 0 -i -f -s telephony_framework::vconf +vconftool set -t bool memory/testmode/fast_dormancy2 0 -i -f -s telephony_framework::vconf + %postun -p /sbin/ldconfig %install @@ -39,7 +46,7 @@ mkdir -p %{buildroot}/usr/share/license cp LICENSE %{buildroot}/usr/share/license/%{name} %files -%manifest %{name}.manifest +%manifest tel-plugin-indicator.manifest %defattr(-,root,root,-) %{_libdir}/telephony/plugins/indicator-plugin* /usr/share/license/%{name} diff --git a/src/desc-indicator.c b/src/desc-indicator.c deleted file mode 100755 index b57771f..0000000 --- a/src/desc-indicator.c +++ /dev/null @@ -1,515 +0,0 @@ -/* - * tel-plugin-indicator - * - * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define INDICATOR_UPDATE_INTERVAL 1 -#define INDICATOR_PROCFILE "/proc/net/dev" -#define INDICATOR_BUFF_SIZE 4096 -#define NO_RX_PKT_TIMEOUT 30 -//enum - -typedef enum _cellular_state { - CELLULAR_OFF = 0x00, - CELLULAR_NORMAL_CONNECTED = 0x01, - CELLULAR_SECURE_CONNECTED = 0x02, - CELLULAR_USING = 0x03, -} cellular_state; - -typedef enum _indicator_state { - INDICATOR_NORMAL = 0x00, - INDICATOR_RX = 0x01, - INDICATOR_TX = 0x02, - INDICATOR_RXTX = 0x03, -} indicator_state; - -typedef struct _indicator_device_state { - gchar *devname; - gboolean active; - guint64 prev_rx; - guint64 prev_tx; - guint64 curr_rx; - guint64 curr_tx; -}indicator_device_state; - -typedef struct _indicator_data { - indicator_device_state indicator_info; - GSource* src; -}indicator_data; - -static gboolean _indicator_update_callback(gpointer user_data); - -static void _indicator_initialize(indicator_data *data) -{ - if (data) { - data->indicator_info.prev_rx = 0; - data->indicator_info.prev_tx = 0; - data->indicator_info.curr_rx = 0; - data->indicator_info.curr_tx = 0; - } else { - err("user data is NULL"); - } -} - - -static gboolean _indicator_start_updater(Server *s, TcorePlugin *plugin) -{ - TcoreStorage *strg_vconf; - indicator_data *data = NULL; - - dbg("indicator is started"); - strg_vconf = tcore_server_find_storage(s, "vconf"); - - data = tcore_plugin_ref_user_data(plugin); - if(!data) { - err("user data is NULL"); - return FALSE; - } - - tcore_storage_set_int(strg_vconf, STORAGE_KEY_PACKET_SERVICE_STATE, CELLULAR_NORMAL_CONNECTED); - tcore_storage_set_int(strg_vconf, STORAGE_KEY_PACKET_INDICATOR_STATE, INDICATOR_NORMAL); - - if(data->src != 0) { - return FALSE; - } - - _indicator_initialize(data); - - data->src = g_timeout_source_new_seconds(INDICATOR_UPDATE_INTERVAL); - g_source_set_callback(data->src, _indicator_update_callback, plugin, NULL); - g_source_set_priority(data->src, G_PRIORITY_HIGH); - g_source_attach(data->src, NULL); - g_source_unref(data->src); - - return TRUE; -} - -static gboolean _indicator_stop_updater(Server *s, TcorePlugin *plugin) -{ - TcoreStorage *strg_vconf; - int t_rx = 0, t_tx = 0; - indicator_data *data = NULL; - - dbg("indicator is stopped"); - data = tcore_plugin_ref_user_data(plugin); - if (!data) { - err("user data is NULL"); - return FALSE; - } - strg_vconf = tcore_server_find_storage(s, "vconf"); - - tcore_storage_set_int(strg_vconf, STORAGE_KEY_PACKET_SERVICE_STATE, CELLULAR_OFF); - tcore_storage_set_int(strg_vconf, STORAGE_KEY_PACKET_INDICATOR_STATE, INDICATOR_NORMAL); - - t_rx = tcore_storage_get_int(strg_vconf, STORAGE_KEY_CELLULAR_PKT_TOTAL_RCV); - t_tx = tcore_storage_get_int(strg_vconf, STORAGE_KEY_CELLULAR_PKT_TOTAL_SNT); - t_rx += (int)data->indicator_info.curr_rx; - t_tx += (int)data->indicator_info.curr_tx; - - tcore_storage_set_int(strg_vconf, STORAGE_KEY_CELLULAR_PKT_TOTAL_RCV, t_rx); - tcore_storage_set_int(strg_vconf, STORAGE_KEY_CELLULAR_PKT_TOTAL_SNT, t_tx); - tcore_storage_set_int(strg_vconf, STORAGE_KEY_CELLULAR_PKT_LAST_RCV, (int)data->indicator_info.curr_rx); - tcore_storage_set_int(strg_vconf, STORAGE_KEY_CELLULAR_PKT_LAST_SNT, (int)data->indicator_info.curr_tx); - - if(data->src == 0){ - return TRUE; - } - - g_source_destroy(data->src); - data->src = 0; - - return TRUE; -} - -static gint _indicator_get_proc_ver(gchar *buff) -{ - if (strstr(buff, "compressed")) return 3; - if (strstr(buff, "bytes")) return 2; - return 1; -} - -static gint _indicator_get_pkt(gchar *buff, gint proc_ver, guint64 *rx_pkt, guint64 *tx_pkt) -{ - gint result = -1; - gchar s_rx[100]; - gchar s_tx[100]; - - memset(s_rx, 0 , 100); - memset(s_tx, 0 , 100); - - if (buff == NULL) - return result; - - switch (proc_ver) { - case 3: - result = sscanf(buff, - "%s %*s %*s %*s %*s %*s %*s %*s %s %*s %*s %*s %*s %*s %*s %*s", - s_rx, s_tx); - break; - case 2: - result = sscanf(buff, - "%s %*s %*s %*s %*s %*s %*s %*s %s %*s %*s %*s %*s %*s %*s %*s", - s_rx, s_tx); - break; - case 1: - result = sscanf(buff, - "%s %*s %*s %*s %*s %*s %*s %*s %s %*s %*s %*s %*s %*s %*s %*s", - s_rx, s_tx); - break; - default: - dbg("stats unknown version"); - break; - } - - *rx_pkt = g_ascii_strtoull(s_rx, NULL, 10); - *tx_pkt = g_ascii_strtoull(s_tx, NULL, 10); - - return result; -} - -static gboolean _indicator_get_pktcnt(indicator_data *data) -{ - FILE *pf = NULL; - gint proc_ver = 0; - char *res; - gchar buff[INDICATOR_BUFF_SIZE]; - - if (!data) { - err("user data is NULL"); - return FALSE; - } - - pf = fopen(INDICATOR_PROCFILE, "r"); - if (pf == NULL) { - err("indicator fail to open file(%s), errno(%d)", INDICATOR_PROCFILE, errno); - return FALSE; - } - - res = fgets(buff, sizeof(buff), pf); - if (res == NULL) - err("fegts fails"); - res = fgets(buff, sizeof(buff), pf); - if (res == NULL) - err("fegts fails"); - proc_ver = _indicator_get_proc_ver(buff); - - while (fgets(buff, sizeof(buff), pf)) { - gint result = 0; - guint64 rx_pkt = 0; - guint64 tx_pkt = 0; - gchar *ifname, *entry; - - ifname = buff; - while (*ifname == ' ') - ifname++; - entry = strrchr(ifname, ':'); - *entry++ = 0; - - result = _indicator_get_pkt(entry, proc_ver, &rx_pkt, &tx_pkt); - if (result <= 0) { - err("stats fail to get proc field"); - fclose(pf); - return FALSE; - } - - if ( g_strcmp0(ifname, data->indicator_info.devname) == 0 ){ - data->indicator_info.prev_rx = data->indicator_info.curr_rx; - data->indicator_info.prev_tx = data->indicator_info.curr_tx; - data->indicator_info.curr_rx = rx_pkt; - data->indicator_info.curr_tx = tx_pkt; - break; - } - } - - fclose(pf); - return TRUE; -} - -static gboolean _indicator_update(Server *s, indicator_data *data) -{ - guint64 rx_changes = 0; - guint64 tx_changes = 0; - TcoreStorage *strg_vconf; - - strg_vconf = tcore_server_find_storage(s, "vconf"); - if(!data) return FALSE; - if(!data->indicator_info.active) return FALSE; - - rx_changes = data->indicator_info.curr_rx - data->indicator_info.prev_rx; - tx_changes = data->indicator_info.curr_tx - data->indicator_info.prev_tx; - - if (rx_changes != 0 || tx_changes != 0) - tcore_storage_set_int(strg_vconf, STORAGE_KEY_PACKET_SERVICE_STATE, CELLULAR_USING); - else - tcore_storage_set_int(strg_vconf, STORAGE_KEY_PACKET_SERVICE_STATE, CELLULAR_NORMAL_CONNECTED); - - if (rx_changes > 0 && tx_changes > 0) - tcore_storage_set_int(strg_vconf, STORAGE_KEY_PACKET_INDICATOR_STATE, INDICATOR_RXTX); - else if (rx_changes > 0 && tx_changes == 0) - tcore_storage_set_int(strg_vconf, STORAGE_KEY_PACKET_INDICATOR_STATE, INDICATOR_RX); - else if (rx_changes == 0 && tx_changes > 0) - tcore_storage_set_int(strg_vconf, STORAGE_KEY_PACKET_INDICATOR_STATE, INDICATOR_TX); - else - tcore_storage_set_int(strg_vconf, STORAGE_KEY_PACKET_INDICATOR_STATE, INDICATOR_NORMAL); - - return TRUE; -} - -static gboolean _indicator_update_callback(gpointer user_data) -{ - gboolean rv = FALSE; - TcorePlugin *indicator_plugin = NULL; - Server *s = NULL; - indicator_data *data = NULL; - - indicator_plugin = (TcorePlugin *)user_data; - s = tcore_plugin_ref_server(indicator_plugin); - data = tcore_plugin_ref_user_data(indicator_plugin); - if(!data){ - err("user data is NULL"); - return FALSE; - } - - rv = _indicator_get_pktcnt(data); - if(!rv){ - data->src = 0; - return FALSE; - } - - rv = _indicator_update(s, data); - if(!rv){ - data->src = 0; - return FALSE; - } - - return TRUE; -} - -static TcoreHookReturn __on_hook_modem_powered(TcorePlugin *source, - TcoreNotification command, guint data_len, void *data, void *user_data) -{ - TelModemPowerStatus *power_status = NULL; - - dbg("powered event called"); - tcore_check_return_value(data != NULL, TCORE_HOOK_RETURN_STOP_PROPAGATION); - - power_status = (TelModemPowerStatus *)data; - if (*power_status == TEL_MODEM_POWER_ERROR) { - Server *s = NULL; - indicator_data *data = NULL; - TcorePlugin *plugin = (TcorePlugin *)user_data; - - data = tcore_plugin_ref_user_data(plugin); - if (data) { - data->indicator_info.active = FALSE; - g_free(data->indicator_info.devname); - data->indicator_info.devname = NULL; - s = tcore_plugin_ref_server(source); - if (s) { - _indicator_stop_updater(s, plugin); - } - }else { - err("user data is NULL"); - } - } - - return TCORE_HOOK_RETURN_CONTINUE; -} - -static TcoreHookReturn __on_hook_ps_callstatus(TcorePlugin *source, - TcoreNotification command, guint data_len, void *data, void *user_data) -{ - unsigned int con_id = 0; - CoreObject *co_ps = NULL, *co_context = NULL; - TcorePsCallStatusInfo *cstatus = NULL; - TcorePlugin *plugin = NULL; - indicator_data *indata = NULL; - Server *s = NULL; - gboolean res = FALSE; - - dbg("call status event"); - tcore_check_return_value((data != NULL) || (user_data != NULL), TCORE_HOOK_RETURN_STOP_PROPAGATION); - - plugin = (TcorePlugin *)user_data; - indata = tcore_plugin_ref_user_data(plugin); - tcore_check_return_value((indata != NULL) , TCORE_HOOK_RETURN_STOP_PROPAGATION); - - s = tcore_plugin_ref_server(source); - co_ps = tcore_plugin_ref_core_object(source, CORE_OBJECT_TYPE_PS); - dbg("ps object(%p)", co_ps); - co_context = tcore_ps_ref_context_by_role(co_ps, TCORE_CONTEXT_ROLE_INTERNET); - res = tcore_context_get_id(co_context, &con_id); - if (res == FALSE) { - err("get context id failed"); - return TCORE_HOOK_RETURN_CONTINUE; - } - dbg("context(%p) con_id(%d)", co_context, con_id); - - cstatus = (TcorePsCallStatusInfo *) data; - if (!cstatus) { - err("PS status is NULL"); - return TCORE_HOOK_RETURN_CONTINUE; - } - dbg("call status event cid(%d) state(%d)", cstatus->context_id, cstatus->state); - - if(con_id != cstatus->context_id) - return TCORE_HOOK_RETURN_CONTINUE; - - if (cstatus->state == TCORE_PS_CALL_STATE_CTX_DEFINED) { - /* do nothing. */ - dbg("Just noti for PDP define complete, do nothing."); - return TCORE_HOOK_RETURN_CONTINUE; - } - else if (cstatus->state == TCORE_PS_CALL_STATE_CONNECTED) { - indata->indicator_info.active = TRUE; - res = tcore_context_get_ipv4_devname(co_context, &indata->indicator_info.devname); - if (res == FALSE) { - err("get context ipv4 failed"); - return TCORE_HOOK_RETURN_CONTINUE; - } - _indicator_start_updater(s, plugin); - return TCORE_HOOK_RETURN_CONTINUE; - } - - indata->indicator_info.active = FALSE; - g_free(indata->indicator_info.devname); - indata->indicator_info.devname = NULL; - _indicator_stop_updater(s, plugin); - return TCORE_HOOK_RETURN_CONTINUE; -} - -static TcoreHookReturn __on_hook_modem_plugin_added(Server *s, - TcoreServerNotification command, - guint data_len, void *data, void *user_data) -{ - TcorePlugin *modem_plugin; - TcorePlugin *indicator_plugin = (TcorePlugin *)user_data; - - modem_plugin = (TcorePlugin *)data; - tcore_check_return_value_assert(NULL != modem_plugin, TCORE_HOOK_RETURN_STOP_PROPAGATION); - - tcore_plugin_add_notification_hook(modem_plugin, TCORE_NOTIFICATION_MODEM_POWER, - __on_hook_modem_powered, indicator_plugin); - tcore_plugin_add_notification_hook(modem_plugin, TCORE_NOTIFICATION_PS_CALL_STATUS, - __on_hook_ps_callstatus, indicator_plugin); - - return TCORE_HOOK_RETURN_CONTINUE; -} - -static TcoreHookReturn __on_hook_modem_plugin_removed(Server *s, - TcoreServerNotification command, - guint data_len, void *data, void *user_data) -{ - TcorePlugin *modem_plugin; - - modem_plugin = (TcorePlugin *)data; - tcore_check_return_value_assert(NULL != modem_plugin, TCORE_HOOK_RETURN_STOP_PROPAGATION); - - tcore_plugin_remove_notification_hook(modem_plugin, TCORE_NOTIFICATION_MODEM_POWER, - __on_hook_modem_powered); - tcore_plugin_remove_notification_hook(modem_plugin, TCORE_NOTIFICATION_PS_CALL_STATUS, - __on_hook_ps_callstatus); - - return TCORE_HOOK_RETURN_CONTINUE; -} - -static gboolean on_load() -{ - dbg("Indicator plugin load!"); - return TRUE; -} - -static gboolean on_init(TcorePlugin *p) -{ - Server *s = NULL; - GSList *list = NULL; - indicator_data *data = NULL; - TelReturn ret = TEL_RETURN_FAILURE; - - data = tcore_malloc0(sizeof(indicator_data)); - if (!data) { - err("Failed to allocate memory"); - return FALSE; - } - ret = tcore_plugin_link_user_data(p, data); - if (ret != TEL_RETURN_SUCCESS) { - err("Unable to link user data"); - free(data); - return FALSE; - } - - s = tcore_plugin_ref_server(p); - list = tcore_server_get_modem_plugin_list(s); - while (list) { /* Process for pre-loaded Modem Plug-in */ - TcorePlugin *modem_plugin; - - modem_plugin = list->data; - if ( NULL != modem_plugin) { - tcore_plugin_add_notification_hook(modem_plugin, TCORE_NOTIFICATION_MODEM_POWER, - __on_hook_modem_powered, p); - tcore_plugin_add_notification_hook(modem_plugin, TCORE_NOTIFICATION_PS_CALL_STATUS, - __on_hook_ps_callstatus, p); - } - list = g_slist_next(list); - } - g_slist_free(list); - - /* Register for post-loaded Modem Plug-ins */ - tcore_server_add_notification_hook(s, TCORE_SERVER_NOTIFICATION_ADDED_MODEM_PLUGIN, - __on_hook_modem_plugin_added, p); - tcore_server_add_notification_hook(s, TCORE_SERVER_NOTIFICATION_REMOVED_MODEM_PLUGIN, - __on_hook_modem_plugin_removed, p); - dbg("initialized Indicator plugin!"); - return TRUE; -} - -static void on_unload(TcorePlugin *p) -{ - indicator_data *data = NULL; - dbg("i'm unload!"); - - data = tcore_plugin_ref_user_data(p); - if (data->src) { - g_source_destroy(data->src); - data->src = NULL; - } - tcore_free(data); - data = NULL; - return; -} - -struct tcore_plugin_define_desc plugin_define_desc = -{ - .name = "INDICATOR", - .priority = TCORE_PLUGIN_PRIORITY_MID + 2, - .version = 1, - .load = on_load, - .init = on_init, - .unload = on_unload -}; diff --git a/src/desc.c b/src/desc.c new file mode 100644 index 0000000..89e2fe2 --- /dev/null +++ b/src/desc.c @@ -0,0 +1,66 @@ +/* + * tel-plugin-indicator + * + * Copyright (c) 2014 Samsung Electronics Co. Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "s_indi_main.h" +#include "s_indi_util.h" + +#ifndef PLUGIN_VERSION +#define PLUGIN_VERSION 1 +#endif + +static gboolean on_load() +{ + dbg("i'm load"); + return TRUE; +} + +static gboolean on_init(TcorePlugin *plugin) +{ + gboolean result = FALSE; + s_indi_assert(NULL != plugin); + + result = s_indi_init(plugin); + if (result == FALSE) { + err("Failed intializing the plugin"); + } else { + dbg("indicator-plugin INIT SUCCESS"); + } + + return result; +} + +static void on_unload(TcorePlugin *plugin) +{ + s_indi_assert(NULL != plugin); + + s_indi_deinit(plugin); + dbg("indicator-plugin UNLOAD COMPLETE"); +} + +EXPORT_API struct tcore_plugin_define_desc plugin_define_desc = +{ + .name = "INDICATOR", + .priority = TCORE_PLUGIN_PRIORITY_MID + 2, + .version = PLUGIN_VERSION, + .load = on_load, + .init = on_init, + .unload = on_unload +}; diff --git a/src/s_indi_log.c b/src/s_indi_log.c new file mode 100644 index 0000000..6741ce5 --- /dev/null +++ b/src/s_indi_log.c @@ -0,0 +1,43 @@ +/* + * tel-plugin-indicator + * + * Copyright (c) 2014 Samsung Electronics Co. Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "s_indi_log.h" + +#ifdef TCORE_LOG_TAG +#define LOG_TAG TCORE_LOG_TAG +#else +#define LOG_TAG "S_INDI" +#endif + +const char *log_tag_name[MODEM_ID_LAST + 1] = { + [MODEM_ID_PRIMARY] = LOG_TAG"/SUBS-0", + [MODEM_ID_SECONDARY] = LOG_TAG"/SUBS-1" +}; + +const char *s_indi_get_log_tag_with_id(unsigned int modem_id) +{ + g_assert(modem_id <= MODEM_ID_SECONDARY); + return log_tag_name[modem_id]; +} + +gchar *s_indi_get_log_tag_with_cp_name(const char *cp_name) +{ + return g_strdup_printf("%s/%s", LOG_TAG, cp_name); +} diff --git a/src/s_indi_main.c b/src/s_indi_main.c new file mode 100644 index 0000000..08740df --- /dev/null +++ b/src/s_indi_main.c @@ -0,0 +1,1456 @@ +/* + * tel-plugin-indicator + * + * Copyright (c) 2014 Samsung Electronics Co. Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "s_indi_main.h" +#include "s_indi_util.h" +#include "s_indi_log.h" + +#define S_INDI_UPDATE_INTERVAL 1 +#define S_INDI_NO_RX_PKT_TIMEOUT 60 +#define S_INDI_PROC_FILE "/proc/net/dev" + +#define S_INDI_DB_STORAGE_NAME "database" +#define S_INDI_DB_STORAGE_PATH "/opt/dbspace/.dnet.db" +#define S_INDI_VCONF_STORAGE_NAME "vconf" + +#define S_INDI_ALLOC_USER_DATA(data, plugin, cp) \ + do { \ + data = s_indi_malloc0(sizeof(__s_indi_cb_user_data)); \ + data->indi_plugin = plugin; \ + data->cp_name = cp; \ + } while (0) + +#define S_INDI_FREE_USER_DATA(data) \ + do { \ + s_indi_free(data->cp_name); \ + s_indi_free(data); \ + } while (0) + +typedef struct { + TcorePlugin *indi_plugin; + gchar *cp_name; +} __s_indi_cb_user_data; + +typedef struct { + struct global_data msg_id; + gboolean b_pm_lock; + + GHashTable *state_info; /* HashTable of s_indi_cp_state_info_type with key = cp_name */ + + GHashTable *vconf_info; /* Mapping of enum tcore_storage_key to cp_name */ +} s_indi_private_info; + +/***************** HOOKS *****************/ +static enum tcore_hook_return s_indi_on_hook_modem_plugin_removed(Server *server, CoreObject *source, + enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data); +static enum tcore_hook_return s_indi_on_hook_modem_plugin_added(Server *server, CoreObject *source, + enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data); +static enum tcore_hook_return s_indi_on_hook_voice_call_status(Server *server, CoreObject *source, + enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data); +static enum tcore_hook_return s_indi_on_hook_sim_init(Server *server, CoreObject *source, + enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data); +static enum tcore_hook_return s_indi_on_hook_net_register(Server *server, CoreObject *source, + enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data); +static enum tcore_hook_return s_indi_on_hook_ps_call_status(Server *server, CoreObject *source, + enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data); +static enum tcore_hook_return s_indi_on_hook_modem_power(Server *server, CoreObject *source, + enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data); + +/***************** VCONF Callbacks *****************/ +static void s_indi_storage_key_callback(enum tcore_storage_key key, void *value, void *user_data); + +/***************** Utilities: GDestroyNotifications *****************/ +static void __s_indi_state_info_value_destroy_notification(gpointer data); +static void __s_indi_dev_info_value_destroy_notification(gpointer data); + +/***************** Utilities: Indicator Plugin *****************/ +static inline s_indi_private_info *__s_indi_get_priv_info(TcorePlugin *plugin); +static gboolean __s_indi_start_updater(TcorePlugin *indi_plugin, gchar *cp_name); +static gboolean __s_indi_update_callback(__s_indi_cb_user_data *data); +static void __s_indi_set_dormancy_value(Server *server, s_indi_dormancy_info_type *dormancy_info, enum tcore_storage_key key_fd); +static void __s_indi_refresh_modems(TcorePlugin *indi_plugin); +static s_indi_cp_state_info_type *__s_indi_alloc_state_info(CoreObject *co_ps); +static s_indi_dev_state_info_type *__s_indi_alloc_device_state(CoreObject *ps_context, s_indi_cp_state_info_type *parent); +static CoreObject *__s_indi_fetch_ps_co(TcorePlugin *plugin); + +static void __s_indi_add_modem_plugin(TcorePlugin *indi_plugin, TcorePlugin *modem_plugin); +static void __s_indi_remove_modem_plugin(TcorePlugin *indi_plugin, TcorePlugin *modem_plugin); +static void __s_indi_register_vconf_key(enum tcore_storage_key key, TcorePlugin *indi_plugin, const char *cp_name); +static void __s_indi_unregister_vconf_key(enum tcore_storage_key key, TcorePlugin *indi_plugin, const char *cp_name); +static void __s_indi_process_fast_dormancy(s_indi_cp_state_info_type *state_info, GVariant *value); +static gboolean __s_indi_cancel_pm_lock(gboolean b_pm_lock); +static gboolean __s_indi_handle_voice_call_status(Server *server, CoreObject *source, + enum tcore_notification_command command, const char *cp_name, + s_indi_cp_state_info_type *state_info); + +static void __s_indi_deactivate_ps_context (gpointer key, gpointer value, gpointer user_data); +static gboolean __s_indi_check_fast_dormancy(TcorePlugin *indi_plugin, CoreObject *co_ps, s_indi_dormancy_info_type *dormancy_info, gboolean b_pm_lock); + +void __s_indi_process_fast_dormancy(s_indi_cp_state_info_type *state_info, GVariant *value) +{ + gboolean fd_set = FALSE; + int on_timeout = S_INDI_ZERO; + int off_timeout = S_INDI_ZERO; + + if (!g_variant_is_of_type(value, G_VARIANT_TYPE_INT32)) { + err("wrong variant data type"); + return; + } + + state_info->dormant_info.b_vconf_checker = TRUE; + + fd_set = g_variant_get_int32(value); + dbg("fast dormancy set (%s)", fd_set ? "TRUE" : "FALSE"); + + if (fd_set) { + on_timeout = S_INDI_FIVE; + off_timeout = S_INDI_FIVE; + } else { + on_timeout = S_INDI_MINUS_ONE; + off_timeout = S_INDI_MINUS_ONE; + } + state_info->dormant_info.lcd_on_timeout = on_timeout; + state_info->dormant_info.lcd_off_timeout = off_timeout; + state_info->dormant_info.is_dormant_set = fd_set; +} + +void __s_indi_register_vconf_key(enum tcore_storage_key key, TcorePlugin *indi_plugin, const char *cp_name) +{ + s_indi_private_info *priv_info = __s_indi_get_priv_info(indi_plugin); + Storage *strg_vconf = tcore_server_find_storage(tcore_plugin_ref_server(indi_plugin), S_INDI_VCONF_STORAGE_NAME); + s_indi_assert(NULL != strg_vconf); + + /** NULL cp_name: subscription independent vconf key */ + if (tcore_storage_set_key_callback(strg_vconf, key, s_indi_storage_key_callback, indi_plugin) + && (NULL != cp_name)) + g_hash_table_insert(priv_info->vconf_info, GUINT_TO_POINTER(key), s_indi_strdup(cp_name)); +} + +void __s_indi_unregister_vconf_key(enum tcore_storage_key key, TcorePlugin *indi_plugin, const char *cp_name) +{ + s_indi_private_info *priv_info = __s_indi_get_priv_info(indi_plugin); + Storage *strg_vconf = tcore_server_find_storage(tcore_plugin_ref_server(indi_plugin), S_INDI_VCONF_STORAGE_NAME); + s_indi_assert(NULL != strg_vconf); + + /** NULL cp_name: subscription independent vconf key */ + if (tcore_storage_remove_key_callback(strg_vconf, key, s_indi_storage_key_callback) + && (NULL != cp_name)) + g_hash_table_remove(priv_info->vconf_info, GUINT_TO_POINTER(key)); +} + +void __s_indi_add_modem_plugin(TcorePlugin *indi_plugin, TcorePlugin *modem_plugin) +{ + gchar *cp_name = NULL; + enum tcore_storage_key vconf_key; + s_indi_private_info *priv_info = __s_indi_get_priv_info(indi_plugin); + + /** @todo: It may be possible to use cp_name without duping as well */ + cp_name = s_indi_strdup(tcore_server_get_cp_name_by_plugin(modem_plugin)); + s_indi_assert(NULL != cp_name); + s_indi_log_ex(cp_name, "Added"); + + /** @todo: Check if key-value replacement is the intended behavior */ + g_hash_table_insert(priv_info->state_info, cp_name, __s_indi_alloc_state_info(__s_indi_fetch_ps_co(modem_plugin))); + + if (s_indi_str_has_suffix(cp_name, "0")) { + vconf_key = STORAGE_KEY_TESTMODE_FAST_DORMANCY; + } else if (s_indi_str_has_suffix(cp_name, "1")) { + vconf_key = STORAGE_KEY_TESTMODE_FAST_DORMANCY2; + } else { + s_indi_assert_not_reached(); + } + + __s_indi_register_vconf_key(vconf_key, indi_plugin, cp_name); +} + +void __s_indi_remove_modem_plugin(TcorePlugin *indi_plugin, TcorePlugin *modem_plugin) +{ + const char *cp_name = NULL; + enum tcore_storage_key vconf_key; + s_indi_private_info *priv_info = __s_indi_get_priv_info(indi_plugin); + + cp_name = tcore_server_get_cp_name_by_plugin(modem_plugin); + s_indi_assert(NULL != cp_name); + s_indi_assert(NULL != priv_info->state_info); + + if (g_hash_table_remove(priv_info->state_info, cp_name)) + s_indi_log_ex(cp_name, "Removed"); + + if (s_indi_str_has_suffix(cp_name, "0")) { + vconf_key = STORAGE_KEY_TESTMODE_FAST_DORMANCY; + } else if (s_indi_str_has_suffix(cp_name, "1")) { + vconf_key = STORAGE_KEY_TESTMODE_FAST_DORMANCY2; + } else { + s_indi_assert_not_reached(); + } + + __s_indi_unregister_vconf_key(vconf_key, indi_plugin, cp_name); +} + +CoreObject *__s_indi_fetch_ps_co(TcorePlugin *plugin) +{ + CoreObject *co_ps = NULL; + GSList *co_list = tcore_plugin_get_core_objects_bytype(plugin, CORE_OBJECT_TYPE_PS); + s_indi_assert(co_list != NULL); + s_indi_assert(g_slist_length(co_list) == S_INDI_ONE); + + co_ps = g_slist_nth_data(co_list, S_INDI_ZERO); + s_indi_assert(co_ps != NULL); + g_slist_free(co_list); + + return co_ps; +} + +s_indi_cp_state_info_type *__s_indi_alloc_state_info(CoreObject *co_ps) +{ + s_indi_cp_state_info_type *state_info = s_indi_malloc0(sizeof(s_indi_cp_state_info_type)); + state_info->co_ps = co_ps; + state_info->ps_state = S_INDI_CELLULAR_UNKNOWN; + state_info->cp_trans_state = S_INDI_TRANSFER_UNKNOWN; + state_info->dormant_info.lcd_state = S_INDI_LCD_UNKNOWN; + state_info->dormant_info.lcd_on_timeout = S_INDI_MINUS_ONE; + state_info->dormant_info.lcd_off_timeout = S_INDI_MINUS_ONE; + state_info->rx_total = S_INDI_ZERO; + state_info->tx_total = S_INDI_ZERO; + state_info->dormant_info.parent = state_info; + + /* tcore_context_get_ipv4_devname uses glib allocator so key should be freed using g_free() */ + state_info->device_info = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, __s_indi_dev_info_value_destroy_notification); + return state_info; +} + +s_indi_dev_state_info_type *__s_indi_alloc_device_state(CoreObject *ps_context, s_indi_cp_state_info_type *parent) +{ + s_indi_dev_state_info_type *dev_state = s_indi_malloc0(sizeof(s_indi_dev_state_info_type)); + dev_state->ps_context = ps_context; + dev_state->parent = parent; + return dev_state; +} + +s_indi_private_info *__s_indi_get_priv_info(TcorePlugin *plugin) +{ + s_indi_private_info *priv_info = tcore_plugin_ref_user_data(plugin); + s_indi_assert(NULL != priv_info); + return priv_info; +} + +gboolean __s_indi_start_updater(TcorePlugin *indi_plugin, gchar *cp_name) +{ + __s_indi_cb_user_data *cb_data = NULL; + s_indi_cp_state_info_type *state_info = NULL; + s_indi_private_info *priv_info = __s_indi_get_priv_info(indi_plugin); + + if ((state_info = g_hash_table_lookup(priv_info->state_info, cp_name)) == NULL) { + warn("CP [%s] Not Present", cp_name); + s_indi_free(cp_name); + return FALSE; + } + + if (state_info->src != NULL) { + dbg("Another one is in progress"); + s_indi_free(cp_name); + return FALSE; + } + + S_INDI_ALLOC_USER_DATA(cb_data, indi_plugin, cp_name); + + dbg("indicator is starting"); + state_info->src = g_timeout_source_new_seconds(S_INDI_UPDATE_INTERVAL); + g_source_set_callback(state_info->src, (GSourceFunc)__s_indi_update_callback, cb_data, NULL); + g_source_set_priority(state_info->src, G_PRIORITY_HIGH); + g_source_attach(state_info->src, NULL); + g_source_unref(state_info->src); + return TRUE; +} + +gboolean __s_indi_cancel_pm_lock(gboolean b_pm_lock) +{ + /* Cancel power lock */ + if (b_pm_lock) { + int rv = S_INDI_ZERO; + rv = display_unlock_state(LCD_OFF, PM_RESET_TIMER); + dbg("display_unlock_state: rv(%d)", rv); + } + + return FALSE; +} + +gboolean __s_indi_update_callback(__s_indi_cb_user_data *data) +{ +#define INDICATOR_BUFF_SIZE 4096 + gchar buff[INDICATOR_BUFF_SIZE]; + s_indi_cp_state_info_type *state_info = NULL; + s_indi_dev_state_info_type *dev_state = NULL; + TcorePlugin *indi_plugin = data->indi_plugin; + const char *cp_name = data->cp_name; + unsigned int modem_id; + FILE *pf = NULL; + gchar *rv = NULL; + unsigned long long rx_curr_total = S_INDI_ZERO, tx_curr_total = S_INDI_ZERO, rx_prev_total = S_INDI_ZERO, tx_prev_total = S_INDI_ZERO; + unsigned long rx_changes_total = S_INDI_ZERO, tx_changes_total = S_INDI_ZERO; + s_indi_transfer_state cp_state = S_INDI_TRANSFER_NORMAL; /* Assume no activity */ + enum tcore_storage_key key_last_rcv, key_last_snt, key_total_rcv, key_total_snt, key_service_state; + s_indi_private_info *priv_info = __s_indi_get_priv_info(indi_plugin); + Storage *strg_vconf = NULL; + + /* VCONF Mapper */ + if (s_indi_str_has_suffix(cp_name, "0")) { + key_last_rcv = STORAGE_KEY_CELLULAR_PKT_LAST_RCV; + key_last_snt = STORAGE_KEY_CELLULAR_PKT_LAST_SNT; + key_total_rcv = STORAGE_KEY_CELLULAR_PKT_TOTAL_RCV; + key_total_snt = STORAGE_KEY_CELLULAR_PKT_TOTAL_SNT; + key_service_state = STORAGE_KEY_PACKET_SERVICE_STATE; + modem_id = MODEM_ID_PRIMARY; + } else if (s_indi_str_has_suffix(cp_name, "1")) { + key_last_rcv = STORAGE_KEY_CELLULAR_PKT_LAST_RCV2; + key_last_snt = STORAGE_KEY_CELLULAR_PKT_LAST_SNT2; + key_total_rcv = STORAGE_KEY_CELLULAR_PKT_TOTAL_RCV2; + key_total_snt = STORAGE_KEY_CELLULAR_PKT_TOTAL_SNT2; + key_service_state = STORAGE_KEY_PACKET_SERVICE_STATE2; + modem_id = MODEM_ID_SECONDARY; + } else { + err("Unhandled CP Name %s", cp_name); + s_indi_assert_not_reached(); + S_INDI_FREE_USER_DATA(data); + return G_SOURCE_REMOVE; + } + + /* Check CP Name presence */ + if ((state_info = g_hash_table_lookup(priv_info->state_info, cp_name)) == NULL) { + warn("%s CP is not present", cp_name); + goto EXIT; + } + + /* Check dev_state presence */ + if (g_hash_table_size(state_info->device_info) == S_INDI_ZERO) { + msg("Nothing to update, aborting timer"); + goto EXIT; + } + + /** @todo: Check if needs to be read atomically */ + pf = fopen(S_INDI_PROC_FILE, "r"); + if (pf == NULL) { + err("indicator fail to open file(%s), errno(%d)", S_INDI_PROC_FILE, errno); + goto EXIT; + } + + /* Skip first line */ + rv = fgets(buff, sizeof(buff), pf); + if (!rv) { + err("fail to read file or reach EOF, plz check %s", S_INDI_PROC_FILE); + goto EXIT; + } + + /* Skip second line */ + rv = fgets(buff, sizeof(buff), pf); + if (!rv) { + err("fail to read file or reach EOF, plz check %s", S_INDI_PROC_FILE); + goto EXIT; + } + + /* Update all devices of state_info */ + while (fgets(buff, sizeof(buff), pf)) { + gchar *ifname = buff, *entry = NULL; + + /* Skip whitespaces */ + while (*ifname == ' ') + ifname++; + + /* Terminate to read ifname */ + entry = strrchr(ifname, ':'); + *entry++ = '\0'; + + /* Read device_info */ + /* Takes care of the fix: Fix the PLM p131003-03182. Sha-ID: 65544f0be8e60ae3f964921755a1e83fa8e71441*/ + if ((dev_state = g_hash_table_lookup(state_info->device_info, ifname)) != NULL) { + gint result = S_INDI_ZERO; + unsigned long rx_pkt = S_INDI_ZERO, tx_pkt = S_INDI_ZERO; + /************************************************************************ + Sample Input of S_INDI_PROC_FILE + ************************************************************************ + Inter-| Receive | Transmit + face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed + lo: 114955545 88409 0 0 0 0 0 0 114955545 88409 0 0 0 0 0 0 + eth0: 2714004148 6475059 0 0 0 0 0 0 72595891 8726308 0 0 0 0 0 0 + ************************************************************************/ + s_indi_log_v("Reading stats of interface %s", ifname); + result = sscanf(entry, "%lu %*s %*s %*s %*s %*s %*s %*s %lu %*s %*s %*s %*s %*s %*s %*s", &rx_pkt, &tx_pkt); + if (result <= S_INDI_ZERO) { + err("stats fail to get proc field => %d", result); + goto EXIT; /** @todo: REMOVE or CONTINUE ? */ + } + + /* Save per device */ + dev_state->prev_rx = dev_state->curr_rx; + dev_state->prev_tx = dev_state->curr_tx; + dev_state->curr_rx = rx_pkt; + dev_state->curr_tx = tx_pkt; + + /* Compute CP totals */ + rx_curr_total += rx_pkt; + tx_curr_total += tx_pkt; + rx_prev_total += dev_state->prev_rx; + tx_prev_total += dev_state->prev_tx; + } + } + + rx_changes_total = rx_curr_total - rx_prev_total; + tx_changes_total = tx_curr_total - tx_prev_total; + + if (rx_changes_total) { + cp_state |= S_INDI_TRANSFER_RX; + } + if (tx_changes_total) { + cp_state |= S_INDI_TRANSFER_TX; + } + + /* todo: reduce the number of conditions */ + if (cp_state == S_INDI_TRANSFER_TX) { + state_info->no_rx_pckt++; + } + else if (cp_state == S_INDI_TRANSFER_NORMAL) { + /* todo: why check against 5 */ + if (state_info->no_rx_pckt > 5) { + state_info->no_rx_pckt++; + } + state_info->dormant_info.dormant_cnt++; + }else { + state_info->dormant_info.dormant_cnt = 0; + state_info->dormant_info.is_dormant = FALSE; + } + + if (cp_state) { + s_indi_log_txrx(modem_id, "Transfer State:[%d] rx_cnt:[%d] RX: [%10lu] TX: [%10lu]", cp_state, state_info->no_rx_pckt, rx_changes_total, tx_changes_total); + } + + if (state_info->dormant_info.lcd_state < S_INDI_LCD_OFF) { + if (state_info->cp_trans_state != cp_state) { /* New Transfer State */ + strg_vconf = tcore_server_find_storage(tcore_plugin_ref_server(indi_plugin), S_INDI_VCONF_STORAGE_NAME); + s_indi_assert(NULL != strg_vconf); + + state_info->cp_trans_state = cp_state; + tcore_storage_set_int(strg_vconf, STORAGE_KEY_PACKET_INDICATOR_STATE, cp_state); + if (cp_state != S_INDI_TRANSFER_NORMAL) { /* Data activity */ + s_indi_log_txrx(modem_id, "pkt_state[%d] rx_changes [%lu] tx_changes [%lu]", + cp_state, rx_changes_total, tx_changes_total); + tcore_storage_set_int(strg_vconf, key_last_rcv, rx_curr_total/1000); + tcore_storage_set_int(strg_vconf, key_last_snt, tx_curr_total/1000); + } + } + } + + if (state_info->no_rx_pckt >= S_INDI_NO_RX_PKT_TIMEOUT) { + state_info->no_rx_pckt = S_INDI_ZERO; + dbg("request to disconnect all ps context"); + g_hash_table_foreach(state_info->device_info, __s_indi_deactivate_ps_context, state_info->co_ps); + } + + priv_info->b_pm_lock = __s_indi_check_fast_dormancy(indi_plugin, state_info->co_ps, &state_info->dormant_info, priv_info->b_pm_lock); + fclose(pf); + return G_SOURCE_CONTINUE; /* Revisit after S_INDI_UPDATE_INTERVAL */ + +EXIT: + dbg("indicator is stopped"); + if (pf) fclose(pf); + + strg_vconf = tcore_server_find_storage(tcore_plugin_ref_server(indi_plugin), S_INDI_VCONF_STORAGE_NAME); + s_indi_assert(NULL != strg_vconf); + + /* Update PS Call and indicator states */ + tcore_storage_set_int(strg_vconf, STORAGE_KEY_PACKET_INDICATOR_STATE, S_INDI_TRANSFER_NORMAL); + tcore_storage_set_int(strg_vconf, key_service_state, S_INDI_CELLULAR_OFF); + dbg("PS Call status (%s) - [DISCONNECTED]", cp_name); + + if (state_info) { + state_info->src = NULL; + state_info->cp_trans_state = S_INDI_TRANSFER_NORMAL; + state_info->ps_state = S_INDI_CELLULAR_OFF; + + /* Update total VCONF before dying updator */ + tcore_storage_set_int(strg_vconf, key_total_rcv, tcore_storage_get_int(strg_vconf, key_total_rcv) + state_info->rx_total); + tcore_storage_set_int(strg_vconf, key_total_snt, tcore_storage_get_int(strg_vconf, key_total_snt) + state_info->tx_total); + + /** @todo: VCONF needs upgrade to support llu */ + s_indi_log_txrx(modem_id, "RX-TOTAL[%d] TX-TOTAL[%d]", + tcore_storage_get_int(strg_vconf, key_total_rcv), tcore_storage_get_int(strg_vconf, key_total_snt)); + state_info->rx_total = S_INDI_ZERO; + state_info->tx_total = S_INDI_ZERO; + } + + S_INDI_FREE_USER_DATA(data); + return G_SOURCE_REMOVE; +} + +static void __s_indi_deactivate_ps_context (gpointer key, gpointer value, gpointer user_data) +{ +#if 1 + dbg("Temp Fix: stopping deactivation from indicator "); + key = key; + value = value; + user_data = user_data; +#else + gchar *ifname = key; + s_indi_dev_state_info_type *dev_state = value; + + if(dev_state->ps_context && user_data){ + dbg("Deactivating PS context [%p] which is associated with interface %s", dev_state->ps_context, ifname); + tcore_ps_deactivate_context(user_data, dev_state->ps_context, NULL); + } +#endif + return; +} + +void __s_indi_state_info_value_destroy_notification(gpointer data) +{ + s_indi_cp_state_info_type *state_info = data; + const char *cp_name = NULL; + Storage *strg_vconf = NULL; + enum tcore_storage_key key_total_rcv, key_total_snt; + s_indi_assert(NULL != state_info); + s_indi_assert(NULL != state_info->co_ps); + + cp_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(state_info->co_ps)); + s_indi_assert(NULL != cp_name); + dbg("CP Name: [%s]", cp_name); + + /* VCONF Mapper */ + if (s_indi_str_has_suffix(cp_name, "0")) { + key_total_rcv = STORAGE_KEY_CELLULAR_PKT_TOTAL_RCV; + key_total_snt = STORAGE_KEY_CELLULAR_PKT_TOTAL_SNT; + } else if (s_indi_str_has_suffix(cp_name, "1")) { + key_total_rcv = STORAGE_KEY_CELLULAR_PKT_TOTAL_RCV2; + key_total_snt = STORAGE_KEY_CELLULAR_PKT_TOTAL_SNT2; + } else { + err("Unhandled CP Name %s", cp_name); + s_indi_assert_not_reached(); + goto OUT; + } + + /* Free device nodes */ + g_hash_table_destroy(state_info->device_info); + strg_vconf = tcore_server_find_storage(tcore_plugin_ref_server(tcore_object_ref_plugin(state_info->co_ps)), S_INDI_VCONF_STORAGE_NAME); + s_indi_assert(NULL != strg_vconf); + + /* Update VCONF before dying */ + tcore_storage_set_int(strg_vconf, key_total_rcv, tcore_storage_get_int(strg_vconf, key_total_rcv) + state_info->rx_total); + tcore_storage_set_int(strg_vconf, key_total_snt, tcore_storage_get_int(strg_vconf, key_total_snt) + state_info->tx_total); + dbg("CP[%s] RX-TOTAL[%10llu] TX-TOTAL[%10llu]", cp_name, + tcore_storage_get_int(strg_vconf, key_total_rcv), tcore_storage_get_int(strg_vconf, key_total_snt)); + +OUT: + s_indi_free(state_info->dormant_info.mccmnc); + s_indi_free(data); +} + +void __s_indi_dev_info_value_destroy_notification(gpointer data) +{ + s_indi_dev_state_info_type *dev_state = data; + s_indi_cp_state_info_type *state_info = NULL; + s_indi_assert(NULL != dev_state); + state_info = dev_state->parent; + s_indi_assert(NULL != state_info); + + /* Update parent before dying */ + state_info->rx_total += dev_state->curr_rx/1000; + state_info->tx_total += dev_state->curr_tx/1000; + + s_indi_log_v("DYING after contributing [RX: %lu][TX: %lu] OUT OF [RX: %llu][TX: %llu]", + dev_state->curr_rx/1000, dev_state->curr_tx/1000, + state_info->rx_total, state_info->tx_total); + + s_indi_free(data); +} + +void __s_indi_refresh_modems(TcorePlugin *indi_plugin) +{ + GSList *mp_list = tcore_server_get_modem_plugin_list(tcore_plugin_ref_server(indi_plugin)); + s_indi_log_v("Processing %u present modems", g_slist_length(mp_list)); + + while (mp_list) { + __s_indi_add_modem_plugin(indi_plugin, mp_list->data); + mp_list = mp_list->next; + } + + g_slist_free(mp_list); +} + +void __s_indi_set_dormancy_value(Server *server, s_indi_dormancy_info_type *dormancy_info, enum tcore_storage_key key_fd) +{ + if (dormancy_info->b_vconf_checker) { + Storage *strg_vconf = tcore_server_find_storage(server, S_INDI_VCONF_STORAGE_NAME); + gboolean b_fd_force = tcore_storage_get_bool(strg_vconf, key_fd); + + s_indi_assert(NULL != strg_vconf); + + if (b_fd_force) { + dbg("forcely enable fast dormancy "); + dormancy_info->lcd_on_timeout = S_INDI_FIVE; + dormancy_info->lcd_off_timeout = S_INDI_FIVE; + } else { + dbg("forcely disable fast dormancy "); + dormancy_info->lcd_on_timeout = S_INDI_MINUS_ONE; + dormancy_info->lcd_off_timeout = S_INDI_MINUS_ONE; + } + } + + if (!dormancy_info->mccmnc) { + dbg("mccmnc is null"); + return; + } + + /** @todo: Make List of blocked mccmnc and use that */ + /* + * Fast dormancy values are updated currently only for SKT and KT operators in DB.Revisit. + * + */ + if ((g_strcmp0((const char *)dormancy_info->mccmnc, "00101") == S_INDI_ZERO) + || (g_strcmp0((const char *)dormancy_info->mccmnc, "99999") == S_INDI_ZERO)) { + dormancy_info->lcd_on_timeout = S_INDI_ZERO; + dormancy_info->lcd_off_timeout = S_INDI_ZERO; + dbg("FD does not work in testsim"); + } + else { +#define szQUERY_SIZE 5000 + Storage *strg_db; + void *db_handle; + char szQuery[szQUERY_SIZE]; + GHashTableIter iter; + gpointer key, value; + GHashTable *in_param, *out_param; + + + /* Initialize Storage */ + strg_db = tcore_server_find_storage(server, S_INDI_DB_STORAGE_NAME); + db_handle = tcore_storage_create_handle(strg_db, S_INDI_DB_STORAGE_PATH); + if (db_handle == NULL) { + err("Failed to get Storage handle"); + return; + } + + /* Initialize parameters */ + in_param = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free); + g_hash_table_insert(in_param, "1", g_strdup(dormancy_info->mccmnc)); + + out_param = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_hash_table_destroy); + + memset(szQuery, '\0', szQUERY_SIZE); + strcpy(szQuery, "select"); + strcat(szQuery, " a.dormant_id, a.network_info_id, a.lcd_on_timeout, a.lcd_off_timeout"); //0,1,2,3 + strcat(szQuery, " from fast_dormancy a, network_info b"); + strcat(szQuery, " where b.mccmnc= ? and a.network_info_id = b.network_info_id "); + + tcore_storage_read_query_database(strg_db, db_handle, szQuery, in_param, out_param, 4); + + dbg("Get dormancy value"); + g_hash_table_iter_init(&iter, out_param); + while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) { + GHashTableIter iter2; + gpointer key2, value2; + + if (value) { + g_hash_table_iter_init(&iter2, (GHashTable *)value); + while (g_hash_table_iter_next(&iter2, &key2, &value2) == TRUE) { + if (g_str_equal(key2, "2") == TRUE) { + dormancy_info->lcd_on_timeout = atoi((const char*)value2); + dbg("lcd on timeout(%d)", dormancy_info->lcd_on_timeout); + } + else if (g_str_equal(key2, "3") == TRUE) { + dormancy_info->lcd_off_timeout = atoi((const char*)value2); + dbg("lcd off timeout(%d)", dormancy_info->lcd_off_timeout); + } + } + break; + } + } + + /* Free resources */ + g_hash_table_destroy(in_param); + g_hash_table_destroy(out_param); + + if(dormancy_info->lcd_on_timeout > 0 || dormancy_info->lcd_off_timeout > 0) { + dormancy_info->is_dormant_set = TRUE; + } + + /* De-initialize Storage */ + tcore_storage_remove_handle(strg_db, db_handle); + } +} + +static gboolean __s_indi_check_fast_dormancy(TcorePlugin *indi_plugin, CoreObject *co_ps, s_indi_dormancy_info_type *dormancy_info, gboolean b_pm_lock) +{ + int rv =0; + + S_INDI_NOT_USED(indi_plugin); + S_INDI_NOT_USED(co_ps); + + if(!dormancy_info->is_dormant_set){ + dormancy_info->dormant_cnt = 0; + dormancy_info->is_dormant = FALSE; + + //cancle pm lock + b_pm_lock = __s_indi_cancel_pm_lock(b_pm_lock); + return b_pm_lock; + } + + if(dormancy_info->is_dormant){ + dormancy_info->dormant_cnt = 0; + return b_pm_lock; + } + + if(dormancy_info->lcd_state < 3 && dormancy_info->lcd_on_timeout > 0){ //on 1 && dim 2 + + //satisfy with fd condition, set fd and cancle the pm lock + if(dormancy_info->dormant_cnt >= dormancy_info->lcd_on_timeout){ + dbg("set lcd on fast dormancy"); + dormancy_info->dormant_cnt = 0; + dormancy_info->is_dormant = TRUE; + } + + } + else if(dormancy_info->lcd_state < 3 && dormancy_info->lcd_on_timeout <= 0){ + dormancy_info->dormant_cnt = 0; + } + else if(dormancy_info->lcd_state == 3 && dormancy_info->lcd_off_timeout > 0){ //off 3 + + //call the pm lock state if pkt exist and not dormant state + if(dormancy_info->dormant_cnt < dormancy_info->lcd_off_timeout){ + b_pm_lock = __s_indi_cancel_pm_lock(b_pm_lock); + return b_pm_lock; + } + else if(dormancy_info->dormant_cnt >= dormancy_info->lcd_off_timeout){ + dbg("set lcd off fast dormancy"); + dormancy_info->dormant_cnt = 0; + dormancy_info->is_dormant = TRUE; + } + } + else if(dormancy_info->lcd_state == 3 && dormancy_info->lcd_off_timeout <= 0){ //off 3 + dormancy_info->dormant_cnt = 0; + } + + //pm unlock + if(b_pm_lock){ + rv = display_unlock_state(LCD_OFF, PM_RESET_TIMER); + b_pm_lock = FALSE; + dbg("display_unlock_state: rv(%d)", rv); + } + + return b_pm_lock; +} + +void s_indi_storage_key_callback(enum tcore_storage_key key, void *value, void *user_data) +{ + s_indi_cp_state_info_type *state_info = NULL; + GVariant *tmp = value; + s_indi_private_info *priv_info = __s_indi_get_priv_info(user_data); + + s_indi_assert(NULL != tmp); + + switch (key) { + case STORAGE_KEY_TESTMODE_FAST_DORMANCY: /* Fall Through */ + case STORAGE_KEY_TESTMODE_FAST_DORMANCY2: + { + const gchar *cp_name = NULL; + if ((cp_name = g_hash_table_lookup(priv_info->vconf_info, GUINT_TO_POINTER(key))) != NULL) + if ((state_info = g_hash_table_lookup(priv_info->state_info, cp_name)) != NULL) { + s_indi_log_ex(cp_name, "Processing Fast Dormancy"); + + /*TODO: Currently testmodem fast dormancy is not enabled.so process fast dormancy will not happen */ + + __s_indi_process_fast_dormancy(state_info, tmp); + } + } break; + + case STORAGE_KEY_PM_STATE: + { + GHashTableIter iter; + gpointer key, value; + gint pm_state = S_INDI_ZERO; + + if (!g_variant_is_of_type(tmp, G_VARIANT_TYPE_INT32)) { + err("Wrong variant data type"); + return; + } + + pm_state = g_variant_get_int32(tmp); + + dbg("PM state Value:[%d]", pm_state); + + g_hash_table_iter_init(&iter, priv_info->state_info); + while (g_hash_table_iter_next (&iter, &key, &value)) { + state_info = value; + state_info->dormant_info.lcd_state = pm_state; + } + } break; + + default: + s_indi_assert_not_reached(); + } +} + +enum tcore_hook_return s_indi_on_hook_modem_power(Server *server, CoreObject *source, + enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data) +{ + struct tnoti_modem_power *modem_power = data; + s_indi_assert(modem_power != NULL); + + S_INDI_NOT_USED(server); + S_INDI_NOT_USED(command); + S_INDI_NOT_USED(data_len); + + CORE_OBJECT_CHECK_RETURN(source, CORE_OBJECT_TYPE_MODEM, TCORE_HOOK_RETURN_CONTINUE); + + if (modem_power->state == MODEM_STATE_ERROR) { /* CP reset */ + TcorePlugin *indi_plugin = user_data; + const char *cp_name = NULL; + s_indi_cp_state_info_type *state_info = NULL; + s_indi_private_info *priv_info = __s_indi_get_priv_info(indi_plugin); + + cp_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(source)); + s_indi_assert(NULL != cp_name); + s_indi_log_ex(cp_name, "MODEM_STATE_ERROR"); + + if ((state_info = g_hash_table_lookup(priv_info->state_info, cp_name)) == NULL) { + warn("BAILING OUT: [%s] not found", cp_name); + return TCORE_HOOK_RETURN_CONTINUE; + } + + /* Remove all device states since PS releasing all contexts */ + g_hash_table_remove_all(state_info->device_info); + + /* Free MCC/MNC. It will be received again */ + s_indi_free(state_info->dormant_info.mccmnc); + state_info->dormant_info.mccmnc = NULL; + + /* Reset Dormant Information @todo: Why is this required? */ + state_info->dormant_info.lcd_on_timeout = S_INDI_ZERO; + state_info->dormant_info.lcd_off_timeout = S_INDI_ZERO; + priv_info->b_pm_lock = __s_indi_cancel_pm_lock(priv_info->b_pm_lock); + } + + return TCORE_HOOK_RETURN_CONTINUE; +} + +enum tcore_hook_return s_indi_on_hook_ps_call_status(Server *server, CoreObject *source, + enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data) +{ + struct tnoti_ps_call_status *cstatus = data; + TcorePlugin *indi_plugin = user_data; + const char *cp_name = NULL; + s_indi_cp_state_info_type *state_info = NULL; + GHashTableIter iter; + gpointer cp_name_key, cp_state = NULL; + unsigned char active_pdp_count = S_INDI_ZERO; + s_indi_private_info *priv_info = __s_indi_get_priv_info(indi_plugin); + + s_indi_assert(cstatus != NULL); + + S_INDI_NOT_USED(command); + S_INDI_NOT_USED(data_len); + + CORE_OBJECT_CHECK_RETURN(source, CORE_OBJECT_TYPE_PS, TCORE_HOOK_RETURN_CONTINUE); + + cp_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(source)); + s_indi_assert(NULL != cp_name); + + s_indi_log_ex(cp_name, "cid(%d) state(%d) reason(%d)", + cstatus->context_id, cstatus->state, cstatus->result); + + if (cstatus->state == S_INDI_PS_CALL_OK) + return TCORE_HOOK_RETURN_CONTINUE; + + if ((state_info = g_hash_table_lookup(priv_info->state_info, cp_name)) == NULL) { + warn("BAILING OUT: [%s] not found", cp_name); + return TCORE_HOOK_RETURN_CONTINUE; + } + + s_indi_assert(source == state_info->co_ps); + + if (cstatus->state == S_INDI_PS_CALL_CONNECT) { + GSList *l_context = NULL; + CoreObject *co_context = NULL; + gchar *dev_name = NULL; + s_indi_dev_state_info_type *dev_state = NULL; + enum tcore_storage_key key_service_state, key_fd; + Storage *strg_vconf = NULL; + int role = CONTEXT_ROLE_UNKNOWN; + gboolean data_allowed = FALSE; + gboolean roaming_allowed = FALSE; + + /* Fetch context with internet/tethering role */ + l_context = tcore_ps_ref_context_by_id(source, cstatus->context_id); + while (l_context) { + role = tcore_context_get_role(l_context->data); + if (role == CONTEXT_ROLE_INTERNET || role == CONTEXT_ROLE_TETHERING || role == CONTEXT_ROLE_MMS) { + co_context = l_context->data; + break; + } + + l_context = l_context->next; + } + + if (!co_context) { + err("INTERNET/TETHERING/MMS role not found"); + return TCORE_HOOK_RETURN_CONTINUE; + } + + dev_name = tcore_context_get_ipv4_devname(co_context); /* glib allocator */ + s_indi_assert(NULL != dev_name); + + /* Check if dev_name already exists */ + if (g_hash_table_lookup(state_info->device_info, dev_name)) { + dbg("default connection is already connected"); + g_free(dev_name); + return TCORE_HOOK_RETURN_CONTINUE; + } + + /* Update Cellular State */ + if (s_indi_str_has_suffix(cp_name, "0")) { + key_service_state = STORAGE_KEY_PACKET_SERVICE_STATE; + key_fd = STORAGE_KEY_TESTMODE_FAST_DORMANCY; + } else if (s_indi_str_has_suffix(cp_name, "1")) { + key_service_state = STORAGE_KEY_PACKET_SERVICE_STATE2; + key_fd = STORAGE_KEY_TESTMODE_FAST_DORMANCY2; + } else { + err("Un-handled CP"); + g_free(dev_name); + s_indi_assert_not_reached(); + return TCORE_HOOK_RETURN_CONTINUE; + } + + /* Fresh */ + strg_vconf = tcore_server_find_storage(server, S_INDI_VCONF_STORAGE_NAME); + s_indi_assert(NULL != strg_vconf); + + data_allowed = tcore_storage_get_bool(strg_vconf, STORAGE_KEY_3G_ENABLE); + roaming_allowed = tcore_storage_get_bool(strg_vconf, STORAGE_KEY_SETAPPL_STATE_DATA_ROAMING_BOOL); + + if (!data_allowed) + return TCORE_HOOK_RETURN_CONTINUE; + else if (state_info->roaming_status && !roaming_allowed) + return TCORE_HOOK_RETURN_CONTINUE; + + /* Set Cellular state connected */ + if (role == CONTEXT_ROLE_INTERNET || role == CONTEXT_ROLE_TETHERING) { + state_info->ps_state = S_INDI_CELLULAR_CONNECTED; + tcore_storage_set_int(strg_vconf, key_service_state, S_INDI_CELLULAR_CONNECTED); + }else if(role == CONTEXT_ROLE_MMS){ + state_info->ps_state = S_INDI_CELLULAR_MMS_CONNECTED; + tcore_storage_set_int(strg_vconf, key_service_state, S_INDI_CELLULAR_MMS_CONNECTED); + } + + /* Initialize Packet indicator to Normal */ + tcore_storage_set_int(strg_vconf, STORAGE_KEY_PACKET_INDICATOR_STATE, S_INDI_TRANSFER_NORMAL); + state_info->cp_trans_state = S_INDI_TRANSFER_NORMAL; + + s_indi_log_ex(cp_name, "PS Call status - [CONNECTED]"); + + /* Create new dev state */ + dev_state = __s_indi_alloc_device_state(co_context, state_info); + g_hash_table_insert(state_info->device_info, dev_name, dev_state); + + key_fd = key_fd; + + /* Read & Update dormancy values */ + __s_indi_set_dormancy_value(server, &state_info->dormant_info, key_fd); + + /* Start Updater */ + __s_indi_start_updater(indi_plugin, s_indi_strdup(cp_name)); + + } + else if (cstatus->state == S_INDI_PS_CALL_NO_CARRIER) { + gchar *dev_name = NULL; + GSList *l_context = tcore_ps_ref_context_by_id(source, cstatus->context_id); + + /* Remove all related contexts */ + while (l_context) { + dev_name = tcore_context_get_ipv4_devname(l_context->data); + if (dev_name != NULL) { + g_hash_table_remove(state_info->device_info, dev_name); + g_free(dev_name); + } + l_context = l_context->next; + } + + g_hash_table_iter_init(&iter, (GHashTable *)priv_info->state_info); + while (g_hash_table_iter_next(&iter, &cp_name_key, &cp_state) == TRUE) { + s_indi_log_ex(cp_name_key, "State: [0x%x]", cp_state); + if (g_hash_table_size(((s_indi_cp_state_info_type *)cp_state)->device_info) != S_INDI_ZERO) { + active_pdp_count++; + break; + } + } + + /* Cancel PM Lock if there doens't exist any active PDP connection */ + if (active_pdp_count == S_INDI_ZERO) { + dbg("No Active PDP context. Resetting 'PM Lock' status"); + priv_info->b_pm_lock = __s_indi_cancel_pm_lock(priv_info->b_pm_lock); + } + } + + return TCORE_HOOK_RETURN_CONTINUE; +} + +enum tcore_hook_return s_indi_on_hook_net_register(Server *server, CoreObject *source, + enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data) +{ + TcorePlugin *indi_plugin = user_data; + const char *cp_name = NULL; + s_indi_cp_state_info_type *state_info = NULL; + gboolean active = FALSE; + s_indi_private_info *priv_info = __s_indi_get_priv_info(indi_plugin); + gboolean gsm_dtm_support = FALSE; + struct tnoti_network_registration_status *regist_status = data; + int roaming_status = S_INDI_ZERO; + + S_INDI_NOT_USED(command); + S_INDI_NOT_USED(data_len); + CORE_OBJECT_CHECK_RETURN(source, CORE_OBJECT_TYPE_NETWORK, TCORE_HOOK_RETURN_CONTINUE); + + cp_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(source)); + s_indi_assert(NULL != cp_name); + s_indi_assert(NULL != regist_status); + + if ((state_info = g_hash_table_lookup(priv_info->state_info, cp_name)) == NULL) { + warn("BAILING OUT: [%s] not found", cp_name); + return TCORE_HOOK_RETURN_CONTINUE; + } + + roaming_status = state_info->roaming_status = regist_status->roaming_status; + gsm_dtm_support = tcore_network_get_gsm_dtm_support(source); + + s_indi_log_ex(cp_name, "roam_status: [0x%x] dtm_support: [0x%x]", + roaming_status, gsm_dtm_support); + + if (gsm_dtm_support) + return TCORE_HOOK_RETURN_CONTINUE; + + active = (g_hash_table_size(state_info->device_info) >= S_INDI_ONE) ? TRUE : FALSE; + + if (active) { + Storage *strg_vconf = NULL; + GSList *co_list = NULL; + CoreObject *co_call = NULL; + unsigned int total_call_cnt = S_INDI_ZERO; + enum telephony_network_service_type svc_type; + enum tcore_storage_key key_service_state; + gboolean roaming_allowed = FALSE; + + /* VCONF Mapper */ + if (s_indi_str_has_suffix(cp_name, "0")) { + key_service_state = STORAGE_KEY_PACKET_SERVICE_STATE; + } else if (s_indi_str_has_suffix(cp_name, "1")) { + key_service_state = STORAGE_KEY_PACKET_SERVICE_STATE2; + } else { + err("Un-handled CP"); + s_indi_assert_not_reached(); + return TCORE_HOOK_RETURN_CONTINUE; + } + + strg_vconf = tcore_server_find_storage(server, S_INDI_VCONF_STORAGE_NAME); + roaming_allowed = tcore_storage_get_bool(strg_vconf, STORAGE_KEY_SETAPPL_STATE_DATA_ROAMING_BOOL); + + svc_type = regist_status->service_type; + s_indi_log_ex(cp_name, "srvc_type(%d), roaming_allowed(%d)", + svc_type, roaming_allowed); + + /** + * If Roaming is NOT allowed and indication provides Roaming + * status Available, there is a mismatch. + * Set Cellular state OFF. + */ + if (state_info->ps_state != S_INDI_CELLULAR_OFF && !roaming_allowed && roaming_status) { + tcore_storage_set_int(strg_vconf, key_service_state, S_INDI_CELLULAR_OFF); /* Set Cellular State OFF */ + + /* Indicator need not know worry about roaming status. packet service plugin should take care of de-activating the contexts + when roaming is enabled and network enters roaming. When all the contexts associated with that network is de-activated. Indicator + plugin will automatically ps status for that CP to S_INDI_CELLULAR_OFF + */ + state_info->ps_state = S_INDI_CELLULAR_OFF; /* Update cache */ + + s_indi_log_ex(cp_name, "PS Call status - [DISCONNECTED]"); + return TCORE_HOOK_RETURN_CONTINUE; + } + + if (svc_type < NETWORK_SERVICE_TYPE_2G || svc_type > NETWORK_SERVICE_TYPE_2_5G_EDGE) + return TCORE_HOOK_RETURN_CONTINUE; + + co_list = tcore_plugin_get_core_objects_bytype(tcore_object_ref_plugin(source), CORE_OBJECT_TYPE_CALL); + if (!co_list) { + err("[ error ] co_list : NULL"); + return TCORE_HOOK_RETURN_CONTINUE; + } + s_indi_assert(g_slist_length(co_list) == S_INDI_ONE); + + co_call = (CoreObject *)co_list->data; + g_slist_free(co_list); + + total_call_cnt = tcore_call_object_total_length(co_call); + s_indi_log_ex(cp_name, "totall call cnt (%d)", total_call_cnt); + + if (total_call_cnt > S_INDI_ONE) { + s_indi_cellular_state pkg_state = S_INDI_CELLULAR_UNKNOWN; + pkg_state = tcore_storage_get_int(strg_vconf, key_service_state); + if (pkg_state != S_INDI_CELLULAR_OFF) { + tcore_storage_set_int(strg_vconf, key_service_state, S_INDI_CELLULAR_OFF); + state_info->ps_state = S_INDI_CELLULAR_OFF; /* Update cache */ + } + } + } + + return TCORE_HOOK_RETURN_CONTINUE; +} + +enum tcore_hook_return s_indi_on_hook_sim_init(Server *server, CoreObject *source, + enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data) +{ + struct tnoti_sim_status *sim_data = data; + enum tcore_storage_key fd_key; + s_indi_assert(NULL != sim_data); + + S_INDI_NOT_USED(command); + S_INDI_NOT_USED(data_len); + + CORE_OBJECT_CHECK_RETURN(source, CORE_OBJECT_TYPE_SIM, TCORE_HOOK_RETURN_CONTINUE); + + if (sim_data->sim_status == SIM_STATUS_INIT_COMPLETED) { + struct tel_sim_imsi *sim_imsi = NULL; + const char *cp_name = NULL; + s_indi_cp_state_info_type *state_info = NULL; + TcorePlugin *indi_plugin = user_data; + s_indi_private_info *priv_info = __s_indi_get_priv_info(indi_plugin); + + cp_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(source)); + s_indi_assert(NULL != cp_name); + s_indi_log_ex(cp_name, "SIM_STATUS_INIT_COMPLETED"); + + if ((state_info = g_hash_table_lookup(priv_info->state_info, cp_name)) == NULL) { + warn("BAILING OUT: [%s] not found", cp_name); + return TCORE_HOOK_RETURN_CONTINUE; + } + + sim_imsi = tcore_sim_get_imsi(source); + s_indi_assert(NULL != sim_imsi); + state_info->dormant_info.mccmnc = s_indi_strdup((gchar *)sim_imsi->plmn); + free(sim_imsi); /* libc allocator */ + + /* Update Cellular State */ + if (s_indi_str_has_suffix(cp_name, "0")) { + fd_key = STORAGE_KEY_TESTMODE_FAST_DORMANCY; + } else if (s_indi_str_has_suffix(cp_name, "1")) { + fd_key = STORAGE_KEY_TESTMODE_FAST_DORMANCY2; + } else { + err("Un-handled CP"); + return TCORE_HOOK_RETURN_CONTINUE; + } + + /* Caching the lcdontimer and lcdofftimer dormant values for different network from db */ + __s_indi_set_dormancy_value(server, &(state_info->dormant_info), fd_key); + } + + return TCORE_HOOK_RETURN_CONTINUE; +} + +gboolean __s_indi_handle_voice_call_status(Server *server, CoreObject *source, + enum tcore_notification_command command, const char *cp_name, + s_indi_cp_state_info_type *state_info) +{ + CoreObject *co_network = NULL; + enum tcore_storage_key vconf_key; + Storage *strg_vconf; + enum telephony_network_service_type svc_type; + gboolean show_icon = TRUE; + + if (g_hash_table_size(state_info->device_info) == S_INDI_ZERO) { + s_indi_log_ex(cp_name, "PS state is already OFF"); + return TRUE; + } + + co_network = tcore_plugin_ref_core_object(tcore_object_ref_plugin(state_info->co_ps), + CORE_OBJECT_TYPE_NETWORK); + + if (co_network) { + gboolean gsm_dtm_support = FALSE; + gsm_dtm_support = tcore_network_get_gsm_dtm_support(co_network); + if (gsm_dtm_support) { + s_indi_log_ex(cp_name, "GSM DTM supported! UI need not be synchronized"); + return TRUE; + } + } + + /* Mapping VCONF keys */ + if (s_indi_str_has_suffix(cp_name, "0")) { + vconf_key = STORAGE_KEY_PACKET_SERVICE_STATE; + } else if (s_indi_str_has_suffix(cp_name, "1")) { + vconf_key = STORAGE_KEY_PACKET_SERVICE_STATE2; + } else { + s_indi_assert_not_reached(); + return TRUE; + } + + tcore_network_get_service_type(co_network, &svc_type); + + switch (svc_type) { + case NETWORK_SERVICE_TYPE_2G: + case NETWORK_SERVICE_TYPE_2_5G: + case NETWORK_SERVICE_TYPE_2_5G_EDGE: + show_icon = FALSE; + break; + + case NETWORK_SERVICE_TYPE_3G: + case NETWORK_SERVICE_TYPE_HSDPA: + if (tcore_object_ref_plugin(co_network) != tcore_object_ref_plugin(source)) + show_icon = FALSE; + break; + + default: + break; + } + + s_indi_log_ex(cp_name, "RAT: [0x%x], ps_state: [0x%x], show_icon[%d]", + svc_type, state_info->ps_state, show_icon); + + if (show_icon == TRUE) { + if (state_info->ps_state == S_INDI_CELLULAR_OFF) { + state_info->ps_state = S_INDI_CELLULAR_CONNECTED; + goto OUT; + } + return TRUE; + } + + switch(command) { + case TNOTI_CALL_STATUS_IDLE: { + int total_call_cnt = S_INDI_ZERO; + total_call_cnt = tcore_call_object_total_length(source); + if (total_call_cnt > S_INDI_ONE) { + s_indi_log_ex(cp_name, "Call is still connected"); + return TRUE; + } + state_info->ps_state = S_INDI_CELLULAR_CONNECTED; + } break; + + case TNOTI_CALL_STATUS_DIALING: + case TNOTI_CALL_STATUS_INCOMING: + case TNOTI_CALL_STATUS_ACTIVE: { + state_info->ps_state = S_INDI_CELLULAR_OFF; + } break; + + default: { + s_indi_log_ex(cp_name, "Unexpected command: [0x%x]", command); + s_indi_assert_not_reached(); + return TRUE; + } + } + +OUT: + /* Update PS Call state */ + strg_vconf = tcore_server_find_storage(server, S_INDI_VCONF_STORAGE_NAME); + if (state_info->ps_state != tcore_storage_get_int(strg_vconf, vconf_key)) { + tcore_storage_set_int(strg_vconf, vconf_key, state_info->ps_state); + s_indi_log_ex(cp_name, "PS Call status - [%s]", (state_info->ps_state == S_INDI_CELLULAR_CONNECTED ? "CONNECTED" + : (state_info->ps_state == S_INDI_CELLULAR_OFF ? "DISCONNECTED" + : (state_info->ps_state == S_INDI_CELLULAR_USING ? "IN USE" : "UNKNOWN")))); + } + + return TRUE; +} + +enum tcore_hook_return s_indi_on_hook_voice_call_status(Server *server, CoreObject *source, + enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data) +{ + TcorePlugin *indi_plugin = user_data; + s_indi_private_info *priv_info = __s_indi_get_priv_info(indi_plugin); + const char *cp_name = NULL; + s_indi_cp_state_info_type *state_info = NULL; + + GHashTableIter iter; + gpointer key, value; + + S_INDI_NOT_USED(data_len); + S_INDI_NOT_USED(data); + + CORE_OBJECT_CHECK_RETURN(source, CORE_OBJECT_TYPE_CALL, TCORE_HOOK_RETURN_CONTINUE); + + /* Update all modem states */ + g_hash_table_iter_init(&iter, priv_info->state_info); + while (g_hash_table_iter_next (&iter, &key, &value)) { + cp_name = key; + state_info = value; + + (void)__s_indi_handle_voice_call_status(server, source, command, + cp_name, state_info); + } + + return TCORE_HOOK_RETURN_CONTINUE; +} + +enum tcore_hook_return s_indi_on_hook_modem_plugin_added(Server *server, CoreObject *source, + enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data) +{ + s_indi_assert(NULL != data); + s_indi_assert(NULL != user_data); + + S_INDI_NOT_USED(server); + S_INDI_NOT_USED(source); + S_INDI_NOT_USED(command); + S_INDI_NOT_USED(data_len); + + __s_indi_add_modem_plugin(user_data, data); + + return TCORE_HOOK_RETURN_CONTINUE; +} + +enum tcore_hook_return s_indi_on_hook_modem_plugin_removed(Server *server, CoreObject *source, + enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data) +{ + s_indi_assert(NULL != data); + s_indi_assert(NULL != user_data); + + S_INDI_NOT_USED(server); + S_INDI_NOT_USED(source); + S_INDI_NOT_USED(command); + S_INDI_NOT_USED(data_len); + + __s_indi_remove_modem_plugin(user_data, data); + + return TCORE_HOOK_RETURN_CONTINUE; +} + +gboolean s_indi_init(TcorePlugin *plugin) +{ + Server *server = NULL; + s_indi_private_info *priv_info = NULL; + + priv_info = s_indi_malloc0(sizeof(*priv_info)); + if (tcore_plugin_link_user_data(plugin, priv_info) != TCORE_RETURN_SUCCESS) { + err("Failed to link private data"); + s_indi_free(priv_info); + return FALSE; + } + + server = tcore_plugin_ref_server(plugin); + + /* Initialize SIPC counter */ + priv_info->msg_id.id_current = S_INDI_SIPC_ITER_START - S_INDI_ONE; + priv_info->msg_id.id_start = S_INDI_SIPC_ITER_START; + priv_info->msg_id.id_end = S_INDI_SIPC_ITER_END; + + /* Initialize VCONF => CP_NAME mapping */ + priv_info->vconf_info = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, s_indi_free_func); + + /* Initialize State Information */ + priv_info->state_info = g_hash_table_new_full(g_str_hash, g_str_equal, s_indi_free_func, __s_indi_state_info_value_destroy_notification); + + if (priv_info->state_info == NULL + || priv_info->vconf_info == NULL) { + err("Memory allocation problem! Bailing Out"); + goto OUT; + } + + priv_info->b_pm_lock = FALSE; + + /* Register vconf key callbacks */ + __s_indi_register_vconf_key(STORAGE_KEY_PM_STATE, plugin, NULL); + + /* Server Hooks*/ + tcore_server_add_notification_hook(server, TNOTI_MODEM_POWER, s_indi_on_hook_modem_power, plugin); + tcore_server_add_notification_hook(server, TNOTI_PS_CALL_STATUS, s_indi_on_hook_ps_call_status, plugin); + tcore_server_add_notification_hook(server, TNOTI_NETWORK_REGISTRATION_STATUS, s_indi_on_hook_net_register, plugin); + tcore_server_add_notification_hook(server, TNOTI_SIM_STATUS, s_indi_on_hook_sim_init, plugin); + + /* For 2G PS suspend/resume */ + tcore_server_add_notification_hook(server, TNOTI_CALL_STATUS_IDLE, s_indi_on_hook_voice_call_status, plugin); + tcore_server_add_notification_hook(server, TNOTI_CALL_STATUS_DIALING, s_indi_on_hook_voice_call_status, plugin); + tcore_server_add_notification_hook(server, TNOTI_CALL_STATUS_INCOMING, s_indi_on_hook_voice_call_status, plugin); + tcore_server_add_notification_hook(server, TNOTI_CALL_STATUS_ACTIVE, s_indi_on_hook_voice_call_status, plugin); + + /* For new Modems */ + tcore_server_add_notification_hook(server, TNOTI_SERVER_ADDED_MODEM_PLUGIN, s_indi_on_hook_modem_plugin_added, plugin); + tcore_server_add_notification_hook(server, TNOTI_SERVER_REMOVED_MODEM_PLUGIN, s_indi_on_hook_modem_plugin_removed, plugin); + + /* Add existing Modems */ + __s_indi_refresh_modems(plugin); + + return TRUE; + +OUT: + s_indi_deinit(plugin); + return FALSE; +} + +void s_indi_deinit(TcorePlugin *plugin) +{ + Server *server = NULL; + GList *iter; + s_indi_cp_state_info_type *state_info = NULL; + TcorePlugin *modem_plugin = NULL; + s_indi_private_info *priv_info = __s_indi_get_priv_info(plugin); + + /* Remove Hooks */ + server = tcore_plugin_ref_server(plugin); + tcore_server_remove_notification_hook(server, s_indi_on_hook_modem_power); + tcore_server_remove_notification_hook(server, s_indi_on_hook_ps_call_status); + tcore_server_remove_notification_hook(server, s_indi_on_hook_net_register); + tcore_server_remove_notification_hook(server, s_indi_on_hook_sim_init); + tcore_server_remove_notification_hook(server, s_indi_on_hook_voice_call_status); + tcore_server_remove_notification_hook(server, s_indi_on_hook_modem_plugin_added); + tcore_server_remove_notification_hook(server, s_indi_on_hook_modem_plugin_removed); + + /* Remove key callback */ + __s_indi_unregister_vconf_key(STORAGE_KEY_PM_STATE, plugin, NULL); + + /* Destroy all watched modems */ + iter = g_hash_table_get_values(priv_info->state_info); + while (iter) { + state_info = iter->data; + modem_plugin = tcore_object_ref_plugin(state_info->co_ps); + __s_indi_remove_modem_plugin(plugin, modem_plugin); + + iter = g_list_delete_link(iter, iter); + } + + /* Decrement hash table reference */ + g_hash_table_destroy(priv_info->state_info); + g_hash_table_destroy(priv_info->vconf_info); + + /* Finalize */ + s_indi_free(priv_info); + tcore_plugin_link_user_data(plugin, NULL); +} diff --git a/packaging/tel-plugin-indicator.manifest b/tel-plugin-indicator.manifest similarity index 66% rename from packaging/tel-plugin-indicator.manifest rename to tel-plugin-indicator.manifest index 017d22d..573257c 100644 --- a/packaging/tel-plugin-indicator.manifest +++ b/tel-plugin-indicator.manifest @@ -1,5 +1,5 @@ - + -- 2.34.1