From: jk7744.park Date: Tue, 8 Sep 2015 13:39:46 +0000 (+0900) Subject: tizen 2.3.1 release X-Git-Tag: submit/tizen_2.3.1/20150915.082219^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Ftizen_2.3.1;p=framework%2Ftelephony%2Flibtcore.git tizen 2.3.1 release --- diff --git a/CMakeLists.txt b/CMakeLists.txt index e003579..1cd1394 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,20 +10,26 @@ SET(INCLUDEDIR "\${prefix}/include") # Set required packages INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED glib-2.0 dlog gudev-1.0) +pkg_check_modules(pkgs REQUIRED glib-2.0 gudev-1.0) FOREACH(flag ${pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR}/include ${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} -I${CMAKE_SOURCE_DIR}/include ${EXTRA_CFLAGS} -Werror -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wdeclaration-after-statement -Wmissing-declarations -Wredundant-decls -Wcast-align -O2 -Wall -Wno-array-bounds -Wno-empty-body -Wno-ignored-qualifiers -Wshadow -Wwrite-strings -Wswitch-default -Wno-unused-but-set-variable") -ADD_DEFINITIONS("-DFEATURE_DLOG_DEBUG") +ADD_DEFINITIONS("-DFEATURE_TLOG_DEBUG") ADD_DEFINITIONS("-DTCORE_LOG_TAG=\"TCORE\"") +#ADD_DEFINITIONS("-DTCORE_HAL_DEBUG") +ADD_DEFINITIONS("-DTCORE_VERSION=\"${VERSION}\"") MESSAGE(${CMAKE_C_FLAGS}) MESSAGE(${CMAKE_EXE_LINKER_FLAGS}) +IF (ARCH_EMUL) + ADD_DEFINITIONS("-DEMULATOR") +ENDIF (ARCH_EMUL) + SET(SRCS src/server.c src/plugin.c @@ -48,6 +54,7 @@ SET(SRCS src/co_sms.c src/co_phonebook.c src/co_gps.c + src/co_custom.c src/mux.c ) @@ -68,5 +75,6 @@ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include/tcore INSTALL(TARGETS tcore LIBRARY DESTINATION lib) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/tcore.pc DESTINATION lib/pkgconfig) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION /usr/share/license RENAME libtcore) #ADD_SUBDIRECTORY(unit-test) 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/debian/changelog b/debian/changelog deleted file mode 100644 index 4a3c5d8..0000000 --- a/debian/changelog +++ /dev/null @@ -1,201 +0,0 @@ -libtcore (0.1.23) unstable; urgency=low - - * Replace dun_pin_ctrl from ps to modem - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.23 - - -- DongHoo Park Mon, 11 Jun 2012 14:32:10 +0900 - -libtcore (0.1.22) unstable; urgency=low - - * Add phonebook selection feature - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.22 - - -- Youngman Park Tue, 22 May 2012 11:57:45 +0900 - -libtcore (0.1.21) unstable; urgency=low - - * Add sat proactive command - * Fix user_request_dup - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.21 - - -- Inho Oh Tue, 22 May 2012 10:47:29 +0900 - -libtcore (0.1.20) unstable; urgency=low - - * add req,resp type for getting sim lock info - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.20 - - -- Kyeongchul Kim Thu, 17 May 2012 17:35:34 +0900 - -libtcore (0.1.19) unstable; urgency=low - - * Fix SPN in NO-SIM state - * Add HSUPA, HSPA - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.19 - - -- Inho Oh Thu, 10 May 2012 11:00:05 +0900 - -libtcore (0.1.18) unstable; urgency=low - - * Fix OBS build error - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.18 - - -- Youngman Park Tue, 08 May 2012 16:17:01 +0900 - -libtcore (0.1.17) unstable; urgency=low - - * Add Call New API ( call custom service ) - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.17 - - -- Youngman Park Mon, 07 May 2012 17:40:01 +0900 - -libtcore (0.1.16) unstable; urgency=low - - * Add pending timeout - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.16 - - -- Inho Oh Thu, 03 May 2012 15:12:01 +0900 - -libtcore (0.1.15) unstable; urgency=low - - * Fix typo bug & network icon info type - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.15 - - -- Inho Oh Tue, 24 Apr 2012 14:24:50 +0900 - -libtcore (0.1.14) unstable; urgency=low - - * Fix ip string bug - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.14 - - -- Inho Oh Thu, 05 Apr 2012 13:40:08 +0900 - -libtcore (0.1.13) unstable; urgency=low - - * fixed SAT TR operation - RESULT_BACKWARD_MOVE_BY_USER case and so on - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.13 - - -- Kyeongchul Kim Mon, 02 Apr 2012 20:33:33 +0900 - -libtcore (0.1.12) unstable; urgency=low - - * version up for code sync with public binary - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.12 - - -- Kyeongchul Kim Mon, 02 Apr 2012 12:18:03 +0900 - -libtcore (0.1.11) unstable; urgency=low - - * Apply coding guide line, Fix obs build break - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.11 - - -- DongHoo Park Fri, 30 Mar 2012 10:53:48 +0900 - -libtcore (0.1.10) unstable; urgency=low - - * Fix SAT TR - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.10 - - -- DongHoo Park Thu, 29 Mar 2012 16:35:42 +0900 - -libtcore (0.1.9) unstable; urgency=low - - * Fix prefix (TAPI_ to TCORE_) - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.9 - - -- Inho Oh Tue, 27 Mar 2012 22:04:25 +0900 - -libtcore (0.1.8) unstable; urgency=low - - * Apply SAT encoding functions - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.8 - - -- Kyeongchul Kim Tue, 27 Mar 2012 20:46:13 +0900 - -libtcore (0.1.7) unstable; urgency=low - - * Fix sat - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.7 - - -- Inho Oh Thu, 22 Mar 2012 14:33:47 +0900 - -libtcore (0.1.6) unstable; urgency=low - - * version up - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.6 - - -- DongHoo Park Wed, 21 Mar 2012 14:08:51 +0900 - -libtcore (0.1.5) unstable; urgency=low - - * add tcore_network_get/set_network_name_priority - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.5 - - -- Inho Oh Tue, 20 Mar 2012 17:04:56 +0900 - -libtcore (0.1.4) unstable; urgency=low - - * change member name of enum telephony_ps_pdp_err - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.4 - - -- Kyeongchul Kim Mon, 19 Mar 2012 22:56:49 +0900 - -libtcore (0.1.3) unstable; urgency=low - - * Add the HSDPA Noti - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.3 - - -- DongHoo Park Mon, 19 Mar 2012 14:44:45 +0900 - -libtcore (0.1.2) unstable; urgency=low - - * Add Code for Video Call - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.2 - - -- Youngman Park Sat, 17 Mar 2012 18:15:30 +0900 - -libtcore (0.1.1) unstable; urgency=low - - * Version info change & Fix OBS Build break - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.1 - - -- DongHoo Park Fri, 16 Mar 2012 13:40:30 +0900 - -libtcore (0.1.0-1) unstable; urgency=low - - * Fix arm/i386 version mismatch - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.0-1 - - -- Inho Oh Thu, 15 Mar 2012 23:40:55 +0900 - -libtcore (0.1.0) unstable; urgency=low - - * Initial - * Git: slp/pkgs/l/libtcore - * Tag: libtcore_0.1.0 - - -- Inho Oh Thu, 15 Mar 2012 22:37:29 +0900 diff --git a/debian/compat b/debian/compat deleted file mode 100644 index 7ed6ff8..0000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -5 diff --git a/debian/control b/debian/control deleted file mode 100644 index 50ccc37..0000000 --- a/debian/control +++ /dev/null @@ -1,27 +0,0 @@ -Source: libtcore -Section: libs -Priority: extra -Maintainer: Jongman Park -Uploaders: Jayoung Gu , Kyeongchul Kim , Youngman Park , Inho Oh , DongHoo Park -Build-Depends: debhelper (>= 5), libglib2.0-dev, dlog-dev -Standards-Version: 0.0.0 - -Package: libtcore-dev -Section: libs -Architecture: any -Depends: libtcore (= ${Source-Version}), - libglib2.0-dev -Description: telephony client API library (Development) - -Package: libtcore -Section: libs -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, -Description: telephony client API library (Shared Object) - -Package: libtcore-dbg -Section: debug -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, libtcore (= ${Source-Version}) -Description: telephony client API library (dbg package) - diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index d5a0cca..0000000 --- a/debian/copyright +++ /dev/null @@ -1,7 +0,0 @@ -Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License version 2.1. - -The full text of the LGPL 2.1 can be found in -/usr/share/common-licenses. diff --git a/debian/dirs b/debian/dirs deleted file mode 100644 index ca882bb..0000000 --- a/debian/dirs +++ /dev/null @@ -1,2 +0,0 @@ -usr/bin -usr/sbin diff --git a/debian/docs b/debian/docs deleted file mode 100644 index e69de29..0000000 diff --git a/debian/libtcore-dev.install.in b/debian/libtcore-dev.install.in deleted file mode 100644 index 77573d0..0000000 --- a/debian/libtcore-dev.install.in +++ /dev/null @@ -1,2 +0,0 @@ -@PREFIX@/include/* -@PREFIX@/lib/pkgconfig/tcore.pc diff --git a/debian/libtcore.install.in b/debian/libtcore.install.in deleted file mode 100644 index 143a4e8..0000000 --- a/debian/libtcore.install.in +++ /dev/null @@ -1 +0,0 @@ -@PREFIX@/lib/libtcore* diff --git a/debian/rules b/debian/rules deleted file mode 100755 index afa2a34..0000000 --- a/debian/rules +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- -# Sample debian/rules that uses debhelper. -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -CFLAGS ?= -Wall -g -CXXFLAGS ?= -Wall -g -LDFLAGS ?= -PREFIX ?= /usr -DATADIR ?= /opt - -ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) - CFLAGS += -O0 - CXXFLAGS += -O0 -else - CFLAGS += -O2 - CXXFLAGS += -O2 -endif - -#CFLAGS += -fvisibility=hidden -fPIC -CFLAGS += -fvisibility=default -fPIC -LDFLAGS += -rdynamic -fPIC -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed -#LDFLAGS += -Wl,--unresolved-symbols=ignore-in-shared-libs,--as-needed - -CMAKE_TMP_DIR = $(CURDIR)/cmake_tmp - -configure: configure-stamp -configure-stamp: - dh_testdir - # Add here commands to configure the package. - mkdir -p $(CMAKE_TMP_DIR); - cd $(CMAKE_TMP_DIR); CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" cmake .. -DCMAKE_INSTALL_PREFIX=$(PREFIX) - - touch configure-stamp - -build: build-stamp - -build-stamp: configure-stamp - dh_testdir - - # Add here commands to compile the package. - cd $(CMAKE_TMP_DIR) && $(MAKE) all - - for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ - cat $$f > $${f%.in}; \ - sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \ - sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \ - done - - touch $@ - -clean: - dh_testdir - dh_testroot - rm -f build-stamp configure-stamp - - # Add here commands to clean up after the build process. - rm -rf $(CMAKE_TMP_DIR) - - for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ - rm -f $${f%.in}; \ - done - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - - # Add here commands to install the package into debian/wavplayer. - cd $(CMAKE_TMP_DIR) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install - - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs - dh_installexamples - dh_install --sourcedir=debian/tmp -# dh_installmenu -# dh_installdebconf -# dh_installlogrotate -# dh_installemacsen -# dh_installpam -# dh_installmime -# dh_python -# dh_installinit -# dh_installcron -# dh_installinfo - dh_installman - dh_link - dh_strip --dbg-package=libtcore-dbg - dh_compress - dh_fixperms -# dh_perl - dh_makeshlibs - dh_installdeb - dh_shlibdeps --dpkg-shlibdeps-params="-v" - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/include/at.h b/include/at.h index 8c9ad81..0793f95 100644 --- a/include/at.h +++ b/include/at.h @@ -1,3 +1,22 @@ +/* + * libtcore + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Ja-young Gu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef __TCORE_AT_H__ #define __TCORE_AT_H__ @@ -7,6 +26,8 @@ __BEGIN_DECLS #include #include +#define ZERO 0 + enum tcore_at_command_type { TCORE_AT_NO_RESULT, /* no intermediate response expected */ TCORE_AT_NUMERIC, /* a single intermediate response starting with a 0-9 */ @@ -93,6 +114,9 @@ TReturn tcore_at_set_request(TcoreAT *at, TcoreATRequest *req, gboolean TcoreATRequest* tcore_at_get_request(TcoreAT *at); TcoreATResponse* tcore_at_get_response(TcoreAT *at); +void tcore_at_process_binary_data(TcoreAT *at, char *position, int data_len); +gboolean tcore_at_add_hook(TcoreHal *hal, void *hook_func); + TReturn tcore_at_add_notification(TcoreAT *at, const char *prefix, gboolean pdu, TcoreATNotificationCallback callback, void *user_data); @@ -117,7 +141,20 @@ GSList* tcore_at_tok_new(const char *line); void tcore_at_tok_free(GSList *tokens); char* tcore_at_tok_extract(const char *src); char* tcore_at_tok_nth(GSList *tokens, unsigned int token_index); - +void tcore_free_pending_timeout_at_request(TcoreAT *at); + +TReturn tcore_prepare_and_send_at_request(CoreObject *co, + const char *at_cmd, + const char *at_cmd_prefix, + enum tcore_at_command_type at_cmd_type, + UserRequest *ur, + TcorePendingResponseCallback resp_cb, + void *resp_cb_data, + TcorePendingSendCallback send_cb, + void *send_cb_data, + unsigned int timeout, + TcorePendingTimeoutCallback timeout_cb, + void *timeout_cb_data); __END_DECLS diff --git a/include/co_call.h b/include/co_call.h index 8061deb..eb2e3ad 100644 --- a/include/co_call.h +++ b/include/co_call.h @@ -32,6 +32,8 @@ enum tcore_call_type { TCORE_CALL_TYPE_VOICE, TCORE_CALL_TYPE_VIDEO, TCORE_CALL_TYPE_E911, + TCORE_CALL_TYPE_STDOTASP, + TCORE_CALL_TYPE_NONSTDOTASP, }; enum tcore_call_direction { @@ -50,10 +52,19 @@ enum tcore_call_status { TCORE_CALL_STATUS_WAITING, }; +enum tcore_call_no_cli_cause { + TCORE_CALL_NO_CLI_CAUSE_NONE = -1, + TCORE_CALL_NO_CLI_CAUSE_UNAVAILABLE, + TCORE_CALL_NO_CLI_CAUSE_USER_REJECTED, + TCORE_CALL_NO_CLI_CAUSE_OTHERS, + TCORE_CALL_NO_CLI_CAUSE_PAY_PHONE +}; + enum tcore_call_cli_mode { - TCORE_CALL_CLI_MODE_DEFAULT, TCORE_CALL_CLI_MODE_PRESENT, TCORE_CALL_CLI_MODE_RESTRICT, + TCORE_CALL_CLI_MODE_UNAVAILABLE, + TCORE_CALL_CLI_MODE_DEFAULT, }; enum tcore_call_cna_mode { @@ -89,19 +100,25 @@ struct tcore_call_operations { TReturn (*split)(CoreObject *o, UserRequest *ur); TReturn (*deflect)(CoreObject* o, UserRequest *ur); TReturn (*transfer)(CoreObject* o, UserRequest *ur); - TReturn (*send_dtmf)(CoreObject *o, UserRequest *ur); + TReturn (*start_cont_dtmf)(CoreObject *o, UserRequest *ur); + TReturn (*stop_cont_dtmf)(CoreObject *o, UserRequest *ur); + TReturn (*send_burst_dtmf)(CoreObject *o, UserRequest *ur); TReturn (*set_sound_path)(CoreObject *o, UserRequest *ur); TReturn (*set_sound_volume_level)(CoreObject *o, UserRequest *ur); TReturn (*get_sound_volume_level)(CoreObject *o, UserRequest *ur); - TReturn (*mute)(CoreObject *o, UserRequest *ur); - TReturn (*unmute)(CoreObject *o, UserRequest *ur); - TReturn (*get_mute_status)(CoreObject *o, UserRequest *ur); + TReturn (*set_sound_mute_status)(CoreObject *o, UserRequest *ur); + TReturn (*get_sound_mute_status)(CoreObject *o, UserRequest *ur); TReturn (*set_sound_recording)(CoreObject *o, UserRequest *ur); TReturn (*set_sound_equalization)(CoreObject *o, UserRequest *ur); TReturn (*set_sound_noise_reduction)(CoreObject *o, UserRequest *ur); + TReturn (*set_sound_clock_status)(CoreObject *o, UserRequest *ur); TReturn (*set_active_line)(CoreObject *o, UserRequest *ur); TReturn (*get_active_line)(CoreObject *o, UserRequest *ur); TReturn (*activate_ccbs)(CoreObject *o, UserRequest *ur); + TReturn (*set_preferred_voice_subscription)(CoreObject *o, UserRequest *ur); + TReturn (*get_preferred_voice_subscription)(CoreObject *o, UserRequest *ur); + TReturn (*set_privacy_mode)(CoreObject *o, UserRequest *ur); + TReturn (*get_privacy_mode)(CoreObject *o, UserRequest *ur); }; struct tcore_call_information_operations { @@ -152,11 +169,13 @@ struct tcore_call_control_operations { CoreObject* tcore_call_new(TcorePlugin *p, const char *name, struct tcore_call_operations *ops, TcoreHal *hal); void tcore_call_free( CoreObject *o); +void tcore_call_set_ops(CoreObject *o, struct tcore_call_operations *ops); // Call Object API CallObject* tcore_call_object_new( CoreObject *o, int id ); gboolean tcore_call_object_free( CoreObject *o, CallObject *co ); +int tcore_call_object_total_length( CoreObject *o ); CallObject* tcore_call_object_current_on_mt_processing( CoreObject *o ); CallObject* tcore_call_object_current_on_mo_processing( CoreObject *o ); CallObject* tcore_call_object_find_by_id( CoreObject *o, int id ); @@ -174,8 +193,11 @@ enum tcore_call_direction tcore_call_object_get_direction( CallObject *co ); gboolean tcore_call_object_set_status( CallObject *co, enum tcore_call_status cs ); enum tcore_call_status tcore_call_object_get_status( CallObject *co ); -gboolean tcore_call_object_set_cli_info( CallObject *co, enum tcore_call_cli_mode mode, char *num ); +gboolean tcore_call_object_set_cli_info(struct call_object *co, + enum tcore_call_cli_mode mode, enum tcore_call_no_cli_cause cause, + char *num, int num_len); enum tcore_call_cli_mode tcore_call_object_get_cli_mode( CallObject *co ); +enum tcore_call_no_cli_cause tcore_call_object_get_no_cli_cause(struct call_object *co); int tcore_call_object_get_number( CallObject *co, char *num ); gboolean tcore_call_object_set_cna_info( CallObject *co, enum tcore_call_cna_mode mode, char *name, int dcs ); diff --git a/include/co_context.h b/include/co_context.h index 64aeca2..0ead6f6 100644 --- a/include/co_context.h +++ b/include/co_context.h @@ -39,6 +39,7 @@ enum co_context_type { CONTEXT_TYPE_IHOST, CONTEXT_TYPE_PPP, CONTEXT_TYPE_IPV6, + CONTEXT_TYPE_IPV4V6, }; enum co_context_role { @@ -77,8 +78,8 @@ void tcore_context_free(CoreObject *o); TReturn tcore_context_set_state(CoreObject *o, enum co_context_state state); enum co_context_state tcore_context_get_state(CoreObject *o); -TReturn tcore_context_set_id(CoreObject *o, unsigned int id); -unsigned int tcore_context_get_id(CoreObject *o); +TReturn tcore_context_set_id(CoreObject *o, unsigned char id); +unsigned char tcore_context_get_id(CoreObject *o); TReturn tcore_context_set_role(CoreObject *o, enum co_context_role type); enum co_context_role tcore_context_get_role(CoreObject *o); @@ -120,6 +121,11 @@ char* tcore_context_get_ipv4_dns2(CoreObject *o); char* tcore_context_get_ipv4_gw(CoreObject *o); char* tcore_context_get_ipv4_devname(CoreObject *o); +char* tcore_context_get_ipv6_addr(CoreObject *o); +char* tcore_context_get_ipv6_dns1(CoreObject *o); +char* tcore_context_get_ipv6_dns2(CoreObject *o); +char* tcore_context_get_ipv6_gw(CoreObject *o); + __END_DECLS #endif diff --git a/include/co_custom.h b/include/co_custom.h new file mode 100644 index 0000000..e590297 --- /dev/null +++ b/include/co_custom.h @@ -0,0 +1,35 @@ +/* + * custom + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Anga Santhosh Kumar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TCORE_CO_CUSTOM_H__ +#define __TCORE_CO_CUSTOM_H__ + +__BEGIN_DECLS + +typedef void *tcore_custom_operations; + +CoreObject *tcore_custom_new(TcorePlugin *p, + const char *name, tcore_custom_operations ops, + CoreObjectDispatcher dispatcher, TcoreHal *hal); +void tcore_custom_free(CoreObject *co); + +__END_DECLS + +#endif /* __TCORE_CO_CUSTOM_H__ */ diff --git a/include/co_gps.h b/include/co_gps.h index 726888c..d97881a 100644 --- a/include/co_gps.h +++ b/include/co_gps.h @@ -25,13 +25,21 @@ __BEGIN_DECLS - struct tcore_gps_operations { TReturn (*confirm_measure_pos)(CoreObject *o, UserRequest *ur); + TReturn (*set_frequency_aiding)(CoreObject *o, UserRequest *ur); + TReturn (*enable_smart_assistant)(CoreObject *o, UserRequest *ur); + TReturn (*disable_smart_assistant)(CoreObject *o, UserRequest *ur); + TReturn (*sync_smart_assistant_area_list)(CoreObject *o, UserRequest *ur); + TReturn (*del_smart_assistant_area_list)(CoreObject *o, UserRequest *ur); + TReturn (*add_smart_assistant_area)(CoreObject *o, UserRequest *ur); + TReturn (*modify_smart_assistant_area)(CoreObject *o, UserRequest *ur); + TReturn (*set_smart_assistant_info)(CoreObject *o, UserRequest *ur); }; CoreObject* tcore_gps_new(TcorePlugin *p, const char *name, struct tcore_gps_operations *ops, TcoreHal *hal); void tcore_gps_free(CoreObject *o); +void tcore_gps_set_ops(CoreObject *o, struct tcore_gps_operations *ops); __END_DECLS diff --git a/include/co_modem.h b/include/co_modem.h index b251e73..ccc5be2 100644 --- a/include/co_modem.h +++ b/include/co_modem.h @@ -30,17 +30,21 @@ struct tcore_modem_operations { TReturn (*power_on)(CoreObject *o, UserRequest *ur); TReturn (*power_off)(CoreObject *o, UserRequest *ur); TReturn (*power_reset)(CoreObject *o, UserRequest *ur); + TReturn (*power_low)(CoreObject *o, UserRequest *ur); TReturn (*set_flight_mode)(CoreObject *o, UserRequest *ur); TReturn (*get_imei)(CoreObject *o, UserRequest *ur); TReturn (*get_version)(CoreObject *o, UserRequest *ur); TReturn (*get_sn)(CoreObject *o, UserRequest *ur); TReturn (*dun_pin_ctrl)(CoreObject *o, UserRequest *ur); + TReturn (*get_flight_mode)(CoreObject *o, UserRequest *ur); }; CoreObject* tcore_modem_new(TcorePlugin *p, const char *name, struct tcore_modem_operations *ops, TcoreHal *hal); void tcore_modem_free(CoreObject *o); +void tcore_modem_set_ops(CoreObject *o, struct tcore_modem_operations *ops); + TReturn tcore_modem_set_flight_mode_state(CoreObject *o, gboolean flag); gboolean tcore_modem_get_flight_mode_state(CoreObject *o); TReturn tcore_modem_set_powered(CoreObject *o, gboolean pwr); diff --git a/include/co_network.h b/include/co_network.h index 78c63c0..0cd7f19 100644 --- a/include/co_network.h +++ b/include/co_network.h @@ -25,6 +25,42 @@ __BEGIN_DECLS +/* + * Manual PLMN property + * + * Value: MCC+MNC or Empty(Unknown mode) + */ +#define PROP_NET_MANUAL_PLMN "manual_plmn" + +/* + * Manual Selection status property + * + * Value: 'waiting' / 'success' / 'failure' / Empty(Unknown state) + */ +#define PROP_NET_MANUAL_SELECTION_STATUS "manual_selection_status" + +/* + * Network Registration Reject Cause Property + * + * Value: LU registration reject cause strings + */ +#define PROP_NET_REG_LU_REJECT_CAUSE "reg_reject_cause" + +/* + * Read mdn Property + * + * Value: mdn strings + */ +#define PROP_NET_READ_MDN_FOR_ACTIVATION "mdn_for_activation" + +/* + * Read pESN Property + * + * Value: pESN strings + */ +#define PROP_MODEM_READ_ESN_FOR_ACTIVATION "esn_for_activation" + + enum tcore_network_service_domain_type { TCORE_NETWORK_SERVICE_DOMAIN_TYPE_CIRCUIT, @@ -44,7 +80,15 @@ enum tcore_network_name_priority { TCORE_NETWORK_NAME_PRIORITY_ANY, }; +enum tcore_network_operator_info_type { + TCORE_NETWORK_OPERATOR_INFO_TYPE_TS25_DB = 0, + TCORE_NETWORK_OPERATOR_INFO_TYPE_DELTA_DB, + TCORE_NETWORK_OPERATOR_INFO_TYPE_NITZ, + TCORE_NETWORK_OPERATOR_INFO_TYPE_EONS, +}; + struct tcore_network_operator_info { + enum tcore_network_operator_info_type type; char mcc[4]; char mnc[4]; char name[41]; @@ -69,6 +113,16 @@ struct tcore_network_operations { TReturn (*get_serving_network)(CoreObject *o, UserRequest *ur); TReturn (*set_mode)(CoreObject *o, UserRequest *ur); TReturn (*get_mode)(CoreObject *o, UserRequest *ur); + TReturn (*set_neighboring_cell_info)(CoreObject *o, UserRequest *ur); + TReturn (*get_neighboring_cell_info)(CoreObject *o, UserRequest *ur); + TReturn (*set_default_data_subscription)(CoreObject *o, UserRequest *ur); + TReturn (*get_default_data_subscription)(CoreObject *o, UserRequest *ur); + TReturn (*set_default_subscription)(CoreObject *o, UserRequest *ur); + TReturn (*get_default_subscription)(CoreObject *o, UserRequest *ur); + TReturn (*set_emergency_callback_mode)(CoreObject *o, UserRequest *ur); /* 3GPP2 spcefic */ + TReturn (*set_roaming_preference)(CoreObject *o, UserRequest *ur); /* 3GPP2 spcefic */ + TReturn (*get_roaming_preference)(CoreObject *o, UserRequest *ur); /* 3GPP2 spcefic */ + TReturn (*get_subscription_info)(CoreObject *o, UserRequest *ur); /* 3GPP2 spcefic */ }; @@ -76,6 +130,8 @@ CoreObject* tcore_network_new(TcorePlugin *plugin, const char *name, struct tcore_network_operations *ops, TcoreHal *hal); void tcore_network_free(CoreObject *co); +void tcore_network_set_ops(CoreObject *co, struct tcore_network_operations *ops); + TReturn tcore_network_set_plmn(CoreObject *co, const char *plmn); char* tcore_network_get_plmn(CoreObject *co); @@ -92,6 +148,9 @@ TReturn tcore_network_get_network_name_priority(CoreObject *co, TReturn tcore_network_set_roaming_state(CoreObject *co, gboolean state); gboolean tcore_network_get_roaming_state(CoreObject *co); +TReturn tcore_network_set_restricted_state(CoreObject *co, int state); +int tcore_network_get_restricted_state(CoreObject *co); + TReturn tcore_network_set_service_status(CoreObject *co, enum tcore_network_service_domain_type type, enum telephony_network_service_domain_status status); @@ -113,13 +172,16 @@ TReturn tcore_network_get_rac(CoreObject *co, unsigned int *result); TReturn tcore_network_set_cell_id(CoreObject *co, unsigned int cell_id); TReturn tcore_network_get_cell_id(CoreObject *co, unsigned int *result); +TReturn tcore_network_set_gsm_dtm_support(CoreObject *co, gboolean state); +gboolean tcore_network_get_gsm_dtm_support(CoreObject *co); + TReturn tcore_network_set_service_type(CoreObject *co, enum telephony_network_service_type service_type); TReturn tcore_network_get_service_type(CoreObject *co, enum telephony_network_service_type *result); TReturn tcore_network_operator_info_add(CoreObject *co, - struct tcore_network_operator_info *noi); + const struct tcore_network_operator_info *noi); struct tcore_network_operator_info* tcore_network_operator_info_find(CoreObject *co, diff --git a/include/co_phonebook.h b/include/co_phonebook.h index c37b563..0ddea4f 100644 --- a/include/co_phonebook.h +++ b/include/co_phonebook.h @@ -26,9 +26,6 @@ __BEGIN_DECLS struct tcore_phonebook_operations { - /*WILL BE REMOVED - START*/ - TReturn (*select)(CoreObject *o, UserRequest *ur); - /*WILL BE REMOVED - END*/ TReturn (*get_count)(CoreObject *o, UserRequest *ur); TReturn (*get_info)(CoreObject *o, UserRequest *ur); TReturn (*get_usim_info)(CoreObject *o, UserRequest *ur); @@ -40,12 +37,17 @@ struct tcore_phonebook_operations { CoreObject* tcore_phonebook_new(TcorePlugin *p, const char *name, struct tcore_phonebook_operations *ops, TcoreHal *hal); void tcore_phonebook_free(CoreObject *n); +void tcore_phonebook_set_ops(CoreObject *o, struct tcore_phonebook_operations *ops); + gboolean tcore_phonebook_get_status(CoreObject *o); gboolean tcore_phonebook_set_status(CoreObject *o, gboolean b_init); struct tel_phonebook_support_list* tcore_phonebook_get_support_list(CoreObject *o); gboolean tcore_phonebook_set_support_list(CoreObject *o, struct tel_phonebook_support_list *list); +struct tel_phonebook_field_support_list* tcore_phonebook_get_field_support_list(CoreObject *o); +gboolean tcore_phonebook_set_field_support_list(CoreObject *o, struct tel_phonebook_field_support_list *list); + enum tel_phonebook_type tcore_phonebook_get_selected_type(CoreObject *o); gboolean tcore_phonebook_set_selected_type(CoreObject *o, enum tel_phonebook_type t); diff --git a/include/co_ps.h b/include/co_ps.h index 36e55f3..75c2115 100644 --- a/include/co_ps.h +++ b/include/co_ps.h @@ -30,6 +30,7 @@ __BEGIN_DECLS #define PS_MAX_CID 4 struct tcore_ps_operations { + TReturn (*define_context)(CoreObject *co_ps, CoreObject *context, void *user_data); TReturn (*activate_context)(CoreObject *co_ps, CoreObject *context, void *user_data); TReturn (*deactivate_context)(CoreObject *co_ps, CoreObject *context, void *user_data); }; @@ -37,19 +38,32 @@ struct tcore_ps_operations { CoreObject* tcore_ps_new(TcorePlugin *p, const char *name, struct tcore_ps_operations *ops, TcoreHal *hal); void tcore_ps_free(CoreObject *o); +void tcore_ps_set_ops(CoreObject *o, struct tcore_ps_operations *ops); + TReturn tcore_ps_add_context(CoreObject *o, CoreObject *ctx_o); TReturn tcore_ps_remove_context(CoreObject *o, CoreObject *ctx_o); CoreObject* tcore_ps_ref_context_by_role(CoreObject *o, enum co_context_role role); GSList* tcore_ps_ref_context_by_id(CoreObject *o, unsigned int id); +gboolean tcore_ps_any_context_activating_activated(CoreObject *o, int * state); TReturn tcore_ps_set_online(CoreObject *o, gboolean state); - -TReturn tcore_ps_assign_context_id(CoreObject *o, CoreObject *context, unsigned int cid); +TReturn tcore_ps_set_num_of_pdn(CoreObject *o, gint numbers); +unsigned int tcore_ps_get_num_of_pdn(CoreObject *o); +unsigned int tcore_ps_set_cid_active(CoreObject *o, unsigned int cid, unsigned int enable); +unsigned int tcore_ps_get_cid_active(CoreObject *o, unsigned int cid); +GSList* tcore_ps_get_active_cids(CoreObject *o); +unsigned int tcore_ps_set_cid_connected(CoreObject *o, unsigned int cid, unsigned int connected); +unsigned int tcore_ps_get_cid_connected(CoreObject *o, unsigned int cid); +GSList* tcore_ps_get_connected_cids(CoreObject *o); +unsigned int tcore_ps_is_active_apn(CoreObject *o, const char* apn); +TReturn tcore_ps_assign_context_id(CoreObject *o, CoreObject *context, unsigned char cid); TReturn tcore_ps_clear_context_id(CoreObject *o, CoreObject *context); +TReturn tcore_ps_define_context(CoreObject *o, CoreObject *context, void *user_data); TReturn tcore_ps_activate_context(CoreObject *o, CoreObject *context, void *user_data); TReturn tcore_ps_deactivate_context(CoreObject *o, CoreObject *context, void *user_data); TReturn tcore_ps_deactivate_contexts(CoreObject *o); +TReturn tcore_ps_deactivate_cid(CoreObject *o, unsigned int cid); __END_DECLS diff --git a/include/co_sap.h b/include/co_sap.h index a8a3fab..451051a 100644 --- a/include/co_sap.h +++ b/include/co_sap.h @@ -38,6 +38,7 @@ struct tcore_sap_operations { CoreObject* tcore_sap_new(TcorePlugin *p, const char *name, struct tcore_sap_operations *ops, TcoreHal *hal); void tcore_sap_free(CoreObject *o); +void tcore_sap_set_ops(CoreObject *o, struct tcore_sap_operations *ops); __END_DECLS diff --git a/include/co_sat.h b/include/co_sat.h index ad9f35a..ceecd03 100644 --- a/include/co_sat.h +++ b/include/co_sat.h @@ -61,31 +61,24 @@ struct tcore_sat_proactive_command { struct tel_sat_receive_channel_tlv receive_data; struct tel_sat_send_channel_tlv send_data; struct tel_sat_get_channel_status_tlv get_channel_status; -/* - TelSatRefreshIndInfo_t refresh; - TelSatProvideLocalInfoIndInfo_t provideLocInfo; - TelSatLaunchBrowserIndInfo_t launchBrowser; - TelSatSetupIdleModeTextIndInfo_t idleText; - TelSatSendDtmfIndInfo_t sendDtmf; - TelSatLanguageNotificationIndInfo_t languageNotification; - TelSatOpenChannelIndInfo_t openChannel; - TelSatCloseChannelIndInfo_t closeChannel; - TelSatReceiveDataIndInfo_t receiveData; - TelSatSendDataIndInfo_t sendData; - TelSatGetChannelStatusIndInfo_t getChannelStatus;*/ + struct tel_sat_unsupproted_command_tlv unsupport_cmd; } data; }; struct tcore_sat_operations { TReturn (*envelope)(CoreObject *o, UserRequest *ur); TReturn (*terminal_response)(CoreObject *o, UserRequest *ur); + TReturn (*user_confirmation)(CoreObject *o, UserRequest *ur); }; int tcore_sat_decode_proactive_command(unsigned char* tlv_origin, unsigned int tlv_length, struct tcore_sat_proactive_command* decoded_tlv); +int tcore_sat_decode_call_control_result(unsigned char* tlv_origin, unsigned int tlv_length, struct tnoti_sat_call_control_result_ind* call_ctrl_result_tlv); int tcore_sat_encode_envelop_cmd(const struct treq_sat_envelop_cmd_data *src_envelop, char *dst_envelop); int tcore_sat_encode_terminal_response(const struct treq_sat_terminal_rsp_data *src_tr, char *dst_tr); CoreObject* tcore_sat_new(TcorePlugin *p, const char *name, struct tcore_sat_operations *ops, TcoreHal *hal); void tcore_sat_free(CoreObject *n); +void tcore_sat_set_ops(CoreObject *o, struct tcore_sat_operations *ops); + #endif diff --git a/include/co_sim.h b/include/co_sim.h index df0d346..f4f0993 100644 --- a/include/co_sim.h +++ b/include/co_sim.h @@ -38,69 +38,109 @@ struct tcore_sim_operations { TReturn (*transmit_apdu)(CoreObject *o, UserRequest *ur); TReturn (*get_atr)(CoreObject *o, UserRequest *ur); TReturn (*req_authentication)(CoreObject *o, UserRequest *ur); + TReturn (*set_powerstate)(CoreObject *o, UserRequest *ur); }; -CoreObject* tcore_sim_new(TcorePlugin *p, const char *name, struct tcore_sim_operations *ops, TcoreHal *hal); -void tcore_sim_free(CoreObject *n); - -enum tel_sim_type tcore_sim_get_type(CoreObject *o); -gboolean tcore_sim_set_type(CoreObject *o, enum tel_sim_type type); - -struct tel_sim_imsi* tcore_sim_get_imsi(CoreObject *o); -gboolean tcore_sim_set_imsi(CoreObject *o, struct tel_sim_imsi *imsi); - -enum tel_sim_status tcore_sim_get_status(CoreObject *o); -gboolean tcore_sim_set_status(CoreObject *o, enum tel_sim_status status); - -gboolean tcore_sim_get_identification(CoreObject *o); -gboolean tcore_sim_set_identification(CoreObject *o, gboolean b_changed); - -gboolean tcore_sim_get_cphs_status(CoreObject *o); -gboolean tcore_sim_set_cphs_status(CoreObject *o, gboolean b_support); - -gboolean tcore_sim_link_userdata(CoreObject *o, void *userdata); -void* tcore_sim_ref_userdata(CoreObject *o); - -gboolean tcore_sim_decode_iccid(struct tel_sim_iccid *p_out, unsigned char *p_in, int in_length); -gboolean tcore_sim_decode_lp(struct tel_sim_language *p_out, unsigned char *p_in, int in_length); -char* tcore_sim_encode_lp(int *out_length, struct tel_sim_language *p_in); -gboolean tcore_sim_decode_li(enum tel_sim_file_id file_id, struct tel_sim_language *p_out, unsigned char *p_in, int in_length); -char* tcore_sim_encode_li(int *out_length, struct tel_sim_language *p_in); -gboolean tcore_sim_decode_imsi(struct tel_sim_imsi *p_out, unsigned char *p_in, int in_length); -gboolean tcore_sim_decode_sst(struct tel_sim_sst *p_sst, unsigned char *p_in, int in_length); -gboolean tcore_sim_decode_spn(struct tel_sim_spn *p_spn, unsigned char *p_in, int in_length); -gboolean tcore_sim_decode_spdi(struct tel_sim_spdi *p_spdi, unsigned char *p_in, int in_length); -gboolean tcore_sim_decode_msisdn(struct tel_sim_msisdn *p_msisdn, unsigned char *p_in, int in_length); -gboolean tcore_sim_decode_xdn(struct tel_sim_dialing_number *p_xdn, unsigned char *p_in, int in_length); -gboolean tcore_sim_encode_xdn(char *p_out, int out_length, struct tel_sim_dialing_number *p_xdn); -gboolean tcore_sim_decode_ecc(struct tel_sim_ecc_list *p_ecc, unsigned char *p_in, int in_length); -gboolean tcore_sim_decode_ust(struct tel_sim_ust *p_ust, unsigned char *p_in, int in_length); -gboolean tcore_sim_decode_est(struct tel_sim_est *p_est, unsigned char *p_in, int in_length); -gboolean tcore_sim_decode_uecc(struct tel_sim_ecc *p_ecc, unsigned char* p_in, int in_length); -gboolean tcore_sim_decode_gid( struct tel_sim_gid *p_gid, unsigned char* p_in, int in_length); -gboolean tcore_sim_decode_mbi(struct tel_sim_mbi *p_mbi, unsigned char *p_in, int in_length); -gboolean tcore_sim_encode_mbi(char *p_out, int out_length, struct tel_sim_mbi *p_mbi); -gboolean tcore_sim_decode_cff(struct tel_sim_callforwarding *cfis, unsigned char *p_in, int in_length); -char* tcore_sim_encode_cff(const struct tel_sim_callforwarding *cff); -gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_in, int in_length); -gboolean tcore_sim_encode_csp(unsigned char *p_out, int out_length, struct tel_sim_cphs_csp *p_csp); -gboolean tcore_sim_decode_vmwf(struct tel_sim_cphs_mw *p_vmwf, unsigned char* p_in, unsigned long in_length); -gboolean tcore_sim_decode_mwis(struct tel_sim_mw *pMwis, unsigned char *p_in, int in_length); -gboolean tcore_sim_encode_mwis( char *p_out, int out_length, struct tel_sim_mw *pMwis); -gboolean tcore_sim_encode_vmwf(char *p_out, int out_length, struct tel_sim_cphs_mw *p_vmwf); -gboolean tcore_sim_decode_ons(unsigned char *p_out, unsigned char *p_in, int in_length); -gboolean tcore_sim_decode_cfis(struct tel_sim_callforwarding *cfis, unsigned char *p_in, int in_length); -char* tcore_sim_encode_cfis(int *out_length, const struct tel_sim_callforwarding *p_cfis); -gboolean tcore_sim_decode_dynamic_flag(struct tel_sim_cphs_dflag *p_df, unsigned char *p_in, int in_length); -gboolean tcore_sim_decode_dynamic2_flag(struct tel_sim_cphs_dflag2 *p_d2f, unsigned char *p_in, int in_length); -gboolean tcore_sim_encode_dynamic_flag(char *p_out, int out_length, struct tel_sim_cphs_dflag *p_df); -gboolean tcore_sim_encode_dynamic2_flag(char *p_out, int out_length, struct tel_sim_cphs_dflag2 *p_d2f); -gboolean tcore_sim_decode_cphs_info(struct tel_sim_cphs_info *pCphsInfo, unsigned char *p_in, int in_length); -gboolean tcore_sim_decode_short_ons(unsigned char *p_out, unsigned char *p_in, int in_length); -gboolean tcore_sim_decode_information_number(struct tel_sim_cphs_info_number *p_info, unsigned char* p_in, int in_length); -gboolean tcore_sim_decode_opl(struct tel_sim_opl *p_opl, unsigned char *p_in, int in_length); -gboolean tcore_sim_decode_pnn(struct tel_sim_pnn *p_pnn, unsigned char* p_in, int in_length); -gboolean tcore_sim_decode_oplmnwact(struct tel_sim_oplmnwact_list *p_list, unsigned char *p_in, int in_length); +CoreObject* tcore_sim_new(TcorePlugin *p, const char *name, struct tcore_sim_operations *ops, TcoreHal *hal); +void tcore_sim_free(CoreObject *n); + +void tcore_sim_set_ops(CoreObject *o, struct tcore_sim_operations *ops); + +enum tel_sim_type tcore_sim_get_type(CoreObject *o); +gboolean tcore_sim_set_type(CoreObject *o, enum tel_sim_type type); + +struct tel_sim_imsi* tcore_sim_get_imsi(CoreObject *o); +gboolean tcore_sim_set_imsi(CoreObject *o, const struct tel_sim_imsi *imsi); + +enum tel_sim_status tcore_sim_get_status(CoreObject *o); +gboolean tcore_sim_set_status(CoreObject *o, enum tel_sim_status status); + +gboolean tcore_sim_get_identification(CoreObject *o); +gboolean tcore_sim_set_identification(CoreObject *o, gboolean b_changed); + +struct tel_sim_service_table* tcore_sim_get_service_table(CoreObject *o); +gboolean tcore_sim_set_service_table(CoreObject *o, const struct tel_sim_service_table *svct); +enum tcore_return tcore_sim_delete_service_table(CoreObject *o); + +struct tel_sim_cphs_csp* tcore_sim_get_csp(CoreObject *o); +gboolean tcore_sim_set_csp(CoreObject *o, const struct tel_sim_cphs_csp *csp); +gboolean tcore_sim_delete_csp(CoreObject *o); + + +struct tel_sim_ecc_list* tcore_sim_get_ecc_list(CoreObject *o); +gboolean tcore_sim_set_ecc_list(CoreObject *o, const struct tel_sim_ecc_list *ecc_list); +enum tcore_return tcore_sim_delete_ecc_list(CoreObject *o); + +struct tel_sim_msisdn_list* tcore_sim_get_msisdn_list(CoreObject *o); +gboolean tcore_sim_set_msisdn_list(CoreObject *o, const struct tel_sim_msisdn_list *msisdn_list); +enum tcore_return tcore_sim_delete_msisdn_list(CoreObject *o); + +struct tel_sim_spn* tcore_sim_get_spn(CoreObject *o); +gboolean tcore_sim_set_spn(CoreObject *o, const struct tel_sim_spn *spn); +enum tcore_return tcore_sim_delete_spn(CoreObject *o); + +struct tel_sim_cphs_netname* tcore_sim_get_cphs_netname(CoreObject *o); +gboolean tcore_sim_set_cphs_netname(CoreObject *o, const struct tel_sim_cphs_netname *cphs_netname); +enum tcore_return tcore_sim_delete_cphs_netname(CoreObject *o); + +struct tel_sim_iccid* tcore_sim_get_iccid(CoreObject *o); +gboolean tcore_sim_set_iccid(CoreObject *o, const struct tel_sim_iccid *iccid); +enum tcore_return tcore_sim_delete_iccid(CoreObject *o); + +gboolean tcore_sim_get_cphs_status(CoreObject *o); +gboolean tcore_sim_set_cphs_status(CoreObject *o, gboolean b_support); + +gboolean tcore_sim_link_userdata(CoreObject *o, void *userdata); +void* tcore_sim_ref_userdata(CoreObject *o); + +gboolean tcore_sim_decode_iccid(struct tel_sim_iccid *p_out, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_lp(struct tel_sim_language *p_out, unsigned char *p_in, int in_length); +char* tcore_sim_encode_lp(int *out_length, struct tel_sim_language *p_in); +gboolean tcore_sim_decode_li(enum tel_sim_file_id file_id, struct tel_sim_language *p_out, unsigned char *p_in, int in_length); +char* tcore_sim_encode_li(int *out_length, struct tel_sim_language *p_in); +gboolean tcore_sim_decode_imsi(struct tel_sim_imsi *p_out, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_cdma_imsi(struct tel_sim_imsi *p_out, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_sst(struct tel_sim_sst *p_sst, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_cdma_st(struct tel_sim_cst *p_cdma_st, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_csim_st(struct tel_sim_cst *p_csim_st, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_spn(struct tel_sim_spn *p_spn, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_cdma_spn(struct tel_sim_spn *p_spn, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_spdi(struct tel_sim_spdi *p_spdi, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_msisdn(struct tel_sim_msisdn *p_msisdn, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_mdn(struct tel_sim_msisdn *p_msisdn, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_xdn(struct tel_sim_dialing_number *p_xdn, unsigned char *p_in, int in_length); +char* tcore_sim_encode_xdn(int in_length, struct tel_sim_dialing_number *p_xdn); +gboolean tcore_sim_decode_ecc(struct tel_sim_ecc_list *p_ecc, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_ust(struct tel_sim_ust *p_ust, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_est(struct tel_sim_est *p_est, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_uecc(struct tel_sim_ecc *p_ecc, unsigned char* p_in, int in_length); +gboolean tcore_sim_decode_gid( struct tel_sim_gid *p_gid, unsigned char* p_in, int in_length); +gboolean tcore_sim_decode_mbi(struct tel_sim_mbi *p_mbi, unsigned char *p_in, int in_length); +char* tcore_sim_encode_mbi(const struct tel_sim_mbi *p_mbi, int in_length); +gboolean tcore_sim_decode_mwis(struct tel_sim_mw *pMwis, unsigned char *p_in, int in_length); +char* tcore_sim_encode_mwis(int *out_length, const struct tel_sim_mw *pMwis, int in_length); +gboolean tcore_sim_decode_vmwf(struct tel_sim_cphs_mw *p_vmwf, unsigned char* p_in, unsigned long in_length); +char* tcore_sim_encode_vmwf(int *out_length, const struct tel_sim_cphs_mw *p_vmwf, int in_length); +gboolean tcore_sim_decode_cfis(struct tel_sim_cfis *cfis, unsigned char *p_in, int in_length); +char* tcore_sim_encode_cfis(int *out_length, const struct tel_sim_cfis *p_cfis); +gboolean tcore_sim_decode_cff(struct tel_sim_cphs_cf *cfis, unsigned char *p_in, int in_length); +char* tcore_sim_encode_cff(const struct tel_sim_cphs_cf *cff, int in_length); +gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_in, int in_length); +gboolean tcore_sim_encode_csp(unsigned char *p_out, int out_length, struct tel_sim_cphs_csp *p_csp); +gboolean tcore_sim_decode_dynamic_flag(struct tel_sim_cphs_dflag *p_df, unsigned char *p_in, int in_length); +gboolean tcore_sim_encode_dynamic_flag(char *p_out, int out_length, struct tel_sim_cphs_dflag *p_df); +gboolean tcore_sim_decode_dynamic2_flag(struct tel_sim_cphs_dflag2 *p_d2f, unsigned char *p_in, int in_length); +gboolean tcore_sim_encode_dynamic2_flag(char *p_out, int out_length, struct tel_sim_cphs_dflag2 *p_d2f); +gboolean tcore_sim_decode_cphs_info(struct tel_sim_cphs_info *pCphsInfo, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_short_ons(unsigned char *p_out, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_ons(unsigned char *p_out, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_information_number(struct tel_sim_cphs_info_number *p_info, unsigned char* p_in, int in_length); +gboolean tcore_sim_decode_opl(struct tel_sim_opl *p_opl, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_pnn(struct tel_sim_pnn *p_pnn, unsigned char* p_in, int in_length); +gboolean tcore_sim_decode_oplmnwact(struct tel_sim_oplmnwact_list *p_list, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_ext(struct tel_sim_ext *p_ext, unsigned char *p_in, int in_length); +gboolean tcore_sim_decode_img(struct tel_sim_img *p_out, unsigned char *p_in, int in_length); +gboolean tcore_sim_check_plmn_having_3digits_mnc(char* plmn); __END_DECLS diff --git a/include/co_sms.h b/include/co_sms.h index 576ef76..5621d49 100644 --- a/include/co_sms.h +++ b/include/co_sms.h @@ -40,6 +40,30 @@ __BEGIN_DECLS #define nDCSOffset 26 #define nVPOffset 27 +#define SMS_PARAMID_TELESERVICE_ID 0x01 /* Teleservice Identifier */ +#define SMS_PARAMID_SERVICE_CATEGORY 0x02 /* Broadcast Service Category */ +#define SMS_PARAMID_ADDRESS 0x03 /* Address */ +#define SMS_PARAMID_SUBADDRESS 0x04 /* Subaddress */ +#define SMS_PARAMID_BEARER_REPLY 0x05 /* Bearer Reply Option */ +#define SMS_PARAMID_CAUSE_CODES 0x06 /* Cause Codes */ +#define SMS_PARAMID_MESSAGE_ID 0x07 /* Message Identifier */ +#define SMS_PARAMID_USER_DATA 0x08 /* User Data */ +#define SMS_PARAMID_USER_RESPONSE_CODE 0x09 /* User Response Code */ +#define SMS_PARAMID_MC_TIME_STAMP 0x0A /* Message Center Time Stamp */ +#define SMS_PARAMID_VALIDITY_PERIOD_ABS 0x0B /* Validity Period - Absolute */ +#define SMS_PARAMID_VALIDITY_PERIOD_REL 0x0C /* Validiry Period - Relative */ +#define SMS_PARAMID_DEFERRED_DELIVERY_ABS 0x0D /* Deferred Delivery Time - Absolute */ +#define SMS_PARAMID_DEFERRED_DELIVERY_REL 0x0E /* Deferred Delivery Time - Relative */ +#define SMS_PARAMID_PRIORITY 0x0F /* Priority Indicator */ +#define SMS_PARAMID_PRIVACY 0x10 /* Privacy Indicator */ +#define SMS_PARAMID_REPLY_OPTION 0x11 /* Reply Option */ +#define SMS_PARAMID_NUMBER_OF_MESSAGE 0x12 /* Number of Messages : Voice Mail Count */ +#define SMS_PARAMID_ALERT_ON_DELIVERY 0x13 /* Alert on Message Delivery */ +#define SMS_PARAMID_LANGUAGE 0x14 /* Langauge Indicator */ +#define SMS_PARAMID_CALLBACK 0x15 /* Call Back Number */ +#define SMS_PARAMID_DISPLAY_MODE 0x16 /* Display Mode */ +#define SMS_PARAMID_MULTI_ENCODING_USER_DATA 0x17 /* Multiply Encoding User Data */ + struct property_sms_info { int g_trans_id; int SMSPRecordLen; @@ -66,13 +90,36 @@ struct tcore_sms_operations { TReturn (*send_cdma_msg)(CoreObject *o, UserRequest *ur); }; - +/** + * This function is used to encode SMS Parameters to TPDU on EFsmsp + * + * @return length of string + * @param[in] incoming - telephony_sms_Params_t + * @param[in] data - TPDU data + * @Interface Synchronous. + * @remark + * @Refer + */ int _tcore_util_sms_encode_smsParameters(const struct telephony_sms_Params *incoming, unsigned char *data, int SMSPRecordLen); + +void tcore_util_sms_semioctet_to_octect(int* nScLength); +TReturn tcore_util_sms_encode_submit_message(const struct telephony_sms_CdmaMsgInfo *pMsgInfo, uint8_t *output, uint32_t *pos); +TReturn tcore_util_sms_encode_cancel_message(const struct telephony_sms_CdmaMsgInfo *pMsgInfo, uint8_t *output, uint32_t *pos); +TReturn tcore_util_sms_encode_user_ack_message(const struct telephony_sms_CdmaMsgInfo *pMsgInfo, uint8_t *output, uint32_t *pos); +int tcore_util_sms_decode_inDeliver_message(uint8_t *incoming, uint32_t length, struct telephony_sms_CdmaMsgInfo *pMsgInfo); +int tcore_util_sms_decode_inAck_message(uint8_t *incoming, uint32_t length, struct telephony_sms_CdmaMsgInfo *pMsgInfo); +int tcore_util_sms_decode_inDeliverAck_message(uint8_t *incoming, uint32_t length, struct telephony_sms_CdmaMsgInfo *pMsgInfo); +int tcore_util_sms_decode_ptp_message(uint8_t *incoming, uint32_t length, struct telephony_sms_CdmaMsgInfo *pMsgInfo); +int tcore_util_sms_decode_broadcast_message(uint8_t *bcmsg, uint32_t length, struct telephony_sms_CdmaMsgInfo *pMsgInfo); +int tcore_util_sms_decode_smsParameters(uint8_t *incoming, uint32_t length, struct telephony_sms_Params *params); + gboolean tcore_sms_get_ready_status(CoreObject *o); gboolean tcore_sms_set_ready_status(CoreObject *o, int status); CoreObject* tcore_sms_new(TcorePlugin *p, const char *name, struct tcore_sms_operations *ops, TcoreHal *hal); void tcore_sms_free(CoreObject * n); +void tcore_sms_set_ops(CoreObject *o, struct tcore_sms_operations *ops); + __END_DECLS #endif diff --git a/include/co_ss.h b/include/co_ss.h index 60a5ad9..75db702 100644 --- a/include/co_ss.h +++ b/include/co_ss.h @@ -169,6 +169,7 @@ struct tcore_ss_operations { TReturn (*waiting_get_status)(CoreObject *o, UserRequest *ur); TReturn (*cli_activate)(CoreObject *o, UserRequest *ur); TReturn (*cli_deactivate)(CoreObject *o, UserRequest *ur); + TReturn (*cli_set_status)(CoreObject *o, UserRequest *ur); TReturn (*cli_get_status)(CoreObject *o, UserRequest *ur); TReturn (*send_ussd)(CoreObject *o, UserRequest *ur); TReturn (*set_aoc)(CoreObject *o, UserRequest *ur); @@ -179,12 +180,15 @@ struct tcore_ss_operations { CoreObject* tcore_ss_new(TcorePlugin *p, const char *name, struct tcore_ss_operations *ops, TcoreHal *hal); void tcore_ss_free(CoreObject *o); +void tcore_ss_set_ops(CoreObject *o, struct tcore_ss_operations *ops); + struct ussd_session* tcore_ss_ussd_create_session( CoreObject *o, enum tcore_ss_ussd_type type, void *data, int data_len ); void tcore_ss_ussd_destroy_session( struct ussd_session *ussd_s ); struct ussd_session* tcore_ss_ussd_get_session( CoreObject *o ); enum tcore_ss_ussd_type tcore_ss_ussd_get_session_type( struct ussd_session* ussd_s ); void tcore_ss_ussd_set_session_type( struct ussd_session* ussd_s, enum tcore_ss_ussd_type type ); int tcore_ss_ussd_get_session_data( struct ussd_session* ussd_s, void** data ); +void tcore_ss_ussd_set_session_data( struct ussd_session* ussd_s, void* data, int data_len ); __END_DECLS diff --git a/include/core_object.h b/include/core_object.h index 0f07e55..49f323e 100644 --- a/include/core_object.h +++ b/include/core_object.h @@ -45,23 +45,69 @@ __BEGIN_DECLS #define CORE_OBJECT_CHECK_RETURN(o,t,r) \ if (!o) { warn("core_object is NULL"); return r; } \ if (tcore_object_get_type(o) != t) { warn("type(0x%x != 0x%x) mismatch", tcore_object_get_type(o), t); return r; } +typedef struct tcore_object_mapping_tbl object_mapping_table_t; + +#define CORE_OBJECT_EVENT_PROPERTY_CHANGED "core_object_property_changed" +#define CORE_OBJECT_KEY_FIND(keys, k) g_slist_find_custom((keys), (k), (GCompareFunc)g_strcmp0) typedef void (*CoreObjectFreeHook)(CoreObject *co); typedef void (*CoreObjectCloneHook)(CoreObject *src, CoreObject *dest); typedef gboolean (*CoreObjectCallback)(CoreObject *co, const void *event_info, void *user_data); +typedef gboolean (*tcore_object_callback)(CoreObject *co, + const void *event_info, void *user_data); typedef TReturn (*CoreObjectDispatcher)(CoreObject *co, UserRequest *ur); +typedef gboolean (*tcore_object_init)(TcorePlugin *plugin, CoreObject *co); +typedef void (*tcore_object_deinit)(TcorePlugin *plugin, CoreObject *co); + +/* Core Object Initializers */ +struct object_initializer { + tcore_object_init modem_init; + tcore_object_init sim_init; + tcore_object_init sat_init; + tcore_object_init sap_init; + tcore_object_init network_init; + tcore_object_init ps_init; + tcore_object_init call_init; + tcore_object_init ss_init; + tcore_object_init sms_init; + tcore_object_init phonebook_init; + tcore_object_init gps_init; + /* To be updated based on New modules */ +}; + +/* Core Object De-initializers */ +struct object_deinitializer { + tcore_object_deinit modem_deinit; + tcore_object_deinit sim_deinit; + tcore_object_deinit sat_deinit; + tcore_object_deinit sap_deinit; + tcore_object_deinit network_deinit; + tcore_object_deinit ps_deinit; + tcore_object_deinit call_deinit; + tcore_object_deinit ss_deinit; + tcore_object_deinit sms_deinit; + tcore_object_deinit phonebook_deinit; + tcore_object_deinit gps_deinit; + /* To be updated based on New modules */ +}; + + CoreObject* tcore_object_new(TcorePlugin *plugin, const char *name, TcoreHal *hal); void tcore_object_free(CoreObject *co); TReturn tcore_object_set_free_hook(CoreObject *co, CoreObjectFreeHook free_hook); TReturn tcore_object_set_clone_hook(CoreObject *co, CoreObjectCloneHook clone_hook); -CoreObject* tcore_object_clone(CoreObject *src, TcorePlugin *new_parent, const char *new_name); +CoreObject* tcore_object_clone(CoreObject *src, TcorePlugin *new_parent); TReturn tcore_object_set_name(CoreObject *co, const char *name); const char* tcore_object_ref_name(CoreObject *co); +CoreObject *tcore_object_clone_template_object(TcorePlugin *p, + unsigned int co_type); + + TReturn tcore_object_set_plugin(CoreObject *co, TcorePlugin *plugin); TcorePlugin* tcore_object_ref_plugin(CoreObject *co); @@ -82,8 +128,29 @@ TReturn tcore_object_dispatch_request(CoreObject *co, UserRequest *ur); TReturn tcore_object_add_callback(CoreObject *co, const char *event, CoreObjectCallback callback, void *user_data); TReturn tcore_object_del_callback(CoreObject *co, const char *event, CoreObjectCallback callback); +TReturn tcore_object_override_callback(CoreObject *co, const char *event, CoreObjectCallback callback, void *user_data); TReturn tcore_object_emit_callback(CoreObject *co, const char *event, const void *event_info); +#define tcore_object_set_property(co, ...) tcore_object_set_property_full(co, __VA_ARGS__, NULL, NULL) +TReturn tcore_object_set_property_full(CoreObject *co, const char *first_property, ...); +const char* tcore_object_ref_property(CoreObject *co, const char *key); +GHashTable* tcore_object_ref_property_hash(CoreObject *co); +void *tcore_object_add_mapping_tbl_entry(void *mapping_tbl, + unsigned int object_type, TcoreHal *hal); +void tcore_object_remove_mapping_tbl(void *mapping_tbl); +void *tcore_object_remove_mapping_tbl_entry(void *mapping_tbl, TcoreHal *hal); +void tcore_object_remove_mapping_tbl_entry_by_type(void *mapping_tbl, + unsigned int co_type); + +void tcore_object_print_mapping_tbl(void *mapping_tbl); + +TReturn tcore_object_init_objects(TcorePlugin *plugin, + struct object_initializer *initializer_list); +void tcore_object_deinit_objects(TcorePlugin *plugin, + struct object_deinitializer *deinitializer_list); + + + __END_DECLS #endif diff --git a/include/hal.h b/include/hal.h old mode 100755 new mode 100644 index 5a54a54..024bcb1 --- a/include/hal.h +++ b/include/hal.h @@ -25,6 +25,7 @@ __BEGIN_DECLS typedef void (*TcoreHalReceiveCallback)(TcoreHal *hal, unsigned int data_len, const void *data, void *user_data); typedef enum tcore_hook_return (*TcoreHalSendHook)(TcoreHal *hal, unsigned int data_len, void *data, void *user_data); +typedef void (*TcoreHalSetupNetifCallback)(CoreObject *co, int result, const char* devname, void *user_data); enum tcore_hal_recv_data_type { TCORE_HAL_RECV_INDICATION, @@ -43,6 +44,10 @@ enum tcore_hal_mode { struct tcore_hal_operations { TReturn (*power)(TcoreHal *hal, gboolean flag); TReturn (*send)(TcoreHal *hal, unsigned int data_len, void *data); + TReturn (*setup_netif)(CoreObject *co, + TcoreHalSetupNetifCallback func, + void *user_data, unsigned int cid, + gboolean enable); }; TcoreHal* tcore_hal_new(TcorePlugin *plugin, const char *name, @@ -55,7 +60,7 @@ char* tcore_hal_get_name(TcoreHal *hal); TcoreAT* tcore_hal_get_at(TcoreHal *hal); enum tcore_hal_mode tcore_hal_get_mode(TcoreHal *hal); -TReturn tcore_hal_set_mode(TcoreHal *hal, enum tcore_hal_mode mode); +TReturn tcore_hal_set_mode(TcoreHal *hal, enum tcore_hal_mode mode); TReturn tcore_hal_set_power(TcoreHal *hal, gboolean flag); @@ -66,6 +71,8 @@ TReturn tcore_hal_send_data(TcoreHal *hal, unsigned int data_len, void *dat TReturn tcore_hal_send_request(TcoreHal *hal, TcorePending *pending); TReturn tcore_hal_send_force(TcoreHal *hal); +TReturn tcore_hal_free_timeout_pending_request(TcoreHal *hal, TcorePending *p, + unsigned int data_len, const void *data); TReturn tcore_hal_dispatch_response_data(TcoreHal *hal, int id, unsigned int data_len, const void *data); @@ -86,6 +93,11 @@ gboolean tcore_hal_get_power_state(TcoreHal *hal); TcoreQueue* tcore_hal_ref_queue(TcoreHal *hal); TcorePlugin* tcore_hal_ref_plugin(TcoreHal *hal); +TReturn tcore_hal_setup_netif(TcoreHal *hal, CoreObject *co, + TcoreHalSetupNetifCallback func, + void *user_data, unsigned int cid, + gboolean enable); + __END_DECLS #endif diff --git a/include/log.h b/include/log.h index 4966982..94607ec 100644 --- a/include/log.h +++ b/include/log.h @@ -23,6 +23,9 @@ __BEGIN_DECLS +#include +extern gboolean tcore_debug; + #ifdef FEATURE_DLOG_DEBUG #include @@ -31,11 +34,59 @@ __BEGIN_DECLS #define TCORE_LOG_TAG "UNKNOWN" #endif -#define info(fmt,args...) { RLOG(LOG_INFO, TCORE_LOG_TAG, fmt "\n", ##args); } -#define msg(fmt,args...) { RLOG(LOG_DEBUG, TCORE_LOG_TAG, fmt "\n", ##args); } -#define dbg(fmt,args...) { RLOG(LOG_DEBUG, TCORE_LOG_TAG, "<%s:%d> " fmt "\n", __func__, __LINE__, ##args); } -#define warn(fmt,args...) { RLOG(LOG_WARN, TCORE_LOG_TAG, "<%s:%d> " fmt "\n", __func__, __LINE__, ##args); } -#define err(fmt,args...) { RLOG(LOG_FATAL, TCORE_LOG_TAG, "<%s:%d> " fmt "\n", __func__, __LINE__, ##args); } +#define info(fmt,args...) { if(tcore_debug) RLOG(LOG_INFO, TCORE_LOG_TAG, fmt "\n", ##args); } +#define msg(fmt,args...) { if(tcore_debug) RLOG(LOG_DEBUG, TCORE_LOG_TAG, fmt "\n", ##args); } +#define dbg(fmt,args...) { if(tcore_debug) RLOG(LOG_DEBUG, TCORE_LOG_TAG, fmt "\n", ##args); } +#define warn(fmt,args...) { RLOG(LOG_WARN, TCORE_LOG_TAG, fmt "\n", ##args); } +#define err(fmt,args...) { RLOG(LOG_ERROR, TCORE_LOG_TAG, fmt "\n", ##args); } +#define fatal(fmt,args...) { RLOG(LOG_FATAL, TCORE_LOG_TAG, fmt "\n", ##args); } + +#elif defined(FEATURE_TLOG_DEBUG) + +#ifndef TCORE_LOG_TAG +#define TCORE_LOG_TAG "UNKNOWN" +#endif + +enum tcore_log_type { + TCORE_LOG_TYPE_MAIN = 0, + TCORE_LOG_TYPE_RADIO, + TCORE_LOG_TYPE_SYSTEM, + TCORE_LOG_TYPE_TIME_CHECK +}; + +enum tcore_log_priority { + TCORE_LOG_UNKNOWN = 0, + TCORE_LOG_DEFAULT, + TCORE_LOG_VERBOSE, + TCORE_LOG_DEBUG, + TCORE_LOG_INFO, + TCORE_LOG_WARN, + TCORE_LOG_ERROR, + TCORE_LOG_FATAL, + TCORE_LOG_SILENT +}; + +/* + * Virtual log function. + * Daemon should implement the actual content. (printrf/file writing/...) + */ +void tcore_log(enum tcore_log_type type, enum tcore_log_priority priority, const char *tag, const char *fmt, ...); + +#define info(fmt,args...) { if(tcore_debug) tcore_log(TCORE_LOG_TYPE_RADIO, TCORE_LOG_INFO, TCORE_LOG_TAG, fmt "\n", ##args); } +#define msg(fmt,args...) { if(tcore_debug) tcore_log(TCORE_LOG_TYPE_RADIO, TCORE_LOG_DEBUG, TCORE_LOG_TAG, fmt "\n", ##args); } +#define dbg(fmt,args...) { if(tcore_debug) tcore_log(TCORE_LOG_TYPE_RADIO, TCORE_LOG_DEBUG, TCORE_LOG_TAG, "<%s:%d> " fmt "\n", __func__, __LINE__, ##args); } +#define warn(fmt,args...) { tcore_log(TCORE_LOG_TYPE_RADIO, TCORE_LOG_WARN, TCORE_LOG_TAG, "<%s:%d> " fmt "\n", __func__, __LINE__, ##args); } +#define err(fmt,args...) { tcore_log(TCORE_LOG_TYPE_RADIO, TCORE_LOG_ERROR, TCORE_LOG_TAG, "<%s:%d> " fmt "\n", __func__, __LINE__, ##args); } +#define fatal(fmt,args...) { tcore_log(TCORE_LOG_TYPE_RADIO, TCORE_LOG_FATAL, TCORE_LOG_TAG, "<%s:%d> " fmt "\n", __func__, __LINE__, ##args); } + +#define info_ex(tag,fmt,args...) { if(tcore_debug) tcore_log(TCORE_LOG_TYPE_RADIO, TCORE_LOG_INFO, tag, fmt "\n", ##args); } +#define msg_ex(tag,fmt,args...) { if(tcore_debug) tcore_log(TCORE_LOG_TYPE_RADIO, TCORE_LOG_DEBUG, tag, fmt "\n", ##args); } +#define dbg_ex(tag,fmt,args...) { if(tcore_debug) tcore_log(TCORE_LOG_TYPE_RADIO, TCORE_LOG_DEBUG, tag, "<%s:%d> " fmt "\n", __func__, __LINE__, ##args); } +#define warn_ex(tag,fmt,args...) { tcore_log(TCORE_LOG_TYPE_RADIO, TCORE_LOG_WARN, tag, "<%s:%d> " fmt "\n", __func__, __LINE__, ##args); } +#define err_ex(tag,fmt,args...) { tcore_log(TCORE_LOG_TYPE_RADIO, TCORE_LOG_ERROR, tag, "<%s:%d> " fmt "\n", __func__, __LINE__, ##args); } +#define fatal_ex(tag,fmt,args...) { tcore_log(TCORE_LOG_TYPE_RADIO, TCORE_LOG_FATAL, tag, "<%s:%d> " fmt "\n", __func__, __LINE__, ##args); } + +#define TIME_CHECK(fmt,args...) { tcore_log(TCORE_LOG_TYPE_TIME_CHECK, TCORE_LOG_INFO, "TIME_CHECK", fmt "\n", ##args); } #else @@ -67,11 +118,12 @@ __BEGIN_DECLS #define TCORE_LOG_FUNC fprintf #endif -#define info(fmt,args...) TCORE_LOG_FUNC(TCORE_LOG_FILE, fmt "\n", ##args); fflush(TCORE_LOG_FILE); -#define msg(fmt,args...) TCORE_LOG_FUNC(TCORE_LOG_FILE, fmt "\n", ##args); fflush(TCORE_LOG_FILE); -#define dbg(fmt,args...) TCORE_LOG_FUNC(TCORE_LOG_FILE, ANSI_COLOR_LIGHTGRAY "<%s:%s> " ANSI_COLOR_NORMAL fmt "\n", __FILE__, __FUNCTION__, ##args); fflush(TCORE_LOG_FILE); +#define info(fmt,args...) { if(tcore_debug) TCORE_LOG_FUNC(TCORE_LOG_FILE, fmt "\n", ##args); fflush(TCORE_LOG_FILE);} +#define msg(fmt,args...) { if(tcore_debug) TCORE_LOG_FUNC(TCORE_LOG_FILE, fmt "\n", ##args); fflush(TCORE_LOG_FILE);} +#define dbg(fmt,args...) { if(tcore_debug) TCORE_LOG_FUNC(TCORE_LOG_FILE, ANSI_COLOR_LIGHTGRAY "<%s:%s> " ANSI_COLOR_NORMAL fmt "\n", __FILE__, __FUNCTION__, ##args); fflush(TCORE_LOG_FILE);} #define warn(fmt,args...) TCORE_LOG_FUNC(TCORE_LOG_FILE, ANSI_COLOR_YELLOW "<%s:%s> " ANSI_COLOR_NORMAL fmt "\n", __FILE__, __FUNCTION__, ##args); fflush(TCORE_LOG_FILE); #define err(fmt,args...) TCORE_LOG_FUNC(TCORE_LOG_FILE, ANSI_COLOR_LIGHTRED "<%s:%s> " ANSI_COLOR_NORMAL fmt "\n", __FILE__, __FUNCTION__, ##args); fflush(TCORE_LOG_FILE); +#define fatal(fmt,args...) TCORE_LOG_FUNC(TCORE_LOG_FILE, ANSI_COLOR_LIGHTRED "<%s:%s> " ANSI_COLOR_NORMAL fmt "\n", __FILE__, __FUNCTION__, ##args); fflush(TCORE_LOG_FILE); #endif diff --git a/include/mux.h b/include/mux.h index bdd2a34..a17f127 100644 --- a/include/mux.h +++ b/include/mux.h @@ -21,8 +21,45 @@ #ifndef __MUX_H__ #define __MUX_H__ -TReturn tcore_cmux_init(TcorePlugin *plugin, TcoreHal *hal); -void tcore_cmux_close(void); -int tcore_cmux_rcv_from_hal(unsigned char *data, size_t length); +#include "queue.h" + +/* CMUX modes */ +typedef enum { + CMUX_MODE_BASIC = 0x00, + CMUX_MODE_ADVANCED +} tcore_cmux_mode; + +/* CMUX Channel */ +typedef struct cmux_channel tcore_cmux_channel; + +/* Global MUX Object */ +typedef struct cmux_obj tcore_cmux_object; + +/* CMUX setup complete callback prototype */ +typedef void (*cmux_setup_complete_cb_func) (gpointer user_data); + +/* CMUX setup callback prototype */ +typedef void (*cmux_setup_cb_func) (int channel_id, TcoreHal *hal, + gpointer user_data); + +/* CMUX Channel close callback prototype */ +typedef void (*cmux_channel_close_cb_func) (TcoreHal *hal, gpointer user_data); + +/* CMUX initialization - Internal and Kernel */ +TReturn tcore_cmux_init(TcoreHal *phy_hal, unsigned int frame_size, + TcorePendingResponseCallback resp_cb, void *resp_cb_data); + +/* Setup Internal CMUX */ +TReturn tcore_cmux_setup_internal_mux(tcore_cmux_mode mode, + int max_channels, unsigned int cmux_buf_size, TcoreHal *phy_hal, + cmux_setup_cb_func channel_setup_cb, gpointer channel_setup_user_data, + cmux_setup_complete_cb_func setup_complete_cb, gpointer setup_complete_user_data); + +/* Close CMUX */ +void tcore_cmux_close(TcoreHal *phy_hal, + cmux_channel_close_cb_func channel_close_cb, gpointer channel_close_user_data); + +/* HAL Receive for Internal CMUX */ +void tcore_cmux_rcv_from_hal(TcoreHal *hal, unsigned char *data, size_t length); #endif /* __MUX_H__ */ diff --git a/include/plugin.h b/include/plugin.h index f4eded2..081d0f8 100644 --- a/include/plugin.h +++ b/include/plugin.h @@ -30,7 +30,7 @@ enum tcore_plugin_priority { }; struct tcore_plugin_define_desc { - gchar *name; + const gchar *name; enum tcore_plugin_priority priority; int version; gboolean (*load)(); @@ -48,14 +48,17 @@ const struct tcore_plugin_define_desc* tcore_plugin_get_description(TcorePlugin *plugin); char* tcore_plugin_get_filename(TcorePlugin *plugin); -char* tcore_plugin_ref_plugin_name(TcorePlugin *plugin); +const char* tcore_plugin_ref_plugin_name(TcorePlugin *plugin); Server* tcore_plugin_ref_server(TcorePlugin *plugin); TReturn tcore_plugin_link_user_data(TcorePlugin *plugin, void *user_data); void* tcore_plugin_ref_user_data(TcorePlugin *plugin); TReturn tcore_plugin_add_core_object(TcorePlugin *plugin, CoreObject *co); -CoreObject* tcore_plugin_ref_core_object(TcorePlugin *plugin, const char *name); +TReturn tcore_plugin_remove_core_object(TcorePlugin *plugin, CoreObject *co); + +CoreObject *tcore_plugin_ref_core_object(TcorePlugin *plugin, unsigned int type); +GSList* tcore_plugin_get_core_objects(TcorePlugin *plugin); GSList* tcore_plugin_get_core_objects_bytype(TcorePlugin *plugin, unsigned int type); diff --git a/include/queue.h b/include/queue.h index 796da23..856afd9 100644 --- a/include/queue.h +++ b/include/queue.h @@ -49,6 +49,7 @@ void* tcore_pending_ref_request_data(TcorePending *pending, unsigned int *data_len); TReturn tcore_pending_set_timeout(TcorePending *pending, unsigned int timeout); +unsigned int tcore_pending_get_timeout(TcorePending *pending); TcorePlugin* tcore_pending_ref_plugin(TcorePending *pending); CoreObject* tcore_pending_ref_core_object(TcorePending *pending); TReturn tcore_pending_set_priority(TcorePending *pending, @@ -61,6 +62,8 @@ TReturn tcore_pending_link_user_request(TcorePending *pending, UserRequest *ur); UserRequest* tcore_pending_ref_user_request(TcorePending *pending); +TReturn tcore_pending_start_timer(TcorePending *pending); + TReturn tcore_pending_set_send_callback(TcorePending *pending, TcorePendingSendCallback func, void *user_data); TReturn tcore_pending_emit_send_callback(TcorePending *pending, int bytes); @@ -88,6 +91,7 @@ TcorePending* tcore_queue_pop_by_id(TcoreQueue *queue, unsigned int id); TcorePending* tcore_queue_ref_pending_by_id(TcoreQueue *queue, unsigned int id); TcorePending* tcore_queue_ref_next_pending(TcoreQueue *queue); unsigned int tcore_queue_get_length(TcoreQueue *queue); +unsigned int tcore_queue_get_normal_length(TcoreQueue *queue); TcoreHal* tcore_queue_ref_hal(TcoreQueue *queue); TReturn tcore_queue_cancel_pending_by_command(TcoreQueue *queue, enum tcore_request_command command); TcorePending* tcore_queue_search_by_command(TcoreQueue *queue, enum tcore_request_command command, gboolean flag_sent); diff --git a/include/server.h b/include/server.h index 1f9a305..c7a83d0 100644 --- a/include/server.h +++ b/include/server.h @@ -40,6 +40,7 @@ GSList* tcore_server_ref_plugins(Server *s); TcorePlugin* tcore_server_find_plugin(Server *s, const char *name); TReturn tcore_server_add_communicator(Server *s, Communicator *comm); +TReturn tcore_server_remove_communicator(Server *s, Communicator *comm); GSList* tcore_server_ref_communicators(Server *s); Communicator* tcore_server_find_communicator(Server *s, const char *name); @@ -48,9 +49,12 @@ GSList* tcore_server_ref_storages(Server *s); Storage* tcore_server_find_storage(Server *s, const char *name); TReturn tcore_server_add_hal(Server *s, TcoreHal *hal); +TReturn tcore_server_remove_hal(Server *s, TcoreHal *hal); GSList* tcore_server_ref_hals(Server *s); TcoreHal* tcore_server_find_hal(Server *s, const char *name); +CoreObject *tcore_server_find_template_object(Server *s, unsigned int type); + TReturn tcore_server_link_udev(Server *s, TcoreUdev *udev); TcoreUdev* tcore_server_ref_udev(Server *s); @@ -70,6 +74,27 @@ TReturn tcore_server_add_notification_hook(Server *s, TReturn tcore_server_remove_notification_hook(Server *s, TcoreServerNotificationHook func); +TcoreModem *tcore_server_register_modem(Server *s, TcorePlugin *modem_iface_plugin); +void tcore_server_unregister_modem(Server *s, TcoreModem *modem); +gboolean tcore_server_update_modem_plugin(TcorePlugin *modem_iface_plugin, + TcorePlugin *modem_plugin); +GSList *tcore_server_get_cp_name_list(Server *s); +const char *tcore_server_get_cp_name_by_plugin(TcorePlugin *modem_plugin); + +gboolean tcore_server_add_cp_mapping_tbl_entry(TcoreModem *modem, + unsigned int co_type, TcoreHal *hal); +void tcore_server_remove_cp_mapping_tbl(TcoreModem *modem); +void tcore_server_remove_cp_mapping_tbl_entry(TcoreModem *modem, + TcoreHal *hal); +void *tcore_server_get_cp_mapping_tbl(TcorePlugin *modem_plugin); +void tcore_server_print_modems(Server *s); + +TReturn tcore_server_load_modem_plugin(Server *s, + TcoreModem *modem, + const char *name) +; +void tcore_server_unload_modem_plugin(Server *s, TcoreModem *modem); +GSList *tcore_server_get_modem_plugin_list(Server *s); __END_DECLS #endif diff --git a/include/storage.h b/include/storage.h index cd85640..e15a993 100644 --- a/include/storage.h +++ b/include/storage.h @@ -39,8 +39,6 @@ enum tcore_storage_key { STORAGE_KEY_TELEPHONY_SVC_PS, STORAGE_KEY_TELEPHONY_SVC_ROAM, STORAGE_KEY_TELEPHONY_ZONE_TYPE, - STORAGE_KEY_TELEPHONY_SIM_INIT, - STORAGE_KEY_TELEPHONY_SIM_CHV,//10 STORAGE_KEY_TELEPHONY_SIM_PB_INIT, STORAGE_KEY_TELEPHONY_CALL_STATE, @@ -48,45 +46,60 @@ enum tcore_storage_key { STORAGE_KEY_TELEPHONY_TAPI_STATE, STORAGE_KEY_TELEPHONY_SPN_DISP_CONDITION,//15 - STORAGE_KEY_TELEPHONY_SAT_STATE, - STORAGE_KEY_TELEPHONY_ZONE_ZUHAUSE, STORAGE_KEY_TELEPHONY_RSSI, STORAGE_KEY_TELEPHONY_LOW_BATTERY, - STORAGE_KEY_TELEPHONY_EVENT_SYSTEM_READY,//20 - + STORAGE_KEY_TELEPHONY_EVENT_SYSTEM_READY, STORAGE_KEY_TELEPHONY_SIM_SLOT, - STORAGE_KEY_PM_STATE, + STORAGE_KEY_TELEPHONY_SIM_SLOT2, + STORAGE_KEY_TELEPHONY_SIM_SLOT_COUNT, + STORAGE_KEY_PM_STATE,//20 + + STORAGE_KEY_PACKET_INDICATOR_STATE, STORAGE_KEY_PACKET_SERVICE_STATE, + STORAGE_KEY_PACKET_SERVICE_STATE2, STORAGE_KEY_MESSAGE_NETWORK_MODE, - STORAGE_KEY_CELLULAR_STATE,//25 + STORAGE_KEY_CELLULAR_STATE, STORAGE_KEY_CELLULAR_PKT_TOTAL_RCV, + STORAGE_KEY_CELLULAR_PKT_TOTAL_RCV2, STORAGE_KEY_CELLULAR_PKT_TOTAL_SNT, - STORAGE_KEY_CELLULAR_PKT_LAST_RCV, + STORAGE_KEY_CELLULAR_PKT_TOTAL_SNT2, + STORAGE_KEY_CELLULAR_PKT_LAST_RCV,//30 + + STORAGE_KEY_CELLULAR_PKT_LAST_RCV2, STORAGE_KEY_CELLULAR_PKT_LAST_SNT, + STORAGE_KEY_CELLULAR_PKT_LAST_SNT2, + STORAGE_KEY_TELEPHONY_DUALSIM_DEFAULT_DATA_SERVICE_INT, + STORAGE_KEY_TELEPHONY_PREFERRED_VOICE_SUBSCRIPTION, + STORAGE_KEY_TELEPHONY_DUALSIM_DEFAULT_SERVICE_INT, + STORAGE_KEY_WIFI_STATE_INT, STORAGE_KEY_TELEPHONY_BOOL = STORAGE_KEY_BOOL, STORAGE_KEY_3G_ENABLE, STORAGE_KEY_TELEPHONY_READY, STORAGE_KEY_SETAPPL_STATE_DATA_ROAMING_BOOL, + STORAGE_KEY_SETAPPL_STATE_DATA_ROAMING_APP_STATUS, STORAGE_KEY_SETAPPL_STATE_AUTOMATIC_TIME_UPDATE_BOOL, - STORAGE_KEY_SETAPPL_FLIGHT_MODE_BOOL, + STORAGE_KEY_SETAPPL_NETWORK_RESTRICT_MODE, + STORAGE_KEY_SETAPPL_MOBILE_DATA_POPUP_DONE_BOOL, + STORAGE_KEY_MSG_SERVER_READY_BOOL, STORAGE_KEY_TELEPHONY_STRING = STORAGE_KEY_STRING, STORAGE_KEY_TELEPHONY_NWNAME, STORAGE_KEY_TELEPHONY_SPN_NAME, - STORAGE_KEY_TELEPHONY_SAT_SETUP_IDLE_TEXT, STORAGE_KEY_TELEPHONY_IMEI, - STORAGE_KEY_TELEPHONY_SUBSCRIBER_NUMBER, - STORAGE_KEY_TELEPHONY_SUBSCRIBER_NAME, STORAGE_KEY_TELEPHONY_SWVERSION, STORAGE_KEY_TELEPHONY_HWVERSION, STORAGE_KEY_TELEPHONY_CALDATE, STORAGE_KEY_TELEPHONY_IMEI_FACTORY_REBOOT, STORAGE_KEY_TELEPHONY_SIM_FACTORY_MODE, STORAGE_KEY_TELEPHONY_PRODUCTCODE, - STORAGE_KEY_TELEPHONY_FACTORY_KSTRINGB, - STORAGE_KEY_TELEPHONY_IMSI, + STORAGE_KEY_LANGUAGE_SET, + STORAGE_KEY_FLIGHT_MODE_BOOL, + STORAGE_KEY_TESTMODE_FAST_DORMANCY, + STORAGE_KEY_TESTMODE_FAST_DORMANCY2, + STORAGE_KEY_IDLE_SCREEN_LAUNCHED_BOOL, + STORAGE_KEY_POWER_SAVING_MODE }; enum storage_value { diff --git a/include/tcore.h b/include/tcore.h index afa8741..514ae90 100644 --- a/include/tcore.h +++ b/include/tcore.h @@ -42,10 +42,13 @@ #include #include #include +#include +#include typedef struct tcore_object_type CoreObject; typedef struct tcore_hal_type TcoreHal; typedef struct tcore_plugin_type TcorePlugin; +typedef struct tcore_modem_type TcoreModem; typedef struct tcore_queue_type TcoreQueue; typedef struct tcore_pending_type TcorePending; typedef struct tcore_communicator_type Communicator; diff --git a/include/type/call.h b/include/type/call.h index 080db87..06b1b4e 100644 --- a/include/type/call.h +++ b/include/type/call.h @@ -25,102 +25,104 @@ __BEGIN_DECLS #include -enum telephony_call_error_cause { - CALL_CAUSE_NONE, /**< Success */ - CALL_CAUSE_ACCESSDISCARD, /**< Access discarded */ - CALL_CAUSE_BARR_BYOPERATOR, /**< Barred by operator */ - CALL_CAUSE_BEARERMODE_NOTIMPL, /**< Bearer mode not implemented */ - CALL_CAUSE_BEARERMODE_RESTRICTED, /**< Bearer mode restricted */ - CALL_CAUSE_BEARERMODE_UNAUTH, /**< Bearer mode un authorized */ - CALL_CAUSE_BEARERMODE_UNAVAIL, /**< Bearer mode not available */ - CALL_CAUSE_BUSY, /**< (Network/Server) busy */ - CALL_CAUSE_CALLMETER_EXPIRED, /**< Call meter expired */ - CALL_CAUSE_CALLNO_ERROR, /**< Call number error */ - CALL_CAUSE_CKTUNAVAIL, /**< Circuit channel unavailable */ //10 - CALL_CAUSE_CONGESTION, /**< Congestion happened */ - CALL_CAUSE_NO_CIRCUIT_AVAIL, /**< Circuit not available */ - CALL_CAUSE_DESTIN_INCOMPAT, /**< Destination incompatibility */ - CALL_CAUSE_DTMF_NOSPEECH, /**< No speech in DTMF */ - CALL_CAUSE_DTMF_REJECTED, /**< DTMF rejected */ - CALL_CAUSE_FACILITY_NOTIMPL, /**< Facility not implemented */ - CALL_CAUSE_FACILITY_NOTSUBSCRIBED, /**< Facility not subscribed */ - CALL_CAUSE_INCOMINGCUGCALLS_BARRED, /**< Incoming CUG Calls barred */ - CALL_CAUSE_INVALNUM, /**< Invalid number */ - CALL_CAUSE_MPTY_ERROR, /**< Multiparty error */ //20 - CALL_CAUSE_NOANSWER, /**< No answer */ - CALL_CAUSE_NONCUGMEMBER, /**< Non CUG member */ - CALL_CAUSE_NUMBERCHANGED, /**< Number changed */ - CALL_CAUSE_NUMBER_ERROR, /**< Number error */ - CALL_CAUSE_NWFAILURE, /**< Network failure */ - CALL_CAUSE_OPERATIONUNAVAIL, /**< Operation not available */ - CALL_CAUSE_OUTOFORDER, /**< Out of order */ - CALL_CAUSE_PROTOCOL_ERROR, /**< Protocol error */ - CALL_CAUSE_QOSUNAVAIL, /**< QOS unavailable */ - CALL_CAUSE_REJECT, /**< Rejected */ //30 - CALL_CAUSE_REJ_FAIL, /**< Rejection failed */ - CALL_CAUSE_REJ_SRVC_NOT_AVL, /**< Rejection service not available */ - CALL_CAUSE_REMOTE_CKTUNAVAIL, /**< Remote Circuit channel unavailable */ - CALL_CAUSE_RESOURCEUNAVAIL, /**< Resource not available */ - CALL_CAUSE_SERVICEID_ERROR, /**< Service id error */ - CALL_CAUSE_SERVICE_NOTIMPL, /**< Service not implemented */ - CALL_CAUSE_SERVICE_UNAVAIL, /**< Service not available */ - CALL_CAUSE_MODIFY_SAME_BEARER, /**< Modify same bearer */ - CALL_CAUSE_MODIFY_NOT_PERMITTED, /**< Modification not permitted */ - CALL_CAUSE_HOLD_FAIL, /**< Call hold fail */ //40 - CALL_CAUSE_TEMPFAILURE, /**< Temporary failure */ - CALL_CAUSE_WRONGNUM, /**< Wrong number */ - CALL_CAUSE_NORMAL_UNSPECIFIED, /**< Normal but unspecified */ - CALL_CAUSE_SSERRINVALIDTIVALUE, /**< SS invalid Transaction ID Value */ - CALL_CAUSE_SSERRINVALIDTI, /**< SS Invalid transaction ID */ - CALL_CAUSE_SSINCOMPATIBLESTATE, /**< SS incompatible state */ - CALL_CAUSE_SSERRSYNTAXERROR, /**< SS syntax error */ - CALL_CAUSE_SSPROTOCOLERROR, /**< Protocol error */ - CALL_CAUSE_SSNEGATIVEPASSWORDCHECK, /**< Negative password check */ - CALL_CAUSE_SSSENTASPHASE1, /**< SS sent as phase1 message */ //50 - CALL_CAUSE_SSERROR, /**< Supplementary service error */ - CALL_CAUSE_SS_USSD_BUSY, /**< Second USSD request will be rejected when already USSD transaction is ongoing. */ - CALL_CAUSE_IDLE, /**< Idle */ - CALL_CAUSE_NETWORK_SPECIFIC, /**< Network specific error */ - CALL_CAUSE_FADE, /**< voice call was dropped e.g. because of a loss of signal */ - CALL_CAUSE_UNKNOWN, /**< unknown no details available */ - CALL_CAUSE_INCOM_CALL, /**< terminated by incoming call */ - CALL_CAUSE_ALERT_STOP, /**< terminated by alert stop */ - CALL_CAUSE_INTERCEPT, /**< voice call was dropped by interception */ - CALL_CAUSE_REORDER, /**< voice call was dropped by reordering */ //60 - CALL_CAUSE_CLIENT_END, /**< client ended the call */ - CALL_CAUSE_ACCESS_CLASS_BLOCKED, /**< access class blocked */ - CALL_CAUSE_MEMCAPEXCEEDED, /**< Memory capacity exceeded */ - CALL_CAUSE_TYPENOTSUPPORTED, /**< Type not supported */ - CALL_CAUSE_REPLACENOTSUPPORTED, /**< Replace not supported */ - CALL_CAUSE_PROTOCOLID_ERROR, /**< Protocol id error */ - CALL_CAUSE_CLASSNOTSUPPORTED, /**< Class not supported */ - CALL_CAUSE_DATACODING_ERROR, /**< Data coding error */ - CALL_CAUSE_INVAL_MSG, /**< Invalid message */ - CALL_CAUSE_CALL_BARRED, /**< Call barred */ //70 - CALL_CAUSE_SIM_CALL_CONTROL_CHANGED_TO_SS, /**< Sim call control changed to SS */ - CALL_CAUSE_SIM_CALL_CONTROL_CHANGED_TO_CALL, /**< SIM Call control changed to call */ - CALL_CAUSE_SIM_ERROR, /**< SIM error */ - CALL_CAUSE_SIM_CALL_CONTROL_MODIFIED, /**< SIM call control modified */ - CALL_CAUSE_RANDOM_ACCESS_FAILURE, /**< Random access error */ - CALL_CAUSE_LOWER_LAYER_FAILURE, /**< Lower layer error */ - CALL_CAUSE_ACCESS_REJECTED, /**< Access rejected */ - CALL_CAUSE_RESET_NOT_ALLOWED, /**< Reset not allowed */ - CALL_CAUSE_EMERGENCY_CALL_NOT_ALLOWED, /**< Emergency call not allowed */ - CALL_CAUSE_ACCESS_NOT_ALLOWED, /**< Access not allowed */ //80 - CALL_CAUSE_RADIO_LINK_FAILURE, /**< Radio link failure */ - CALL_CAUSE_INVALID_IDENTITY, /**< Invalid identity */ - CALL_CAUSE_UNKNOWN_IDENTITY, /**< Unknown identity */ - CALL_CAUSE_UNACCEPTABLE_IDENTITY, /**< Un acceptable identity */ - CALL_CAUSE_NO_SERVICE_HERE, /**< No service here */ - CALL_CAUSE_SERVICE_NOT_ALLOWED, /**< Service not allowed */ - CALL_CAUSE_SERVICE_NOT_AVAIL, /**< Service not available */ - CALL_CAUSE_SERVICE_NOT_WORKING, /**< Service not working */ - CALL_CAUSE_CANNOT_IDENTIFY_CALL, /**< Cannot identify the call */ - CALL_CAUSE_DEACTIVATION, /**< Deactivation */ //90 - CALL_CAUSE_FATAL_ERROR, /**< Fatal error */ - CALL_CAUSE_SEND_DTMF_SUCCESS, /**< Sending DTMF Success */ - CALL_CAUSE_SEND_DTMF_FAIL, /**< Sending DTMF Failed */ - CALL_CAUSE_TIMER_EXPIRED, /**< Call Timer Expired */ +enum telephony_call_error { + CALL_ERROR_NONE, /**< Success */ + CALL_ERROR_ACCESSDISCARD, /**< Access discarded */ + CALL_ERROR_BARR_BYOPERATOR, /**< Barred by operator */ + CALL_ERROR_BEARERMODE_NOTIMPL, /**< Bearer mode not implemented */ + CALL_ERROR_BEARERMODE_RESTRICTED, /**< Bearer mode restricted */ + CALL_ERROR_BEARERMODE_UNAUTH, /**< Bearer mode un authorized */ + CALL_ERROR_BEARERMODE_UNAVAIL, /**< Bearer mode not available */ + CALL_ERROR_BUSY, /**< (Network/Server) busy */ + CALL_ERROR_CALLMETER_EXPIRED, /**< Call meter expired */ + CALL_ERROR_CALLNO_ERROR, /**< Call number error */ + CALL_ERROR_CKTUNAVAIL, /**< Circuit channel unavailable */ //10 + CALL_ERROR_CONGESTION, /**< Congestion happened */ + CALL_ERROR_NO_CIRCUIT_AVAIL, /**< Circuit not available */ + CALL_ERROR_DESTIN_INCOMPAT, /**< Destination incompatibility */ + CALL_ERROR_DTMF_NOSPEECH, /**< No speech in DTMF */ + CALL_ERROR_DTMF_REJECTED, /**< DTMF rejected */ + CALL_ERROR_FACILITY_NOTIMPL, /**< Facility not implemented */ + CALL_ERROR_FACILITY_NOTSUBSCRIBED, /**< Facility not subscribed */ + CALL_ERROR_INCOMINGCUGCALLS_BARRED, /**< Incoming CUG Calls barred */ + CALL_ERROR_INVALNUM, /**< Invalid number */ + CALL_ERROR_MPTY_ERROR, /**< Multiparty error */ //20 + CALL_ERROR_NOANSWER, /**< No answer */ + CALL_ERROR_NONCUGMEMBER, /**< Non CUG member */ + CALL_ERROR_NUMBERCHANGED, /**< Number changed */ + CALL_ERROR_NUMBER_ERROR, /**< Number error */ + CALL_ERROR_NWFAILURE, /**< Network failure */ + CALL_ERROR_OPERATIONUNAVAIL, /**< Operation not available */ + CALL_ERROR_OUTOFORDER, /**< Out of order */ + CALL_ERROR_PROTOCOL_ERROR, /**< Protocol error */ + CALL_ERROR_QOSUNAVAIL, /**< QOS unavailable */ + CALL_ERROR_REJECT, /**< Rejected */ //30 + CALL_ERROR_REJ_FAIL, /**< Rejection failed */ + CALL_ERROR_REJ_SRVC_NOT_AVL, /**< Rejection service not available */ + CALL_ERROR_REJ_SAT_CALL_CTRL, /**< Rejection by SAT call control */ + CALL_ERROR_REMOTE_CKTUNAVAIL, /**< Remote Circuit channel unavailable */ + CALL_ERROR_RESOURCEUNAVAIL, /**< Resource not available */ + CALL_ERROR_SERVICEID_ERROR, /**< Service id error */ + CALL_ERROR_SERVICE_NOTIMPL, /**< Service not implemented */ + CALL_ERROR_SERVICE_UNAVAIL, /**< Service not available */ + CALL_ERROR_MODIFY_SAME_BEARER, /**< Modify same bearer */ + CALL_ERROR_MODIFY_NOT_PERMITTED, /**< Modification not permitted */ + CALL_ERROR_HOLD_FAIL, /**< Call hold fail */ //40 + CALL_ERROR_TEMPFAILURE, /**< Temporary failure */ + CALL_ERROR_WRONGNUM, /**< Wrong number */ + CALL_ERROR_NORMAL_UNSPECIFIED, /**< Normal but unspecified */ + CALL_ERROR_SSERRINVALIDTIVALUE, /**< SS invalid Transaction ID Value */ + CALL_ERROR_SSERRINVALIDTI, /**< SS Invalid transaction ID */ + CALL_ERROR_SSINCOMPATIBLESTATE, /**< SS incompatible state */ + CALL_ERROR_SSERRSYNTAXERROR, /**< SS syntax error */ + CALL_ERROR_SSPROTOCOLERROR, /**< Protocol error */ + CALL_ERROR_SSNEGATIVEPASSWORDCHECK, /**< Negative password check */ + CALL_ERROR_SSSENTASPHASE1, /**< SS sent as phase1 message */ //50 + CALL_ERROR_SSERROR, /**< Supplementary service error */ + CALL_ERROR_SS_USSD_BUSY, /**< Second USSD request will be rejected when already USSD transaction is ongoing. */ + CALL_ERROR_IDLE, /**< Idle */ + CALL_ERROR_NETWORK_SPECIFIC, /**< Network specific error */ + CALL_ERROR_FADE, /**< voice call was dropped e.g. because of a loss of signal */ + CALL_ERROR_UNKNOWN, /**< unknown no details available */ + CALL_ERROR_INCOM_CALL, /**< terminated by incoming call */ + CALL_ERROR_ALERT_STOP, /**< terminated by alert stop */ + CALL_ERROR_INTERCEPT, /**< voice call was dropped by interception */ + CALL_ERROR_REORDER, /**< voice call was dropped by reordering */ //60 + CALL_ERROR_CLIENT_END, /**< client ended the call */ + CALL_ERROR_ACCESS_CLASS_BLOCKED, /**< access class blocked */ + CALL_ERROR_MEMCAPEXCEEDED, /**< Memory capacity exceeded */ + CALL_ERROR_TYPENOTSUPPORTED, /**< Type not supported */ + CALL_ERROR_REPLACENOTSUPPORTED, /**< Replace not supported */ + CALL_ERROR_PROTOCOLID_ERROR, /**< Protocol id error */ + CALL_ERROR_CLASSNOTSUPPORTED, /**< Class not supported */ + CALL_ERROR_DATACODING_ERROR, /**< Data coding error */ + CALL_ERROR_INVAL_MSG, /**< Invalid message */ + CALL_ERROR_CALL_BARRED, /**< Call barred */ //70 + CALL_ERROR_SIM_CALL_CONTROL_CHANGED_TO_SS, /**< Sim call control changed to SS */ + CALL_ERROR_SIM_CALL_CONTROL_CHANGED_TO_CALL, /**< SIM Call control changed to call */ + CALL_ERROR_SIM_ERROR, /**< SIM error */ + CALL_ERROR_SIM_CALL_CONTROL_MODIFIED, /**< SIM call control modified */ + CALL_ERROR_RANDOM_ACCESS_FAILURE, /**< Random access error */ + CALL_ERROR_LOWER_LAYER_FAILURE, /**< Lower layer error */ + CALL_ERROR_ACCESS_REJECTED, /**< Access rejected */ + CALL_ERROR_RESET_NOT_ALLOWED, /**< Reset not allowed */ + CALL_ERROR_EMERGENCY_CALL_NOT_ALLOWED, /**< Emergency call not allowed */ + CALL_ERROR_ACCESS_NOT_ALLOWED, /**< Access not allowed */ //80 + CALL_ERROR_RADIO_LINK_FAILURE, /**< Radio link failure */ + CALL_ERROR_INVALID_IDENTITY, /**< Invalid identity */ + CALL_ERROR_UNKNOWN_IDENTITY, /**< Unknown identity */ + CALL_ERROR_UNACCEPTABLE_IDENTITY, /**< Un acceptable identity */ + CALL_ERROR_NO_SERVICE_HERE, /**< No service here */ + CALL_ERROR_SERVICE_NOT_ALLOWED, /**< Service not allowed */ + CALL_ERROR_SERVICE_NOT_AVAIL, /**< Service not available */ + CALL_ERROR_SERVICE_NOT_WORKING, /**< Service not working */ + CALL_ERROR_CANNOT_IDENTIFY_CALL, /**< Cannot identify the call */ + CALL_ERROR_DEACTIVATION, /**< Deactivation */ //90 + CALL_ERROR_FATAL_ERROR, /**< Fatal error */ + CALL_ERROR_SEND_DTMF_SUCCESS, /**< Sending DTMF Success */ + CALL_ERROR_SEND_DTMF_FAIL, /**< Sending DTMF Failed */ + CALL_ERROR_FIXED_DIALING_NUMBER_ONLY,/**< Fixed Dialing Number Only */ + CALL_ERROR_TIMER_EXPIRED, /**< Call Timer Expired */ }; enum telephony_call_answer_type { @@ -136,6 +138,16 @@ enum telephony_call_type { CALL_TYPE_E911 }; +enum telephony_call_emergency_category { + CALL_EMERGENCY_CATEGORY_DEFAULT = 0x00, + CALL_EMERGENCY_CATEGORY_POLICE = 0x01, + CALL_EMERGENCY_CATEGORY_AMBULANCE = 0x02, + CALL_EMERGENCY_CATEGORY_FIRE_BRIGADE = 0x04, + CALL_EMERGENCY_CATEGORY_MARINE_GUARD = 0x08, + CALL_EMERGENCY_CATEGORY_MOUNTAIN_RESCUE = 0x10, + CALL_EMERGENCY_CATEGORY_NONE = 0xff, +}; + enum telephony_call_status { CALL_STATUS_IDLE, CALL_STATUS_ACTIVE, @@ -153,6 +165,12 @@ enum telephony_call_end_type { CALL_END_TYPE_HOLD_ALL, }; +enum telephony_call_rec_type { + CALL_REC_NAME_INFO, + CALL_REC_NUMBER_INFO, +}; + + enum telephony_call_end_cause { CALL_END_CAUSE_NONE = 0x00, /**< No Cause */ @@ -213,6 +231,7 @@ enum telephony_call_end_cause { CALL_END_CAUSE_RECOVERY_ON_TIMER_EXPIRY, /**< Recovery on timer expiry */ CALL_END_CAUSE_PROTOCOL_ERROR_UNSPECIFIED, /**< Protocol error unspecified */ CALL_END_CAUSE_INTERWORKING_UNSPECIFIED, /**< Interworking unspecified */ + CALL_END_CAUSE_REORDER, /**< Reorder */ CALL_END_CAUSE_END = 128, @@ -289,10 +308,19 @@ enum telephony_call_end_cause { CALL_END_CAUSE_CNM_INVALID_USER_DATA, /**< Invalid user data */ }; +enum telephony_call_no_cli_cause { + CALL_NO_CLI_CAUSE_NONE = -1, /**< None value - Infers NO CLI Cause */ + CALL_NO_CLI_CAUSE_UNAVAILABLE, /**< Unavailable */ + CALL_NO_CLI_CAUSE_USER_REJECTED, /**< Rejected by user */ + CALL_NO_CLI_CAUSE_OTHERS, /**< Interaction with other services */ + CALL_NO_CLI_CAUSE_PAY_PHONE /**< Coin line/ Pay phone */ +}; + enum telephony_call_cli_mode { - CALL_CLI_MODE_DEFAULT, CALL_CLI_MODE_PRESENT, CALL_CLI_MODE_RESTRICT, + CALL_CLI_MODE_UNAVAILABLE, + CALL_CLI_MODE_DEFAULT, }; enum telephony_call_cna_mode { @@ -345,9 +373,20 @@ enum telephony_call_sound_volume_level { CALL_SOUND_VOLUME_LEVEL_9, }; +enum telephony_call_sound_mute_path { + CALL_SOUND_MUTE_PATH_TX = 0x00, + CALL_SOUND_MUTE_PATH_RX = 0x02, + CALL_SOUND_MUTE_PATH_ALL = 0x04, +}; + +enum telephony_call_sound_mute_status { + CALL_SOUND_MUTE_STATUS_OFF = 0x00, + CALL_SOUND_MUTE_STATUS_ON = 0x01, +}; + enum telephony_call_sound_ringback_tone_status { - CALL_SOUND_RINGBACK_TONE_START, CALL_SOUND_RINGBACK_TONE_END, + CALL_SOUND_RINGBACK_TONE_START, }; enum telephony_call_sound_direction { @@ -355,6 +394,127 @@ enum telephony_call_sound_direction { CALL_SOUND_DIRECTION_RIGHT, }; +enum telephony_call_preferred_voice_subs { + CALL_PREFERRED_VOICE_SUBS_UNKNOWN = -1, /**< Unknown status **/ + CALL_PREFERRED_VOICE_SUBS_CURRENT_NETWORK = 0, /**< Current network **/ + CALL_PREFERRED_VOICE_SUBS_ASK_ALWAYS, /**< ASK Always **/ + CALL_PREFERRED_VOICE_SUBS_SIM1, /**< SIM 1 **/ + CALL_PREFERRED_VOICE_SUBS_SIM2 /**< SIM 2 **/ +}; + +enum telephony_call_voice_privacy_mode { + CALL_PRIVACY_MODE_STANDARD, + CALL_PRIVACY_MODE_ENHANCED, +}; + +enum telephony_call_otasp_status{ + CALL_OTASP_OK_SPL_UNLOCKED = 0x01, + CALL_OTASP_OK_AKEY_EXCESS, + CALL_OTASP_OK_SSD_UPDATE, + CALL_OTASP_OK_NAM_DWNLD, + CALL_OTASP_OK_MDN_DWNLD, + CALL_OTASP_OK_IMSI_DWNLD, + CALL_OTASP_OK_PRL_DWNLD, + CALL_OTASP_OK_COMMIT, + CALL_OTASP_OK_PROGRAMMING, + CALL_OTASP_SUCCESS, + CALL_OTASP_UNSUCCESS, + CALL_OTASP_OK_OTAPA_VERIFY, + CALL_OTASP_PROGRESS, + CALL_OTASP_FAILURES_EXCESS_SPC, + CALL_OTASP_LOCK_CODE_PW_SET, +}; + +enum telephony_call_otapa_status{ + CALL_OTAPA_STOP = 0x00, + CALL_OTAPA_START, + CALL_OTAPA_ABORTED, + CALL_OTAPA_COMMITTED, +}; + +enum telephony_call_otasp_result{ + CALL_OTASP_FAIL = 0x00, + CALL_OTASP_PASS, +}; + +enum telephony_call_alert_signal_type{ + CALL_SIGNAL_TYPE_TONE = 0x00, + CALL_SIGNAL_TYPE_ISDN_ALERTING, + CALL_SIGNAL_TYPE_IS54B_ALERTING, + CALL_SIGNAL_TYPE_RESERVED, +}; + +enum telephony_call_alert_pitch_type{ + CALL_ALERT_PITCH_MED = 0x00, + CALL_ALERT_PITCH_HIGH, + CALL_ALERT_PITCH_LOW, + CALL_ALERT_PITCH_RESERVED, +}; + +// SIGNAL : SIGNAL TYPE SIGNAL_TONE +enum telephony_call_tone_signal{ + CALL_SIGNAL_TONE_DIAL = 0x00, + CALL_SIGNAL_TONE_RINGBACK_TONE_ON, + CALL_SIGNAL_TONE_INTERCEPT_TONE_ON, + CALL_SIGNAL_TONE_ABBREV_TONE, + CALL_SIGNAL_TONE_NETWORK_CONGESTION_TONE_ON, + CALL_SIGNAL_TONE_ABBREV_NETWORK_CONGESTION, + CALL_SIGNAL_TONE_BUSY_TONE_ON, + CALL_SIGNAL_TONE_CFRM_TONE_ON, + CALL_SIGNAL_TONE_ANSWER_TONE_ON, + CALL_SIGNAL_TONE_CALL_WAITING_TONE_ON, + CALL_SINGNAL_TONE_PIPE_TONE_ON, + CALL_SIGNAL_TONE_OFF, +}; + +// SIGNAL : SIGNAL TYPE SIGNAL_ISDNALERT +enum telephony_call_isdn_alert_signal{ + CALL_SIGNAL_ISDN_ALERT_NORMAL = 0x00, + CALL_SIGNAL_ISDN_ALERT_INTER_GROUP, + CALL_SIGNAL_ISDN_ALERT_SPECIAL_PRIORITY, + CALL_SIGNAL_ISDN_ALERT_ISDN_RESERVED1, + CALL_SIGNAL_ISDN_ALERT_PING_RING, + CALL_SIGNAL_ISDN_ALERT_ISDN_RESERVED2, + CALL_SIGNAL_ISDN_ALERT_ISDN_RESERVED3, + CALL_SIGNAL_ISDN_ALERT_ISDN_RESERVED4, + CALL_SIGNAL_ISDN_ALERT_OFF, +}; + +// SIGNAL : SIGNAL TYPE IS- SIGNAL_IS54BALERT +enum telephony_call_is54b_alert_signal{ + CALL_SIGNAL_IS54B_ALERT_NOTONE = 0x00, + CALL_SIGNAL_IS54B_ALERT_LONG, + CALL_SIGNAL_IS54B_ALERT_SHORT_SHORT, + CALL_SIGNAL_IS54B_ALERT_SHORT_SHORT_LONG, + CALL_SIGNAL_IS54B_ALERT_SHORT_SHORT_2, + CALL_SIGNAL_IS54B_ALERT_SHORT_LONG_SHORT, + CALL_SIGNAL_IS54B_ALERT_SHORT_SHORT_SHORT_SHORT, + CALL_SIGNAL_IS54B_ALERT_PBX_LONG, + CALL_SIGNAL_IS54B_ALERT_PBX_SHORT_SHORT, + CALL_SIGNAL_IS54B_ALERT_PBX_SHORT_SHORT_LONG, + CALL_SIGNAL_IS54B_ALERT_PBX_SHORT_LONG_SHORT, + CALL_SIGNAL_IS54B_ALERT_PBX_SHORT_SHORT_SHORT_SHORT, + CALL_SIGNAL_IS54B_ALERT_PIP_PIP_PIP_PIP, +}; + +enum telephony_call_dtmf_inter_digit_interval{ + CALL_DTMF_OFFLENGTH_60MS, + CALL_DTMF_OFFLENGTH_100MS, + CALL_DTMF_OFFLENGTH_150MS, + CALL_DTMF_OFFLENGTH_200MS, +}; + +enum telephony_call_dtmf_pulse_width{ + CALL_DTMF_ONLENGTH_95MS, + CALL_DTMF_ONLENGTH_150MS, + CALL_DTMF_ONLENGTH_200MS, + CALL_DTMF_ONLENGTH_250MS, + CALL_DTMF_ONLENGTH_300MS, + CALL_DTMF_ONLENGTH_350MS, + CALL_DTMF_ONLENGTH_SMS +}; + + /********** Struct **********/ @@ -363,14 +523,18 @@ enum telephony_call_sound_direction { #define MAX_CALL_NUMBER_LEN 83 #define MAX_CALL_DIAL_NUM_LEN MAX_CALL_NUMBER_LEN -#define MAX_CALL_DTMF_DIGITS_LEN 32 +#define MAX_CALL_BURST_DTMF_STRING_LEN 32 +#define MAX_ALPHA_INFO_LEN 64 #define MAX_CALL_CLI_NUM_LEN MAX_CALL_NUMBER_LEN #define MAX_CALL_CNA_NAME_LEN 83 +#define MAX_CALL_DISPLAY_INFORMATION 182 + struct telephony_call_cli_info { enum telephony_call_cli_mode mode; + enum telephony_call_no_cli_cause no_cli_cause; char number[ MAX_CALL_CLI_NUM_LEN ]; }; @@ -379,10 +543,18 @@ struct telephony_call_cna_info { char name[ MAX_CALL_CNA_NAME_LEN ]; }; - +struct telephony_call_rec_info { + unsigned int id; + enum telephony_call_rec_type type; + union { + char name[ MAX_ALPHA_INFO_LEN ]; + char number[ MAX_CALL_NUMBER_LEN ]; + } data; +}; struct treq_call_dial { enum telephony_call_type type; + enum telephony_call_emergency_category ecc; char number[ MAX_CALL_DIAL_NUM_LEN ]; }; @@ -396,8 +568,14 @@ struct treq_call_end { enum telephony_call_end_type type; }; -struct treq_call_dtmf { - char digits[ MAX_CALL_DTMF_DIGITS_LEN ]; +struct treq_call_start_cont_dtmf { + unsigned char dtmf_digit; +}; + +struct treq_call_send_burst_dtmf { + char dtmf_string[ MAX_CALL_BURST_DTMF_STRING_LEN + 1]; + enum telephony_call_dtmf_pulse_width pulse_width; + enum telephony_call_dtmf_inter_digit_interval inter_digit_interval; }; struct treq_call_active { @@ -429,135 +607,174 @@ struct treq_call_deflect { char number[MAX_CALL_NUMBER_LEN]; }; -struct treq_call_sound_set_path { +struct treq_call_set_sound_path { enum telephony_call_sound_path path; gboolean extra_volume_on; }; -struct treq_call_sound_set_volume_level { +struct treq_call_set_sound_volume_level { enum telephony_call_sound_type sound; enum telephony_call_sound_device device; enum telephony_call_sound_volume_level volume; }; -struct treq_call_sound_get_volume_level { +struct treq_call_get_sound_volume_level { enum telephony_call_sound_type sound; enum telephony_call_sound_device device; }; -struct treq_call_sound_set_recording { +struct treq_call_set_sound_mute_status { + enum telephony_call_sound_mute_path path; + enum telephony_call_sound_mute_status status; +}; + +struct treq_call_set_sound_recording { gboolean state; }; #define MAX_CALL_EQ_PARAMETER_SIZE 6 -struct treq_call_sound_set_equalization { - gboolean mode; +struct treq_call_set_sound_equalization { + int mode; enum telephony_call_sound_direction direction; unsigned short parameter[ MAX_CALL_EQ_PARAMETER_SIZE ]; }; -struct treq_call_sound_set_noise_reduction { +struct treq_call_set_sound_noise_reduction { + gboolean status; +}; + +struct treq_call_set_sound_clock_status { gboolean status; }; +struct treq_call_set_voice_privacy_mode { + enum telephony_call_voice_privacy_mode privacy_mode; +}; + +struct treq_call_set_preferred_voice_subscription { + enum telephony_call_preferred_voice_subs preferred_subs; +}; + +struct treq_call_get_preferred_voice_subscription { +}; + + // Response struct tresp_call_dial { - gboolean err; + enum telephony_call_error err; }; struct tresp_call_answer { unsigned int id; - gboolean err; + enum telephony_call_error err; }; struct tresp_call_end { enum telephony_call_end_type type; unsigned int id; - gboolean err; + enum telephony_call_error err; }; struct tresp_call_hold { unsigned int id; - gboolean err; + enum telephony_call_error err; }; struct tresp_call_active { unsigned int id; - gboolean err; + enum telephony_call_error err; }; struct tresp_call_swap { unsigned int id; - gboolean err; + enum telephony_call_error err; }; struct tresp_call_join { unsigned int id; - gboolean err; + enum telephony_call_error err; }; struct tresp_call_split { unsigned int id; - gboolean err; + enum telephony_call_error err; }; struct tresp_call_deflect { unsigned int id; - gboolean err; + enum telephony_call_error err; }; struct tresp_call_transfer { unsigned int id; - gboolean err; + enum telephony_call_error err; }; struct tresp_call_dtmf { - gboolean err; + enum telephony_call_error err; }; -struct tresp_call_sound_set_path { - gboolean err; +struct tresp_call_set_sound_path { + enum telephony_call_error err; }; -struct tresp_call_sound_set_volume_level { - gboolean err; +struct tresp_call_set_sound_volume_level { + enum telephony_call_error err; }; -struct tresp_call_sound_get_volume_level { +struct tresp_call_get_sound_volume_level { + enum telephony_call_error err; int record_num; struct volume_info { enum telephony_call_sound_type sound; enum telephony_call_sound_volume_level volume; } *record; - gboolean err; }; -struct tresp_call_mute { - gboolean err; +struct tresp_call_set_sound_mute_status { + enum telephony_call_error err; +}; + +struct tresp_call_get_sound_mute_status { + enum telephony_call_error err; + enum telephony_call_sound_mute_path path; + enum telephony_call_sound_mute_status status; +}; + +struct tresp_call_set_sound_recording { + enum telephony_call_error err; }; -struct tresp_call_unmute { - gboolean err; +struct tresp_call_set_sound_equalization { + enum telephony_call_error err; }; -struct tresp_call_get_mute_status { - int status; - gboolean err; +struct tresp_call_set_sound_noise_reduction { + enum telephony_call_error err; }; -struct tresp_call_sound_set_recording { - gboolean err; +struct tresp_call_set_sound_clock_status { + enum telephony_call_error err; }; -struct tresp_call_sound_set_equalization { - gboolean err; +struct tresp_call_set_preferred_voice_subscription { + enum telephony_call_error err; }; -struct tresp_call_sound_set_noise_reduction { - gboolean err; +struct tresp_call_get_preferred_voice_subscription { + enum telephony_call_error err; + enum telephony_call_preferred_voice_subs preferred_subs; }; +struct tresp_call_set_voice_privacy_mode { + enum telephony_call_error err; +}; + +struct tresp_call_get_voice_privacy_mode { + enum telephony_call_error err; + enum telephony_call_voice_privacy_mode privacy_mode; +}; // Notification @@ -614,7 +831,7 @@ struct tnoti_call_sound_wbamr { }; struct tnoti_call_sound_equalization { - gboolean mode; + int mode; enum telephony_call_sound_direction direction; }; @@ -622,6 +839,53 @@ struct tnoti_call_sound_noise_reduction { gboolean status; }; +struct tnoti_call_sound_clock_status { + gboolean status; +}; + +struct tnoti_call_info_extra_information { + int type; + int data_len; + void *data; +}; + +struct tnoti_call_preferred_voice_subscription { + enum telephony_call_preferred_voice_subs preferred_subs; +}; + +struct tnoti_call_info_voice_privacy_mode { + enum telephony_call_voice_privacy_mode privacy_mode; +}; + +struct tnoti_call_signal_info { + enum telephony_call_alert_signal_type signal_type; + enum telephony_call_alert_pitch_type pitch_type; + union { + enum telephony_call_tone_signal sig_tone_type; + enum telephony_call_isdn_alert_signal sig_isdn_alert_type; + enum telephony_call_is54b_alert_signal sig_is54b_alert_type; + } signal; +}; + +struct tnoti_call_otasp_status { + enum telephony_call_otasp_status otasp_status ; +}; + +struct tnoti_call_otapa_status { + enum telephony_call_otapa_status otapa_status; +}; + +struct tnoti_call_otasp_result { + enum telephony_call_otasp_result otasp_result ; +}; + +struct tnoti_call_display_information { + unsigned char display_information[ MAX_CALL_DISPLAY_INFORMATION + 1]; +}; + +struct tnoti_call_info_rec { + struct telephony_call_rec_info rec_info; +}; __END_DECLS #endif diff --git a/include/type/common.h b/include/type/common.h index 0da05b2..092ec89 100644 --- a/include/type/common.h +++ b/include/type/common.h @@ -56,7 +56,7 @@ __BEGIN_DECLS enum tcore_return { TCORE_RETURN_SUCCESS = 0, TCORE_RETURN_FAILURE = -1, - + TCORE_RETURN_OPERATION_ABORTED = 1, /**< Operation Aborted */ TCORE_RETURN_ENOENT = ENOENT, /* No such file or directory */ TCORE_RETURN_EPERM = EPERM, /* Operation not permitted */ TCORE_RETURN_ENOMEM = ENOMEM, /* Out of memory */ @@ -80,6 +80,9 @@ enum tcore_return { TCORE_RETURN_HOOK_STOP = TCORE_RETURN | TCORE_TYPE_HOOK, + TCORE_RETURN_SIM = TCORE_RETURN | TCORE_TYPE_SIM, + TCORE_RETURN_SIM_DISABLED_IN_SST, /* feature in sst is disabled */ + /* NETTEXT */ TCORE_RETURN_SMS = TCORE_RETURN | TCORE_TYPE_SMS, TCORE_RETURN_SMS_DEVICE_NOT_READY, /** +#define PHONEBOOK_NAME_BYTE_MAX 256 //Samsung IPC defined +#define PHONEBOOK_NUMBER_BYTE_MAX 256 //Samsung IPC defined +#define PHONEBOOK_EMAIL_BYTE_MAX 256 //Samsung IPC defined enum tel_phonebook_type { PB_TYPE_FDN, /**< Fixed Dialing Number */ @@ -72,20 +75,26 @@ enum tel_phonebook_ton { enum tel_phonebook_dcs { PB_TEXT_ASCII, /**< ASCII Encoding */ - PB_TEXT_GSM7BIT, /**< GSM 7 Bit Encoding */ + PB_TEXT_GSM7BIT, /**< GSM 7 Bit with bit 8 set to 0 Encoding */ PB_TEXT_UCS2, /**< UCS2 Encoding */ PB_TEXT_HEX, /**< HEX Encoding */ }; struct tel_phonebook_support_list { gboolean b_fdn; /**< Fixed Dialing Number */ - gboolean b_adn; /**< SIM - ADN(2G phonebook */ + gboolean b_adn; /**< SIM - ADN(2G phonebook, Under DF phonebook */ gboolean b_sdn; /**< Service Dialing Number */ gboolean b_usim; /**< USIM - 3G phonebook */ gboolean b_aas; /**< Additional number Alpha String phonebook */ gboolean b_gas; /**< Grouping information Alpha String phonebook */ }; +struct tel_phonebook_field_support_list { + gboolean b_field_list[13]; + //supported fields are 12 according to 'enum tel_phonebook_field_type'. each index number means enum value. + //it is used from index 1. (index 0 doesn't match to any enum value. (no meaning)) +}; + struct treq_phonebook_get_count { enum tel_phonebook_type phonebook_type; }; @@ -107,24 +116,33 @@ struct treq_phonebook_update_record { enum tel_phonebook_type phonebook_type; unsigned short index; - unsigned char name[60]; + unsigned char name[PHONEBOOK_NAME_BYTE_MAX+1]; // +1 is for Null termination + unsigned short name_len; enum tel_phonebook_dcs dcs; - unsigned char number[40]; + unsigned char number[PHONEBOOK_NUMBER_BYTE_MAX+1]; // +1 is for Null termination enum tel_phonebook_ton ton; - /* following field is valid in only USIM*/ - unsigned char anr1[40]; + /* following fields are valid in only USIM*/ + unsigned char sne[PHONEBOOK_NAME_BYTE_MAX+1]; // +1 is for Null termination + unsigned short sne_len; + enum tel_phonebook_dcs sne_dcs; + + unsigned char anr1[PHONEBOOK_NUMBER_BYTE_MAX+1]; // +1 is for Null termination enum tel_phonebook_ton anr1_ton; - unsigned char anr2[40]; + unsigned char anr2[PHONEBOOK_NUMBER_BYTE_MAX+1]; // +1 is for Null termination enum tel_phonebook_ton anr2_ton; - unsigned char anr3[40]; + unsigned char anr3[PHONEBOOK_NUMBER_BYTE_MAX+1]; // +1 is for Null termination enum tel_phonebook_ton anr3_ton; - unsigned char email1[60]; - unsigned char email2[60]; - unsigned char email3[60]; - unsigned char email4[60]; + unsigned char email1[PHONEBOOK_EMAIL_BYTE_MAX+1]; // +1 is for Null termination + unsigned short email1_len; + unsigned char email2[PHONEBOOK_EMAIL_BYTE_MAX+1]; // +1 is for Null termination + unsigned short email2_len; + unsigned char email3[PHONEBOOK_EMAIL_BYTE_MAX+1]; // +1 is for Null termination + unsigned short email3_len; + unsigned char email4[PHONEBOOK_EMAIL_BYTE_MAX+1]; // +1 is for Null termination + unsigned short email4_len; unsigned short group_index; //GRP unsigned short pb_control; //PBC @@ -134,11 +152,7 @@ struct treq_phonebook_delete_record { enum tel_phonebook_type phonebook_type; unsigned short index; }; -/*WILL BE REMOVED - START*/ -struct tresp_phonebook_select { - enum tel_phonebook_result result; -}; -/*WILL BE REMOVED - END*/ + struct tresp_phonebook_get_count { enum tel_phonebook_result result; enum tel_phonebook_type type; @@ -153,6 +167,7 @@ struct tresp_phonebook_get_info { unsigned short index_max; unsigned short number_length_max; unsigned short text_length_max; + unsigned short used_count; }; struct tel_phonebook_usim_meta { @@ -174,24 +189,33 @@ struct tresp_phonebook_read_record { unsigned short index; unsigned short next_index; - unsigned char name[60]; + unsigned char name[PHONEBOOK_NAME_BYTE_MAX+1]; // +1 is for Null termination + unsigned short name_len; enum tel_phonebook_dcs dcs; - unsigned char number[40]; + unsigned char number[PHONEBOOK_NUMBER_BYTE_MAX+1]; // +1 is for Null termination enum tel_phonebook_ton ton; - /* following field is valid in only USIM*/ - unsigned char anr1[40]; + /* following fields are valid in only USIM*/ + unsigned char sne[PHONEBOOK_NAME_BYTE_MAX+1]; // +1 is for Null termination + unsigned short sne_len; + enum tel_phonebook_dcs sne_dcs; + + unsigned char anr1[PHONEBOOK_NUMBER_BYTE_MAX+1]; // +1 is for Null termination enum tel_phonebook_ton anr1_ton; - unsigned char anr2[40]; + unsigned char anr2[PHONEBOOK_NUMBER_BYTE_MAX+1]; // +1 is for Null termination enum tel_phonebook_ton anr2_ton; - unsigned char anr3[40]; + unsigned char anr3[PHONEBOOK_NUMBER_BYTE_MAX+1]; // +1 is for Null termination enum tel_phonebook_ton anr3_ton; - unsigned char email1[60]; - unsigned char email2[60]; - unsigned char email3[60]; - unsigned char email4[60]; + unsigned char email1[PHONEBOOK_EMAIL_BYTE_MAX+1]; // +1 is for Null termination + unsigned short email1_len; + unsigned char email2[PHONEBOOK_EMAIL_BYTE_MAX+1]; // +1 is for Null termination + unsigned short email2_len; + unsigned char email3[PHONEBOOK_EMAIL_BYTE_MAX+1]; // +1 is for Null termination + unsigned short email3_len; + unsigned char email4[PHONEBOOK_EMAIL_BYTE_MAX+1]; // +1 is for Null termination + unsigned short email4_len; unsigned short group_index; //GRP unsigned short pb_control; //PBC diff --git a/include/type/ps.h b/include/type/ps.h index e816f9b..3408921 100644 --- a/include/type/ps.h +++ b/include/type/ps.h @@ -57,6 +57,7 @@ enum telephony_ps_protocol_status { TELEPHONY_HSDPA_ON = 0x01, TELEPHONY_HSUPA_ON = 0x02, TELEPHONY_HSPA_ON = 0x03, + TELEPHONY_HSPAP_ON = 0x04 }; enum telephony_ps_state { @@ -64,7 +65,8 @@ enum telephony_ps_state { TELEPHONY_PS_3G_OFF, TELEPHONY_PS_ROAMING_OFF, TELEPHONY_PS_FLIGHT_MODE, - TELEPHONY_PS_NO_SERVICE + TELEPHONY_PS_NO_SERVICE, + TELEPHONY_PS_RESTRICTED_SERVICE }; struct treq_ps_pdp_activate { @@ -117,12 +119,19 @@ struct tnoti_ps_pdp_ipconfiguration { enum telephony_ps_pdp_err err; unsigned short field_flag; + + char devname[16]; + unsigned char ip_address[4]; unsigned char primary_dns[4]; unsigned char secondary_dns[4]; unsigned char gateway[4]; unsigned char subnet_mask[4]; - char devname[16]; + + unsigned char ipv6_address[128]; + unsigned char ipv6_primary_dns[128]; + unsigned char ipv6_secondary_dns[128]; + unsigned char ipv6_gateway[128]; }; struct tnoti_ps_external_call { diff --git a/include/type/request.h b/include/type/request.h index 8b050d5..40e3f6c 100644 --- a/include/type/request.h +++ b/include/type/request.h @@ -39,6 +39,7 @@ enum tcore_request_command { TREQ_MODEM_POWER_ON, TREQ_MODEM_POWER_OFF, TREQ_MODEM_POWER_RESET, + TREQ_MODEM_POWER_LOW, TREQ_MODEM_SET_FLIGHTMODE, TREQ_MODEM_GET_FLIGHTMODE, TREQ_MODEM_GET_IMEI, @@ -57,16 +58,22 @@ enum tcore_request_command { TREQ_CALL_SPLIT, TREQ_CALL_DEFLECT, TREQ_CALL_TRANSFER, - TREQ_CALL_SEND_DTMF, + TREQ_CALL_START_CONT_DTMF, + TREQ_CALL_STOP_CONT_DTMF, + TREQ_CALL_SEND_BURST_DTMF, + TREQ_CALL_SET_PRIVACY_MODE, + TREQ_CALL_GET_PRIVACY_MODE, TREQ_CALL_SET_SOUND_PATH, TREQ_CALL_GET_SOUND_VOLUME_LEVEL, TREQ_CALL_SET_SOUND_VOLUME_LEVEL, - TREQ_CALL_MUTE, - TREQ_CALL_UNMUTE, - TREQ_CALL_GET_MUTE_STATUS, + TREQ_CALL_SET_SOUND_MUTE_STATUS, + TREQ_CALL_GET_SOUND_MUTE_STATUS, TREQ_CALL_SET_SOUND_RECORDING, TREQ_CALL_SET_SOUND_EQUALIZATION, TREQ_CALL_SET_SOUND_NOISE_REDUCTION, + TREQ_CALL_SET_SOUND_CLOCK_STATUS, + TREQ_CALL_SET_PREFERRED_VOICE_SUBSCRIPTION, + TREQ_CALL_GET_PREFERRED_VOICE_SUBSCRIPTION, TREQ_CALL_SET_ACTIVE_LINE, TREQ_CALL_GET_ACTIVE_LINE, @@ -88,6 +95,7 @@ enum tcore_request_command { TREQ_SS_WAITING_GET_STATUS, TREQ_SS_CLI_ACTIVATE, TREQ_SS_CLI_DEACTIVATE, + TREQ_SS_CLI_SET_STATUS, TREQ_SS_CLI_GET_STATUS, TREQ_SS_SEND_USSD, TREQ_SS_SET_AOC, @@ -107,10 +115,13 @@ enum tcore_request_command { TREQ_SIM_SET_LANGUAGE, TREQ_SIM_GET_ICCID, TREQ_SIM_GET_MAILBOX, + TREQ_SIM_SET_MAILBOX, TREQ_SIM_GET_CALLFORWARDING, TREQ_SIM_SET_CALLFORWARDING, TREQ_SIM_GET_MESSAGEWAITING, + TREQ_SIM_SET_MESSAGEWAITING, TREQ_SIM_GET_CPHS_INFO, + TREQ_SIM_GET_SERVICE_TABLE, TREQ_SIM_GET_MSISDN, TREQ_SIM_GET_SPN, TREQ_SIM_GET_SPDI, @@ -120,10 +131,18 @@ enum tcore_request_command { TREQ_SIM_GET_OPLMNWACT, TREQ_SIM_REQ_AUTHENTICATION, TREQ_SIM_GET_LOCK_INFO, + TREQ_SIM_GET_ICON, + TREQ_SIM_SET_POWERSTATE, + TREQ_SIM_GET_GID, +#if defined TIZEN_GLOBALCONFIG_ENABLE_CSP + TREQ_SIM_GET_CPHS_CSP_INFO, + TREQ_SIM_SET_CPHS_CSP_INFO, +#endif TREQ_SAT = TCORE_REQUEST | TCORE_TYPE_SAT, TREQ_SAT_REQ_ENVELOPE, TREQ_SAT_REQ_TERMINALRESPONSE, + TREQ_SAT_REQ_USERCONFIRMATION, TREQ_SAP = TCORE_REQUEST | TCORE_TYPE_SAP, TREQ_SAP_REQ_CONNECT, @@ -153,6 +172,16 @@ enum tcore_request_command { TREQ_NETWORK_GET_SERVING_NETWORK, TREQ_NETWORK_SET_MODE, TREQ_NETWORK_GET_MODE, + TREQ_NETWORK_SET_NEIGHBORING_CELL_INFO, + TREQ_NETWORK_GET_NEIGHBORING_CELL_INFO, + TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION, + TREQ_NETWORK_GET_DEFAULT_DATA_SUBSCRIPTION, + TREQ_NETWORK_SET_DEFAULT_SUBSCRIPTION, + TREQ_NETWORK_GET_DEFAULT_SUBSCRIPTION, + TREQ_NETWORK_SET_EMERGENCY_CALLBACK_MODE, + TREQ_NETWORK_SET_ROAMING_PREFERENCE, + TREQ_NETWORK_GET_ROAMING_PREFERENCE, + TREQ_NETWORK_GET_SUBSCRIPTION_INFO, TREQ_PS = TCORE_REQUEST | TCORE_TYPE_PS, TREQ_PS_SET_PDP_ACTIVATE, @@ -179,9 +208,6 @@ enum tcore_request_command { TREQ_SMS_SEND_CDMA_MSG, TREQ_PHONEBOOK = TCORE_REQUEST | TCORE_TYPE_PHONEBOOK, - /*WILL BE REMOVED - START*/ - TREQ_PHONEBOOK_SELECT, - /*WILL BE REMOVED - END*/ TREQ_PHONEBOOK_GETCOUNT, TREQ_PHONEBOOK_GETMETAINFO, TREQ_PHONEBOOK_GETUSIMINFO, @@ -193,6 +219,14 @@ enum tcore_request_command { TREQ_GPS = TCORE_REQUEST | TCORE_TYPE_GPS, TREQ_GPS_CONFIRM_MEASURE_POS, + TREQ_GPS_SET_FREQUENCY_AIDING, + TREQ_ENABLE_SMART_ASSISTANT, + TREQ_DISABLE_SMART_ASSISTANT, + TREQ_SYNC_SMART_ASSISTANT_AREA_LIST, + TREQ_DEL_SMART_ASSISTANT_AREA_LIST, + TREQ_ADD_SMART_ASSISTANT_AREA, + TREQ_MODIFY_SMART_ASSISTANT_AREA, + TREQ_SET_SMART_ASSISTANT_INFO, TREQ_CUSTOM = TCORE_REQUEST | TCORE_TYPE_CUSTOM, }; @@ -200,11 +234,6 @@ enum tcore_request_command { struct treq_server_get_plugins { }; -struct treq_custom { - unsigned int custom_command; - GHashTable *data; -}; - __END_DECLS #endif diff --git a/include/type/response.h b/include/type/response.h index 5d49b63..f2f1f7c 100644 --- a/include/type/response.h +++ b/include/type/response.h @@ -34,6 +34,7 @@ enum tcore_response_command { TRESP_MODEM_POWER_ON, TRESP_MODEM_POWER_OFF, TRESP_MODEM_POWER_RESET, + TRESP_MODEM_POWER_LOW, TRESP_MODEM_SET_FLIGHTMODE, TRESP_MODEM_GET_FLIGHTMODE, TRESP_MODEM_GET_IMEI, @@ -52,19 +53,25 @@ enum tcore_response_command { TRESP_CALL_SPLIT, TRESP_CALL_DEFLECT, TRESP_CALL_TRANSFER, - TRESP_CALL_SEND_DTMF, + TRESP_CALL_START_CONT_DTMF, + TRESP_CALL_STOP_CONT_DTMF, + TRESP_CALL_SEND_BURST_DTMF, + TRESP_CALL_SET_PRIVACY_MODE, + TRESP_CALL_GET_PRIVACY_MODE, TRESP_CALL_SET_SOUND_PATH, TRESP_CALL_GET_SOUND_VOLUME_LEVEL, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, - TRESP_CALL_MUTE, - TRESP_CALL_UNMUTE, - TRESP_CALL_GET_MUTE_STATUS, + TRESP_CALL_SET_SOUND_MUTE_STATUS, + TRESP_CALL_GET_SOUND_MUTE_STATUS, TRESP_CALL_SET_SOUND_RECORDING, TRESP_CALL_SET_SOUND_EQUALIZATION, TRESP_CALL_SET_SOUND_NOISE_REDUCTION, + TRESP_CALL_SET_SOUND_CLOCK_STATUS, TRESP_CALL_SET_ACTIVE_LINE, TRESP_CALL_GET_ACTIVE_LINE, TRESP_CALL_ACTIVATE_CCBS, + TRESP_CALL_SET_PREFERRED_VOICE_SUBSCRIPTION, + TRESP_CALL_GET_PREFERRED_VOICE_SUBSCRIPTION, TRESP_SS = TCORE_RESPONSE | TCORE_TYPE_SS, TRESP_SS_BARRING_ACTIVATE, @@ -81,6 +88,7 @@ enum tcore_response_command { TRESP_SS_WAITING_GET_STATUS, TRESP_SS_CLI_ACTIVATE, TRESP_SS_CLI_DEACTIVATE, + TRESP_SS_CLI_SET_STATUS, TRESP_SS_CLI_GET_STATUS, TRESP_SS_SEND_USSD, TRESP_SS_SET_AOC, @@ -100,10 +108,13 @@ enum tcore_response_command { TRESP_SIM_SET_LANGUAGE, TRESP_SIM_GET_ICCID, TRESP_SIM_GET_MAILBOX, + TRESP_SIM_SET_MAILBOX, TRESP_SIM_GET_CALLFORWARDING, TRESP_SIM_SET_CALLFORWARDING, TRESP_SIM_GET_MESSAGEWAITING, + TRESP_SIM_SET_MESSAGEWAITING, TRESP_SIM_GET_CPHS_INFO, + TRESP_SIM_GET_SERVICE_TABLE, TRESP_SIM_GET_MSISDN, TRESP_SIM_GET_SPN, TRESP_SIM_GET_SPDI, @@ -113,6 +124,12 @@ enum tcore_response_command { TRESP_SIM_GET_OPLMNWACT, TRESP_SIM_REQ_AUTHENTICATION, TRESP_SIM_GET_LOCK_INFO, + TRESP_SIM_SET_POWERSTATE, + TRESP_SIM_GET_GID, +#if defined TIZEN_GLOBALCONFIG_ENABLE_CSP + TRESP_SIM_GET_CPHS_CSP_INFO, + TRESP_SIM_SET_CPHS_CSP_INFO, +#endif TRESP_SAT = TCORE_RESPONSE | TCORE_TYPE_SAT, TRESP_SAT_REQ_ENVELOPE, @@ -146,6 +163,16 @@ enum tcore_response_command { TRESP_NETWORK_GET_SERVING_NETWORK, TRESP_NETWORK_SET_MODE, TRESP_NETWORK_GET_MODE, + TRESP_NETWORK_SET_NEIGHBORING_CELL_INFO, + TRESP_NETWORK_GET_NEIGHBORING_CELL_INFO, + TRESP_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION, + TRESP_NETWORK_GET_DEFAULT_DATA_SUBSCRIPTION, + TRESP_NETWORK_SET_DEFAULT_SUBSCRIPTION, + TRESP_NETWORK_GET_DEFAULT_SUBSCRIPTION, + TRESP_NETWORK_SET_EMERGENCY_CALLBACK_MODE, + TRESP_NETWORK_SET_ROAMING_PREFERENCE, + TRESP_NETWORK_GET_ROAMING_PREFERENCE, + TRESP_NETWORK_GET_SUBSCRIPTION_INFO, TRESP_PS = TCORE_RESPONSE | TCORE_TYPE_PS, TRESP_PS_SET_PDP_ACTIVATE, @@ -172,9 +199,6 @@ enum tcore_response_command { TRESP_SMS_SEND_CDMA_MSG, /* This event is returned in response to SMS message extended sent*/ TRESP_PHONEBOOK = TCORE_RESPONSE | TCORE_TYPE_PHONEBOOK, - /*WILL BE REMOVED - START*/ - TRESP_PHONEBOOK_SELECT, - /*WILL BE REMOVED - END*/ TRESP_PHONEBOOK_GETCOUNT, TRESP_PHONEBOOK_GETMETAINFO, TRESP_PHONEBOOK_GETUSIMINFO, @@ -185,16 +209,18 @@ enum tcore_response_command { TRESP_SOUND = TCORE_RESPONSE | TCORE_TYPE_SOUND, TRESP_GPS = TCORE_RESPONSE | TCORE_TYPE_GPS, - TRESP_GPS_CONFIRM_MEASURE_POS, + TRESP_GPS_SET_FREQUENCY_AIDING, + TRESP_ENABLE_SMART_ASSISTANT, + TRESP_DISABLE_SMART_ASSISTANT, + TRESP_SYNC_SMART_ASSISTANT_AREA_LIST, + TRESP_DEL_SMART_ASSISTANT_AREA_LIST, + TRESP_ADD_SMART_ASSISTANT_AREA, + TRESP_MODIFY_SMART_ASSISTANT_AREA, + TRESP_SET_SMART_ASSISTANT_INFO, TRESP_CUSTOM = TCORE_RESPONSE | TCORE_TYPE_CUSTOM, }; -struct tresp_custom { - unsigned int custom_command; - GHashTable *data; -}; - __END_DECLS #endif diff --git a/include/type/sat.h b/include/type/sat.h index 98cd456..659c1ce 100644 --- a/include/type/sat.h +++ b/include/type/sat.h @@ -34,56 +34,56 @@ __BEGIN_DECLS #define SAT_DIALING_NUMBER_LEN_MAX 200 #define SAT_SS_STRING_LEN_MAX 160 #define SAT_USSD_STRING_LEN_MAX 255 -#define SAT_ALPHA_ID_LEN_MAX 255 /**< max length of alpha identifier */ -#define SAT_ITEM_TEXT_LEN_MAX 45 /**< max length of item text */ +#define SAT_ALPHA_ID_LEN_MAX 255 /**< max length of alpha identifier */ +#define SAT_ITEM_TEXT_LEN_MAX 255 /**< max length of item text */ #define SAT_SMS_TPDU_SMS_DATA_LEN_MAX 175 #define SAT_ITEMS_NEXT_ACTION_INDI_LIST_MAX_COUNT 50 /**< max count of items next action indication list */ #define SAT_IMG_DATA_FILE_PATH_LEN_MAX 50 /**< max length of image data file name (Icon, CLUT) */ -#define SAT_ICON_LIST_MAX_COUNT 50 /**< max count of icon list */ +#define SAT_ICON_LIST_MAX_COUNT 50 /**< max count of icon list */ #define SAT_DTMF_STRING_LEN_MAX 30 /**< max length of dtmf string */ -#define SAT_URL_LEN_MAX 129 /**< max length of URL */ +#define SAT_URL_LEN_MAX 129 /**< max length of URL */ #define SAT_ITEM_TEXT_ATTRIBUTES_LIST_MAX_COUNT 50 /**< max count of item text attributes list */ #define SAT_EVENT_LIST_MAX 17 /**< max count of event list */ #define SAT_FILE_ID_LIST_MAX_COUNT 255 #define SAT_ENVELOPE_CMD_LEN_MAX 256 #define SAT_AID_LEN_MAX 128 #define SAT_SUB_ADDR_LEN_MAX 30 -#define SAT_CCP_DATA_LEN_MAX 30 /**< max length of ccp data */ -#define SAT_URL_LEN_MAX 129 /**< max length of url */ -#define SAT_BEARER_LIST_MAX_COUNT 5 /**< max count of bearer list */ +#define SAT_CCP_DATA_LEN_MAX 30 /**< max length of ccp data */ +#define SAT_URL_LEN_MAX 129 /**< max length of url */ +#define SAT_BEARER_LIST_MAX_COUNT 5 /**< max count of bearer list */ #define SAT_PROVISIONING_REF_MAX_COUNT 10 /**< max count of sat provisioning reference */ -#define SAT_PROVISIONING_FILE_PATH_LEN_MAX 50 /**< max length of provisioning file path */ -#define SAT_BEARER_PARAMS_LEN_MAX 10 /**< max length of bearer parameters */ -#define SAT_OTHER_ADDR_LEN_MAX 30 /**< max length of other address */ +#define SAT_PROVISIONING_FILE_PATH_LEN_MAX 50 /**< max length of provisioning file path */ +#define SAT_BEARER_PARAMS_LEN_MAX 10 /**< max length of bearer parameters */ +#define SAT_OTHER_ADDR_LEN_MAX 30 /**< max length of other address */ #define SAT_NET_ACC_NAM_LEN_MAX 30 /**< max length of net acc name */ -#define SAT_REMOTE_ENTITY_ADDR_LEN_MAX 50 /**< max length of remote entity address */ +#define SAT_REMOTE_ENTITY_ADDR_LEN_MAX 50 /**< max length of remote entity address */ #define SAT_CHANNEL_DATA_STRING_LEN_MAX 255 enum tel_sat_proactive_cmd_type { - SAT_PROATV_CMD_NONE = 0x00, /**< command type - None */ - SAT_PROATV_CMD_REFRESH = 0x01, /**< command type - refresh */ + SAT_PROATV_CMD_NONE = 0x00, /**< command type - None */ + SAT_PROATV_CMD_REFRESH = 0x01, /**< command type - refresh */ SAT_PROATV_CMD_MORE_TIME = 0x02, /**< command type - more time */ - SAT_PROATV_CMD_SETUP_EVENT_LIST = 0x05, /**< command type - setup event list */ + SAT_PROATV_CMD_SETUP_EVENT_LIST = 0x05, /**< command type - setup event list */ SAT_PROATV_CMD_SETUP_CALL = 0x10, /**< command type - setup call */ SAT_PROATV_CMD_SEND_SS = 0x11, /**< command type - send ss */ SAT_PROATV_CMD_SEND_USSD = 0x12, /**< command type - send ussd */ - SAT_PROATV_CMD_SEND_SMS = 0x13, /**< command type - send sms */ - SAT_PROATV_CMD_SEND_DTMF = 0x14, /**< command type - send dtmf */ - SAT_PROATV_CMD_LAUNCH_BROWSER = 0x15, /**< command type - launch browser */ + SAT_PROATV_CMD_SEND_SMS = 0x13, /**< command type - send sms */ + SAT_PROATV_CMD_SEND_DTMF = 0x14, /**< command type - send dtmf */ + SAT_PROATV_CMD_LAUNCH_BROWSER = 0x15, /**< command type - launch browser */ SAT_PROATV_CMD_PLAY_TONE = 0x20, /**< command type - play tone */ SAT_PROATV_CMD_DISPLAY_TEXT = 0x21, /**< command type - display text */ SAT_PROATV_CMD_GET_INKEY = 0x22, /**< command type - get inkey */ SAT_PROATV_CMD_GET_INPUT = 0x23, /**< command type - get input */ SAT_PROATV_CMD_SELECT_ITEM = 0x24, /**< command type - select item */ SAT_PROATV_CMD_SETUP_MENU = 0x25, /**< command type - setup menu */ - SAT_PROATV_CMD_PROVIDE_LOCAL_INFO = 0x26, /**< command type - provide local info */ + SAT_PROATV_CMD_PROVIDE_LOCAL_INFO = 0x26, /**< command type - provide local info */ SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT = 0x28, /**< command type - setup idle mode text */ SAT_PROATV_CMD_LANGUAGE_NOTIFICATION = 0x35, /**< command type - language notification */ SAT_PROATV_CMD_OPEN_CHANNEL = 0x40, /**< command type - open channel -class e */ SAT_PROATV_CMD_CLOSE_CHANNEL = 0x41, /**< command type - close channel - class e */ - SAT_PROATV_CMD_RECEIVE_DATA = 0x42, /**< command type - receive data -class e */ - SAT_PROATV_CMD_SEND_DATA = 0x43, /**< command type - send data */ - SAT_PROATV_CMD_GET_CHANNEL_STATUS = 0x44, /**< command type - get channel status -class e */ + SAT_PROATV_CMD_RECEIVE_DATA = 0x42, /**< command type - receive data -class e */ + SAT_PROATV_CMD_SEND_DATA = 0x43, /**< command type - send data */ + SAT_PROATV_CMD_GET_CHANNEL_STATUS = 0x44, /**< command type - get channel status -class e */ SAT_PROATV_CMD_TYPE_END_PROACTIVE_SESSION = 0xFE, SAT_PROATV_CMD_RESERVED = 0xFF /**< command type - reserved */ }; @@ -97,10 +97,10 @@ enum tel_sat_proactive_cmd_type { * Data Coding Scheme Object */ enum alphabet_format{ - ALPHABET_FROMAT_SMS_DEFAULT = 0x00, - ALPHABET_FROMAT_8BIT_DATA = 0x01, - ALPHABET_FROMAT_UCS2 = 0x02, - ALPHABET_FROMAT_RESERVED = 0x03 + ALPHABET_FORMAT_SMS_DEFAULT = 0x00, + ALPHABET_FORMAT_8BIT_DATA = 0x01, + ALPHABET_FORMAT_UCS2 = 0x02, + ALPHABET_FORMAT_RESERVED = 0x03 }; enum msg_class{ @@ -130,7 +130,7 @@ enum type_of_number{ TON_DEDICATED_ACCESS = 4, /*< subscriber number */ TON_ALPHA_NUMERIC = 5, /*< alphanumeric, GSM 7-bit default alphabet) */ TON_ABBREVIATED_NUMBER = 6, /*< abbreviated number */ - TON_RESERVED_FOR_EXT = 7 /*< reserved for extension */ + TON_RESERVED_FOR_EXT = 0xF /*< reserved for extension */ }; enum numbering_plan_identifier{ @@ -159,8 +159,8 @@ struct tel_sat_address{ struct tel_sat_alpha_identifier{ gboolean is_exist; struct data_coding_scheme dcs; - unsigned char alpha_data_len; /**< alpha identifier length */ - char alpha_data[SAT_ALPHA_ID_LEN_MAX]; /**< alpha identifier info */ + unsigned char alpha_data_len; /**< alpha identifier length */ + char alpha_data[SAT_ALPHA_ID_LEN_MAX]; /**< alpha identifier info */ }; /* @@ -226,26 +226,15 @@ struct tel_sat_cmd_qualifier_get_input{ enum vibration_alert{ VIBRATE_ALERT_OPTIONAL = 0, /**< VIBRATE ALERT UPTO THE TERMINAL */ - VIBRATE_ALERT_REQUIRED = 1 /**< VIBRATE, IF AVAILABLE, WITH TONE. */ + VIBRATE_ALERT_REQUIRED = 1 /**< VIBRATE, IF AVAILABLE, WITH TONE. */ }; struct tel_sat_cmd_qualifier_play_tone{ enum vibration_alert vibration_alert; }; -enum refresh_command{ - REFRESH_SIM_INIT_AND_FULL_FCN = 0, /**< command qualifier for REFRESH SIM INIT AND FULL FILE CHANGE_NOTIFICATION */ - REFRESH_FCN = 1, /**< command qualifier for REFRESH FILE CHANGE NOTIFICATION */ - REFRESH_SIM_INIT_AND_FCN = 2, /**< command qualifier for REFRESH SIM INIT AND FILE CHANGE NOTIFICATION */ - REFRESH_SIM_INIT = 3, /**< command qualifier for REFRESH SIM INIT */ - REFRESH_SIM_RESET = 4, /**< command qualifier for REFRESH SIM RESET */ - REFRESH_3G_APPLICATION_RESET = 5, /**< command qualifier for REFRESH 3G APPLICATION RESET */ - REFRESH_3G_SESSION_RESET = 6, /**< command qualifier for REFRESH 3G SESSION RESET */ - REFRESH_RESERVED = 0xFF /**< command qualifier for REFRESH RESERVED */ -}; - struct tel_sat_cmd_qualifier_refresh{ - enum refresh_command refresh; + enum tel_sim_refresh_command refresh; }; enum provide_local_info_command{ @@ -273,7 +262,7 @@ enum setup_call_command{ SETUP_CALL_PUT_ALL_OTHER_CALLS_ON_HOLD_WITH_REDIAL = 0x03, /**< command qualifier for SETUP CALL PUTTING ALL OTHER CALLS ON HOLD WITH REDIAL */ SETUP_CALL_DISCONN_ALL_OTHER_CALLS = 0x04, /**< command qualifier for SETUP CALL DISCONNECTING ALL OTHER CALLS */ SETUP_CALL_DISCONN_ALL_OTHER_CALLS_WITH_REDIAL = 0x05, /**< command qualifier for SETUP CALL DISCONNECTING ALL OTHER CALLS WITH REDIAL */ - SETUP_CALL_RESERVED = 0xFF /**< command qualifier for SETUP CALL RESERVED */ + SETUP_CALL_RESERVED = 0xFF /**< command qualifier for SETUP CALL RESERVED */ }; struct tel_sat_cmd_qualifier_setup_call{ @@ -310,7 +299,7 @@ enum launch_browser_command{ LAUNCH_BROWSER_IF_NOT_ALREADY_LAUNCHED = 0, /**< command qualifier for LAUNCH BROWSER */ LAUNCH_BROWSER_NOT_USED = 1, /**< command qualifier for NOT USED */ LAUNCH_BROWSER_USE_EXISTING_BROWSER = 2, /**< command qualifier for USE EXISTING BROWSER if secure session, do not use it. */ - LAUNCH_BROWSER_CLOSE_AND_LAUNCH_NEW_BROWSER = 3, /**< command qualifier for CLOSE AND LAUNCH NEW BROWSER */ + LAUNCH_BROWSER_CLOSE_AND_LAUNCH_NEW_BROWSER = 3, /**< command qualifier for CLOSE AND LAUNCH NEW BROWSER */ LAUNCH_BROWSER_NOT_USED2 = 4, /**< command qualifier for NOT USED2 */ LAUNCH_BROWSER_RESERVED = 0xFF /**< reserved */ }; @@ -352,7 +341,7 @@ struct tel_sat_cmd_detail_info{ struct tel_sat_cmd_qualifier_launch_browser launch_browser; struct tel_sat_cmd_qualifier_open_channel open_channel; struct tel_sat_cmd_qualifier_send_data send_data; - }cmd_qualifier; /**< Union */ + }cmd_qualifier; /**< Union */ }; /* @@ -396,6 +385,7 @@ struct tel_sat_item_info{ unsigned char item_id; unsigned char text_len; unsigned char text[SAT_ITEM_TEXT_LEN_MAX + 1]; + struct data_coding_scheme dcs; }; /* @@ -418,44 +408,44 @@ struct tel_sat_response_length{ */ enum tel_sat_result_type{ RESULT_SUCCESS = 0x0, /**< command performed successfully */ - RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION = 0x01, /**< command performed with partial comprehension */ - RESULT_SUCCESS_WITH_MISSING_INFO = 0x02, /**< command performed, with missing information */ + RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION = 0x01, /**< command performed with partial comprehension */ + RESULT_SUCCESS_WITH_MISSING_INFO = 0x02, /**< command performed, with missing information */ - RESULT_REFRESH_PERFORMED_WITH_ADDITIONAL_EFS_READ = 0x03, /**< REFRESH PERFORMED WITH ADDITIONAL EFS READ */ + RESULT_REFRESH_PERFORMED_WITH_ADDITIONAL_EFS_READ = 0x03, /**< REFRESH PERFORMED WITH ADDITIONAL EFS READ */ RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED = 0x04, /**< command performed but REQUESTED ICON NOT DISPLAYED */ RESULT_SUCCESS_BUT_MODIFIED_BY_CALL_CONTROL_BY_SIM = 0x05, /**< command performed but MODIFIED BY CALL CONTROL BY SIM */ RESULT_SUCCESS_LIMITED_SERVICE = 0x06, /**< command performed with LIMITED SERVICE */ RESULT_SUCCESS_WITH_MODIFICATION = 0x07, /**< command performed with MODIFICATION */ - RESULT_REFRESH_PRFRMD_BUT_INDICATED_USIM_NOT_ACTIVE = 0x08, /**< REFRESH PERFORMED BUT INDICATED USIM NOT ACTIVE */ + RESULT_REFRESH_PRFRMD_BUT_INDICATED_USIM_NOT_ACTIVE = 0x08, /**< REFRESH PERFORMED BUT INDICATED USIM NOT ACTIVE */ RESULT_SUCCESS_BUT_TONE_NOT_PLAYED = 0x09, /**< command performed successfully, tone not played*/ RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER = 0x10, /**< proactive sim application session terminated by user */ - RESULT_BACKWARD_MOVE_BY_USER = 0x11, /**< backward move in the proactive sim application session request by the user */ + RESULT_BACKWARD_MOVE_BY_USER = 0x11, /**< backward move in the proactive sim application session request by the user */ RESULT_NO_RESPONSE_FROM_USER = 0x12, /**< no response from user */ - RESULT_HELP_INFO_REQUIRED_BY_USER = 0x13, /**< HELP INFO REQUIRED BY USER */ + RESULT_HELP_INFO_REQUIRED_BY_USER = 0x13, /**< HELP INFO REQUIRED BY USER */ RESULT_USSD_OR_SS_TRANSACTION_TERMINATED_BY_USER = 0x14, /**< USSD OR SS TRANSACTION TERMINATED BY USER */ - RESULT_ME_UNABLE_TO_PROCESS_COMMAND = 0x20, /**< ME currently unable to process command */ - RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND = 0x21, /**< Network currently unable to process command */ - RESULT_USER_DID_NOT_ACCEPT_CALL_SETUP_REQ = 0x22, /**< User did not accept call setup request */ + RESULT_ME_UNABLE_TO_PROCESS_COMMAND = 0x20, /**< ME currently unable to process command */ + RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND = 0x21, /**< Network currently unable to process command */ + RESULT_USER_DID_NOT_ACCEPT_CALL_SETUP_REQ = 0x22, /**< User did not accept call setup request */ RESULT_USER_CLEAR_DOWN_CALL_BEFORE_CONN = 0x23, /**< User cleared down call before connection or network released */ - RESULT_INTERACTION_WITH_CC_BY_SIM_IN_TMP_PRBLM = 0x25, /**< INTERACTION WITH CALL CONTROL BY SIM IN TEMPORARY PROBLEM */ - RESULT_LAUNCH_BROWSER_GENERIC_ERROR_CODE = 0x26, /**< LAUNCH BROWSER GENERIC ERROR CODE */ + RESULT_INTERACTION_WITH_CC_BY_SIM_IN_TMP_PRBLM = 0x25, /**< INTERACTION WITH CALL CONTROL BY SIM IN TEMPORARY PROBLEM */ + RESULT_LAUNCH_BROWSER_GENERIC_ERROR_CODE = 0x26, /**< LAUNCH BROWSER GENERIC ERROR CODE */ - RESULT_BEYOND_ME_CAPABILITIES = 0x30, /**< command beyond ME's capabilities */ - RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME = 0x31, /**< command type not understood by ME */ + RESULT_BEYOND_ME_CAPABILITIES = 0x30, /**< command beyond ME's capabilities */ + RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME = 0x31, /**< command type not understood by ME */ RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME = 0x32, /**< command data not understood by ME */ - RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME = 0x33, /**< command number not known by ME */ + RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME = 0x33, /**< command number not known by ME */ RESULT_SS_RETURN_ERROR = 0x34, /**< SS return error */ RESULT_SMS_RP_ERROR = 0x35, /**< SMS rp-error */ - RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING = 0x36, /**< Error, required values are missing */ + RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING = 0x36, /**< Error, required values are missing */ - RESULT_USSD_RETURN_ERROR = 0x37, /**< USSD_RETURN_ERROR */ - RESULT_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM = 0x39, /**< INTERACTION WITH CALL CONTROL OR SMS CONTROL PERMANENT PROBLEM */ - RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR = 0x3A, /**< BEARER INDEPENDENT PROTOCOL ERROR */ - RESULT_FRAMES_ERROR = 0x3C /**< FRAMES ERROR */ + RESULT_USSD_RETURN_ERROR = 0x37, /**< USSD_RETURN_ERROR */ + RESULT_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM = 0x39, /**< INTERACTION WITH CALL CONTROL OR SMS CONTROL PERMANENT PROBLEM */ + RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR = 0x3A, /**< BEARER INDEPENDENT PROTOCOL ERROR */ + RESULT_FRAMES_ERROR = 0x3C /**< FRAMES ERROR */ }; enum tel_sat_me_problem_type{ @@ -469,12 +459,13 @@ enum tel_sat_me_problem_type{ ME_PROBLEM_NOT_IN_SPEECH_CALL = 0x07, /**< ME problem with NOT IN SPEECH CALL */ ME_PROBLEM_ME_BUSY_ON_USSD = 0x08, /**< ME problem with ME BUSY ON USSD */ ME_PROBLEM_ME_BUSY_ON_SEND_DTMF_CMD = 0x09, /**< ME problem with ME BUSY ON SEND DTMF CMD */ - ME_PROBLEM_NO_USIM_ACTIVE = 0x0A, /**< ME problem with NO USIM ACTIVE */ - ME_PROBLEM_INVALID = 0xFF /**< ME problem with INVALID */ + ME_PROBLEM_NO_USIM_ACTIVE = 0x0A, /**< ME problem with NO USIM ACTIVE */ + ME_PROBLEM_INVALID = 0xFF /**< ME problem with INVALID */ }; enum tel_sat_user_confirm_type{ - USER_CONFIRM_YES, /**= '0' && (h) <= '9') (i) = (h) - '0'; \ + else if ((h) >= 'A' && (h) <= 'F') (i) = (h) - 'A' + 10; \ + else if ((h) >= 'a' && (h) <= 'f') (i) = (h) - 'a' + 10; \ + else (i) = 0; enum tcore_util_marshal_data_type { TCORE_UTIL_MARSHAL_DATA_CHAR_TYPE = G_TYPE_CHAR, @@ -54,6 +58,8 @@ TReturn tcore_util_netif_up(const char *name); TReturn tcore_util_netif_down(const char *name); TReturn tcore_util_netif_set(const char *name, const char *ipaddr, const char *gateway, const char *netmask); +TReturn tcore_util_reset_ipv4_socket(const char *name, const char *ipaddr); +TReturn tcore_util_netif_set_mtu(const char *name, unsigned int mtu); char* tcore_util_get_string_by_ip4type(union tcore_ip4_type ip); @@ -75,11 +81,25 @@ GHashTable* tcore_util_marshal_get_object(GHashTable *ht, const gchar *key); enum tcore_dcs_type tcore_util_get_cbs_coding_scheme(unsigned char encode); -unsigned char* tcore_util_decode_hex(const char *src, int len); - -unsigned char* tcore_util_unpack_gsm7bit(const unsigned char *src, unsigned int src_len); -unsigned char* tcore_util_pack_gsm7bit(const unsigned char *src, unsigned int src_len); -char* tcore_util_convert_bcd2ascii(const char *src, int src_len, int max_len); +unsigned char* tcore_util_decode_hex(const char *src, int len); +void tcore_util_hex_dump(const char *pad, int size, const void *data); + +unsigned char* tcore_util_unpack_gsm7bit(const unsigned char *src, unsigned int src_len); +unsigned char* tcore_util_pack_gsm7bit(const unsigned char *src, unsigned int src_len); +char* tcore_util_convert_bcd_str_2_ascii_str(const char* src, int src_len); +char* tcore_util_convert_bcd2ascii(const char *src, int src_len, int max_len); +char* tcore_util_convert_digit2ascii(const char* src, int src_len); +gboolean tcore_util_convert_utf8_to_gsm(unsigned char *dest, int *dest_len, unsigned char* src, int src_len); +gboolean tcore_util_convert_utf8_to_ucs2(char **dest, int *dest_len, unsigned char *src, int src_len); +gboolean tcore_util_convert_string_to_utf8(unsigned char *dest, unsigned short *dest_len, + enum alphabet_format dcs, const unsigned char *src, unsigned short src_len); +gboolean tcore_util_convert_ascii_to_utf8(unsigned char **dest, int *dest_len, unsigned char *src, int src_len); +int tcore_util_convert_ucs2_to_utf8(char *out, unsigned short *out_len, char *in, unsigned short in_len); + +void tcore_util_swap_byte_order(unsigned char* dest, const unsigned char* src, int src_len); + +char* tcore_util_get_version(void); +void tcore_util_set_log(gboolean enable); __END_DECLS diff --git a/libtcore.manifest b/libtcore.manifest new file mode 100644 index 0000000..dfdc35c --- /dev/null +++ b/libtcore.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/libtcore.spec b/packaging/libtcore.spec old mode 100644 new mode 100755 index 4d7c1bd..c3c2d98 --- a/packaging/libtcore.spec +++ b/packaging/libtcore.spec @@ -1,25 +1,27 @@ -#sbs-git:slp/pkgs/l/libtcore -Name: libtcore -Summary: Telephony-core library -Version: 0.1.61 -Release: 1 -Group: System/Libraries -License: Apache -Source0: libtcore-%{version}.tar.gz -Requires(post): /sbin/ldconfig -Requires(postun): /sbin/ldconfig +%define major 0 +%define minor 2 +%define patchlevel 59 + +Name: libtcore +Version: %{major}.%{minor}.%{patchlevel} +Release: 1 +License: Apache-2.0 +Summary: Telephony-core library +Group: System/Libraries +Source0: libtcore-%{version}.tar.gz BuildRequires: cmake BuildRequires: pkgconfig(glib-2.0) -BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(gudev-1.0) +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig %description Telephony-core library %package devel Summary: Telephony-core library (Development) -Requires: %{name} = %{version} Group: Development/Libraries +Requires: %{name} = %{version} %description devel Telephony-core library (Development) @@ -28,25 +30,32 @@ Telephony-core library (Development) %setup -q %build -cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -make %{?jobs:-j%jobs} +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DVERSION=%{version} \ +%ifarch %{arm} +%else + -DARCH_EMUL=1 \ +%endif -%post -/sbin/ldconfig +make %{?_smp_mflags} + +%post -p /sbin/ldconfig %postun -p /sbin/ldconfig %install -rm -rf %{buildroot} %make_install +mkdir -p %{buildroot}%{_datadir}/license %files +%manifest libtcore.manifest %defattr(-,root,root,-) #%doc COPYING %{_libdir}/libtcore* #%{_bindir}/* +%{_datadir}/license/libtcore %files devel %defattr(-,root,root,-) %{_includedir}/* %{_libdir}/pkgconfig/tcore.pc + diff --git a/src/at.c b/src/at.c index ee98332..1bcbcb8 100644 --- a/src/at.c +++ b/src/at.c @@ -1,3 +1,22 @@ +/* + * libtcore + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Ja-young Gu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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 @@ -11,8 +30,11 @@ #include "queue.h" #include "user_request.h" #include "at.h" +#include "core_object.h" #define NUM_ELEMS(x) (sizeof(x)/sizeof(x[0])) +#define MODE_HEX 0 +#define MODE_BIN 1 #define CR '\r' #define LF '\n' @@ -20,6 +42,8 @@ #define MAX_AT_RESPONSE 255 // for testing //#define MAX_AT_RESPONSE 8191 +typedef gboolean (*rfs_hook_cb) (const gchar *data); + struct tcore_at_type { TcoreHal *hal; @@ -38,6 +62,9 @@ struct tcore_at_type { gboolean pdu_status; struct _notification *pdu_noti; GSList *pdu_lines; + + rfs_hook_cb rfs_hook; + gboolean data_mode; }; struct _notification_callback { @@ -56,6 +83,7 @@ struct _notification { */ static const char *list_final_responses_success[] = { "OK", + "CONNECT", }; /** @@ -92,13 +120,22 @@ static int _check_final_response(const char *line) static char *_find_next_EOL(char *cur) { - if (cur[0] == '>' && cur[1] == ' ' && cur[2] == '\0') { + if ((cur[0] == '>' && cur[1] == ' ') + && (cur[2] == '\0' || cur[2] == CR)) { /* SMS prompt character...not \r terminated */ + dbg("SMS prompt character: [%c]", cur[0]); return cur + 2; } - // Find next newline - while (*cur != '\0' && *cur != CR) + /* + * Find next newline + * + * Line should either end with - + * - '\0' termination + * or + * - Carriage Return '\r' and Line Feed '\n'. + */ + while (*cur != '\0' && !((*cur == CR) && (*(cur + 1) == LF))) cur++; return *cur == '\0' ? NULL : cur; @@ -108,7 +145,7 @@ static struct tcore_at_response* _response_new() { struct tcore_at_response *resp; - resp = calloc(sizeof(struct tcore_at_response), 1); + resp = calloc(1, sizeof(struct tcore_at_response)); if (!resp) return NULL; @@ -149,16 +186,16 @@ static void _emit_pending_response(TcoreAT *at) if (!at) return; - tcore_at_request_free(at->req); - at->req = NULL; - p = tcore_queue_pop(tcore_hal_ref_queue(at->hal)); if (!p) { dbg("no pending"); } - tcore_pending_emit_response_callback(p, sizeof(TcoreATResponse *), at->resp); + tcore_pending_emit_response_callback(p, sizeof(TcoreATResponse), at->resp); tcore_user_request_unref(tcore_pending_ref_user_request(p)); + + tcore_at_request_free(at->req); + at->req = NULL; tcore_pending_free(p); _response_free(at->resp); @@ -178,6 +215,7 @@ static void _emit_unsolicited_message(TcoreAT *at, const char *line) if (!at || !line) return; + dbg("at->pdu_status %d line 0x%x at->data_mode %d", at->pdu_status, line, at->data_mode); if (at->pdu_status == FALSE) { g_hash_table_iter_init(&iter, at->unsolicited_table); @@ -200,13 +238,25 @@ static void _emit_unsolicited_message(TcoreAT *at, const char *line) return; } - data = g_slist_append(NULL, g_strdup(line)); + if (at->data_mode == MODE_BIN) { + at->pdu_lines = g_slist_append(at->pdu_lines, (gpointer)line); + data = at->pdu_lines; + } else { + data = g_slist_append(NULL, g_strdup(line)); + } } else { noti = at->pdu_noti; at->pdu_status = FALSE; at->pdu_noti = NULL; - at->pdu_lines = g_slist_append(at->pdu_lines, g_strdup(line)); + + if (at->data_mode == MODE_BIN) { + dbg("Binary mode"); + at->pdu_lines = g_slist_append(at->pdu_lines, (gpointer)line); + dbg("at->pdu_lines: 0x%x", at->pdu_lines); + } else { + at->pdu_lines = g_slist_append(at->pdu_lines, g_strdup(line)); + } data = at->pdu_lines; } @@ -229,14 +279,16 @@ static void _emit_unsolicited_message(TcoreAT *at, const char *line) p = p->next; } - - g_slist_free_full(data, g_free); + dbg(" Free the list"); + if (at->data_mode != MODE_BIN) { + g_slist_free_full(data, g_free); + } at->pdu_lines = NULL; if (g_slist_length(noti->callbacks) == 0) { g_hash_table_remove(at->unsolicited_table, key); } - + dbg("exit"); } static void _free_noti_list(void *data) @@ -291,16 +343,16 @@ TcoreAT *tcore_at_new(TcoreHal *hal) { TcoreAT *at; - at = calloc(sizeof(struct tcore_at_type), 1); + at = calloc(1, sizeof(struct tcore_at_type)); if (!at) return NULL; at->hal = hal; at->buf_size = MAX_AT_RESPONSE; - at->buf = calloc(at->buf_size + 1, 1); + at->buf = calloc(1, at->buf_size + 1); at->buf_read_pos = at->buf; at->buf_write_pos = at->buf; - + at->data_mode = MODE_HEX; at->unsolicited_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, _free_noti_list ); @@ -382,7 +434,7 @@ TReturn tcore_at_add_notification(TcoreAT *at, const char *prefix, noti = g_hash_table_lookup(at->unsolicited_table, prefix); if (!noti) { - noti = calloc(sizeof(struct _notification), 1); + noti = calloc(1, sizeof(struct _notification)); if (!noti) return TCORE_RETURN_ENOMEM; @@ -395,7 +447,7 @@ TReturn tcore_at_add_notification(TcoreAT *at, const char *prefix, if (noti->type_pdu != pdu) return TCORE_RETURN_EINVAL; - item = calloc(sizeof(struct _notification_callback), 1); + item = calloc(1, sizeof(struct _notification_callback)); if (!item) return TCORE_RETURN_ENOMEM; @@ -413,35 +465,46 @@ TReturn tcore_at_set_request(TcoreAT *at, TcoreATRequest *req, gboolean send) char *end; char next; - if (!at) + if (!at || !req) { + dbg("Invalid data"); return TCORE_RETURN_EINVAL; + } - at->req = req; - - if (req) { - dbg("req->cmd = [%s]", at->req->cmd); - dbg("req->prefix = [%s]", at->req->prefix); - dbg("req->type = %d", at->req->type); + if (!req->cmd) { + dbg("Invalid cmd"); + return TCORE_RETURN_EINVAL; } + at->req = req; + if (send == FALSE) return TCORE_RETURN_SUCCESS; - end = strchr(at->req->cmd, CR); - next = *(end + 1); - if (next == '\0') { +#ifdef EMULATOR + if (strstr(at->req->cmd, "CMGS")) { + dbg("In case of emulator, do not check CR for CMGS"); return tcore_hal_send_data(at->hal, strlen(req->cmd), req->cmd); } +#endif - dbg("backup data = [%c]", next); - at->req->next_send_pos = end + 1; - dbg("next data = [%s]", at->req->next_send_pos); + end = strchr(at->req->cmd, CR); + if(end) { + next = *(end + 1); + if (next == '\0') { + return tcore_hal_send_data(at->hal, strlen(req->cmd), req->cmd); + } - *(end+1) = '\0'; - ret = tcore_hal_send_data(at->hal, strlen(req->cmd), req->cmd); - *(end+1) = next; + at->req->next_send_pos = end + 1; + dbg("backup data = [%c] next data = [%s]", next, at->req->next_send_pos); - return ret; + *(end+1) = '\0'; + ret = tcore_hal_send_data(at->hal, strlen(req->cmd), req->cmd); + *(end+1) = next; + + return ret; + } else { + return TCORE_RETURN_EINVAL; + } } TcoreATRequest *tcore_at_get_request(TcoreAT *at) @@ -466,8 +529,10 @@ TReturn tcore_at_buf_write(TcoreAT *at, unsigned int data_len, const char *data) unsigned int read_pos; unsigned int write_pos; - if (!at) + if (!at) { + err("at is NULL"); return TCORE_RETURN_EINVAL; + } read_pos = at->buf_read_pos - at->buf; write_pos = at->buf_write_pos - at->buf; @@ -503,7 +568,6 @@ TReturn tcore_at_buf_write(TcoreAT *at, unsigned int data_len, const char *data) memcpy(at->buf_write_pos, data, data_len); at->buf_write_pos += data_len; - return TCORE_RETURN_SUCCESS; } @@ -517,7 +581,7 @@ TcoreATRequest* tcore_at_request_new(const char *cmd, const char *prefix, enum t if (strlen(cmd) < 1) return NULL; - req = calloc(sizeof(struct tcore_at_request), 1); + req = calloc(1, sizeof(struct tcore_at_request)); if (!req) return NULL; @@ -548,6 +612,48 @@ void tcore_at_request_free(TcoreATRequest *req) free(req); } +/* To get the length value from little-endian bytes */ +static int __sum_4_bytes(const char *posn) +{ + int sum = 0; + sum = sum | (*(posn+3)) << 24; + sum = sum | (*(posn+2)) << 16; + sum = sum | (*(posn+1)) << 8; + sum = sum | *posn ; + return sum; +} + +/* Function to process binary data received as part of XDRV Indication */ +void tcore_at_process_binary_data(TcoreAT *at, char *position, int data_len) +{ + + #define NVM_PAYLOAD_LENGTH_0 52 + #define NVM_PAYLOAD_LENGTH_1 68 + + int m_length_0 = ZERO , m_length_1 = ZERO; + static int data_len_final = ZERO, actual_buffer_size = ZERO; + dbg("Entered"); + + m_length_0 = __sum_4_bytes(&position[NVM_PAYLOAD_LENGTH_0]); + m_length_1 = __sum_4_bytes(&position[NVM_PAYLOAD_LENGTH_1]); + data_len_final = data_len_final + data_len; + + dbg("m_length_0 = %d , m_length_1 = %d, data_len_final = %d actual_buffer_size: %d", m_length_0, m_length_1, data_len_final, actual_buffer_size); + if (actual_buffer_size == ZERO) { + actual_buffer_size = data_len + m_length_0 + m_length_1; + dbg("Actual buffer size is %d", actual_buffer_size); + } + + if (data_len_final == actual_buffer_size) { + _emit_unsolicited_message(at, position); + at->data_mode = MODE_HEX; + at->buf_read_pos = at->buf_read_pos + (actual_buffer_size + 1); + data_len_final = ZERO; + actual_buffer_size = ZERO; + } + dbg("Exit"); +} + gboolean tcore_at_process(TcoreAT *at, unsigned int data_len, const char *data) { char *pos; @@ -560,6 +666,7 @@ gboolean tcore_at_process(TcoreAT *at, unsigned int data_len, const char *data) tcore_at_buf_write(at, data_len, data); pos = at->buf_read_pos; + dbg("On entry at->buf_read_pos: 0x%x", at->buf_read_pos); while (1) { @@ -567,8 +674,18 @@ gboolean tcore_at_process(TcoreAT *at, unsigned int data_len, const char *data) pos++; next_pos = _find_next_EOL(pos); - if (!next_pos) + if (!next_pos) { + dbg("Data could be in Binary mode !!"); + if (at->rfs_hook) { + if (TRUE == at->rfs_hook(pos)){ + at->data_mode = MODE_BIN; + tcore_at_process_binary_data(at, pos, data_len); + } + dbg("Not Binary data"); + }else + dbg("Rfs hook is not set !!"); break; + } if (pos != next_pos) *next_pos = '\0'; @@ -581,12 +698,11 @@ gboolean tcore_at_process(TcoreAT *at, unsigned int data_len, const char *data) _emit_unsolicited_message(at, pos); } else { - if (g_strcmp0(pos, "> ") == 0) { if (at->req->next_send_pos) { dbg("send next: [%s]", at->req->next_send_pos); tcore_hal_send_data(at->hal, strlen(at->req->next_send_pos), at->req->next_send_pos); - pos += 2; + pos += 3; /* Including NULL character */ at->buf_read_pos = pos; break; } @@ -594,6 +710,8 @@ gboolean tcore_at_process(TcoreAT *at, unsigned int data_len, const char *data) if (!at->resp) { at->resp = _response_new(); + if (!at->resp) + return FALSE; } ret = _check_final_response(pos); @@ -787,7 +905,9 @@ GSList *tcore_at_tok_new(const char *line) case TYPE_STR: if (*pos == '"') { type = TYPE_STR_FIN; - buf = calloc(pos - begin + 2, 1); + buf = calloc(1, (pos - begin) + 2); + if (!buf) + return NULL; memcpy(buf, begin, pos - begin + 1); tokens = g_slist_append(tokens, buf); } @@ -796,7 +916,9 @@ GSList *tcore_at_tok_new(const char *line) case TYPE_PAREN: if (*pos == ')') { type = TYPE_PAREN_FIN; - buf = calloc(pos - begin + 2, 1); + buf = calloc(1, (pos - begin) + 2); + if (!buf) + return NULL; memcpy(buf, begin, pos - begin + 1); tokens = g_slist_append(tokens, buf); } @@ -805,7 +927,9 @@ GSList *tcore_at_tok_new(const char *line) case TYPE_RAW: if (*pos == ',' || *pos == '\0') { type = TYPE_NONE; - buf = calloc(pos - begin + 1, 1); + buf = calloc(1, (pos - begin) + 1); + if (!buf) + return NULL; memcpy(buf, begin, pos - begin); tokens = g_slist_append(tokens, buf); } @@ -817,6 +941,9 @@ GSList *tcore_at_tok_new(const char *line) type = TYPE_NONE; } break; + default: + err("invalid string type"); + break; } if (*pos == '\0' || pos == mark_end) @@ -826,7 +953,9 @@ GSList *tcore_at_tok_new(const char *line) } while (1); if (type == TYPE_RAW) { - buf = calloc(pos - begin + 1, 1); + buf = calloc(1, (pos - begin) + 1); + if (!buf) + return NULL; memcpy(buf, begin, pos - begin); tokens = g_slist_append(tokens, buf); } @@ -888,3 +1017,81 @@ char *tcore_at_tok_nth(GSList *tokens, unsigned int token_index) return (char *)g_slist_nth_data(tokens, token_index); } + +gboolean tcore_at_add_hook(TcoreHal *hal, void *hook_func) +{ + TcoreAT *at; + at = tcore_hal_get_at(hal); + + if (at != NULL) { + dbg("Setting the rfs hook callback function"); + at->rfs_hook = (rfs_hook_cb) hook_func; + return TRUE; + } + dbg("AT is NULL !!!"); + return FALSE; +} + +void tcore_free_pending_timeout_at_request(TcoreAT *at) +{ + if (!at) + return; + + tcore_at_request_free(at->req); + at->req = NULL; +} + +TReturn tcore_prepare_and_send_at_request(CoreObject *co, + const char *at_cmd, + const char *at_cmd_prefix, + enum tcore_at_command_type at_cmd_type, + UserRequest *ur, + TcorePendingResponseCallback resp_cb, + void *resp_cb_data, + TcorePendingSendCallback send_cb, + void *send_cb_data, + unsigned int timeout, + TcorePendingTimeoutCallback timeout_cb, + void *timeout_cb_data) +{ + TcorePending *pending = NULL; + TcoreATRequest *req = NULL; + TcoreHal *hal = NULL; + TReturn ret = TCORE_RETURN_FAILURE; + + hal = tcore_object_get_hal(co); + if (!hal) { + dbg("HAL is NULL"); + return ret; + } + dbg("hal: [0x%x]", hal); + + /* Create Pending Request */ + pending = tcore_pending_new(co, 0); + if (!pending) { + dbg("Pending is NULL"); + return ret; + } + + /* Create AT-Command Request */ + req = tcore_at_request_new(at_cmd, at_cmd_prefix, at_cmd_type); + if (req == NULL) { + dbg("Request is NULL"); + tcore_pending_free(pending); + return ret; + } + dbg("AT Command: [%s], Prefix(if any): [%s], AT-Command length: [%d]", + req->cmd, req->prefix, strlen(req->cmd)); + + tcore_pending_set_request_data(pending, 0, req); + tcore_pending_set_response_callback(pending, resp_cb, resp_cb_data); + tcore_pending_set_send_callback(pending, send_cb, send_cb_data); + tcore_pending_set_timeout(pending, timeout); + tcore_pending_set_timeout_callback(pending, timeout_cb, timeout_cb_data); + tcore_pending_link_user_request(pending, ur); + + ret = tcore_hal_send_request(hal, pending); + dbg("ret: [0x%x]", ret); + return ret; +} + diff --git a/src/co_call.c b/src/co_call.c index 4fd6649..2566eb1 100644 --- a/src/co_call.c +++ b/src/co_call.c @@ -31,6 +31,8 @@ #include "co_call.h" +#define MAX_CALL_OBJECTS 6 + #define _check_null( name, value, err ) { \ if ( !value ) { \ dbg("[error] %s : NULL", name ); \ @@ -40,6 +42,7 @@ struct call_cli_info { enum tcore_call_cli_mode mode; + enum tcore_call_no_cli_cause no_cli_cause; char number[MAX_CALL_NUMBER_LEN]; int number_len; }; @@ -82,7 +85,7 @@ static void _clone_hook(CoreObject *src, CoreObject *dest) if (!src || !dest) return; - dest_po = calloc(sizeof(struct private_object_data), 1); + dest_po = g_try_new0(struct private_object_data, 1); if (!dest_po) { tcore_object_link_object(dest, NULL); return; @@ -120,56 +123,97 @@ static TReturn _dispatcher(CoreObject *o, UserRequest *ur) return po->ops->end(o, ur); case TREQ_CALL_HOLD: + _check_null( "po->ops->hold", po->ops->hold, TCORE_RETURN_FAILURE); return po->ops->hold(o, ur); case TREQ_CALL_ACTIVE: + _check_null( "po->ops->active", po->ops->active, TCORE_RETURN_FAILURE); return po->ops->active(o, ur); case TREQ_CALL_SWAP: + _check_null( "po->ops->swap", po->ops->swap, TCORE_RETURN_FAILURE); return po->ops->swap(o, ur); case TREQ_CALL_JOIN: + _check_null( "po->ops->join", po->ops->join, TCORE_RETURN_FAILURE); return po->ops->join(o, ur); case TREQ_CALL_SPLIT: + _check_null( "po->ops->split", po->ops->split, TCORE_RETURN_FAILURE); return po->ops->split(o, ur); case TREQ_CALL_DEFLECT: + _check_null( "po->ops->deflect", po->ops->deflect, TCORE_RETURN_FAILURE); return po->ops->deflect(o, ur); case TREQ_CALL_TRANSFER: + _check_null( "po->ops->transfer", po->ops->transfer, TCORE_RETURN_FAILURE); return po->ops->transfer(o, ur); - case TREQ_CALL_SEND_DTMF: - return po->ops->send_dtmf(o, ur); + case TREQ_CALL_START_CONT_DTMF: + _check_null( "po->ops->start_cont_dtmf", po->ops->start_cont_dtmf, TCORE_RETURN_FAILURE); + return po->ops->start_cont_dtmf(o, ur); + + case TREQ_CALL_STOP_CONT_DTMF: + _check_null( "po->ops->stop_cont_dtmf", po->ops->stop_cont_dtmf, TCORE_RETURN_FAILURE); + return po->ops->stop_cont_dtmf(o, ur); + + case TREQ_CALL_SEND_BURST_DTMF: + _check_null( "po->ops->send_burst_dtmf", po->ops->send_burst_dtmf, TCORE_RETURN_FAILURE); + return po->ops->send_burst_dtmf(o, ur); + + case TREQ_CALL_GET_PRIVACY_MODE: + _check_null( "po->ops->get_privacy_mode", po->ops->get_privacy_mode, TCORE_RETURN_FAILURE); + return po->ops->get_privacy_mode(o, ur); + + case TREQ_CALL_SET_PRIVACY_MODE: + _check_null( "po->ops->set_privacy_mode", po->ops->set_privacy_mode, TCORE_RETURN_FAILURE); + return po->ops->set_privacy_mode(o, ur); case TREQ_CALL_SET_SOUND_PATH: + _check_null( "po->ops->set_sound_path", po->ops->set_sound_path, TCORE_RETURN_FAILURE); return po->ops->set_sound_path(o, ur); case TREQ_CALL_GET_SOUND_VOLUME_LEVEL: + _check_null( "po->ops->get_sound_volume_level", po->ops->get_sound_volume_level, TCORE_RETURN_FAILURE); return po->ops->get_sound_volume_level(o, ur); case TREQ_CALL_SET_SOUND_VOLUME_LEVEL: + _check_null( "po->ops->set_sound_volume_level", po->ops->set_sound_volume_level, TCORE_RETURN_FAILURE); return po->ops->set_sound_volume_level(o, ur); - case TREQ_CALL_MUTE: - return po->ops->mute(o, ur); - - case TREQ_CALL_UNMUTE: - return po->ops->unmute(o, ur); + case TREQ_CALL_SET_SOUND_MUTE_STATUS: + _check_null( "po->ops->set_sound_mute_status", po->ops->set_sound_mute_status, TCORE_RETURN_FAILURE); + return po->ops->set_sound_mute_status(o, ur); - case TREQ_CALL_GET_MUTE_STATUS: - return po->ops->get_mute_status(o, ur); + case TREQ_CALL_GET_SOUND_MUTE_STATUS: + _check_null( "po->ops->get_sound_mute_status", po->ops->get_sound_mute_status, TCORE_RETURN_FAILURE); + return po->ops->get_sound_mute_status(o, ur); case TREQ_CALL_SET_SOUND_RECORDING: + _check_null( "po->ops->set_sound_recording", po->ops->set_sound_recording, TCORE_RETURN_FAILURE); return po->ops->set_sound_recording(o, ur); case TREQ_CALL_SET_SOUND_EQUALIZATION: + _check_null( "po->ops->set_sound_equalization", po->ops->set_sound_equalization, TCORE_RETURN_FAILURE); return po->ops->set_sound_equalization(o, ur); case TREQ_CALL_SET_SOUND_NOISE_REDUCTION: + _check_null( "po->ops->set_sound_noise_reduction", po->ops->set_sound_noise_reduction, TCORE_RETURN_FAILURE); return po->ops->set_sound_noise_reduction(o, ur); + case TREQ_CALL_SET_SOUND_CLOCK_STATUS: + _check_null( "po->ops->set_sound_clock_status", po->ops->set_sound_clock_status, TCORE_RETURN_FAILURE); + return po->ops->set_sound_clock_status(o, ur); + + case TREQ_CALL_SET_PREFERRED_VOICE_SUBSCRIPTION: + _check_null( "po->ops->set_preferred_voice_subscription", po->ops->set_preferred_voice_subscription, TCORE_RETURN_FAILURE); + return po->ops->set_preferred_voice_subscription(o, ur); + + case TREQ_CALL_GET_PREFERRED_VOICE_SUBSCRIPTION: + _check_null( "po->ops->get_preferred_voice_subscription", po->ops->get_preferred_voice_subscription, TCORE_RETURN_FAILURE); + return po->ops->get_preferred_voice_subscription(o, ur); + default: break; } @@ -180,28 +224,14 @@ static TReturn _dispatcher(CoreObject *o, UserRequest *ur) static void _free_hook(CoreObject *o) { struct private_object_data *po = NULL; - GSList *list; po = tcore_object_ref_object(o); if (!po) return; - if (po->cobjs) { - for (list = po->cobjs; list; list = list->next) { - if (!list) - continue; - - if (list->data) - free(list->data); - - list->data = NULL; - } - - g_slist_free(po->cobjs); - po->cobjs = NULL; - } + g_slist_free_full(po->cobjs, g_free); + g_free(po); - free(po); tcore_object_link_object(o, NULL); } @@ -321,19 +351,25 @@ struct call_object *tcore_call_object_new(CoreObject *o, int id) else { dbg("[ error ] call object exist already. [ %d ]", id); g_free(co); - return 0; + return NULL; } } else { int i = 0; - for (i = 1; i < 6; i++) { - // 6 is MAX call count + for (i = 1; i <= MAX_CALL_OBJECTS; i++) { /* 6 is MAX call count */ if (!_find_object(po->cobjs, (void*) &i, (void*) _compare_by_id)) { co->id = i; break; } } + + /* Free the allocated Core Object if ID is not allocated */ + if (i > MAX_CALL_OBJECTS) { + err("[ error ] failed to assign call id"); + g_free(co); + return NULL; + } } po->cobjs = g_slist_append(po->cobjs, co); @@ -353,24 +389,29 @@ gboolean tcore_call_object_free(CoreObject *o, struct call_object *co) _check_null( "co", co, FALSE); po->cobjs = g_slist_remove(po->cobjs, co); - - if (!co) { - dbg("co is not free"); - g_free(co); - } - else - dbg("co is also free"); + g_free(co); return TRUE; } +int tcore_call_object_total_length( CoreObject *o ) +{ + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + + _check_null( "po", po, FALSE); + _check_null( "po->cobjs", po->cobjs, FALSE); + + return (int)g_slist_length(po->cobjs); +} + struct call_object *tcore_call_object_current_on_mt_processing(CoreObject *o) { struct private_object_data *po = NULL; + struct call_object *call_obj = NULL; GSList *l = 0; enum tcore_call_status cs = CALL_STATUS_INCOMING; - po = tcore_object_ref_object(o); _check_null( "po", po, 0); @@ -384,16 +425,18 @@ struct call_object *tcore_call_object_current_on_mt_processing(CoreObject *o) return 0; } - return (struct call_object*) l->data; + call_obj = (struct call_object*) l ->data; + g_slist_free(l); + return call_obj; } struct call_object *tcore_call_object_current_on_mo_processing(CoreObject *o) { struct private_object_data *po = NULL; + struct call_object *call_obj = NULL; GSList *l = 0; enum tcore_call_status cs = CALL_STATUS_DIALING; - po = tcore_object_ref_object(o); _check_null( "po", po, 0); @@ -407,7 +450,9 @@ struct call_object *tcore_call_object_current_on_mo_processing(CoreObject *o) return 0; } - return (struct call_object*) l->data; + call_obj = (struct call_object*) l ->data; + g_slist_free(l); + return call_obj; } struct call_object *tcore_call_object_find_by_id(CoreObject *o, int id) @@ -499,38 +544,53 @@ enum tcore_call_status tcore_call_object_get_status(struct call_object *co) return co->status; } -gboolean tcore_call_object_set_cli_info(struct call_object *co, enum tcore_call_cli_mode mode, char *num) +gboolean tcore_call_object_set_cli_info(struct call_object *co, + enum tcore_call_cli_mode mode, enum tcore_call_no_cli_cause cause, + char *num, int num_len) { char *pos = 0; _check_null( "co", co, FALSE); + dbg("num : %s", num); + dbg("mode : 0x%x", mode); + if (!num) { co->cli.mode = mode; + if (mode == TCORE_CALL_CLI_MODE_RESTRICT) + co->cli.no_cli_cause = cause; + else + co->cli.no_cli_cause = TCORE_CALL_NO_CLI_CAUSE_NONE; + + co->cli.number_len = num_len ; + co->cli.number [0] = '\0'; + return TRUE; } - dbg("num : %s", num); - dbg("mode : 0x%x", mode); - pos = num; - if (!mode) { + if (mode == TCORE_CALL_CLI_MODE_DEFAULT) { co->cli.mode = _check_cli_mode_by_number(num); - if (co->cli.mode) + if (co->cli.mode != TCORE_CALL_CLI_MODE_DEFAULT) pos = (num + 4); } else { co->cli.mode = mode; + if (mode == TCORE_CALL_CLI_MODE_RESTRICT) + co->cli.no_cli_cause = cause; + else + co->cli.no_cli_cause = TCORE_CALL_NO_CLI_CAUSE_NONE; } - strncpy(co->cli.number, pos, (strlen(pos) + 1)); + strncpy(co->cli.number, pos, ((num_len - (pos - num)) + 1)); co->cli.number_len = strlen(co->cli.number); - dbg("co->cli.mode : 0x%x", co->cli.mode); - dbg("co->cli.number : %s", co->cli.number); - dbg("co->cli.number_len : %d", co->cli.number_len); + dbg("co->cli.mode: [0x%x]", co->cli.mode); + dbg("co->cli.no_cli_cause: [0x%x]", co->cli.no_cli_cause); + dbg("co->cli.number: [%s]", co->cli.number); + dbg("co->cli.number_len: [%d]", co->cli.number_len); return TRUE; } @@ -550,13 +610,28 @@ enum tcore_call_cli_mode tcore_call_object_get_cli_mode(struct call_object *co) return co->cli.mode; } +enum tcore_call_no_cli_cause tcore_call_object_get_no_cli_cause(struct call_object *co) +{ + _check_null( "co", co, -1); + return co->cli.no_cli_cause; +} + + gboolean tcore_call_object_set_cna_info(struct call_object *co, enum tcore_call_cna_mode mode, char *name, int dcs) { + int len; _check_null( "co", co, FALSE); _check_null( "name", name, FALSE); + len = strlen(name); + if (len >= MAX_CALL_NAME_LEN) + return FALSE; + + strncpy(co->cna.name, name, len); + co->cna.name[len] = '\0'; + co->cna.mode = mode; - strncpy(co->cna.name, name, MAX_CALL_NAME_LEN); + return TRUE; } @@ -611,8 +686,8 @@ TReturn tcore_call_control_answer_hold_and_accept(CoreObject* o, UserRequest* ur struct private_object_data *po = NULL; po = tcore_object_ref_object(o); - if (!po && !po->cops) - return TCORE_RETURN_FAILURE; + _check_null( "po", po, TCORE_RETURN_FAILURE); + _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE); return po->cops->answer_hold_and_accept(o, ur, cb, user_data); } @@ -622,8 +697,8 @@ TReturn tcore_call_control_answer_replace(CoreObject* o, UserRequest* ur, Confir struct private_object_data *po = NULL; po = tcore_object_ref_object(o); - if (!po && !po->cops) - return TCORE_RETURN_FAILURE; + _check_null( "po", po, TCORE_RETURN_FAILURE); + _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE); return po->cops->answer_replace(o, ur, cb, user_data); } @@ -633,8 +708,8 @@ TReturn tcore_call_control_answer_reject(CoreObject* o, UserRequest* ur, Confirm struct private_object_data *po = NULL; po = tcore_object_ref_object(o); - if (!po && !po->cops) - return TCORE_RETURN_FAILURE; + _check_null( "po", po, TCORE_RETURN_FAILURE); + _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE); return po->cops->answer_reject(o, ur, cb, user_data); } @@ -645,8 +720,8 @@ TReturn tcore_call_control_end_specific(CoreObject* o, UserRequest* ur, const in struct private_object_data *po = NULL; po = tcore_object_ref_object(o); - if (!po && !po->cops) - return TCORE_RETURN_FAILURE; + _check_null( "po", po, TCORE_RETURN_FAILURE); + _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE); return po->cops->end_specific(o, ur, id, cb, user_data); } @@ -656,8 +731,8 @@ TReturn tcore_call_control_end_all_active(CoreObject* o, UserRequest* ur, Confir struct private_object_data *po = NULL; po = tcore_object_ref_object(o); - if (!po && !po->cops) - return TCORE_RETURN_FAILURE; + _check_null( "po", po, TCORE_RETURN_FAILURE); + _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE); return po->cops->end_all_active(o, ur, cb, user_data); } @@ -667,8 +742,8 @@ TReturn tcore_call_control_end_all_held(CoreObject* o, UserRequest* ur, ConfirmC struct private_object_data *po = NULL; po = tcore_object_ref_object(o); - if (!po && !po->cops) - return TCORE_RETURN_FAILURE; + _check_null( "po", po, TCORE_RETURN_FAILURE); + _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE); return po->cops->end_all_held(o, ur, cb, user_data); } @@ -678,8 +753,8 @@ TReturn tcore_call_control_active(CoreObject* o, UserRequest* ur, ConfirmCallbac struct private_object_data *po = NULL; po = tcore_object_ref_object(o); - if (!po && !po->cops) - return TCORE_RETURN_FAILURE; + _check_null( "po", po, TCORE_RETURN_FAILURE); + _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE); return po->cops->active(o, ur, cb, user_data); } @@ -689,8 +764,8 @@ TReturn tcore_call_control_hold(CoreObject* o, UserRequest* ur, ConfirmCallback struct private_object_data *po = NULL; po = tcore_object_ref_object(o); - if (!po && !po->cops) - return TCORE_RETURN_FAILURE; + _check_null( "po", po, TCORE_RETURN_FAILURE); + _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE); return po->cops->hold(o, ur, cb, user_data); } @@ -700,8 +775,8 @@ TReturn tcore_call_control_swap(CoreObject* o, UserRequest* ur, ConfirmCallback struct private_object_data *po = NULL; po = tcore_object_ref_object(o); - if (!po && !po->cops) - return TCORE_RETURN_FAILURE; + _check_null( "po", po, TCORE_RETURN_FAILURE); + _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE); return po->cops->swap(o, ur, cb, user_data); } @@ -711,8 +786,8 @@ TReturn tcore_call_control_join(CoreObject* o, UserRequest* ur, ConfirmCallback struct private_object_data *po = NULL; po = tcore_object_ref_object(o); - if (!po && !po->cops) - return TCORE_RETURN_FAILURE; + _check_null( "po", po, TCORE_RETURN_FAILURE); + _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE); return po->cops->join(o, ur, cb, user_data); } @@ -722,8 +797,8 @@ TReturn tcore_call_control_split(CoreObject* o, UserRequest* ur, const int id, C struct private_object_data *po = NULL; po = tcore_object_ref_object(o); - if (!po && !po->cops) - return TCORE_RETURN_FAILURE; + _check_null( "po", po, TCORE_RETURN_FAILURE); + _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE); return po->cops->split(o, ur, id, cb, user_data); } @@ -733,8 +808,8 @@ TReturn tcore_call_control_transfer(CoreObject* o, UserRequest* ur, ConfirmCallb struct private_object_data *po = NULL; po = tcore_object_ref_object(o); - if (!po && !po->cops) - return TCORE_RETURN_FAILURE; + _check_null( "po", po, TCORE_RETURN_FAILURE); + _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE); return po->cops->transfer(o, ur, cb, user_data); } @@ -745,8 +820,8 @@ TReturn tcore_call_control_deflect(CoreObject* o, UserRequest* ur, const char* n struct private_object_data *po = NULL; po = tcore_object_ref_object(o); - if (!po && !po->cops) - return TCORE_RETURN_FAILURE; + _check_null( "po", po, TCORE_RETURN_FAILURE); + _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE); return po->cops->deflect(o, ur, number, cb, user_data); } @@ -772,8 +847,8 @@ void tcore_call_information_mo_col(CoreObject *o, char* number) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po, ); + _check_null( "po->iops", po->iops,); po->iops->mo_call_col(o, number); } @@ -786,8 +861,8 @@ void tcore_call_information_mo_waiting(CoreObject *o) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po, ); + _check_null( "po->iops", po->iops,); po->iops->mo_call_waiting(o); } @@ -800,8 +875,8 @@ void tcore_call_information_mo_cug(CoreObject *o, int cug_index) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po, ); + _check_null( "po->iops", po->iops,); po->iops->mo_call_cug(o, cug_index); } @@ -814,8 +889,8 @@ void tcore_call_information_mo_forwarded(CoreObject *o) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->mo_call_forwarded(o); } @@ -828,8 +903,8 @@ void tcore_call_information_mo_barred_incoming(CoreObject *o) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->mo_call_barred_incoming(o); } @@ -842,8 +917,8 @@ void tcore_call_information_mo_barred_outgoing(CoreObject *o) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->mo_call_barred_outgoing(o); } @@ -856,8 +931,8 @@ void tcore_call_information_mo_deflected(CoreObject *o) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->mo_call_deflected(o); } @@ -870,8 +945,8 @@ void tcore_call_information_mo_clir_suppression_reject(CoreObject *o) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->mo_call_clir_suppression_reject(o); } @@ -884,8 +959,8 @@ void tcore_call_information_mo_cfu(CoreObject *o) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->mo_call_cfu(o); } @@ -898,8 +973,8 @@ void tcore_call_information_mo_cfc(CoreObject *o) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->mo_call_cfc(o); } @@ -912,8 +987,8 @@ void tcore_call_information_mt_cli(CoreObject *o, enum tcore_call_cli_mode mode, po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po, ); + _check_null( "po->iops", po->iops,); po->iops->mt_call_cli(o, mode, number); } @@ -926,8 +1001,8 @@ void tcore_call_information_mt_cna(CoreObject *o, enum tcore_call_cna_mode mode, po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->mt_call_cna(o, mode, name, dcs); } @@ -940,8 +1015,8 @@ void tcore_call_information_mt_forwarded_call(CoreObject *o, char* number) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->mt_call_forwarded_call(o, number); } @@ -954,8 +1029,8 @@ void tcore_call_information_mt_cug_call(CoreObject *o, int cug_index, char* numb po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->mt_call_cug_call(o, cug_index, number); } @@ -968,8 +1043,8 @@ void tcore_call_information_mt_deflected_call(CoreObject *o, char* number) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->mt_call_deflected_call(o, number); } @@ -982,8 +1057,8 @@ void tcore_call_information_mt_transfered(CoreObject *o, char* number) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->mt_call_transfered(o, number); } @@ -996,8 +1071,8 @@ void tcore_call_information_held(CoreObject *o, char* number) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->call_held(o, number); } @@ -1010,8 +1085,8 @@ void tcore_call_information_active(CoreObject *o, char* number) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->call_active(o, number); } @@ -1024,8 +1099,8 @@ void tcore_call_information_joined(CoreObject *o, char* number) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->call_joined(o, number); } @@ -1038,8 +1113,8 @@ void tcore_call_information_released_on_hold(CoreObject *o, char* number) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->call_released_on_hold(o, number); } @@ -1052,8 +1127,8 @@ void tcore_call_information_transfer_alert(CoreObject *o, char* number) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->call_transfer_alert(o, number); } @@ -1066,8 +1141,8 @@ void tcore_call_information_transfered(CoreObject *o, char* number) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->call_transfered(o, number); } @@ -1080,8 +1155,8 @@ void tcore_call_information_cf_check_ss_message(CoreObject *o, char* number) po = tcore_object_ref_object(o); - if (!po && !po->iops) - return; + _check_null( "po", po,); + _check_null( "po->iops", po->iops,); po->iops->call_cf_check_message(o, number); } @@ -1111,8 +1186,8 @@ CoreObject *tcore_call_new(TcorePlugin *p, const char *name, struct tcore_call_o if (!o) return NULL; - po = calloc(sizeof(struct private_object_data), 1); - if (!po) { + po = g_try_new0(struct private_object_data, 1); + if (po == NULL) { tcore_object_free(o); return NULL; } @@ -1130,14 +1205,20 @@ CoreObject *tcore_call_new(TcorePlugin *p, const char *name, struct tcore_call_o void tcore_call_free(CoreObject *o) { + CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL); + tcore_object_free(o); +} + +void tcore_call_set_ops(CoreObject *o, struct tcore_call_operations *ops) +{ struct private_object_data *po = NULL; CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL); - po = tcore_object_ref_object(o); - if (!po) + po = (struct private_object_data *)tcore_object_ref_object(o); + if (!po) { return; + } - free(po); - tcore_object_free(o); + po->ops = ops; } diff --git a/src/co_context.c b/src/co_context.c index 3f1596c..60f3699 100644 --- a/src/co_context.c +++ b/src/co_context.c @@ -32,7 +32,7 @@ struct private_object_data { enum co_context_state state; - unsigned int id; + unsigned char id; enum co_context_role role; char *apn; @@ -53,6 +53,11 @@ struct private_object_data { union tcore_ip4_type dns_secondary_v4; /*IPv6 will be supported*/ + char* ip_v6; + char* gateway_v6; + char* dns_primary_v6; + char* dns_secondary_v6; + char *proxy; char *mmsurl; @@ -66,7 +71,7 @@ static void _free_hook(CoreObject *o) po = tcore_object_ref_object(o); if (po) { - g_free(po); + free(po); tcore_object_link_object(o, NULL); } } @@ -83,7 +88,7 @@ CoreObject *tcore_context_new(TcorePlugin *p, const char *name, TcoreHal *hal) if (!o) return NULL; - po = calloc(sizeof(struct private_object_data), 1); + po = calloc(1, sizeof(struct private_object_data)); if (!po) { tcore_object_free(o); return NULL; @@ -104,16 +109,7 @@ CoreObject *tcore_context_new(TcorePlugin *p, const char *name, TcoreHal *hal) void tcore_context_free(CoreObject *o) { - struct private_object_data *po = NULL; - CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS_CONTEXT); - - po = tcore_object_ref_object(o); - if (!po) - return; - - g_free(po); - tcore_object_link_object(o, NULL); tcore_object_free(o); } @@ -145,7 +141,7 @@ enum co_context_state tcore_context_get_state(CoreObject *o) return po->state; } -TReturn tcore_context_set_id(CoreObject *o, unsigned int id) +TReturn tcore_context_set_id(CoreObject *o, unsigned char id) { struct private_object_data *po = NULL; @@ -160,7 +156,7 @@ TReturn tcore_context_set_id(CoreObject *o, unsigned int id) return TCORE_RETURN_SUCCESS; } -unsigned int tcore_context_get_id(CoreObject *o) +unsigned char tcore_context_get_id(CoreObject *o) { struct private_object_data *po = NULL; @@ -667,6 +663,10 @@ TReturn tcore_context_set_devinfo(CoreObject *o, struct tnoti_ps_pdp_ipconfigura if (!devinfo) return FALSE; + po->ip_v6 = g_strdup((gchar *)devinfo->ipv6_address); + po->dns_primary_v6 = g_strdup((gchar *)devinfo->ipv6_primary_dns); + po->dns_secondary_v6 = g_strdup((gchar *)devinfo->ipv6_secondary_dns); + po->gateway_v6 = g_strdup((gchar *)devinfo->ipv6_gateway); memcpy(&(po->ip_v4), devinfo->ip_address, sizeof(union tcore_ip4_type)); memcpy(&(po->dns_primary_v4), devinfo->primary_dns, sizeof(union tcore_ip4_type)); memcpy(&(po->dns_secondary_v4), devinfo->secondary_dns, sizeof(union tcore_ip4_type)); @@ -686,6 +686,18 @@ TReturn tcore_context_reset_devinfo(CoreObject *o) if (!po) return FALSE; + if(po->ip_v6) g_free(po->ip_v6); + po->ip_v6 = NULL; + + if(po->dns_primary_v6) g_free(po->dns_primary_v6); + po->dns_primary_v6 = NULL; + + if(po->dns_secondary_v6) g_free(po->dns_secondary_v6); + po->dns_secondary_v6 = NULL; + + if(po->gateway_v6) g_free(po->gateway_v6); + po->gateway_v6 = NULL; + memset(&(po->ip_v4), 0, sizeof(union tcore_ip4_type)); memset(&(po->dns_primary_v4), 0, sizeof(union tcore_ip4_type)); memset(&(po->dns_secondary_v4), 0, sizeof(union tcore_ip4_type)); @@ -708,6 +720,12 @@ void tcore_context_cp_service_info(CoreObject *dest, CoreObject *src) d_po->state = s_po->state; d_po->id = s_po->id; + + d_po->ip_v6 = g_strdup(s_po->ip_v6); + d_po->dns_primary_v6 = g_strdup(s_po->dns_primary_v6); + d_po->dns_secondary_v6 = g_strdup(s_po->dns_secondary_v6); + d_po->gateway_v6 = g_strdup(s_po->gateway_v6); + memcpy(&(d_po->ip_v4), &(s_po->ip_v4), sizeof(union tcore_ip4_type)); memcpy(&(d_po->dns_primary_v4), &(s_po->dns_primary_v4), sizeof(union tcore_ip4_type)); memcpy(&(d_po->dns_secondary_v4), &(s_po->dns_secondary_v4), sizeof(union tcore_ip4_type)); @@ -779,8 +797,60 @@ char* tcore_context_get_ipv4_devname(CoreObject *o) if (!po) return NULL; - if (!po->devname) + if (po->devname[0] == 0) return NULL; return g_strdup(po->devname); } + +char* tcore_context_get_ipv6_addr(CoreObject *o) +{ + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL); + + po = tcore_object_ref_object(o); + if (!po) + return NULL; + + return po->ip_v6; +} + +char* tcore_context_get_ipv6_dns1(CoreObject *o) +{ + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL); + + po = tcore_object_ref_object(o); + if (!po) + return NULL; + + return po->dns_primary_v6; +} + +char* tcore_context_get_ipv6_dns2(CoreObject *o) +{ + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL); + + po = tcore_object_ref_object(o); + if (!po) + return NULL; + + return po->dns_secondary_v6; +} + +char* tcore_context_get_ipv6_gw(CoreObject *o) +{ + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS_CONTEXT, NULL); + + po = tcore_object_ref_object(o); + if (!po) + return NULL; + + return po->gateway_v6; +} diff --git a/src/co_custom.c b/src/co_custom.c new file mode 100644 index 0000000..c9b6284 --- /dev/null +++ b/src/co_custom.c @@ -0,0 +1,64 @@ +/* + * custom + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Anga Santhosh Kumar + * + * 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 "tcore.h" +#include "core_object.h" +#include "co_custom.h" + +static void _free_hook(CoreObject *co) +{ + CORE_OBJECT_CHECK(co, CORE_OBJECT_TYPE_CUSTOM); + + tcore_object_link_object(co, NULL); +} + +CoreObject *tcore_custom_new(TcorePlugin *p, + const char *name, tcore_custom_operations ops, + CoreObjectDispatcher dispatcher, TcoreHal *hal) +{ + CoreObject *co = NULL; + + if (!p) + return NULL; + + co = tcore_object_new(p, name, hal); + if (!co) + return NULL; + + tcore_object_set_type(co, CORE_OBJECT_TYPE_CUSTOM); + + tcore_object_link_object(co, ops); + tcore_object_set_free_hook(co, _free_hook); + tcore_object_set_dispatcher(co, dispatcher); + + return co; +} + +void tcore_custom_free(CoreObject *co) +{ + CORE_OBJECT_CHECK(co, CORE_OBJECT_TYPE_CUSTOM); + + tcore_object_free(co); +} diff --git a/src/co_gps.c b/src/co_gps.c old mode 100755 new mode 100644 index 4134089..761c42d --- a/src/co_gps.c +++ b/src/co_gps.c @@ -33,6 +33,17 @@ struct private_object_data { struct tcore_gps_operations *ops; }; +static void _free_hook(CoreObject *o) +{ + struct private_object_data *po = NULL; + + po = tcore_object_ref_object(o); + if (po) { + free(po); + tcore_object_link_object(o, NULL); + } +} + static void _clone_hook(CoreObject *src, CoreObject *dest) { struct private_object_data *src_po = NULL; @@ -41,7 +52,7 @@ static void _clone_hook(CoreObject *src, CoreObject *dest) if (!src || !dest) return; - dest_po = calloc(sizeof(struct private_object_data), 1); + dest_po = calloc(1, sizeof(struct private_object_data)); if (!dest_po) { tcore_object_link_object(dest, NULL); return; @@ -73,7 +84,63 @@ static TReturn _dispatcher(CoreObject *o, UserRequest *ur) return TCORE_RETURN_ENOSYS; return po->ops->confirm_measure_pos(o, ur); - break; + + case TREQ_GPS_SET_FREQUENCY_AIDING: + dbg("TREQ_GPS_SET_FREQUENCY_AIDING"); + if (!po->ops->set_frequency_aiding) + return TCORE_RETURN_ENOSYS; + + return po->ops->set_frequency_aiding(o, ur); + + case TREQ_ENABLE_SMART_ASSISTANT: + dbg("TREQ_ENABLE_SMART_ASSISTANT"); + if (!po->ops->enable_smart_assistant) + return TCORE_RETURN_ENOSYS; + + return po->ops->enable_smart_assistant(o, ur); + + case TREQ_DISABLE_SMART_ASSISTANT: + dbg("TREQ_DISABLE_SMART_ASSISTANT"); + if (!po->ops->disable_smart_assistant) + return TCORE_RETURN_ENOSYS; + + return po->ops->disable_smart_assistant(o, ur); + + case TREQ_SYNC_SMART_ASSISTANT_AREA_LIST: + dbg("TREQ_SYNC_SMART_ASSISTANT_AREA_LIST"); + if (!po->ops->sync_smart_assistant_area_list) + return TCORE_RETURN_ENOSYS; + + return po->ops->sync_smart_assistant_area_list(o, ur); + + case TREQ_DEL_SMART_ASSISTANT_AREA_LIST: + dbg("TREQ_DEL_SMART_ASSISTANT_AREA_LIST"); + if (!po->ops->del_smart_assistant_area_list) + return TCORE_RETURN_ENOSYS; + + return po->ops->del_smart_assistant_area_list(o, ur); + + case TREQ_ADD_SMART_ASSISTANT_AREA: + dbg("TREQ_ADD_SMART_ASSISTANT_AREA"); + if (!po->ops->add_smart_assistant_area) + return TCORE_RETURN_ENOSYS; + + return po->ops->add_smart_assistant_area(o, ur); + + case TREQ_MODIFY_SMART_ASSISTANT_AREA: + dbg("TREQ_MODIFY_SMART_ASSISTANT_AREA"); + if (!po->ops->modify_smart_assistant_area) + return TCORE_RETURN_ENOSYS; + + return po->ops->modify_smart_assistant_area(o, ur); + + case TREQ_SET_SMART_ASSISTANT_INFO: + dbg("TREQ_SET_SMART_ASSISTANT_INFO"); + if (!po->ops->set_smart_assistant_info) + return TCORE_RETURN_ENOSYS; + + return po->ops->set_smart_assistant_info(o, ur); + default: dbg("not supported cmd"); break; @@ -94,7 +161,7 @@ CoreObject *tcore_gps_new(TcorePlugin *p, const char *name, if (!o) return NULL; - po = calloc(sizeof(struct private_object_data), 1); + po = calloc(1, sizeof(struct private_object_data)); if (!po) { tcore_object_free(o); return NULL; @@ -105,6 +172,7 @@ CoreObject *tcore_gps_new(TcorePlugin *p, const char *name, tcore_object_set_type(o, CORE_OBJECT_TYPE_GPS); tcore_object_link_object(o, po); tcore_object_set_dispatcher(o, _dispatcher); + tcore_object_set_free_hook(o, _free_hook); tcore_object_set_clone_hook(o, _clone_hook); return o; @@ -112,16 +180,21 @@ CoreObject *tcore_gps_new(TcorePlugin *p, const char *name, void tcore_gps_free(CoreObject *o) { + CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_GPS); + + tcore_object_free(o); +} + +void tcore_gps_set_ops(CoreObject *o, struct tcore_gps_operations *ops) +{ struct private_object_data *po = NULL; CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_GPS); - po = tcore_object_ref_object(o); - if (!po) + po = (struct private_object_data *)tcore_object_ref_object(o); + if (!po) { return; + } - g_free(po); - tcore_object_link_object(o, po); - tcore_object_free(o); + po->ops = ops; } - diff --git a/src/co_modem.c b/src/co_modem.c index 88960f3..ca1662a 100644 --- a/src/co_modem.c +++ b/src/co_modem.c @@ -56,7 +56,7 @@ static void _clone_hook(CoreObject *src, CoreObject *dest) if (!src || !dest) return; - dest_po = calloc(sizeof(struct private_object_data), 1); + dest_po = calloc(1, sizeof(struct private_object_data)); if (!dest_po) { tcore_object_link_object(dest, NULL); return; @@ -102,6 +102,13 @@ static TReturn _dispatcher(CoreObject *o, UserRequest *ur) return po->ops->power_reset(o, ur); break; + case TREQ_MODEM_POWER_LOW: + if (!po->ops->power_low) + return TCORE_RETURN_ENOSYS; + + return po->ops->power_low(o, ur); + break; + case TREQ_MODEM_SET_FLIGHTMODE: if (!po->ops->set_flight_mode) return TCORE_RETURN_ENOSYS; @@ -137,6 +144,13 @@ static TReturn _dispatcher(CoreObject *o, UserRequest *ur) return po->ops->dun_pin_ctrl(o, ur); break; + case TREQ_MODEM_GET_FLIGHTMODE: + if (!po->ops->get_flight_mode) + return TCORE_RETURN_ENOSYS; + + return po->ops->get_flight_mode(o, ur); + break; + default: return TCORE_RETURN_EINVAL; } @@ -157,7 +171,7 @@ CoreObject *tcore_modem_new(TcorePlugin *p, const char *name, if (!o) return NULL; - po = calloc(sizeof(struct private_object_data), 1); + po = calloc(1, sizeof(struct private_object_data)); if (!po) { tcore_object_free(o); return NULL; @@ -176,16 +190,22 @@ CoreObject *tcore_modem_new(TcorePlugin *p, const char *name, void tcore_modem_free(CoreObject *o) { + CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_MODEM); + tcore_object_free(o); +} + +void tcore_modem_set_ops(CoreObject *o, struct tcore_modem_operations *ops) +{ struct private_object_data *po = NULL; CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_MODEM); - po = tcore_object_ref_object(o); - if (!po) + po = (struct private_object_data *)tcore_object_ref_object(o); + if (!po) { return; + } - free(po); - tcore_object_free(o); + po->ops = ops; } TReturn tcore_modem_set_flight_mode_state(CoreObject *o, gboolean flag) @@ -200,7 +220,7 @@ TReturn tcore_modem_set_flight_mode_state(CoreObject *o, gboolean flag) po->flight_mode = flag; - return TRUE; + return TCORE_RETURN_SUCCESS; } gboolean tcore_modem_get_flight_mode_state(CoreObject *o) @@ -228,7 +248,7 @@ TReturn tcore_modem_set_powered(CoreObject *o, gboolean pwr) tcore_hal_set_power_state(h, pwr); - return TRUE; + return TCORE_RETURN_SUCCESS; } gboolean tcore_modem_get_powered(CoreObject *o) diff --git a/src/co_network.c b/src/co_network.c index 90afedd..55602b1 100644 --- a/src/co_network.c +++ b/src/co_network.c @@ -39,16 +39,17 @@ struct private_object_data { enum telephony_network_service_domain_status ps_domain_status; char *plmn; gboolean roaming_state; + int restricted_state; unsigned int lac; unsigned int rac; unsigned int cell_id; + gboolean gsm_dtm_support; // DTM (Dual Transfer Mode) char *network_name_short; char *network_name_full; char *network_name_spn; enum tcore_network_name_priority network_name_priority; - - GSList *network_operator_info_table[1000]; + GHashTable *operator_info_hash; }; static TReturn _dispatcher(CoreObject *co, UserRequest *ur) @@ -69,119 +70,162 @@ static TReturn _dispatcher(CoreObject *co, UserRequest *ur) return TCORE_RETURN_ENOSYS; return po->ops->search(co, ur); - break; case TREQ_NETWORK_SET_PLMN_SELECTION_MODE: if (!po->ops->set_plmn_selection_mode) return TCORE_RETURN_ENOSYS; return po->ops->set_plmn_selection_mode(co, ur); - break; case TREQ_NETWORK_GET_PLMN_SELECTION_MODE: if (!po->ops->get_plmn_selection_mode) return TCORE_RETURN_ENOSYS; return po->ops->get_plmn_selection_mode(co, ur); - break; case TREQ_NETWORK_SET_SERVICE_DOMAIN: if (!po->ops->set_service_domain) return TCORE_RETURN_ENOSYS; return po->ops->set_service_domain(co, ur); - break; case TREQ_NETWORK_GET_SERVICE_DOMAIN: if (!po->ops->get_service_domain) return TCORE_RETURN_ENOSYS; return po->ops->get_service_domain(co, ur); - break; case TREQ_NETWORK_SET_BAND: if (!po->ops->set_band) return TCORE_RETURN_ENOSYS; return po->ops->set_band(co, ur); - break; case TREQ_NETWORK_GET_BAND: if (!po->ops->get_band) return TCORE_RETURN_ENOSYS; return po->ops->get_band(co, ur); - break; case TREQ_NETWORK_SET_PREFERRED_PLMN: if (!po->ops->set_preferred_plmn) return TCORE_RETURN_ENOSYS; return po->ops->set_preferred_plmn(co, ur); - break; case TREQ_NETWORK_GET_PREFERRED_PLMN: if (!po->ops->get_preferred_plmn) return TCORE_RETURN_ENOSYS; return po->ops->get_preferred_plmn(co, ur); - break; case TREQ_NETWORK_SET_ORDER: if (!po->ops->set_order) return TCORE_RETURN_ENOSYS; return po->ops->set_order(co, ur); - break; case TREQ_NETWORK_GET_ORDER: if (!po->ops->get_order) return TCORE_RETURN_ENOSYS; return po->ops->get_order(co, ur); - break; case TREQ_NETWORK_SET_POWER_ON_ATTACH: if (!po->ops->set_power_on_attach) return TCORE_RETURN_ENOSYS; return po->ops->set_power_on_attach(co, ur); - break; case TREQ_NETWORK_GET_POWER_ON_ATTACH: if (!po->ops->get_power_on_attach) return TCORE_RETURN_ENOSYS; return po->ops->get_power_on_attach(co, ur); - break; case TREQ_NETWORK_SET_CANCEL_MANUAL_SEARCH: if (!po->ops->set_cancel_manual_search) return TCORE_RETURN_ENOSYS; return po->ops->set_cancel_manual_search(co, ur); - break; case TREQ_NETWORK_GET_SERVING_NETWORK: if (!po->ops->get_serving_network) return TCORE_RETURN_ENOSYS; return po->ops->get_serving_network(co, ur); - break; case TREQ_NETWORK_SET_MODE: if (!po->ops->set_mode) return TCORE_RETURN_ENOSYS; return po->ops->set_mode(co, ur); - break; case TREQ_NETWORK_GET_MODE: if (!po->ops->get_mode) return TCORE_RETURN_ENOSYS; return po->ops->get_mode(co, ur); - break; + + case TREQ_NETWORK_SET_NEIGHBORING_CELL_INFO: + if (!po->ops->set_neighboring_cell_info) + return TCORE_RETURN_ENOSYS; + + return po->ops->set_neighboring_cell_info(co, ur); + + case TREQ_NETWORK_GET_NEIGHBORING_CELL_INFO: + if (!po->ops->get_neighboring_cell_info) + return TCORE_RETURN_ENOSYS; + + return po->ops->get_neighboring_cell_info(co, ur); + + case TREQ_NETWORK_SET_DEFAULT_DATA_SUBSCRIPTION: + if (!po->ops->set_default_data_subscription) + return TCORE_RETURN_ENOSYS; + + return po->ops->set_default_data_subscription(co, ur); + + case TREQ_NETWORK_GET_DEFAULT_DATA_SUBSCRIPTION: + if (!po->ops->get_default_data_subscription) + return TCORE_RETURN_ENOSYS; + + return po->ops->get_default_data_subscription(co, ur); + + case TREQ_NETWORK_SET_DEFAULT_SUBSCRIPTION: + if (!po->ops->set_default_subscription) + return TCORE_RETURN_ENOSYS; + + return po->ops->set_default_subscription(co, ur); + + case TREQ_NETWORK_GET_DEFAULT_SUBSCRIPTION: + if (!po->ops->get_default_subscription) + return TCORE_RETURN_ENOSYS; + + return po->ops->get_default_subscription(co, ur); + + case TREQ_NETWORK_SET_EMERGENCY_CALLBACK_MODE: + if (!po->ops->set_emergency_callback_mode) + return TCORE_RETURN_ENOSYS; + + return po->ops->set_emergency_callback_mode(co, ur); + + case TREQ_NETWORK_SET_ROAMING_PREFERENCE: + if (!po->ops->set_roaming_preference) + return TCORE_RETURN_ENOSYS; + + return po->ops->set_roaming_preference(co, ur); + + case TREQ_NETWORK_GET_ROAMING_PREFERENCE: + if (!po->ops->get_roaming_preference) + return TCORE_RETURN_ENOSYS; + + return po->ops->get_roaming_preference(co, ur); + + case TREQ_NETWORK_GET_SUBSCRIPTION_INFO: + if (!po->ops->get_subscription_info) + return TCORE_RETURN_ENOSYS; + + return po->ops->get_subscription_info(co, ur); default: break; @@ -211,7 +255,7 @@ static void _clone_hook(CoreObject *src, CoreObject *dest) if (!src || !dest) return; - dest_po = calloc(sizeof(struct private_object_data), 1); + dest_po = calloc(1, sizeof(struct private_object_data)); if (!dest_po) { tcore_object_link_object(dest, NULL); return; @@ -236,13 +280,14 @@ CoreObject *tcore_network_new(TcorePlugin *plugin, const char *name, if (!o) return NULL; - po = calloc(sizeof(struct private_object_data), 1); + po = calloc(1, sizeof(struct private_object_data)); if (!po) { tcore_object_free(o); return NULL; } po->ops = ops; + po->operator_info_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); tcore_object_set_type(o, CORE_OBJECT_TYPE_NETWORK); tcore_object_link_object(o, po); @@ -256,8 +301,6 @@ CoreObject *tcore_network_new(TcorePlugin *plugin, const char *name, void tcore_network_free(CoreObject *co) { struct private_object_data *po = NULL; - GSList *list; - int i; CORE_OBJECT_CHECK(co, CORE_OBJECT_TYPE_NETWORK); @@ -265,22 +308,6 @@ void tcore_network_free(CoreObject *co) if (!po) return; - for (i=0; i<999; i++) { - list = po->network_operator_info_table[i]; - if (!list) - continue; - - for (; list; list = list->next) { - if (!list) - continue; - - if (list->data) - free(list->data); - } - - g_slist_free(po->network_operator_info_table[i]); - } - if (po->network_name_short) free(po->network_name_short); if (po->network_name_full) @@ -290,10 +317,26 @@ void tcore_network_free(CoreObject *co) if (po->plmn) free(po->plmn); - free(po); + if (po->operator_info_hash) + g_hash_table_destroy(po->operator_info_hash); + tcore_object_free(co); } +void tcore_network_set_ops(CoreObject *o, struct tcore_network_operations *ops) +{ + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_NETWORK); + + po = (struct private_object_data *)tcore_object_ref_object(o); + if (!po) { + return; + } + + po->ops = ops; +} + char* tcore_network_get_plmn(CoreObject *co) { struct private_object_data *po = NULL; @@ -358,35 +401,47 @@ TReturn tcore_network_set_network_name(CoreObject *co, if (!po) return TCORE_RETURN_EINVAL; - if (type == TCORE_NETWORK_NAME_TYPE_SHORT) { - if (po->network_name_short) - free(po->network_name_short); + switch (type) { + case TCORE_NETWORK_NAME_TYPE_SHORT: + if (po->network_name_short) { + free (po->network_name_short); + po->network_name_short = NULL; + } - dbg("short network_name = [%s]", network_name); - po->network_name_short = g_strdup(network_name); - } - else if (type == TCORE_NETWORK_NAME_TYPE_FULL) { - if (po->network_name_full) - free(po->network_name_full); + if (network_name) + po->network_name_short = g_strdup (network_name); - dbg("full network_name = [%s]", network_name); - po->network_name_full = g_strdup(network_name); - } - else if (type == TCORE_NETWORK_NAME_TYPE_SPN) { - if (po->network_name_spn) - free(po->network_name_spn); + break; - dbg("spn network_name = [%s]", network_name); - po->network_name_spn = g_strdup(network_name); - } - else { - return TCORE_RETURN_EINVAL; + case TCORE_NETWORK_NAME_TYPE_FULL: + if (po->network_name_full) { + free (po->network_name_full); + po->network_name_full = NULL; + } + + if (network_name) + po->network_name_full = g_strdup (network_name); + + break; + + case TCORE_NETWORK_NAME_TYPE_SPN: + if (po->network_name_spn) { + free (po->network_name_spn); + po->network_name_spn = NULL; + } + + if (network_name) + po->network_name_spn = g_strdup (network_name); + + break; + + default: + return TCORE_RETURN_EINVAL; } return TCORE_RETURN_SUCCESS; } - TReturn tcore_network_get_network_name_priority(CoreObject *co, enum tcore_network_name_priority *priority) { @@ -451,6 +506,35 @@ TReturn tcore_network_set_roaming_state(CoreObject *co, gboolean state) return TCORE_RETURN_SUCCESS; } +int tcore_network_get_restricted_state(CoreObject *co) +{ + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, FALSE); + + po = tcore_object_ref_object(co); + if (!po) + return FALSE; + + return po->restricted_state; +} + +TReturn tcore_network_set_restricted_state(CoreObject *co, int state) +{ + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL); + + po = tcore_object_ref_object(co); + if (!po) + return TCORE_RETURN_EINVAL; + + po->restricted_state = state; + dbg("restricted_state = 0x%x", state); + + return TCORE_RETURN_SUCCESS; +} + TReturn tcore_network_get_service_status(CoreObject *co, enum tcore_network_service_domain_type type, enum telephony_network_service_domain_status *result) @@ -474,6 +558,9 @@ TReturn tcore_network_get_service_status(CoreObject *co, case TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET: *result = po->ps_domain_status; break; + default: + err("invalid network type"); + break; } return TCORE_RETURN_SUCCESS; @@ -499,8 +586,12 @@ TReturn tcore_network_set_service_status(CoreObject *co, case TCORE_NETWORK_SERVICE_DOMAIN_TYPE_PACKET: po->ps_domain_status = status; - dbg("cs.status = 0x%x", status); + dbg("ps.status = 0x%x", status); break; + default: + err("invalid network type"); + break; + } return TCORE_RETURN_SUCCESS; @@ -640,6 +731,35 @@ TReturn tcore_network_get_cell_id(CoreObject *co, unsigned int *result) return TCORE_RETURN_SUCCESS; } +gboolean tcore_network_get_gsm_dtm_support(CoreObject *co) +{ + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, FALSE); + + po = tcore_object_ref_object(co); + if (!po) + return FALSE; + + return po->gsm_dtm_support; +} + +TReturn tcore_network_set_gsm_dtm_support(CoreObject *co, gboolean state) +{ + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL); + + po = tcore_object_ref_object(co); + if (!po) + return TCORE_RETURN_EINVAL; + + po->gsm_dtm_support = state; + dbg("gsm_dtm_support = %d", state); + + return TCORE_RETURN_SUCCESS; +} + TReturn tcore_network_set_service_type(CoreObject *co, enum telephony_network_service_type service_type) { @@ -676,26 +796,39 @@ TReturn tcore_network_get_service_type(CoreObject *co, } TReturn tcore_network_operator_info_add(CoreObject *co, - struct tcore_network_operator_info *noi) + const struct tcore_network_operator_info *noi) { struct private_object_data *po = NULL; - int mcc_index = 0; + char plmn[7]; + int mcc_index, mnc_index; CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, TCORE_RETURN_EINVAL); if (!noi) return TCORE_RETURN_EINVAL; + mcc_index = atoi(noi->mcc); + mnc_index = atoi(noi->mnc); + + if (mcc_index > 999 || mnc_index > 999) { + err("mcc_index %d mnc_index %d", mcc_index, mnc_index); + return TCORE_RETURN_EINVAL; + } + po = tcore_object_ref_object(co); if (!po) return TCORE_RETURN_EINVAL; - mcc_index = atoi(noi->mcc); - if (mcc_index > 999) - return TCORE_RETURN_EINVAL; + g_strlcpy(plmn, noi->mcc, 4); + g_strlcpy(plmn+3, noi->mnc, 3); + + if (g_hash_table_lookup(po->operator_info_hash, plmn)) { + //dbg("Remove existed (key:%s)", plmn); + g_hash_table_remove(po->operator_info_hash, plmn); + } - po->network_operator_info_table[mcc_index] = g_slist_append( - po->network_operator_info_table[mcc_index], noi); + //dbg("Adding mcc[%s] mnc[%s] name[%s] type[%d] in operator info table", noi->mcc, noi->mnc, noi->name, noi->type); + g_hash_table_insert(po->operator_info_hash, g_strdup(plmn), g_memdup(noi, sizeof(struct tcore_network_operator_info))); return TCORE_RETURN_SUCCESS; } @@ -704,44 +837,39 @@ struct tcore_network_operator_info * tcore_network_operator_info_find(CoreObject *co, const char *mcc, const char *mnc) { struct private_object_data *po = NULL; - GSList *list; - int mcc_index = 0; struct tcore_network_operator_info *data; + char plmn[7]; + int mcc_index, mnc_index; CORE_OBJECT_CHECK_RETURN(co, CORE_OBJECT_TYPE_NETWORK, NULL); if (!mcc || !mnc) return NULL; - po = tcore_object_ref_object(co); - if (!po) - return NULL; - mcc_index = atoi(mcc); - if (mcc_index > 999) - return NULL; + mnc_index = atoi(mnc); - list = po->network_operator_info_table[mcc_index]; - if (list == NULL) { - dbg("mcc[%d] is not in operator table", mcc_index); + if (mcc_index > 999 || mnc_index > 999) { + err("mcc_index %d mnc_index %d", mcc_index, mnc_index); return NULL; } - for (; list; list = list->next) { - if (!list) - continue; + po = tcore_object_ref_object(co); + if (!po) + return NULL; - if (!list->data) - continue; + g_strlcpy(plmn, mcc, 4); + g_strlcpy(plmn+3, mnc, 3); - data = list->data; + data = g_hash_table_lookup(po->operator_info_hash, plmn); - dbg(" +- mnc[%s]", data->mnc); - if (g_strcmp0(data->mnc, mnc) == 0) - return data; + if (data) { + dbg("found mcc[%s], mnc[%s] name[%s] type[%d] in operator info table (%p)", + data->mcc, data->mnc, data->name, data->type, po->operator_info_hash); + } else { + dbg("mcc[%s] mnc[%s] not present in operator table (%p)", + mcc, mnc, po->operator_info_hash); } - dbg("mcc[%s] mnc[%s] is not in operator table", mcc, mnc); - - return NULL; + return data; } diff --git a/src/co_phonebook.c b/src/co_phonebook.c index 9ca0eab..8bd6d65 100644 --- a/src/co_phonebook.c +++ b/src/co_phonebook.c @@ -35,6 +35,7 @@ struct private_object_data { struct tcore_phonebook_operations *ops; gboolean b_init; struct tel_phonebook_support_list support_list; + struct tel_phonebook_field_support_list field_support_list; enum tel_phonebook_type selected; }; @@ -51,13 +52,6 @@ static TReturn _dispatcher(CoreObject *o, UserRequest *ur) command = tcore_user_request_get_command(ur); switch (command) { - case TREQ_PHONEBOOK_SELECT: - if (!po->ops->select) - return TCORE_RETURN_ENOSYS; - - return po->ops->select(o, ur); - break; - case TREQ_PHONEBOOK_GETCOUNT: if (!po->ops->get_count) return TCORE_RETURN_ENOSYS; @@ -115,7 +109,7 @@ static void _clone_hook(CoreObject *src, CoreObject *dest) if (!src || !dest) return; - dest_po = calloc(sizeof(struct private_object_data), 1); + dest_po = calloc(1, sizeof(struct private_object_data)); if (!dest_po) { tcore_object_link_object(dest, NULL); return; @@ -163,7 +157,9 @@ struct tel_phonebook_support_list* tcore_phonebook_get_support_list(CoreObject * struct private_object_data *po = NULL; CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, NULL); po = tcore_object_ref_object(o); - tmp = calloc(sizeof(struct tel_phonebook_support_list), 1); + tmp = calloc(1, sizeof(struct tel_phonebook_support_list)); + if (!tmp) + return NULL; memcpy(tmp, &po->support_list, sizeof(struct tel_phonebook_support_list)); return tmp; } @@ -177,6 +173,28 @@ gboolean tcore_phonebook_set_support_list(CoreObject *o, struct tel_phonebook_su return TRUE; } +struct tel_phonebook_field_support_list* tcore_phonebook_get_field_support_list(CoreObject *o) +{ + struct tel_phonebook_field_support_list *tmp; + struct private_object_data *po = NULL; + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, NULL); + po = tcore_object_ref_object(o); + tmp = calloc(1, sizeof(struct tel_phonebook_field_support_list)); + if (!tmp) + return NULL; + memcpy(tmp, &po->field_support_list, sizeof(struct tel_phonebook_field_support_list)); + return tmp; +} + +gboolean tcore_phonebook_set_field_support_list(CoreObject *o, struct tel_phonebook_field_support_list *list) +{ + struct private_object_data *po = NULL; + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PHONEBOOK, FALSE); + po = tcore_object_ref_object(o); + memcpy(&po->field_support_list, list, sizeof(struct tel_phonebook_field_support_list)); + return TRUE; +} + enum tel_phonebook_type tcore_phonebook_get_selected_type(CoreObject *o) { struct private_object_data *po = NULL; @@ -207,7 +225,7 @@ CoreObject *tcore_phonebook_new(TcorePlugin *p, const char *name, if (!o) return NULL; - po = calloc(sizeof(struct private_object_data), 1); + po = calloc(1, sizeof(struct private_object_data)); if (!po) { tcore_object_free(o); return NULL; @@ -227,14 +245,20 @@ CoreObject *tcore_phonebook_new(TcorePlugin *p, const char *name, void tcore_phonebook_free(CoreObject *o) { + CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PHONEBOOK); + tcore_object_free(o); +} + +void tcore_phonebook_set_ops(CoreObject *o, struct tcore_phonebook_operations *ops) +{ struct private_object_data *po = NULL; CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PHONEBOOK); - po = tcore_object_ref_object(o); - if (!po) + po = (struct private_object_data *)tcore_object_ref_object(o); + if (!po) { return; + } - free(po); - tcore_object_free(o); + po->ops = ops; } diff --git a/src/co_ps.c b/src/co_ps.c index c259ed8..078eef1 100644 --- a/src/co_ps.c +++ b/src/co_ps.c @@ -31,6 +31,9 @@ struct p_callid_type{ unsigned int cid; + gboolean active; + gboolean connected; + gchar *apn; GSList *contexts; }; @@ -38,6 +41,7 @@ struct private_object_data { struct tcore_ps_operations *ops; gboolean online; + gint num_of_pdn; /* 1 ~ UMTS_PS_MAX_CID */ struct p_callid_type cid[PS_MAX_CID + 1]; @@ -75,7 +79,7 @@ static void _clone_hook(CoreObject *src, CoreObject *dest) if (!src || !dest) return; - dest_po = calloc(sizeof(struct private_object_data), 1); + dest_po = calloc(1, sizeof(struct private_object_data)); if (!dest_po) { tcore_object_link_object(dest, NULL); return; @@ -98,9 +102,6 @@ static void _free_hook(CoreObject *o) if (po->context_list) { for (list = po->context_list; list; list = list->next) { - if (!list) - continue; - if (list->data) free(list->data); @@ -123,30 +124,36 @@ static gboolean _ps_is_active_context(CoreObject *o, CoreObject *ps_context) int idx_cid = 0; struct private_object_data *po = NULL; - CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL); + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, FALSE); po = tcore_object_ref_object(o); - for (idx_cid = 0; idx_cid < PS_MAX_CID; idx_cid++) { - - if (po->cid[idx_cid].cid != 0) { - contexts = po->cid[idx_cid].contexts; + for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) { + if (po->cid[idx_cid].cid == 0) + continue; - do { - s_context = contexts->data; - if (!s_context) - continue; + contexts = po->cid[idx_cid].contexts; + if (!contexts) + continue; - if (ps_context == s_context) { - dbg("find contexts(%p) in cid(%d)", ps_context, idx_cid); - return TRUE; - } + while (contexts) { + s_context = contexts->data; + if (!s_context) { + contexts = contexts->next; + continue; + } - } while ((contexts = g_slist_next(contexts))); + if (ps_context == s_context) { + dbg("find contexts(%p) in cid(%d)", ps_context, idx_cid); + return TRUE; + } + contexts = contexts->next; } } + dbg("cannot find contexts(%p) ", ps_context); + return FALSE; } @@ -159,35 +166,42 @@ static gboolean _ps_is_duplicated_apn(CoreObject *o, CoreObject *ps_context) int idx_cid = 0; struct private_object_data *po = NULL; - CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL); + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, FALSE); po = tcore_object_ref_object(o); t_apn = tcore_context_get_apn(ps_context); - for (idx_cid = 0; idx_cid < PS_MAX_CID; idx_cid++) { + for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) { + if (po->cid[idx_cid].cid == 0) + continue; - if (po->cid[idx_cid].cid != 0) { - contexts = po->cid[idx_cid].contexts; + contexts = po->cid[idx_cid].contexts; + if (!contexts) + continue; - do { - s_context = contexts->data; + while (contexts) { + s_context = contexts->data; + if (!s_context) { + contexts = contexts->next; + continue; + } - if (!s_context) - continue; - if (ps_context == s_context) - continue; + if (ps_context == s_context) { + contexts = contexts->next; + continue; + } - s_apn = tcore_context_get_apn(s_context); - if (g_strcmp0(t_apn, s_apn) == 0) { - dbg("target and source context have same APN"); - tcore_context_cp_service_info(ps_context, s_context); - g_free(t_apn); - g_free(s_apn); - return TRUE; - } + s_apn = tcore_context_get_apn(s_context); + if (g_strcmp0(t_apn, s_apn) == 0) { + dbg("target and source context have same APN"); + tcore_context_cp_service_info(ps_context, s_context); + g_free(t_apn); g_free(s_apn); - } while ((contexts = g_slist_next(contexts))); + return TRUE; + } + g_free (s_apn); + contexts = contexts->next; } } @@ -195,6 +209,14 @@ static gboolean _ps_is_duplicated_apn(CoreObject *o, CoreObject *ps_context) return FALSE; } +static void _deactivate_context (gpointer context, gpointer user_data) +{ + if (!context || !user_data) + return; + + tcore_ps_deactivate_context(user_data, context, NULL); +} + CoreObject *tcore_ps_new(TcorePlugin *p, const char *name, struct tcore_ps_operations *ops, TcoreHal *hal) { @@ -208,7 +230,7 @@ CoreObject *tcore_ps_new(TcorePlugin *p, const char *name, if (!o) return NULL; - po = calloc(sizeof(struct private_object_data), 1); + po = calloc(1, sizeof(struct private_object_data)); if (!po) { tcore_object_free(o); return NULL; @@ -227,17 +249,22 @@ CoreObject *tcore_ps_new(TcorePlugin *p, const char *name, void tcore_ps_free(CoreObject *o) { + CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS); + tcore_object_free(o); +} + +void tcore_ps_set_ops(CoreObject *o, struct tcore_ps_operations *ops) +{ struct private_object_data *po = NULL; CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_PS); - po = tcore_object_ref_object(o); - if (!po) + po = (struct private_object_data *)tcore_object_ref_object(o); + if (!po) { return; + } - g_free(po); - tcore_object_link_object(o, po); - tcore_object_free(o); + po->ops = ops; } TReturn tcore_ps_add_context(CoreObject *o, CoreObject *ctx_o) @@ -289,6 +316,176 @@ TReturn tcore_ps_set_online(CoreObject *o, gboolean state) return TCORE_RETURN_SUCCESS; } +TReturn tcore_ps_set_num_of_pdn(CoreObject *o, gint numbers) +{ + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL); + + po = tcore_object_ref_object(o); + if (!po) + return TCORE_RETURN_EINVAL; + + po->num_of_pdn = numbers; + dbg("ps num of pdn = %d", po->num_of_pdn); + + return TCORE_RETURN_SUCCESS; +} + +unsigned int tcore_ps_get_num_of_pdn(CoreObject *o) +{ + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0); + + po = tcore_object_ref_object(o); + if (!po) + return 0; + + return po->num_of_pdn; +} + +unsigned int tcore_ps_set_cid_active(CoreObject *o, unsigned int cid, unsigned int enable) +{ + int idx_cid = 0; + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0); + if(cid == 0){ + return 0; + } + + po = tcore_object_ref_object(o); + for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) { + if (po->cid[idx_cid].cid == cid){ + po->cid[idx_cid].active = enable; + return 1; + } + } + + return 0; +} + +unsigned int tcore_ps_get_cid_active(CoreObject *o, unsigned int cid) +{ + int idx_cid = 0; + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0); + if(cid == 0){ + return 0; + } + + po = tcore_object_ref_object(o); + for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) { + if (po->cid[idx_cid].cid == cid){ + return po->cid[idx_cid].active; + } + } + + return 0; +} + +GSList* tcore_ps_get_active_cids(CoreObject *o) +{ + int idx_cid = 0; + GSList *active_list = NULL; + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL); + + po = tcore_object_ref_object(o); + + for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) { + if (po->cid[idx_cid].active){ + active_list = g_slist_append(active_list, &po->cid[idx_cid].cid); + } + } + + return active_list; +} + +unsigned int tcore_ps_set_cid_connected(CoreObject *o, unsigned int cid, unsigned int connected) +{ + int idx_cid = 0; + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0); + if(cid == 0){ + return 0; + } + + po = tcore_object_ref_object(o); + for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) { + if (po->cid[idx_cid].cid == cid){ + po->cid[idx_cid].connected = connected; + return 1; + } + } + + return 0; +} + +unsigned int tcore_ps_get_cid_connected(CoreObject *o, unsigned int cid) +{ + int idx_cid = 0; + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0); + if(cid == 0){ + return 0; + } + + po = tcore_object_ref_object(o); + for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) { + if (po->cid[idx_cid].cid == cid){ + return po->cid[idx_cid].connected; + } + } + + return 0; +} + +GSList* tcore_ps_get_connected_cids(CoreObject *o) +{ + int idx_cid = 0; + GSList *active_list = NULL; + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, NULL); + + po = tcore_object_ref_object(o); + + for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++) { + if (po->cid[idx_cid].connected){ + active_list = g_slist_append(active_list, &po->cid[idx_cid].cid); + } + } + + return active_list; +} + +unsigned int tcore_ps_is_active_apn(CoreObject *o, const char* apn) +{ + int idx_cid = 0; + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, 0); + + po = tcore_object_ref_object(o); + + for (idx_cid = 1; idx_cid <= po->num_of_pdn; idx_cid++){ + if (po->cid[idx_cid].cid == 0) + continue; + + if (g_strcmp0((const char*)po->cid[idx_cid].apn, apn) == 0 && po->cid[idx_cid].active) { + return 1; + } + } + + return 0; +} + CoreObject *tcore_ps_ref_context_by_role(CoreObject *o, enum co_context_role role) { struct private_object_data *po = NULL; @@ -308,9 +505,6 @@ CoreObject *tcore_ps_ref_context_by_role(CoreObject *o, enum co_context_role rol if (po->context_list) { for (list = po->context_list; list; list = list->next) { - if (!list) - continue; - if (!list->data) continue; @@ -339,7 +533,7 @@ GSList *tcore_ps_ref_context_by_id(CoreObject *o, unsigned int id) if (!po) return NULL; - if (id == 0 || id > PS_MAX_CID) + if (id == 0 || id > (unsigned int)po->num_of_pdn) return NULL; if (po->cid[id].cid != id) @@ -348,10 +542,54 @@ GSList *tcore_ps_ref_context_by_id(CoreObject *o, unsigned int id) return po->cid[id].contexts; } -TReturn tcore_ps_assign_context_id(CoreObject *o, CoreObject *context, unsigned int cid) +gboolean tcore_ps_any_context_activating_activated(CoreObject *o, int * state) { struct private_object_data *po = NULL; - int idx; + CoreObject *pdp_o; + gboolean ret = FALSE; + GSList *list = NULL; + enum co_context_state context_state = CONTEXT_STATE_DEACTIVATED; + + po = tcore_object_ref_object(o); + if (!po) + return ret; + + if (po->context_list) { + for (list = po->context_list; list; list = list->next) { + if (!list->data) + continue; + + pdp_o = list->data; + + if (tcore_object_get_type(pdp_o) != CORE_OBJECT_TYPE_PS_CONTEXT) + continue; + + context_state = tcore_context_get_state(pdp_o); + + if(CONTEXT_STATE_ACTIVATED == context_state) { + *state = CONTEXT_STATE_ACTIVATED; + return TRUE; + } + else if (CONTEXT_STATE_ACTIVATING == context_state){ + *state = CONTEXT_STATE_ACTIVATING; + ret = TRUE; + continue; + } + else if (CONTEXT_STATE_DEACTIVATING == context_state){ + *state = CONTEXT_STATE_DEACTIVATING; + ret = TRUE; + continue; + } + } + } + return ret; +} + + +TReturn tcore_ps_assign_context_id(CoreObject *o, CoreObject *context, unsigned char cid) +{ + struct private_object_data *po = NULL; + unsigned char idx; CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL); CORE_OBJECT_CHECK_RETURN(context, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL); @@ -362,10 +600,12 @@ TReturn tcore_ps_assign_context_id(CoreObject *o, CoreObject *context, unsigned if (cid == 0) { /* Automatic assign */ - for (idx = 1; idx <= PS_MAX_CID; idx++) { + for (idx = 1; idx <= po->num_of_pdn; idx++) { if (po->cid[idx].cid == 0) { po->cid[idx].cid = idx; po->cid[idx].contexts = g_slist_append(po->cid[idx].contexts, context); + po->cid[idx].apn = tcore_context_get_apn(context); + dbg("assign contexts(%p) in cid(%d), apn(%s)", context, idx, po->cid[idx].apn); return tcore_context_set_id(context, idx); } else { @@ -392,7 +632,7 @@ TReturn tcore_ps_assign_context_id(CoreObject *o, CoreObject *context, unsigned TReturn tcore_ps_clear_context_id(CoreObject *o, CoreObject *context) { struct private_object_data *po = NULL; - int i = 0, cnt = 0; + unsigned char i = 0, cnt = 0; CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL); CORE_OBJECT_CHECK_RETURN(context, CORE_OBJECT_TYPE_PS_CONTEXT, TCORE_RETURN_EINVAL); @@ -406,17 +646,58 @@ TReturn tcore_ps_clear_context_id(CoreObject *o, CoreObject *context) return TCORE_RETURN_PS_CID_ERROR; } - if (i > PS_MAX_CID) + if (i > po->num_of_pdn) return TCORE_RETURN_PS_CID_ERROR; po->cid[i].contexts = g_slist_remove(po->cid[i].contexts, context); cnt = g_slist_length(po->cid[i].contexts); - if (cnt <= 0) + if (cnt <= 0){ po->cid[i].cid = 0; + po->cid[i].active = FALSE; + po->cid[i].connected = FALSE; + g_free(po->cid[i].apn); + po->cid[i].apn = NULL; + } return tcore_context_set_id(context, 0); } +TReturn tcore_ps_define_context(CoreObject *o, CoreObject *ps_context, void *user_data) +{ + int rv; + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL); + + po = tcore_object_ref_object(o); + if (!po) + return TCORE_RETURN_EINVAL; + + if (!ps_context) + return TCORE_RETURN_EINVAL; + + rv = _ps_is_active_context(o, ps_context); + if (rv) + return TCORE_RETURN_SUCCESS; + + rv = _ps_is_duplicated_apn(o, ps_context); + if (rv) { + unsigned char cid = 0; + cid = tcore_context_get_id(ps_context); + po->cid[cid].contexts = g_slist_append(po->cid[cid].contexts, ps_context); + return TCORE_RETURN_SUCCESS; + } + + if (tcore_context_get_id(ps_context) == 0) { + if (tcore_ps_assign_context_id(o, ps_context, 0) != TCORE_RETURN_SUCCESS) + return TCORE_RETURN_PS_CID_ERROR; + } + + dbg("contexts(%p), cid = %d", ps_context, tcore_context_get_id(ps_context)); + + return po->ops->define_context(o, ps_context, user_data); +} + TReturn tcore_ps_activate_context(CoreObject *o, CoreObject *ps_context, void *user_data) { int rv; @@ -429,7 +710,7 @@ TReturn tcore_ps_activate_context(CoreObject *o, CoreObject *ps_context, void *u if (!po) return TCORE_RETURN_EINVAL; - if (!po->online) { + if (!po->online) { dbg("ps network is not online !"); return TCORE_RETURN_PS_NETWORK_NOT_READY; } @@ -438,35 +719,42 @@ TReturn tcore_ps_activate_context(CoreObject *o, CoreObject *ps_context, void *u return TCORE_RETURN_EINVAL; rv = _ps_is_active_context(o, ps_context); - if (rv) - return TCORE_RETURN_SUCCESS; + if (!rv) + { + dbg("it is not defined context"); + return TCORE_RETURN_EINVAL; + } rv = _ps_is_duplicated_apn(o, ps_context); if (rv) { - int cid = 0; - cid = tcore_context_get_id(ps_context); - po->cid[cid].contexts = g_slist_append(po->cid[cid].contexts, ps_context); + dbg("context activation is already requested for the same apn(%s)", + tcore_context_get_apn(ps_context)); return TCORE_RETURN_SUCCESS; } context_state = tcore_context_get_state(ps_context); - if (context_state == CONTEXT_STATE_ACTIVATED) + + if (context_state == CONTEXT_STATE_ACTIVATED){ + dbg("Context state : CONTEXT_STATE_ACTIVATED"); return TCORE_RETURN_SUCCESS; - else if (context_state == CONTEXT_STATE_ACTIVATING) + } + else if (context_state == CONTEXT_STATE_ACTIVATING){ + dbg("Context state : CONTEXT_STATE_ACTIVATING"); return TCORE_RETURN_SUCCESS; - else if (context_state == CONTEXT_STATE_DEACTIVATING) - return TCORE_RETURN_PS_DEACTIVATING; - - if (tcore_context_get_id(ps_context) == 0) { - if (tcore_ps_assign_context_id(o, ps_context, 0) != TCORE_RETURN_SUCCESS) - return TCORE_RETURN_PS_CID_ERROR; } - else { - dbg("cid = %d", tcore_context_get_id(ps_context)); + else if (context_state == CONTEXT_STATE_DEACTIVATING){ + dbg("Context state : CONTEXT_STATE_DEACTIVATING"); + return TCORE_RETURN_PS_DEACTIVATING; } + dbg("cid = %d", tcore_context_get_id(ps_context)); + tcore_context_set_state(ps_context, CONTEXT_STATE_ACTIVATING); - return po->ops->activate_context(o, ps_context, user_data); + rv = po->ops->activate_context(o, ps_context, user_data); + if(rv != TCORE_RETURN_SUCCESS) + tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED); + + return rv; } TReturn tcore_ps_deactivate_context(CoreObject *o, CoreObject *ps_context, void *user_data) @@ -495,7 +783,7 @@ TReturn tcore_ps_deactivate_context(CoreObject *o, CoreObject *ps_context, void rv = _ps_is_duplicated_apn(o, ps_context); if (rv) { - int cid = 0; + unsigned char cid = 0; cid = tcore_context_get_id(ps_context); po->cid[cid].contexts = g_slist_remove(po->cid[cid].contexts, ps_context); tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATED); @@ -503,21 +791,32 @@ TReturn tcore_ps_deactivate_context(CoreObject *o, CoreObject *ps_context, void } context_state = tcore_context_get_state(ps_context); - if (context_state == CONTEXT_STATE_DEACTIVATED) + if (context_state == CONTEXT_STATE_DEACTIVATED){ + dbg("Context State : CONTEXT_STATE_DEACTIVATED"); return TCORE_RETURN_SUCCESS; - else if (context_state == CONTEXT_STATE_DEACTIVATING) + } + else if (context_state == CONTEXT_STATE_DEACTIVATING){ + dbg("Context State : CONTEXT_STATE_DEACTIVATING"); return TCORE_RETURN_SUCCESS; - else if (context_state == CONTEXT_STATE_ACTIVATING) + } + else if (context_state == CONTEXT_STATE_ACTIVATING){ + dbg("Context State :CONTEXT_STATE_ACTIVATING"); return TCORE_RETURN_PS_ACTIVATING; - + } tcore_context_set_state(ps_context, CONTEXT_STATE_DEACTIVATING); - return po->ops->deactivate_context(o, ps_context, user_data); + + rv = po->ops->deactivate_context(o, ps_context, user_data); + if(rv != TCORE_RETURN_SUCCESS) + tcore_context_set_state(ps_context, CONTEXT_STATE_ACTIVATED); + + return rv; } TReturn tcore_ps_deactivate_contexts(CoreObject *o) { - int index = 0; + int temp_index = 0; struct private_object_data *po = NULL; + GSList *contexts = NULL; CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL); @@ -530,21 +829,43 @@ TReturn tcore_ps_deactivate_contexts(CoreObject *o) return TCORE_RETURN_PS_NETWORK_NOT_READY; } - for (index = 0; index < PS_MAX_CID; index++) { - if (po->cid[index].cid != 0) { - GSList *contexts = NULL; - contexts = po->cid[index].contexts; + for (temp_index = 1; temp_index <= po->num_of_pdn; temp_index++) { + if (po->cid[temp_index].cid != 0) { + contexts = po->cid[temp_index].contexts; + if(!contexts) + continue; - do { - CoreObject *context = NULL; - context = contexts->data; + g_slist_foreach (contexts, _deactivate_context, o); + } + } - if (!context) - continue; - tcore_ps_deactivate_context(o, context, NULL); + return TCORE_RETURN_SUCCESS; +} - } while ((contexts = g_slist_next(contexts))); +TReturn tcore_ps_deactivate_cid(CoreObject *o, unsigned int cid) +{ + int temp_index = 0; + struct private_object_data *po = NULL; + GSList *contexts = NULL; + + CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_PS, TCORE_RETURN_EINVAL); + + po = tcore_object_ref_object(o); + if (!po) + return TCORE_RETURN_EINVAL; + + if (!po->online) { + dbg("ps network is not online !"); + return TCORE_RETURN_PS_NETWORK_NOT_READY; + } + + for (temp_index = 1; temp_index <= po->num_of_pdn; temp_index++) { + if (po->cid[temp_index].cid != 0 && po->cid[temp_index].cid == cid) { + contexts = po->cid[temp_index].contexts; + if(!contexts) + continue; + g_slist_foreach (contexts, _deactivate_context, o); } } diff --git a/src/co_sap.c b/src/co_sap.c index def550e..c4adb6e 100644 --- a/src/co_sap.c +++ b/src/co_sap.c @@ -118,7 +118,7 @@ static void _clone_hook(CoreObject *src, CoreObject *dest) if (!src || !dest) return; - dest_po = calloc(sizeof(struct private_object_data), 1); + dest_po = calloc(1, sizeof(struct private_object_data)); if (!dest_po) { tcore_object_link_object(dest, NULL); return; @@ -156,7 +156,7 @@ CoreObject *tcore_sap_new(TcorePlugin *p, const char *name, if (!o) return NULL; - po = calloc(sizeof(struct private_object_data), 1); + po = calloc(1, sizeof(struct private_object_data)); if (!po) { tcore_object_free(o); return NULL; @@ -175,14 +175,20 @@ CoreObject *tcore_sap_new(TcorePlugin *p, const char *name, void tcore_sap_free(CoreObject *o) { + CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAP); + tcore_object_free(o); +} + +void tcore_sap_set_ops(CoreObject *o, struct tcore_sap_operations *ops) +{ struct private_object_data *po = NULL; CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAP); - po = tcore_object_ref_object(o); - if (!po) + po = (struct private_object_data *)tcore_object_ref_object(o); + if (!po) { return; + } - free(po); - tcore_object_free(o); -} + po->ops = ops; +} \ No newline at end of file diff --git a/src/co_sat.c b/src/co_sat.c index 96ffcd2..baff4c6 100644 --- a/src/co_sat.c +++ b/src/co_sat.c @@ -90,7 +90,9 @@ #define SATK_OTHER_ADDRESS_TAG 0x3E /* OTHER ADDRESS */ #define SATK_NETWORK_ACCESS_TAG 0x47 /* NETWORK ACCESS NAME TAG */ #define SATK_CDMA_SMS_TPDU_TAG 0x48 /* CDMA SMS TPDU TAG */ -#define SATK_REMOTE_ENTITY_ADDRESS_TAG 0x48 /* REMOTE ENTITY ADDRESS TAG */ +#define SATK_REMOTE_ENTITY_ADDRESS_TAG 0x49 /* REMOTE ENTITY ADDRESS TAG */ +#define SATK_TEXT_ATTRIBUTE_TAG 0x50 /* TEXT ATTRIBUTE TAG */ +#define SATK_TEXT_ATTRIBUTE_LIST_TAG 0x51 /* TEXT ATTRIBUTE LIST TAG */ /* general data object lengths */ #define SATK_DCS_LENGTH 0x01 @@ -147,6 +149,13 @@ static TReturn _dispatcher(CoreObject *o, UserRequest *ur) return po->ops->terminal_response(o, ur); break; + case TREQ_SAT_REQ_USERCONFIRMATION: + if (!po->ops->user_confirmation) + return TCORE_RETURN_ENOSYS; + + return po->ops->user_confirmation(o, ur); + break; + default: break; } @@ -162,7 +171,7 @@ static void _clone_hook(CoreObject *src, CoreObject *dest) if (!src || !dest) return; - dest_po = calloc(sizeof(struct private_object_data), 1); + dest_po = calloc(1, sizeof(struct private_object_data)); if (!dest_po) { tcore_object_link_object(dest, NULL); return; @@ -246,14 +255,14 @@ static void _get_string_data(unsigned char* src, int len, if (!src || !text_obj) return; switch (text_obj->dcs.a_format) { - case ALPHABET_FROMAT_SMS_DEFAULT: { + case ALPHABET_FORMAT_SMS_DEFAULT: { char* unpacked_str; text_obj->string_length = 0; unpacked_str = (char *)tcore_util_unpack_gsm7bit(src, (unsigned int)len); if (!unpacked_str) return; - text_obj->dcs.a_format = ALPHABET_FROMAT_8BIT_DATA; + text_obj->dcs.a_format = ALPHABET_FORMAT_8BIT_DATA; text_obj->string_length = strlen(unpacked_str); if (text_obj->string_length >= SAT_TEXT_STRING_LEN_MAX) { @@ -268,9 +277,9 @@ static void _get_string_data(unsigned char* src, int len, g_free(unpacked_str); }break; - case ALPHABET_FROMAT_UCS2: - case ALPHABET_FROMAT_8BIT_DATA: { - + case ALPHABET_FORMAT_UCS2: + case ALPHABET_FORMAT_8BIT_DATA: { + text_obj->string_length = len; if (text_obj->string_length >= SAT_TEXT_STRING_LEN_MAX) { text_obj->string_length = SAT_TEXT_STRING_LEN_MAX; memcpy(text_obj->string, src, SAT_TEXT_STRING_LEN_MAX); @@ -278,7 +287,7 @@ static void _get_string_data(unsigned char* src, int len, } else { memcpy(text_obj->string, src, text_obj->string_length); - text_obj->string[text_obj->string_length] = 0x00; + text_obj->string[text_obj->string_length+1] = 0x00; } }break; default: { @@ -317,7 +326,7 @@ static void _sat_decode_dcs(unsigned char dcs, struct data_coding_scheme* dsc_ob dsc_obj->m_class = MSG_CLASS_3; break; default: - dsc_obj->m_class = MSG_CLASS_RESERVED; + err("invalid dcs type"); break; } } @@ -326,19 +335,19 @@ static void _sat_decode_dcs(unsigned char dcs, struct data_coding_scheme* dsc_ob switch (dcs & 0x0C) { case 0x00: case 0x0C: - dsc_obj->a_format = ALPHABET_FROMAT_SMS_DEFAULT; + dsc_obj->a_format = ALPHABET_FORMAT_SMS_DEFAULT; break; case 0x04: - dsc_obj->a_format = ALPHABET_FROMAT_8BIT_DATA; + dsc_obj->a_format = ALPHABET_FORMAT_8BIT_DATA; break; case 0X08: - dsc_obj->a_format = ALPHABET_FROMAT_UCS2; + dsc_obj->a_format = ALPHABET_FORMAT_UCS2; break; default: - dsc_obj->a_format = ALPHABET_FROMAT_RESERVED; + dsc_obj->a_format = ALPHABET_FORMAT_RESERVED; break; } @@ -359,7 +368,7 @@ static void _sat_decode_ton_npi(unsigned char ton_npi, enum type_of_number *ton, ton_value = (ton_npi & 0x70) >> 4; *ton = ton_value; if(*ton > TON_NETWORK_SPECIFIC) - *ton = TON_UNKNOWN; + *ton = TON_RESERVED_FOR_EXT; npi_value = (ton_npi & 0x0F); switch(npi_value){ @@ -424,7 +433,7 @@ static enum tcore_sat_result _sat_decode_address_tlv(unsigned char* tlv_str, int int curr_offset, struct tel_sat_address* address_obj, int* consumed_data_len) { unsigned char* src_data; - int index, len_of_len = 0; + int temp_index, len_of_len = 0; int address_len = 0; gboolean comprehensive_req = FALSE; @@ -439,28 +448,28 @@ static enum tcore_sat_result _sat_decode_address_tlv(unsigned char* tlv_str, int } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if ((src_data[index] & 0x7F) != SATK_ADDRESS_TAG) { + if ((src_data[temp_index] & 0x7F) != SATK_ADDRESS_TAG) { dbg("[SAT] SAT PARSER - address TAG missing"); return TCORE_SAT_REQUIRED_VALUE_MISSING; } //comprehensive required - if((src_data[index++] & 0x80)) + if((src_data[temp_index++] & 0x80)) comprehensive_req = TRUE; //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if (!len_of_len) { dbg("[SAT] SAT PARSER - incorrect length"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - address_len = src_data[index + len_of_len - 1]; + address_len = src_data[temp_index + len_of_len - 1]; //check the address length - index += len_of_len; - if ((index + address_len) > tlv_len) { + temp_index += len_of_len; + if ((temp_index + address_len) > tlv_len) { dbg("[SAT] SAT PARSER - incorrect length"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } @@ -468,8 +477,8 @@ static enum tcore_sat_result _sat_decode_address_tlv(unsigned char* tlv_str, int address_obj->dialing_number_len = 0; if(address_len > 1){ char* str_ascii = NULL; - _sat_decode_ton_npi(src_data[index++], &address_obj->ton, &address_obj->npi); - str_ascii = tcore_util_convert_bcd2ascii((const char*)&src_data[index], address_len-1, SAT_DIALING_NUMBER_LEN_MAX); + _sat_decode_ton_npi(src_data[temp_index++], &address_obj->ton, &address_obj->npi); + str_ascii = tcore_util_convert_bcd2ascii((const char*)&src_data[temp_index], address_len-1, SAT_DIALING_NUMBER_LEN_MAX); if(str_ascii){ memcpy(address_obj->dialing_number, str_ascii, strlen(str_ascii)); address_obj->dialing_number_len = strlen(str_ascii); @@ -494,7 +503,7 @@ static enum tcore_sat_result _sat_decode_subaddress_tlv(unsigned char* tlv_str, int curr_offset, struct tel_sat_subaddress* sub_address_obj, int* consumed_data_len) { unsigned char* src_data; - int index, len_of_len = 0; + int temp_index, len_of_len = 0; int sub_address_len = 0; gboolean comprehensive_req = FALSE; @@ -509,28 +518,28 @@ static enum tcore_sat_result _sat_decode_subaddress_tlv(unsigned char* tlv_str, } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if ((src_data[index] & 0x7F) != SATK_SUB_ADDRESS_TAG) { + if ((src_data[temp_index] & 0x7F) != SATK_SUB_ADDRESS_TAG) { dbg("[SAT] SAT PARSER - sub address TAG missing"); return TCORE_SAT_REQUIRED_VALUE_MISSING; } //comprehensive required - if((src_data[index++] & 0x80)) + if((src_data[temp_index++] & 0x80)) comprehensive_req = TRUE; //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if (!len_of_len) { dbg("[SAT] SAT PARSER - incorrect length"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - sub_address_len = src_data[index + len_of_len - 1]; + sub_address_len = src_data[temp_index + len_of_len - 1]; //check the address length - index += len_of_len; - if ((index + sub_address_len) > tlv_len) { + temp_index += len_of_len; + if ((temp_index + sub_address_len) > tlv_len) { dbg("[SAT] SAT PARSER - incorrect length"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } @@ -553,7 +562,7 @@ static enum tcore_sat_result _sat_decode_subaddress_tlv(unsigned char* tlv_str, } } else{ - memcpy(sub_address_obj->subaddress, &src_data[index], sub_address_obj->subaddress_len); + memcpy(sub_address_obj->subaddress, &src_data[temp_index], sub_address_obj->subaddress_len); } *consumed_data_len = 1 + len_of_len + sub_address_len; @@ -564,7 +573,7 @@ static enum tcore_sat_result _sat_decode_alpha_identifier_tlv(unsigned char* tlv int curr_offset, struct tel_sat_alpha_identifier* alpha_id_obj, int* consumed_data_len) { unsigned char* src_data; - int index, len_of_len = 0; + int temp_index, len_of_len = 0; int alpha_len = 0; if (tlv_str == NULL || consumed_data_len == NULL || alpha_id_obj == NULL) { @@ -578,25 +587,25 @@ static enum tcore_sat_result _sat_decode_alpha_identifier_tlv(unsigned char* tlv } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if ((src_data[index++] & 0x7F) != SATK_ALPHA_IDENTIFIER_TAG) { + if ((src_data[temp_index++] & 0x7F) != SATK_ALPHA_IDENTIFIER_TAG) { dbg("[SAT] SAT PARSER - alphaID TAG missing"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } //length alpha_id_obj->is_exist = TRUE; - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if (!len_of_len) { dbg("[SAT] SAT PARSER - incorrect length"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - alpha_len = alpha_id_obj->alpha_data_len = src_data[index + len_of_len - 1]; + alpha_len = alpha_id_obj->alpha_data_len = src_data[temp_index + len_of_len - 1]; //alpha identifier - index += len_of_len; - if ((index + alpha_len) > tlv_len) { + temp_index += len_of_len; + if ((temp_index + alpha_len) > tlv_len) { dbg("[SAT] SAT PARSER - incorrect length"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } @@ -608,10 +617,10 @@ static enum tcore_sat_result _sat_decode_alpha_identifier_tlv(unsigned char* tlv if (alpha_id_obj->alpha_data_len >= SAT_ALPHA_ID_LEN_MAX) alpha_id_obj->alpha_data_len = SAT_ALPHA_ID_LEN_MAX - 1; - memcpy(alpha_id_obj->alpha_data, &src_data[index], alpha_id_obj->alpha_data_len); + memcpy(alpha_id_obj->alpha_data, &src_data[temp_index], alpha_id_obj->alpha_data_len); alpha_id_obj->alpha_data[alpha_id_obj->alpha_data_len] = 0x00; - if (src_data[index] == 0x80 || src_data[index] == 0x81 || src_data[index] == 0x82) + if (src_data[temp_index] == 0x80 || src_data[temp_index] == 0x81 || src_data[temp_index] == 0x82) dcs = 0X08; else dcs = 0x04; @@ -628,7 +637,7 @@ static enum tcore_sat_result _sat_decode_sub_address_tlv(unsigned char* tlv_str, int curr_offset, struct tel_sat_subaddress* sub_address_obj, int* consumed_data_len) { int i = 0; - int index, len_of_len = 0; + int temp_index, len_of_len = 0; int sub_address_len = 0; unsigned char* src_data; gboolean comprehension_req = FALSE; @@ -644,28 +653,28 @@ static enum tcore_sat_result _sat_decode_sub_address_tlv(unsigned char* tlv_str, } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if ((src_data[index] & 0x7F) != SATK_SUB_ADDRESS_TAG) { + if ((src_data[temp_index] & 0x7F) != SATK_SUB_ADDRESS_TAG) { dbg("[SAT] SAT PARSER - address TAG missing"); return TCORE_SAT_REQUIRED_VALUE_MISSING; } //comprehensive required - if((src_data[index++] & 0x80)) + if((src_data[temp_index++] & 0x80)) comprehension_req = TRUE; //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if (!len_of_len) { dbg("[SAT] SAT PARSER - incorrect length"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - sub_address_len = src_data[index + len_of_len - 1]; + sub_address_len = src_data[temp_index + len_of_len - 1]; //check the address length - index += len_of_len; - if ((index + sub_address_len) > tlv_len) { + temp_index += len_of_len; + if ((temp_index + sub_address_len) > tlv_len) { dbg("[SAT] SAT PARSER - incorrect length"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } @@ -683,7 +692,7 @@ static enum tcore_sat_result _sat_decode_sub_address_tlv(unsigned char* tlv_str, sub_address_obj->subaddress_len = 0; } else{ - memcpy(sub_address_obj->subaddress, &src_data[index],sub_address_obj->subaddress_len); + memcpy(sub_address_obj->subaddress, &src_data[temp_index],sub_address_obj->subaddress_len); } dbg("[SAT] SAT PARSER - subAddressLen=%d",sub_address_obj->subaddress_len); @@ -698,7 +707,7 @@ static enum tcore_sat_result _sat_decode_ccp_tlv(unsigned char* tlv_str, int tlv int curr_offset, struct tel_sat_ccp* ccp_obj, int* consumed_data_len) { int i = 0; - int index, len_of_len = 0; + int temp_index, len_of_len = 0; int ccp_len = 0; unsigned char* src_data; gboolean comprehension_req = FALSE; @@ -714,28 +723,28 @@ static enum tcore_sat_result _sat_decode_ccp_tlv(unsigned char* tlv_str, int tlv } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if ((src_data[index] & 0x7F) != SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG) { + if ((src_data[temp_index] & 0x7F) != SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG) { dbg("[SAT] SAT PARSER - CCP TAG missing"); return TCORE_SAT_REQUIRED_VALUE_MISSING; } //comprehensive required - if((src_data[index++] & 0x80)) + if((src_data[temp_index++] & 0x80)) comprehension_req = TRUE; //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if (!len_of_len) { dbg("[SAT] SAT PARSER - incorrect length"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - ccp_len = src_data[index + len_of_len - 1]; + ccp_len = src_data[temp_index + len_of_len - 1]; //check the address length - index += len_of_len; - if ((index + ccp_len) > tlv_len) { + temp_index += len_of_len; + if ((temp_index + ccp_len) > tlv_len) { dbg("[SAT] SAT PARSER - incorrect length"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } @@ -753,7 +762,7 @@ static enum tcore_sat_result _sat_decode_ccp_tlv(unsigned char* tlv_str, int tlv ccp_obj->data_len = 0; } else{ - memcpy(ccp_obj->data, &src_data[index],ccp_obj->data_len); + memcpy(ccp_obj->data, &src_data[temp_index],ccp_obj->data_len); } dbg("[SAT] SAT PARSER - ccp len=%d",ccp_obj->data_len); @@ -767,39 +776,39 @@ static enum tcore_sat_result _sat_decode_ccp_tlv(unsigned char* tlv_str, int tlv static enum tcore_sat_result _sat_decode_device_identities_tlv(unsigned char* tlv_str, struct tel_sat_device_identities* dev_id_obj) { - int index = 0, i; + int temp_index = 0, i; if (tlv_str == NULL || dev_id_obj == NULL) { dbg("[SAT] SAT PARSER - tlv_str ==NULL || dev_id_obj == NULL"); return TCORE_SAT_ERROR_FATAL; } - if ((tlv_str[index++] & 0x7F) != SATK_DEVICE_IDENTITY_TAG) { + if ((tlv_str[temp_index++] & 0x7F) != SATK_DEVICE_IDENTITY_TAG) { dbg("[SAT] SAT PARSER - device identity tag missing."); return TCORE_SAT_REQUIRED_VALUE_MISSING; //send TR } - if (tlv_str[index++] != SATK_DEVICE_IDENTITY_LENGTH) { + if (tlv_str[temp_index++] != SATK_DEVICE_IDENTITY_LENGTH) { dbg("[SAT] SAT PARSER - device identity length incorrect."); return TCORE_SAT_REQUIRED_VALUE_MISSING; //send TR } for (i = 0; i < 2; i++) { - switch (tlv_str[index]) { + switch (tlv_str[temp_index]) { case DEVICE_ID_KEYPAD: case DEVICE_ID_DISPLAY: case DEVICE_ID_EARPIECE: case DEVICE_ID_SIM: case DEVICE_ID_ME: case DEVICE_ID_NETWORK: - if (i == 0) dev_id_obj->src = tlv_str[index]; - if (i == 1) dev_id_obj->dest = tlv_str[index]; + if (i == 0) dev_id_obj->src = tlv_str[temp_index]; + if (i == 1) dev_id_obj->dest = tlv_str[temp_index]; break; default:{ - if(tlv_str[index] >= 0x21 && tlv_str[index] <= 0x27){ - dbg("BIP channel id(0x%x)", tlv_str[index]) - if (i == 0) dev_id_obj->src = tlv_str[index]; - if (i == 1) dev_id_obj->dest = tlv_str[index]; + if(tlv_str[temp_index] >= 0x21 && tlv_str[temp_index] <= 0x27){ + dbg("BIP channel id(0x%x)", tlv_str[temp_index]) + if (i == 0) dev_id_obj->src = tlv_str[temp_index]; + if (i == 1) dev_id_obj->dest = tlv_str[temp_index]; } else{ dbg("unmatched device id"); @@ -807,7 +816,7 @@ static enum tcore_sat_result _sat_decode_device_identities_tlv(unsigned char* tl } }break; } - index++; + temp_index++; } dbg("[SAT] SAT PARSER - source=%d, dest=%d", dev_id_obj->src, dev_id_obj->dest); @@ -817,7 +826,7 @@ static enum tcore_sat_result _sat_decode_device_identities_tlv(unsigned char* tl static enum tcore_sat_result _sat_decode_duration_tlv(unsigned char* tlv_str, int tlv_len, int curr_offset, struct tel_sat_duration *duration_obj, int* consumed_data_len) { - int index = 0; + int temp_index = 0; unsigned char* src_data = NULL; if (!tlv_str || !duration_obj || !consumed_data_len) { @@ -830,24 +839,24 @@ static enum tcore_sat_result _sat_decode_duration_tlv(unsigned char* tlv_str, in return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if ((src_data[index++] & 0x7F) != SATK_DURATION_TAG) { + if ((src_data[temp_index++] & 0x7F) != SATK_DURATION_TAG) { err("[SAT] SAT PARSER - duration tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } - if (src_data[index++] != SATK_DURATION_LENGTH) { + if (src_data[temp_index++] != SATK_DURATION_LENGTH) { err("[SAT] SAT PARSER - incorrect length value."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } //time unit - switch (src_data[index]) { + switch (src_data[temp_index]) { case TIME_UNIT_MINUTES: case TIME_UNIT_SECONDS: case TIME_UNIT_TENTHS_OF_SECONDS: - duration_obj->time_unit = src_data[index]; + duration_obj->time_unit = src_data[temp_index]; break; default: duration_obj->time_unit = TIME_UNIT_RESERVED; @@ -855,8 +864,8 @@ static enum tcore_sat_result _sat_decode_duration_tlv(unsigned char* tlv_str, in } //interval - index++; - duration_obj->time_interval = src_data[index]; + temp_index++; + duration_obj->time_interval = src_data[temp_index]; *consumed_data_len = 4; dbg("[SAT] SAT PARSER - timeUnit=%d, interval=%d", duration_obj->time_unit, duration_obj->time_interval); @@ -867,8 +876,9 @@ static enum tcore_sat_result _sat_decode_duration_tlv(unsigned char* tlv_str, in static enum tcore_sat_result _sat_decode_item_tlv(unsigned char* tlv_str, int tlv_len, int curr_offset, struct tel_sat_item_info* item_obj, int* consumed_data_len) { - int index, len_of_len=0, i=0; + int temp_index, len_of_len=0, i=0; int item_len =0; + unsigned char dcs; unsigned char* src_data = NULL; if(tlv_str == NULL || consumed_data_len == NULL || item_obj == NULL) { @@ -882,23 +892,23 @@ static enum tcore_sat_result _sat_decode_item_tlv(unsigned char* tlv_str, int tl } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if((src_data[index++]&0x7F) != SATK_ITEM_TAG){ - dbg("[SAT] SAT PARSER - tag not found.=%d",src_data[index-1]); + if((src_data[temp_index++]&0x7F) != SATK_ITEM_TAG){ + dbg("[SAT] SAT PARSER - tag not found.=%d",src_data[temp_index-1]); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if(!len_of_len){ dbg("[SAT] SAT PARSER - incorrect length"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - item_len = src_data[index+len_of_len-1]; + item_len = src_data[temp_index+len_of_len-1]; - index+=len_of_len; //index pointing to item. - if((index+item_len) > tlv_len){ + temp_index+=len_of_len; //temp_index pointing to item. + if((temp_index+item_len) > tlv_len){ dbg("[SAT] SAT PARSER - incorrect length"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } @@ -911,14 +921,14 @@ static enum tcore_sat_result _sat_decode_item_tlv(unsigned char* tlv_str, int tl } //item - item_obj->item_id = src_data[index++]; + item_obj->item_id = src_data[temp_index++]; // fix for orange SIM issue // H0100078487 Strange Character display on SIM SAT // The string length was less than its real length // So garbage characters was displayed. To fix it, we would recalculate the real length. for(i=0; itext_len = i; @@ -927,10 +937,17 @@ static enum tcore_sat_result _sat_decode_item_tlv(unsigned char* tlv_str, int tl return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - if(item_obj->text_len > SAT_ITEM_TEXT_LEN_MAX) - item_obj->text_len = SAT_ITEM_TEXT_LEN_MAX; + if(item_obj->text_len >= SAT_ITEM_TEXT_LEN_MAX) + item_obj->text_len = SAT_ITEM_TEXT_LEN_MAX-1; + + memcpy(item_obj->text, &src_data[temp_index], item_obj->text_len); + if (src_data[temp_index] == 0x80 || src_data[temp_index] == 0x81 || src_data[temp_index] == 0x82) + dcs = 0X08; + else + dcs = 0x04; + + _sat_decode_dcs(dcs, &item_obj->dcs); - memcpy(item_obj->text, &src_data[index], item_obj->text_len); dbg("[SAT] SAT PARSER - item_text=%s", item_obj->text); *consumed_data_len = 1+len_of_len+item_len; @@ -940,7 +957,7 @@ static enum tcore_sat_result _sat_decode_item_tlv(unsigned char* tlv_str, int tl static enum tcore_sat_result _sat_decode_response_length_tlv(unsigned char* tlv_str, int tlv_len, int curr_offset, struct tel_sat_response_length *response_obj, int* consumed_data_len) { - int index = 0; + int temp_index = 0; unsigned char* src_data = NULL; if (!tlv_str || !response_obj || !consumed_data_len) { @@ -953,26 +970,26 @@ static enum tcore_sat_result _sat_decode_response_length_tlv(unsigned char* tlv_ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if ((src_data[index++] & 0x7F) != SATK_RESPONSE_LENGTH_TAG) { + if ((src_data[temp_index++] & 0x7F) != SATK_RESPONSE_LENGTH_TAG) { err("[SAT] SAT PARSER - response length tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } - if (src_data[index++] != SATK_RESPONSE_LENGTH_LENGTH) { + if (src_data[temp_index++] != SATK_RESPONSE_LENGTH_LENGTH) { err("[SAT] SAT PARSER - incorrect length value."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } - response_obj->min = src_data[index++]; - response_obj->max = src_data[index++]; + response_obj->min = src_data[temp_index++]; + response_obj->max = src_data[temp_index++]; dbg("[SAT] SAT PARSER min length(%d), max length(%d)", response_obj->min, response_obj->max); *consumed_data_len = 4; if(response_obj->min > response_obj->max){ err("[SAT] SAT PARSER - : min length is larger than max length"); - return TCORE_SAT_BEYOND_ME_CAPABILITY; + return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } return TCORE_SAT_SUCCESS; @@ -981,7 +998,7 @@ static enum tcore_sat_result _sat_decode_response_length_tlv(unsigned char* tlv_ static enum tcore_sat_result _sat_decode_sms_tpdu_tlv(unsigned char* tlv_str, int tlv_len, int curr_offset, struct tel_sat_sms_tpdu *sms_tpdu_obj, int* consumed_data_len) { - int index = 0, len_of_len = 0; + int temp_index = 0, len_of_len = 0; int tpdu_len = 0; unsigned char* src_data = NULL; @@ -995,21 +1012,21 @@ static enum tcore_sat_result _sat_decode_sms_tpdu_tlv(unsigned char* tlv_str, in return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if ((src_data[index++] & 0x7F) != SATK_SMS_TPDU_TAG) { + if ((src_data[temp_index++] & 0x7F) != SATK_SMS_TPDU_TAG) { err("[SAT] SAT PARSER - sat tpdu tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if(!len_of_len){ err("[SAT] parser: invalid length."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - tpdu_len = src_data[index+len_of_len-1]; - index += len_of_len; + tpdu_len = src_data[temp_index+len_of_len-1]; + temp_index += len_of_len; if(tpdu_len <= 0) return TCORE_SAT_REQUIRED_VALUE_MISSING; @@ -1021,7 +1038,7 @@ static enum tcore_sat_result _sat_decode_sms_tpdu_tlv(unsigned char* tlv_str, in } //data - memcpy(sms_tpdu_obj->data, &src_data[index], sms_tpdu_obj->data_len); + memcpy(sms_tpdu_obj->data, &src_data[temp_index], sms_tpdu_obj->data_len); dbg("[SAT] SAT PARSER tpdu_len (%d)", sms_tpdu_obj->data_len); *consumed_data_len = 1+len_of_len+tpdu_len; @@ -1031,7 +1048,7 @@ static enum tcore_sat_result _sat_decode_sms_tpdu_tlv(unsigned char* tlv_str, in static enum tcore_sat_result _sat_decode_item_identifier_tlv(unsigned char* tlv_str, int tlv_len, int curr_offset, struct tel_sat_item_identifier *item_identifier_obj, int* consumed_data_len) { - int index = 0; + int temp_index = 0; unsigned char* src_data = NULL; if (!tlv_str || !item_identifier_obj || !consumed_data_len) { @@ -1044,19 +1061,19 @@ static enum tcore_sat_result _sat_decode_item_identifier_tlv(unsigned char* tlv_ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if ((src_data[index++] & 0x7F) != SATK_ITEM_IDENTIFIER_TAG) { + if ((src_data[temp_index++] & 0x7F) != SATK_ITEM_IDENTIFIER_TAG) { err("[SAT] SAT PARSER - Item identifier tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } - if (src_data[index++] != SATK_ITEM_IDENTIFIER_LENGTH) { + if (src_data[temp_index++] != SATK_ITEM_IDENTIFIER_LENGTH) { err("[SAT] SAT PARSER - incorrect length value."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } - item_identifier_obj->item_identifier = src_data[index++]; + item_identifier_obj->item_identifier = src_data[temp_index++]; *consumed_data_len = 3; dbg("[SAT] SAT PARSER item identifier(0x%02x)", item_identifier_obj->item_identifier); @@ -1067,7 +1084,7 @@ static enum tcore_sat_result _sat_decode_ss_string_tlv(unsigned char* tlv_str, i int curr_offset, struct tel_sat_ss_string *ss_str_obj, int* consumed_data_len) { char* str_ascii = NULL; - int index, len_of_len=0; + int temp_index, len_of_len=0; int ss_len =0; unsigned char* src_data; gboolean comprehension_req = FALSE; @@ -1082,38 +1099,40 @@ static enum tcore_sat_result _sat_decode_ss_string_tlv(unsigned char* tlv_str, i return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if ((src_data[index++] & 0x7F) != SATK_SS_STRING_TAG) { + if ((src_data[temp_index] & 0x7F) != SATK_SS_STRING_TAG) { err("[SAT] SAT PARSER - SS string tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } - if(src_data[index++]&0x80) + if(src_data[temp_index++]&0x80) comprehension_req = TRUE; + dbg("comprehension_req=[%d]", comprehension_req); + //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if(!len_of_len){ err("[SAT] parser: invalid length."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - ss_len = src_data[index+len_of_len-1]; + ss_len = src_data[temp_index+len_of_len-1]; dbg("[SAT] parser: ss_tlv len=%d",ss_len); - index += len_of_len; + temp_index += len_of_len; ss_str_obj->string_len = 0; //ss data if(ss_len <= 1) return TCORE_SAT_REQUIRED_VALUE_MISSING; - _sat_decode_ton_npi(src_data[index++], &ss_str_obj->ton, &ss_str_obj->npi); - str_ascii = tcore_util_convert_bcd2ascii((const char*)&src_data[index], ss_len-1, SAT_SS_STRING_LEN_MAX); + _sat_decode_ton_npi(src_data[temp_index++], &ss_str_obj->ton, &ss_str_obj->npi); + str_ascii = tcore_util_convert_bcd2ascii((const char*)&src_data[temp_index], ss_len-1, SAT_SS_STRING_LEN_MAX); if(str_ascii){ - memcpy(ss_str_obj->ss_string, str_ascii, sizeof(str_ascii)); - ss_str_obj->string_len = sizeof(str_ascii); + memcpy(ss_str_obj->ss_string, str_ascii, strlen(str_ascii)); + ss_str_obj->string_len = strlen(str_ascii); g_free(str_ascii); } @@ -1125,7 +1144,7 @@ static enum tcore_sat_result _sat_decode_ss_string_tlv(unsigned char* tlv_str, i static enum tcore_sat_result _sat_decode_text_tlv(unsigned char* tlv_str, int tlv_len, int curr_offset, struct tel_sat_text_string_object *text_obj, int* consumed_data_len) { - int index, len_of_len=0; + int temp_index, len_of_len=0; int text_len =0; unsigned char* src_data; gboolean comprehension_req = FALSE; @@ -1141,39 +1160,40 @@ static enum tcore_sat_result _sat_decode_text_tlv(unsigned char* tlv_str, int tl } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if((src_data[index]&0x7F) != SATK_TEXT_STRING_TAG){ - err("[SAT] parser: text string tag missing, tag=0x%x",src_data[index]); + if((src_data[temp_index]&0x7F) != SATK_TEXT_STRING_TAG && (src_data[temp_index]&0x7F) != SATK_DEFAULT_TEXT_TAG){ + err("[SAT] parser: text string tag missing, tag=0x%x",src_data[temp_index]); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - if(src_data[index++]&0x80) + if(src_data[temp_index++]&0x80) comprehension_req = TRUE; + dbg("comprehension_req=[%d]", comprehension_req); + //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if(!len_of_len){ err("[SAT] parser: invalid length."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - text_len = src_data[index+len_of_len-1]; - dbg("[SAT] parser: text_tlv_len=%d",text_len); - - index += len_of_len; + text_len = src_data[temp_index+len_of_len-1]; + temp_index += len_of_len; memset(text_obj->string, 0x00, SAT_TEXT_STRING_LEN_MAX); //text if(text_len <=1){ text_obj->string_length = 0; }else{ - text_obj->string_length = text_len-1; - _sat_decode_dcs(src_data[index++], &text_obj->dcs); - _get_string_data(&src_data[index], text_obj->string_length, text_obj); + _sat_decode_dcs(src_data[temp_index++], &text_obj->dcs); + _get_string_data(&src_data[temp_index], text_len-1, text_obj); } - // 1 is the length of Tag. + dbg("[SAT] parser: text_tlv_len=%d, parsed text length=%d", text_len, text_obj->string_length); + + // 1 is the length of Tag. *consumed_data_len = 1 + len_of_len + text_len; return TCORE_SAT_SUCCESS; @@ -1182,7 +1202,7 @@ static enum tcore_sat_result _sat_decode_text_tlv(unsigned char* tlv_str, int tl static enum tcore_sat_result _sat_decode_tone_tlv(unsigned char* tlv_str, int tlv_len, int curr_offset, struct tel_sat_tone *tone_obj, int* consumed_data_len) { - int index; + int temp_index; unsigned char* src_data; gboolean comprehension_req = FALSE; @@ -1197,30 +1217,30 @@ static enum tcore_sat_result _sat_decode_tone_tlv(unsigned char* tlv_str, int tl } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if((src_data[index]&0x7F) != SATK_TONE_TAG){ + if((src_data[temp_index]&0x7F) != SATK_TONE_TAG){ err("[SAT] parser: tone tag missing"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - if(src_data[index++]&0x80) + if(src_data[temp_index++]&0x80) comprehension_req = TRUE; //length - if (src_data[index++] != SATK_TONE_LENGTH) { + if (src_data[temp_index++] != SATK_TONE_LENGTH) { err("[SAT] SAT PARSER - incorrect length value."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } - if((index+SATK_TONE_LENGTH) > tlv_len) + if((temp_index+SATK_TONE_LENGTH) > tlv_len) { - err("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (index+SATK_TONE_LENGTH),tlv_len); + err("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index+SATK_TONE_LENGTH),tlv_len); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } //tone - switch(src_data[index]) + switch(src_data[temp_index]) { // standard supervisory tones case DIAL_TONE: @@ -1253,13 +1273,13 @@ static enum tcore_sat_result _sat_decode_tone_tlv(unsigned char* tlv_str, int tl case MELODY_6: case MELODY_7: case MELODY_8: - dbg("[SAT] SAT PARSER - Tone =0x%x", src_data[index]); - tone_obj->tone_type = src_data[index]; + dbg("[SAT] SAT PARSER - Tone =0x%x", src_data[temp_index]); + tone_obj->tone_type = src_data[temp_index]; break; case TONE_TYPE_RESERVED: default: - dbg("[SAT] SAT PARSER - Reserved value of Tone =0x%x", src_data[index]); + dbg("[SAT] SAT PARSER - Reserved value of Tone =0x%x", src_data[temp_index]); if(comprehension_req) return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; break; @@ -1272,7 +1292,7 @@ static enum tcore_sat_result _sat_decode_tone_tlv(unsigned char* tlv_str, int tl static enum tcore_sat_result _sat_decode_ussd_string_tlv(unsigned char* tlv_str, int tlv_len, int curr_offset, struct tel_sat_ussd_string *ussd_str_obj, int* consumed_data_len) { - int index, len_of_len=0; + int temp_index, len_of_len=0; int ussd_len =0; unsigned char* src_data; gboolean comprehension_req = FALSE; @@ -1287,36 +1307,38 @@ static enum tcore_sat_result _sat_decode_ussd_string_tlv(unsigned char* tlv_str, return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if ((src_data[index++] & 0x7F) != SATK_USSD_STRING_TAG) { + if ((src_data[temp_index] & 0x7F) != SATK_USSD_STRING_TAG) { err("[SAT] SAT PARSER - SS string tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } - if(src_data[index++]&0x80) + if(src_data[temp_index++]&0x80) comprehension_req = TRUE; + dbg("comprehension_req=[%d]", comprehension_req); + //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if(!len_of_len){ err("[SAT] parser: invalid length."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - ussd_len = src_data[index+len_of_len-1]; + ussd_len = src_data[temp_index+len_of_len-1]; dbg("[SAT] parser: ussd_tlv len=%d",ussd_len); - index += len_of_len; + temp_index += len_of_len; ussd_str_obj->string_len = 0; //ussd data if(ussd_len <= 1) return TCORE_SAT_REQUIRED_VALUE_MISSING; - _sat_decode_dcs(src_data[index++], &ussd_str_obj->dsc); + _sat_decode_dcs(src_data[temp_index++], &ussd_str_obj->dsc); ussd_str_obj->string_len = ussd_len - 1; - memcpy(ussd_str_obj->ussd_string, &src_data[index], ussd_str_obj->string_len); + memcpy(ussd_str_obj->ussd_string, &src_data[temp_index], ussd_str_obj->string_len); // 1 is the length of Tag. *consumed_data_len = 1 + len_of_len + ussd_len; @@ -1327,11 +1349,11 @@ static enum tcore_sat_result _sat_decode_file_list_tlv(unsigned char* tlv_str, i int curr_offset, struct tel_sat_file_list *file_list_obj, int* consumed_data_len) { //tmp - int tmp_cnt, tmp_path_len; + int tmp_cnt; int f_count; unsigned int ef = 0x0000; - int index, len_of_len=0; + int temp_index, len_of_len=0; int file_list_len = 0; unsigned char* src_data; @@ -1346,29 +1368,28 @@ static enum tcore_sat_result _sat_decode_file_list_tlv(unsigned char* tlv_str, i } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if((src_data[index]&0x7F) != SATK_FILE_LIST_TAG){ - err("[SAT] parser: tag missing, tag=0x%x",src_data[index]); + if((src_data[temp_index]&0x7F) != SATK_FILE_LIST_TAG){ + err("[SAT] parser: tag missing, tag=0x%x",src_data[temp_index]); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if(!len_of_len){ err("[SAT] parser: invalid length."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - file_list_len = src_data[index+len_of_len-1]; - index += len_of_len; + file_list_len = src_data[temp_index+len_of_len-1]; + temp_index += len_of_len; - if((index+file_list_len) > tlv_len) { - dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (index+file_list_len),tlv_len); + if((temp_index+file_list_len) > tlv_len) { + dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index+file_list_len),tlv_len); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - tmp_cnt = src_data[index++]; - tmp_path_len = file_list_len - 1; + tmp_cnt = src_data[temp_index++]; file_list_obj->file_count = 0; memset(file_list_obj->file_id, 0, SAT_FILE_ID_LIST_MAX_COUNT); @@ -1380,31 +1401,31 @@ static enum tcore_sat_result _sat_decode_file_list_tlv(unsigned char* tlv_str, i f_count = 0; do{ ef = 0x0000; - if( src_data[index] != 0x3F || src_data[index+1] != 0x00){ - index++; - if(index > tlv_len) break; + if( src_data[temp_index] != 0x3F || src_data[temp_index+1] != 0x00){ + temp_index++; + if(temp_index > tlv_len) break; else continue; } - index+=2; //MASTER FILE (DIR) 0x3F00 + temp_index+=2; //MASTER FILE (DIR) 0x3F00 - if(src_data[index] == 0x2F){ + if(src_data[temp_index] == 0x2F){ //ELEMENTRY FILE (VALUE) - ef = src_data[index] << 8; - index++; - ef = ef | src_data[index]; + ef = src_data[temp_index] << 8; + temp_index++; + ef = ef | src_data[temp_index]; if( _check_file_for_refresh((enum tel_sim_file_id)ef) ){//check file registered for refresh? file_list_obj->file_id[file_list_obj->file_count] = ef; file_list_obj->file_count++; } } - else if(src_data[index] == 0x7F && src_data[index+1] == 0xFF){ + else if(src_data[temp_index] == 0x7F && src_data[temp_index+1] == 0xFF){ //USIM DIRECTORY FILE (DIR) 0x7FFF - index+=2; - if(src_data[index] == 0x6F){ + temp_index+=2; + if(src_data[temp_index] == 0x6F){ ef = 0x6A << 8; - index++; - ef = ef | src_data[index]; + temp_index++; + ef = ef | src_data[temp_index]; if( _check_file_for_refresh((enum tel_sim_file_id)ef) ){//check file registered for refresh? file_list_obj->file_id[file_list_obj->file_count] = ef; @@ -1412,16 +1433,16 @@ static enum tcore_sat_result _sat_decode_file_list_tlv(unsigned char* tlv_str, i } } else{ - index++; + temp_index++; } } - else if(src_data[index] == 0x7F && (src_data[index+1] == 0x10 || src_data[index+1] == 0x20) ){ + else if(src_data[temp_index] == 0x7F && (src_data[temp_index+1] == 0x10 || src_data[temp_index+1] == 0x20) ){ //TELECOM DIRECTORY FILE 0x7F10 or GSM DIRECTORY FILE 0x7F20 - index+=2; - if(src_data[index] == 0x6F){ - ef = src_data[index] << 8; - index++; - ef = ef | src_data[index]; + temp_index+=2; + if(src_data[temp_index] == 0x6F){ + ef = src_data[temp_index] << 8; + temp_index++; + ef = ef | src_data[temp_index]; if( _check_file_for_refresh((enum tel_sim_file_id)ef) ){//check file registered for refresh? file_list_obj->file_id[file_list_obj->file_count] = ef; @@ -1429,12 +1450,12 @@ static enum tcore_sat_result _sat_decode_file_list_tlv(unsigned char* tlv_str, i } } else{ - index++; + temp_index++; } } f_count++; - index++; + temp_index++; }while( f_count < tmp_cnt); dbg("[SAT] SAT PARSER - total file count=%d, PDA file count = %d", tmp_cnt, file_list_obj->file_count); @@ -1447,7 +1468,7 @@ static enum tcore_sat_result _sat_decode_item_next_action_indicator_tlv(unsigned struct tel_sat_item_next_action_indicatior_list* item_next_act_indi_obj, int* consumed_data_len) { - int index; + int temp_index; int item_nai_len; unsigned char* src_data; gboolean comprehension_req = FALSE; @@ -1463,20 +1484,20 @@ static enum tcore_sat_result _sat_decode_item_next_action_indicator_tlv(unsigned } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if((src_data[index]&0x7F) != SATK_ITEMS_NEXT_ACTION_INDICATOR_TAG){ - dbg("[SAT] SAT PARSER - tag not found.=%d",src_data[index]); + if((src_data[temp_index]&0x7F) != SATK_ITEMS_NEXT_ACTION_INDICATOR_TAG){ + dbg("[SAT] SAT PARSER - tag not found.=%d",src_data[temp_index]); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - if((src_data[index++]&0x7F)) + if((src_data[temp_index++]&0x7F)) comprehension_req = TRUE; //item cnt - item_nai_len = item_next_act_indi_obj->cnt = src_data[index++]; - if((index+item_nai_len) > tlv_len) { - dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (index+item_nai_len),tlv_len); + item_nai_len = item_next_act_indi_obj->cnt = src_data[temp_index++]; + if((temp_index+item_nai_len) > tlv_len) { + dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index+item_nai_len),tlv_len); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } @@ -1490,7 +1511,7 @@ static enum tcore_sat_result _sat_decode_item_next_action_indicator_tlv(unsigned memset(item_next_act_indi_obj->indicator_list, 0xFF, SAT_ITEMS_NEXT_ACTION_INDI_LIST_MAX_COUNT); if(item_next_act_indi_obj->cnt > 0) - memcpy(item_next_act_indi_obj->indicator_list, &src_data[index], item_next_act_indi_obj->cnt); + memcpy(item_next_act_indi_obj->indicator_list, &src_data[temp_index], item_next_act_indi_obj->cnt); *consumed_data_len = 1+1+item_nai_len; dbg("[SAT] SAT PARSER - listCount=%d, consumed_data_len = %d",item_next_act_indi_obj->cnt, *consumed_data_len); @@ -1498,10 +1519,10 @@ static enum tcore_sat_result _sat_decode_item_next_action_indicator_tlv(unsigned } static enum tcore_sat_result _sat_decode_event_list_tlv(unsigned char* tlv_str, int tlv_len, - int curr_offset, struct tel_sat_event_list* event_list_obj, struct tel_sat_event_list* modem_event_list_obj, int* consumed_data_len) + int curr_offset, struct tel_sat_event_list* event_list_obj, int* consumed_data_len) { int i = 0; - int index, len_of_len=0; + int temp_index, len_of_len=0; int evt_list_len; unsigned char* src_data; gboolean comprehension_req = FALSE; @@ -1517,29 +1538,29 @@ static enum tcore_sat_result _sat_decode_event_list_tlv(unsigned char* tlv_str, } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if((src_data[index]&0x7F) != SATK_EVENT_LIST_TAG){ - dbg("[SAT] SAT PARSER - tag not found.=%d",src_data[index]); + if((src_data[temp_index]&0x7F) != SATK_EVENT_LIST_TAG){ + dbg("[SAT] SAT PARSER - tag not found.=%d",src_data[temp_index]); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - if((src_data[index++]&0x80)) + if((src_data[temp_index++]&0x80)) comprehension_req = TRUE; //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if(!len_of_len){ err("[SAT] parser: invalid length."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - evt_list_len = src_data[index+len_of_len-1]; + evt_list_len = src_data[temp_index+len_of_len-1]; dbg("[SAT] parser: evt_list_len=%d",evt_list_len); - index += len_of_len; + temp_index += len_of_len; - if((index+evt_list_len) > tlv_len) { - dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (index+evt_list_len),tlv_len); + if((temp_index+evt_list_len) > tlv_len) { + dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index+evt_list_len),tlv_len); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } @@ -1554,13 +1575,10 @@ static enum tcore_sat_result _sat_decode_event_list_tlv(unsigned char* tlv_str, event_list_obj->event_list_cnt = 0; memset(event_list_obj->evt_list, 0xFF, SAT_EVENT_LIST_MAX); - modem_event_list_obj->event_list_cnt = 0; - memset(modem_event_list_obj->evt_list, 0xFF, SAT_EVENT_LIST_MAX); - //event list for(i = 0; i < evt_list_len; i++){ - dbg("[SAT] SAT PARSER - event[%d]=0x%x", i, src_data[index]); - switch(src_data[index]){ + dbg("[SAT] SAT PARSER - event[%d]=0x%x", i, src_data[temp_index]); + switch(src_data[temp_index]){ /*PDA events*/ case EVENT_USER_ACTIVITY: case EVENT_IDLE_SCREEN_AVAILABLE: @@ -1568,17 +1586,13 @@ static enum tcore_sat_result _sat_decode_event_list_tlv(unsigned char* tlv_str, case EVENT_BROWSER_TERMINATION: case EVENT_DATA_AVAILABLE: case EVENT_CHANNEL_STATUS: - event_list_obj->evt_list[i] = src_data[index]; - event_list_obj->event_list_cnt++; - break; - /*MODEM events*/ case EVENT_MT_CALL : case EVENT_CALL_CONNECTED: case EVENT_CALL_DISCONNECTED: case EVENT_LOCATION_STATUS: case EVENT_ACCESS_TECHNOLOGY_CHANGED: - modem_event_list_obj->evt_list[i] = src_data[index]; - modem_event_list_obj->event_list_cnt++; + event_list_obj->evt_list[i] = src_data[temp_index]; + event_list_obj->event_list_cnt++; break; case EVENT_UNKNOWN: default: @@ -1586,7 +1600,7 @@ static enum tcore_sat_result _sat_decode_event_list_tlv(unsigned char* tlv_str, return TCORE_SAT_BEYOND_ME_CAPABILITY; break; } - index++; + temp_index++; } // 1 is the length of Tag. @@ -1598,7 +1612,7 @@ static enum tcore_sat_result _sat_decode_icon_identifier_tlv(unsigned char* tlv_ int curr_offset, struct tel_sat_icon_identifier* icon_id_obj, int* consumed_data_len) { unsigned char* src_data; - int index = 0; + int temp_index = 0; if(tlv_str == NULL || icon_id_obj == NULL ||consumed_data_len == NULL) { dbg("[SAT] SAT PARSER - tlv_str == NULL || icon_id_obj == NULL ||consumed_data_len == NULL"); @@ -1611,31 +1625,31 @@ static enum tcore_sat_result _sat_decode_icon_identifier_tlv(unsigned char* tlv_ } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if((src_data[index++]&0x7F) != SATK_ICON_IDENTIFIER_TAG) { + if((src_data[temp_index++]&0x7F) != SATK_ICON_IDENTIFIER_TAG) { dbg("[SAT] SAT PARSER - icon identity tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } - if(src_data[index++] != SATK_ICON_IDENTITY_LENGTH) { + if(src_data[temp_index++] != SATK_ICON_IDENTITY_LENGTH) { dbg("[SAT] SAT PARSER - incorrect length value."); return FALSE; //send TR } - if((index+SATK_ICON_IDENTITY_LENGTH) > tlv_len) { - dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (index+SATK_ICON_IDENTITY_LENGTH),tlv_len); + if((temp_index+SATK_ICON_IDENTITY_LENGTH) > tlv_len) { + dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index+SATK_ICON_IDENTITY_LENGTH),tlv_len); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } icon_id_obj->is_exist = TRUE; - if((src_data[index++]&0x01)) + if((src_data[temp_index++]&0x01)) icon_id_obj->icon_qualifer = ICON_QUALI_NOT_SELF_EXPLANATORY; else icon_id_obj->icon_qualifer = ICON_QUALI_SELF_EXPLANATORY; - if(src_data[index] > 0x00) { - icon_id_obj->icon_identifier = src_data[index]; + if(src_data[temp_index] > 0x00) { + icon_id_obj->icon_identifier = src_data[temp_index]; } else { dbg("[SAT] SAT PARSER - incorrect icon identifier"); @@ -1651,7 +1665,7 @@ static enum tcore_sat_result _sat_decode_icon_identifier_list_tlv(unsigned char* int tlv_len, int curr_offset, struct tel_sat_icon_identifier_list* icon_list_obj, int* consumed_data_len) { - int index, i; + int temp_index, i; int len_value =0; unsigned char* src_data; gboolean comprehension_req = FALSE; @@ -1667,19 +1681,19 @@ static enum tcore_sat_result _sat_decode_icon_identifier_list_tlv(unsigned char* } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if((src_data[index]&0x7F) != SATK_ITEM_ICON_IDENTIFIER_LIST_TAG) { + if((src_data[temp_index]&0x7F) != SATK_ITEM_ICON_IDENTIFIER_LIST_TAG) { dbg("[SAT] SAT PARSER - icon identity tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } icon_list_obj->is_exist = TRUE; - if(src_data[index++]&0x80) + if(src_data[temp_index++]&0x80) comprehension_req = TRUE; - len_value = src_data[index++]; - if(src_data[index++]&0x01) + len_value = src_data[temp_index++]; + if(src_data[temp_index++]&0x01) icon_list_obj->icon_qualifer = ICON_QUALI_NOT_SELF_EXPLANATORY; else icon_list_obj->icon_qualifer = ICON_QUALI_SELF_EXPLANATORY; @@ -1695,8 +1709,8 @@ static enum tcore_sat_result _sat_decode_icon_identifier_list_tlv(unsigned char* else{ for(i=0;iicon_cnt;i++) { - if(src_data[index] > 0x00) { - icon_list_obj->icon_id_list[i]= src_data[index++]; + if(src_data[temp_index] > 0x00) { + icon_list_obj->icon_id_list[i]= src_data[temp_index++]; } else { dbg("[SAT] SAT PARSER - incorrect icon identifier"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR @@ -1713,7 +1727,7 @@ static enum tcore_sat_result _sat_decode_dtmf_string_tlv(unsigned char* tlv_str, int curr_offset, struct tel_sat_dtmf_string* dtmf_string_obj, int* consumed_data_len) { unsigned char* src_data; - int index, len_of_len = 0; + int temp_index, len_of_len = 0; int dtmf_len = 0; gboolean comprehension_req = FALSE; char* str_ascii = NULL; @@ -1731,38 +1745,40 @@ static enum tcore_sat_result _sat_decode_dtmf_string_tlv(unsigned char* tlv_str, } //Tag - index = curr_offset; - if ((src_data[index] & 0x7F) != SATK_DTMF_STRING_TAG) { + temp_index = curr_offset; + if ((src_data[temp_index] & 0x7F) != SATK_DTMF_STRING_TAG) { dbg("[SAT] SAT PARSER - address tag missing"); return TCORE_SAT_REQUIRED_VALUE_MISSING; } //comprehensive required - if((src_data[index++] & 0x80)) + if((src_data[temp_index++] & 0x80)) comprehension_req = TRUE; + dbg("comprehension_req=[%d]", comprehension_req); + //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if(!len_of_len){ err("[SAT] parser: invalid length."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - dtmf_len = src_data[index + len_of_len - 1]; - index += len_of_len; //index pointing to TON/NPI + dtmf_len = src_data[temp_index + len_of_len - 1]; + temp_index += len_of_len; //temp_index pointing to TON/NPI - if ((index + dtmf_len) > tlv_len) { - dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (index+dtmf_len), tlv_len); + if ((temp_index + dtmf_len) > tlv_len) { + dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index+dtmf_len), tlv_len); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } dtmf_string_obj->dtmf_length = 0; if(dtmf_len > 0){ - str_ascii = tcore_util_convert_bcd2ascii((const char*)&src_data[index], dtmf_len, SAT_DTMF_STRING_LEN_MAX); + str_ascii = tcore_util_convert_bcd2ascii((const char*)&src_data[temp_index], dtmf_len, SAT_DTMF_STRING_LEN_MAX); if(str_ascii){ - memcpy(dtmf_string_obj->dtmf_string, str_ascii, sizeof(str_ascii)); - dtmf_string_obj->dtmf_length = sizeof(str_ascii); + memcpy(dtmf_string_obj->dtmf_string, str_ascii, strlen(str_ascii)); + dtmf_string_obj->dtmf_length = strlen(str_ascii); g_free(str_ascii); } } @@ -1780,7 +1796,7 @@ static enum tcore_sat_result _sat_decode_language_tlv(unsigned char* tlv_str, in int curr_offset, enum tel_sim_language_type* language_obj) { unsigned char* src_data; - int index = 0; + int temp_index = 0; if(tlv_len <= (curr_offset+1)) { dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len); @@ -1788,23 +1804,23 @@ static enum tcore_sat_result _sat_decode_language_tlv(unsigned char* tlv_str, in } src_data = &tlv_str[0]; - index = curr_offset; + temp_index = curr_offset; - if((src_data[index++]&0x7F) != SATK_LANGUAGE_TAG) { + if((src_data[temp_index++]&0x7F) != SATK_LANGUAGE_TAG) { dbg("[SAT] SAT PARSER - Language tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - if(src_data[index++] != SATK_LANGUAGE_LENGTH) { + if(src_data[temp_index++] != SATK_LANGUAGE_LENGTH) { dbg("[SAT] SAT PARSER - incorrect length value."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - if((index+SATK_LANGUAGE_LENGTH) > tlv_len) { - dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (index+SATK_LANGUAGE_LENGTH),tlv_len); + if((temp_index+SATK_LANGUAGE_LENGTH) > tlv_len) { + dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index+SATK_LANGUAGE_LENGTH),tlv_len); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - *language_obj = _sat_decode_language(src_data[index], src_data[index+1]); - dbg("[SAT] SAT PARSER - %c %c, %d", src_data[index], src_data[index+1], *language_obj); + *language_obj = _sat_decode_language(src_data[temp_index], src_data[temp_index+1]); + dbg("[SAT] SAT PARSER - %c %c, %d", src_data[temp_index], src_data[temp_index+1], *language_obj); return TCORE_SAT_SUCCESS; } @@ -1812,7 +1828,7 @@ static enum tcore_sat_result _sat_decode_browser_identity_tlv(unsigned char* tlv enum browser_identity* browser_id, int* consumed_data_len) { unsigned char* src_data; - int index = 0; + int temp_index = 0; if (tlv_str == NULL || browser_id == NULL || consumed_data_len == NULL) { dbg("[SAT] SAT PARSER - tlv_str == NULL || browser_id == NULL ||consumed_data_len == NULL"); @@ -1824,21 +1840,21 @@ static enum tcore_sat_result _sat_decode_browser_identity_tlv(unsigned char* tlv return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if ((src_data[index++] & 0x7F) != SATK_BROWSER_IDENTITY_TAG) { + if ((src_data[temp_index++] & 0x7F) != SATK_BROWSER_IDENTITY_TAG) { dbg("[SAT] SAT PARSER - Browser ID tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - if (src_data[index++] != SATK_BROWSER_ID_LENGTH) { + if (src_data[temp_index++] != SATK_BROWSER_ID_LENGTH) { dbg("[SAT] SAT PARSER - incorrect length value."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - dbg("[SAT] SAT PARSER - : browser ID value:ox%x", src_data[index]); + dbg("[SAT] SAT PARSER - : browser ID value:ox%x", src_data[temp_index]); - switch (src_data[index]) { + switch (src_data[temp_index]) { case 0x00: *browser_id = BROWSER_ID_DEFAULT; break; @@ -1867,7 +1883,7 @@ static enum tcore_sat_result _sat_decode_url_tlv(unsigned char* tlv_str, int tlv struct tel_sat_url* url, int* consumed_data_len) { unsigned char* src_data; - int index= curr_offset; + int temp_index= curr_offset; int len_of_len=0, url_len=0; if (tlv_str == NULL || url == NULL || consumed_data_len == NULL) { @@ -1881,31 +1897,39 @@ static enum tcore_sat_result _sat_decode_url_tlv(unsigned char* tlv_str, int tlv return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - if((src_data[index++]&0x7F) != SATK_URL_TAG) { + if((src_data[temp_index++]&0x7F) != SATK_URL_TAG) { dbg("[SAT] SAT PARSER - Browser URL tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if(!len_of_len){ err("[SAT] parser: invalid length."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - url_len = src_data[index+len_of_len-1]; - index+=len_of_len; //index pointing to url. + url_len = src_data[temp_index+len_of_len-1]; + url->url_length = url_len; + temp_index+=len_of_len; //temp_index pointing to url. + dbg("URL length (%d)", url_len); - if(url_len > 0) { - if(url_len > SAT_URL_LEN_MAX) - return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; - else - memcpy(url->url, &src_data[index], url_len); - } else { - dbg("[SAT] SAT PARSER - NULL string for URL"); + if(url_len < 0){ + dbg("[SAT] URL is null"); + *consumed_data_len = 1+len_of_len+url_len; + return TCORE_SAT_SUCCESS; + } + + if(url_len > SAT_URL_LEN_MAX){ + dbg("[SAT] URL length is wrong"); + *consumed_data_len = 1+len_of_len+url_len; + return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } + memcpy(url->url, &src_data[temp_index], url_len); + dbg("[SAT] url(%s)", url->url); *consumed_data_len = 1+len_of_len+url_len; + return TCORE_SAT_SUCCESS; } @@ -1913,7 +1937,7 @@ static enum tcore_sat_result _sat_decode_bearer_tlv(unsigned char* tlv_str, int struct tel_sat_bearer_list* satk_bearer, int* consumed_data_len) { unsigned char* src_data; - int index, len_of_len = 0; + int temp_index, len_of_len = 0; int list_len = 0, list_idx = 0; if (tlv_str == NULL || consumed_data_len == NULL || satk_bearer == NULL) { @@ -1927,26 +1951,26 @@ static enum tcore_sat_result _sat_decode_bearer_tlv(unsigned char* tlv_str, int } src_data = &tlv_str[0]; - index = curr_offset; + temp_index = curr_offset; - if ((src_data[index++] & 0x7F) != SATK_BEARER_TAG) { + if ((src_data[temp_index++] & 0x7F) != SATK_BEARER_TAG) { dbg("[SAT] SAT PARSER - _sat_decode_bearer_tlv: alphaID TAG missing"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if(!len_of_len){ err("[SAT] parser: invalid length."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - satk_bearer->count = src_data[index + len_of_len - 1]; + satk_bearer->count = src_data[temp_index + len_of_len - 1]; list_len = satk_bearer->count; - index += len_of_len; + temp_index += len_of_len; - if ((index + list_len) > tlv_len) { - dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (index + list_len), tlv_len); + if ((temp_index + list_len) > tlv_len) { + dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index + list_len), tlv_len); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } @@ -1955,7 +1979,7 @@ static enum tcore_sat_result _sat_decode_bearer_tlv(unsigned char* tlv_str, int list_len = SAT_BEARER_LIST_MAX_COUNT; for (list_idx = 0; list_idx < list_len; list_idx++) { - switch (src_data[index]) { + switch (src_data[temp_index]) { case 0x00: satk_bearer->bear[list_idx] = BEARER_LIST_SMS; break; @@ -1973,7 +1997,7 @@ static enum tcore_sat_result _sat_decode_bearer_tlv(unsigned char* tlv_str, int break; } dbg("[SAT] SAT PARSER - bearer[%d]=0x%x", list_idx, satk_bearer->bear[list_idx]); - index++; + temp_index++; } } else { return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; @@ -1987,7 +2011,7 @@ static enum tcore_sat_result _sat_decode_provisioning_file_ref_tlv(unsigned char int tlv_len, int curr_offset, struct tel_sat_provisioning_file_ref* prf, int* data_len_consumed) { unsigned char* src_data; - int index = curr_offset; + int temp_index = curr_offset; int len_of_len = 0, prf_len = 0; if (tlv_str == NULL || prf == NULL || data_len_consumed == NULL) { @@ -2001,27 +2025,27 @@ static enum tcore_sat_result _sat_decode_provisioning_file_ref_tlv(unsigned char return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - if ((src_data[index++] & 0x7F) != SATK_PROVISIONING_REF_FILE_TAG) { + if ((src_data[temp_index++] & 0x7F) != SATK_PROVISIONING_REF_FILE_TAG) { dbg("[SAT] SAT PARSER - PRF tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if(!len_of_len){ err("[SAT] parser: invalid length."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - prf_len = src_data[index + len_of_len - 1]; + prf_len = src_data[temp_index + len_of_len - 1]; prf->file_path_length = prf_len; - index += len_of_len; //index pointing to prf. + temp_index += len_of_len; //temp_index pointing to prf. if (prf_len > 0) { if (prf_len > SAT_PROVISIONING_FILE_PATH_LEN_MAX) return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; else - memcpy(prf->file_path, &src_data[index], prf_len); + memcpy(prf->file_path, &src_data[temp_index], prf_len); } else { dbg("[SAT] SAT PARSER - NULL string for PRF"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; @@ -2035,7 +2059,7 @@ static enum tcore_sat_result _sat_decode_bearer_description_tlv(unsigned char* t int tlv_len, int curr_offset, struct tel_sat_bearer_description *bearer_desc_obj, int* consumed_data_len) { - int index, length=0; + int temp_index, length=0; unsigned char* src_data; if(tlv_len <= (curr_offset+1)+1) { @@ -2043,44 +2067,44 @@ static enum tcore_sat_result _sat_decode_bearer_description_tlv(unsigned char* t return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; while(1){ - if(index >= tlv_len){ + if(temp_index >= tlv_len){ dbg("bearer desc cannot find. UICC Server mode"); *consumed_data_len = 0; return TCORE_SAT_SUCCESS; } - if( (src_data[index]&0x7F) == SATK_BEARER_DISCRIPTION_TAG ){ - dbg("find bearer description tag index(%d)", index); - index++; + if( (src_data[temp_index]&0x7F) == SATK_BEARER_DISCRIPTION_TAG ){ + dbg("find bearer description tag temp_index(%d)", temp_index); + temp_index++; break; } - index++; + temp_index++; } //length - length = src_data[index++]; + length = src_data[temp_index++]; dbg("bearer description length (%d)", length); //bearer parameter - switch(src_data[index++]){ + switch(src_data[temp_index++]){ case BEARER_CSD: bearer_desc_obj->bearer_type = BEARER_CSD; - bearer_desc_obj->bearer_parameter.cs_bearer_param.data_rate = src_data[index++]; - bearer_desc_obj->bearer_parameter.cs_bearer_param.service_type = src_data[index++]; - bearer_desc_obj->bearer_parameter.cs_bearer_param.connection_element_type = src_data[index++]; + bearer_desc_obj->bearer_parameter.cs_bearer_param.data_rate = src_data[temp_index++]; + bearer_desc_obj->bearer_parameter.cs_bearer_param.service_type = src_data[temp_index++]; + bearer_desc_obj->bearer_parameter.cs_bearer_param.connection_element_type = src_data[temp_index++]; break; case BEARER_GPRS: bearer_desc_obj->bearer_type = BEARER_GPRS; - bearer_desc_obj->bearer_parameter.ps_bearer_param.precedence_class = src_data[index++]; - bearer_desc_obj->bearer_parameter.ps_bearer_param.delay_class = src_data[index++]; - bearer_desc_obj->bearer_parameter.ps_bearer_param.reliability_class = src_data[index++]; - bearer_desc_obj->bearer_parameter.ps_bearer_param.peak_throughput_class = src_data[index++]; - bearer_desc_obj->bearer_parameter.ps_bearer_param.mean_throughput_class = src_data[index++]; + bearer_desc_obj->bearer_parameter.ps_bearer_param.precedence_class = src_data[temp_index++]; + bearer_desc_obj->bearer_parameter.ps_bearer_param.delay_class = src_data[temp_index++]; + bearer_desc_obj->bearer_parameter.ps_bearer_param.reliability_class = src_data[temp_index++]; + bearer_desc_obj->bearer_parameter.ps_bearer_param.peak_throughput_class = src_data[temp_index++]; + bearer_desc_obj->bearer_parameter.ps_bearer_param.mean_throughput_class = src_data[temp_index++]; bearer_desc_obj->bearer_parameter.ps_bearer_param.pdp_type = BIP_GPRS_PDP_TYPE_RESERVED; - if(src_data[index] == BIP_GPRS_PDP_TYPE_IP) + if(src_data[temp_index] == BIP_GPRS_PDP_TYPE_IP) bearer_desc_obj->bearer_parameter.ps_bearer_param.pdp_type = BIP_GPRS_PDP_TYPE_IP; break; case BEARER_DEFAULT_BEARER_FROM_TRANSPORT_LAYER: @@ -2103,7 +2127,7 @@ static enum tcore_sat_result _sat_decode_channel_data_tlv(unsigned char* tlv_str int tlv_len, int curr_offset, struct tel_sat_channel_data *channel_data_obj, int* consumed_data_len) { - int index = 0; + int temp_index = 0; int len_of_len = 0, channel_data_len = 0; unsigned char* src_data; @@ -2118,32 +2142,32 @@ static enum tcore_sat_result _sat_decode_channel_data_tlv(unsigned char* tlv_str } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if((src_data[index++]&0x7F) != SATK_CHANNEL_DATA_TAG){ - dbg("[SAT] SAT PARSER - tag not found.=%d",src_data[index]); + if((src_data[temp_index++]&0x7F) != SATK_CHANNEL_DATA_TAG){ + dbg("[SAT] SAT PARSER - tag not found.=%d",src_data[temp_index]); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if(!len_of_len){ err("[SAT] parser: invalid length."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - channel_data_len = src_data[index+len_of_len-1]; + channel_data_len = src_data[temp_index+len_of_len-1]; dbg("[SAT] parser: channel_data_len=%d",channel_data_len); - index += len_of_len; + temp_index += len_of_len; - if((index+channel_data_len) > tlv_len) { - dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (index+channel_data_len),tlv_len); + if((temp_index+channel_data_len) > tlv_len) { + dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index+channel_data_len),tlv_len); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } //data channel_data_obj->data_string_len = channel_data_len; - memcpy(channel_data_obj->data_string, &src_data[index], channel_data_len); + memcpy(channel_data_obj->data_string, &src_data[temp_index], channel_data_len); *consumed_data_len = 1+len_of_len+channel_data_len; return TCORE_SAT_SUCCESS; @@ -2153,7 +2177,7 @@ static enum tcore_sat_result _sat_decode_channel_data_length_tlv(unsigned char* int tlv_len, int curr_offset, struct tel_sat_channel_data_len *data_len_obj, int* consumed_data_len) { - int index; + int temp_index; unsigned char* src_data; if(tlv_str == NULL || consumed_data_len == NULL || data_len_obj == NULL) { @@ -2162,21 +2186,21 @@ static enum tcore_sat_result _sat_decode_channel_data_length_tlv(unsigned char* } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if((src_data[index++]&0x7F) != SATK_CHANNEL_DATA_LEN_TAG) { + if((src_data[temp_index++]&0x7F) != SATK_CHANNEL_DATA_LEN_TAG) { dbg("[SAT] SAT PARSER - channel data tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } //length - if(src_data[index++] != SATK_CHANNEL_DATA_LENGTH_VALUE_LENGTH) { + if(src_data[temp_index++] != SATK_CHANNEL_DATA_LENGTH_VALUE_LENGTH) { dbg("[SAT] SAT PARSER - incorrect length"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } //data - data_len_obj->data_len = src_data[index]; + data_len_obj->data_len = src_data[temp_index]; *consumed_data_len = 3; return TCORE_SAT_SUCCESS; @@ -2186,7 +2210,7 @@ static enum tcore_sat_result _sat_decode_buffer_size_tlv(unsigned char* tlv_str, int tlv_len, int curr_offset, struct tel_sat_buffer_size *buffer_size_obj, int* consumed_data_len) { - int index; + int temp_index; unsigned char* src_data; if(tlv_str == NULL || consumed_data_len == NULL || buffer_size_obj == NULL) { @@ -2200,21 +2224,21 @@ static enum tcore_sat_result _sat_decode_buffer_size_tlv(unsigned char* tlv_str, } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if((src_data[index++]&0x7F) != SATK_BUFFER_SIZE_TAG) { + if((src_data[temp_index++]&0x7F) != SATK_BUFFER_SIZE_TAG) { dbg("[SAT] SAT PARSER - buffer size tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } //length - if(src_data[index++] != SATK_BUFFER_SIZE_LENGTH) { + if(src_data[temp_index++] != SATK_BUFFER_SIZE_LENGTH) { dbg("[SAT] SAT PARSER - incorrect length"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } - buffer_size_obj->size[0] = src_data[index++]; - buffer_size_obj->size[1] = src_data[index]; + buffer_size_obj->size[0] = src_data[temp_index++]; + buffer_size_obj->size[1] = src_data[temp_index]; *consumed_data_len = 4; dbg("[SAT] SAT PARSER - buffer size = 0x%x%x", buffer_size_obj->size[0], buffer_size_obj->size[1]); @@ -2226,7 +2250,7 @@ static enum tcore_sat_result _sat_decode_other_address_tlv(unsigned char* tlv_st int* consumed_data_len) { gchar* address = NULL; - int index, address_len; + int temp_index, address_len; unsigned char* src_data; if(tlv_str == NULL || consumed_data_len == NULL || other_address_obj == NULL) { @@ -2240,17 +2264,17 @@ static enum tcore_sat_result _sat_decode_other_address_tlv(unsigned char* tlv_st } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if((src_data[index++]&0x7F) != SATK_OTHER_ADDRESS_TAG) { + if((src_data[temp_index++]&0x7F) != SATK_OTHER_ADDRESS_TAG) { dbg("[SAT] SAT PARSER - other address tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } //length - address_len = src_data[index++]; - if((index+address_len) > tlv_len) { - dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (index+address_len),tlv_len); + address_len = src_data[temp_index++]; + if((temp_index+address_len) > tlv_len) { + dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index+address_len),tlv_len); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } @@ -2260,18 +2284,18 @@ static enum tcore_sat_result _sat_decode_other_address_tlv(unsigned char* tlv_st } //other address type - switch(src_data[index++]){ + switch(src_data[temp_index++]){ case ADDR_TYPE_IPv4:{ other_address_obj->address_type = ADDR_TYPE_IPv4; - address = g_strdup_printf("%d.%d.%d.%d", src_data[index], src_data[index+1], src_data[index+2], src_data[index+3]); + address = g_strdup_printf("%d.%d.%d.%d", src_data[temp_index], src_data[temp_index+1], src_data[temp_index+2], src_data[temp_index+3]); }break; case ADDR_TYPE_IPv6:{ other_address_obj->address_type = ADDR_TYPE_IPv6; address = g_strdup_printf("%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:", - src_data[index], src_data[index+1], src_data[index+2], src_data[index+3], - src_data[index+4], src_data[index+5], src_data[index+6], src_data[index+7], - src_data[index+8], src_data[index+9], src_data[index+10], src_data[index+11], - src_data[index+12], src_data[index+13], src_data[index+14], src_data[index+15]); + src_data[temp_index], src_data[temp_index+1], src_data[temp_index+2], src_data[temp_index+3], + src_data[temp_index+4], src_data[temp_index+5], src_data[temp_index+6], src_data[temp_index+7], + src_data[temp_index+8], src_data[temp_index+9], src_data[temp_index+10], src_data[temp_index+11], + src_data[temp_index+12], src_data[temp_index+13], src_data[temp_index+14], src_data[temp_index+15]); }break; default:{ other_address_obj->address_type = ADDR_RESERVED; @@ -2280,13 +2304,14 @@ static enum tcore_sat_result _sat_decode_other_address_tlv(unsigned char* tlv_st }//end of switch //address - memcpy(other_address_obj->address, address, strlen(address)); - other_address_obj->address_len = strlen(address); + if (address) { + memcpy(other_address_obj->address, address, strlen(address)); + other_address_obj->address_len = strlen(address); - if(address) g_free(address); + dbg("destination address(%s)", other_address_obj->address); + } - dbg("destination address(%s)", other_address_obj->address); *consumed_data_len = 2+address_len; return TCORE_SAT_SUCCESS; } @@ -2295,7 +2320,7 @@ static enum tcore_sat_result _sat_decode_uicc_terminal_interface_tlv(unsigned ch int tlv_len, int curr_offset, struct tel_sat_uicc_terminal_interface_transport_level *level_obj, int* consumed_data_len) { - int index; + int temp_index; unsigned char* src_data; if(tlv_str == NULL || consumed_data_len == NULL || level_obj == NULL) { @@ -2309,22 +2334,22 @@ static enum tcore_sat_result _sat_decode_uicc_terminal_interface_tlv(unsigned ch } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if((src_data[index++]&0x7F) != SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG) { + if((src_data[temp_index++]&0x7F) != SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG) { dbg("[SAT] SAT PARSER - UICC/TERMINAL Interface transport level tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } //length - if(src_data[index++] != SATK_UICC_ME_TRANS_INTERFACE_LEVEL_LENGTH) { + if(src_data[temp_index++] != SATK_UICC_ME_TRANS_INTERFACE_LEVEL_LENGTH) { dbg("[SAT] SAT PARSER - incorrect length"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } - level_obj->protocol_type = src_data[index++]; - level_obj->port_number = src_data[index++] << 8; - level_obj->port_number |= src_data[index]; + level_obj->protocol_type = src_data[temp_index++]; + level_obj->port_number = src_data[temp_index++] << 8; + level_obj->port_number |= src_data[temp_index]; *consumed_data_len = 2+SATK_UICC_ME_TRANS_INTERFACE_LEVEL_LENGTH; dbg("[SAT] SAT PARSER - protocol type(%d) , port number(%d)", level_obj->protocol_type, level_obj->port_number); @@ -2335,7 +2360,7 @@ static enum tcore_sat_result _sat_decode_remote_entity_address_tlv(unsigned char int tlv_len, int curr_offset, struct tel_sat_remote_entity_address *remote_address_obj, int* consumed_data_len) { - int index = 0; + int temp_index = 0; int len_of_len = 0, remote_data_len = 0; unsigned char* src_data; @@ -2350,26 +2375,26 @@ static enum tcore_sat_result _sat_decode_remote_entity_address_tlv(unsigned char } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if((src_data[index]&0x7F) != SATK_REMOTE_ENTITY_ADDRESS_TAG){ - dbg("[SAT] SAT PARSER - tag not found.=%d",src_data[index]); + if((src_data[temp_index]&0x7F) != SATK_REMOTE_ENTITY_ADDRESS_TAG){ + dbg("[SAT] SAT PARSER - tag not found.=%d",src_data[temp_index]); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } //length - len_of_len = _get_length_filed_size(src_data[index]); + len_of_len = _get_length_filed_size(src_data[temp_index]); if(!len_of_len){ err("[SAT] parser: invalid length."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - remote_data_len = src_data[index+len_of_len-1]; + remote_data_len = src_data[temp_index+len_of_len-1]; dbg("[SAT] parser: remote_data_len=%d",remote_data_len); - index += len_of_len; + temp_index += len_of_len; //data - switch(src_data[index++]){ + switch(src_data[temp_index++]){ case REMOTE_ENTITY_ADDR_CODING_TYPE_IEEE802_48BIT: remote_address_obj->coding_type = REMOTE_ENTITY_ADDR_CODING_TYPE_IEEE802_48BIT; break; @@ -2382,7 +2407,7 @@ static enum tcore_sat_result _sat_decode_remote_entity_address_tlv(unsigned char } remote_address_obj->length = remote_data_len - 1; - memcpy(remote_address_obj->remote_entity_address, &src_data[index], remote_address_obj->length); + memcpy(remote_address_obj->remote_entity_address, &src_data[temp_index], remote_address_obj->length); *consumed_data_len = 1+len_of_len+remote_data_len; return TCORE_SAT_SUCCESS; @@ -2392,7 +2417,7 @@ static enum tcore_sat_result _sat_decode_network_access_name_tlv(unsigned char* int tlv_len, int curr_offset, struct tel_sat_network_access_name *access_name_obj, int* consumed_data_len) { - int index, idx, name_idx, name_length; + int temp_index, idx, name_idx, name_length; unsigned char* src_data; if(tlv_str == NULL || consumed_data_len == NULL || access_name_obj == NULL) { @@ -2406,17 +2431,17 @@ static enum tcore_sat_result _sat_decode_network_access_name_tlv(unsigned char* } //tag - index = curr_offset; + temp_index = curr_offset; src_data = &tlv_str[0]; - if((src_data[index++]&0x7F) != SATK_NETWORK_ACCESS_TAG) { + if((src_data[temp_index++]&0x7F) != SATK_NETWORK_ACCESS_TAG) { dbg("[SAT] SAT PARSER - network access name tag missing."); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR } //length - name_length = src_data[index++]; - if((index+name_length) > tlv_len) { - dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (index+name_length),tlv_len); + name_length = src_data[temp_index++]; + if((temp_index+name_length) > tlv_len) { + dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index+name_length),tlv_len); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } @@ -2428,20 +2453,20 @@ static enum tcore_sat_result _sat_decode_network_access_name_tlv(unsigned char* name_idx = 0; for(idx = 0; idx < access_name_obj->length; idx++){ - dbg("data (%c) Bool(%d)",src_data[index], g_ascii_isalpha(src_data[index]) ); + dbg("data (%c) Bool(%d)",src_data[temp_index], g_ascii_isalpha(src_data[temp_index]) ); - if( g_ascii_isalpha(src_data[index]) ){ - access_name_obj->network_access_name[name_idx] = src_data[index]; + if( g_ascii_isalpha(src_data[temp_index]) ){ + access_name_obj->network_access_name[name_idx] = src_data[temp_index]; name_idx++; } else{ - if(src_data[index] == 0x02){//02 convert to "." + if(src_data[temp_index] == 0x02){//02 convert to "." access_name_obj->network_access_name[name_idx] = '.'; name_idx++; } } - index++; + temp_index++; } //network access name @@ -2451,12 +2476,53 @@ static enum tcore_sat_result _sat_decode_network_access_name_tlv(unsigned char* return TCORE_SAT_SUCCESS; } +static enum tcore_sat_result _sat_decode_text_attribute_tlv(unsigned char* tlv_str, + int tlv_len, int curr_offset, struct tel_sat_text_attribute *text_attribute_obj, + int* consumed_data_len) +{ + int temp_index, length; + unsigned char* src_data; + + if(tlv_str == NULL || consumed_data_len == NULL || text_attribute_obj == NULL) { + dbg("[SAT] SAT PARSER - tlv_str == NULL || consumed_data_len == NULL || text_attribute_obj == NULL"); + return TCORE_SAT_ERROR_FATAL; + } + + if(tlv_len <= (curr_offset+1)) { + dbg("[SAT] SAT PARSER - incorrect length original_command_len=%d", tlv_len); + return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; + } + + //tag + temp_index = curr_offset; + src_data = &tlv_str[0]; + if((src_data[temp_index++]&0x7F) != SATK_TEXT_ATTRIBUTE_TAG) { + dbg("[SAT] SAT PARSER - text attribute tag is missing"); + return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //send TR + } + + //length + length = src_data[temp_index++]; + if((temp_index+length) > tlv_len) { + dbg("[SAT] SAT PARSER - incorrect cmd len, expected len = %d, orig_len=%d", (temp_index+length),tlv_len); + return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; + } + + //attribute data + text_attribute_obj->b_txt_attr = TRUE; + memcpy(text_attribute_obj->text_formatting, &src_data[temp_index], length); + + *consumed_data_len = 2+length; + return TCORE_SAT_SUCCESS; +} + //decode proactive cmd //6.4.1 DISPLAY TEXT static enum tcore_sat_result _sat_decode_display_text(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0; + int temp_index = 0; + int tlv_length = 0, remain_len = 0, expected_len = 0; int data_len_consumed=0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; @@ -2468,12 +2534,13 @@ static enum tcore_sat_result _sat_decode_display_text(unsigned char* o_cmd_data, } cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.display_text.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.display_text.command_detail.cmd_type = cmd_data[index++]; + tlv_length = cmd_data[curr_offset-1]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.display_text.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.display_text.command_detail.cmd_type = cmd_data[temp_index++]; /* ******decode command qualifier****** */ - if (cmd_data[index] & 0x01) { + if (cmd_data[temp_index] & 0x01) { sat_cmd_ind_data->data.display_text.command_detail.cmd_qualifier.display_text.text_priority = TEXT_PRIORITY_HIGH; dbg("[SAT] SAT PARSER - msg_prio=TAPI_SAT_MSG_PRIORITY_HIGH."); @@ -2484,7 +2551,7 @@ static enum tcore_sat_result _sat_decode_display_text(unsigned char* o_cmd_data, dbg("[SAT] SAT PARSER - : msg_prio=TAPI_SAT_MSG_PRIORITY_NORMAL."); } - if (cmd_data[index] & 0x80) { + if (cmd_data[temp_index] & 0x80) { sat_cmd_ind_data->data.display_text.command_detail.cmd_qualifier.display_text.text_clear_type = TEXT_WAIT_FOR_USER_TO_CLEAR_MSG; dbg("[SAT] SAT PARSER - : msgClear=TAPI_SAT_WAIT_FOR_USER_TO_CLEAR_MSG."); @@ -2495,14 +2562,22 @@ static enum tcore_sat_result _sat_decode_display_text(unsigned char* o_cmd_data, dbg("[SAT] SAT PARSER - msgClear=TAPI_SAT_AUTO_CLEAR_MSG_AFTER_A_DELAY."); } - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.display_text.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; - index+=4; - rv = _sat_decode_text_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.display_text.text, &data_len_consumed); + temp_index+=4; // device identities consumes 4 bytes. + + remain_len = o_length-temp_index; + expected_len = tlv_length-5-4; + if(remain_len!=expected_len){ + dbg("[SAT] SAT PARSER - : mismatch!! remain_len=%d, expected_len=%d", remain_len, expected_len); + return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; + } + + rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.display_text.text, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; @@ -2512,54 +2587,78 @@ static enum tcore_sat_result _sat_decode_display_text(unsigned char* o_cmd_data, } dbg("[SAT] SAT PARSER text(%s)",sat_cmd_ind_data->data.display_text.text.string); - dbg("[SAT] SAT PARSER o_len(%d) index(%d) data_len_consumed(%d)",o_length , index, data_len_consumed); + dbg("[SAT] SAT PARSER o_len(%d) temp_index(%d) data_len_consumed(%d)",o_length , temp_index, data_len_consumed); - if(index+data_len_consumed > o_length){ - err("[SAT] SAT PARSER - Wrong String TLV"); - return TCORE_SAT_BEYOND_ME_CAPABILITY; + if(o_length-temp_index < data_len_consumed){ + dbg("[SAT] SAT PARSER - :wrong text TLV."); + return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - else if(index+data_len_consumed == o_length){ + + if(o_length-temp_index == data_len_consumed){ dbg("[SAT] SAT PARSER - :no more TLVs to decode."); return TCORE_SAT_SUCCESS; } + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV //icon identifier - index+=data_len_consumed; - if((cmd_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ - data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.display_text.icon_id, &data_len_consumed); + if((cmd_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.display_text.icon_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ - return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //SEND TR + return rv; //SEND TR } - if(index+data_len_consumed >= o_length){ - dbg("[SAT] SAT PARSER - no more TLVs to decode."); + if(o_length-temp_index == data_len_consumed){ + dbg("[SAT] SAT PARSER - :no more TLVs to decode."); return TCORE_SAT_SUCCESS; } - - index+=data_len_consumed; //index pointing to the Tag of next TLV + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } //immediate response sat_cmd_ind_data->data.display_text.immediate_response_requested = FALSE; - if((cmd_data[index]&0x7F) == SATK_IMMEDIATE_RESPONSE_TAG){ + if((cmd_data[temp_index]&0x7F) == SATK_IMMEDIATE_RESPONSE_TAG){ + data_len_consumed = 2; dbg("[SAT] SAT PARSER - :immediate response required."); sat_cmd_ind_data->data.display_text.immediate_response_requested = TRUE; - index+=2; + if(o_length-temp_index == data_len_consumed){ + dbg("[SAT] SAT PARSER - :no more TLVs to decode."); + return TCORE_SAT_SUCCESS; + } + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } - if(index >= o_length){ - dbg("[SAT] SAT PARSER - :no more TLVs to decode."); - return TCORE_SAT_SUCCESS; + //time duration - optional + if((cmd_data[temp_index]&0x7F)==SATK_DURATION_TAG){ + rv =_sat_decode_duration_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.display_text.duration, &data_len_consumed); + if(rv != TCORE_SAT_SUCCESS){ + return rv; //SEND TR + } + + if(o_length-temp_index == data_len_consumed){ + dbg("[SAT] SAT PARSER - :no more TLVs to decode."); + return TCORE_SAT_SUCCESS; + } + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } - //time duration - if((cmd_data[index]&0x7F)==SATK_DURATION_TAG){ - rv =_sat_decode_duration_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.display_text.duration, &data_len_consumed); + //text attribute - optional + if((cmd_data[temp_index]&0x7F)==SATK_TEXT_ATTRIBUTE_TAG){ + rv =_sat_decode_text_attribute_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.display_text.text_attribute, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } + + if(o_length-temp_index == data_len_consumed){ + dbg("[SAT] SAT PARSER - :no more TLVs to decode."); + return TCORE_SAT_SUCCESS; + } + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV + } + + if(o_length > temp_index){ + dbg("[SAT] SAT PARSER - : wrong text TLV, remaining data is found!!"); + return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } dbg("[SAT] SAT PARSER - :decoding done!."); @@ -2570,7 +2669,8 @@ static enum tcore_sat_result _sat_decode_display_text(unsigned char* o_cmd_data, static enum tcore_sat_result _sat_decode_get_inkey(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0; + int temp_index = 0; + int tlv_length = 0, remain_len = 0, expected_len = 0; int data_len_consumed=0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; @@ -2582,17 +2682,18 @@ static enum tcore_sat_result _sat_decode_get_inkey(unsigned char* o_cmd_data, in } cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.get_inkey.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.get_inkey.command_detail.cmd_type = cmd_data[index++]; + tlv_length = cmd_data[curr_offset-1]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.get_inkey.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.get_inkey.command_detail.cmd_type = cmd_data[temp_index++]; /* ******decode command qualifier****** */ - if (cmd_data[index] & 0x01) { + if (cmd_data[temp_index] & 0x01) { sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.alphabet_set = TRUE; dbg("[SAT] SAT PARSER - Alphabet set"); } - if(cmd_data[index]&0x02){ + if(cmd_data[temp_index]&0x02){ sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.alphabet_type = INPUT_ALPHABET_TYPE_UCS2; dbg("[SAT] SAT PARSER - INPUT_ALPHABET_TYPE_UCS2"); } @@ -2601,7 +2702,7 @@ static enum tcore_sat_result _sat_decode_get_inkey(unsigned char* o_cmd_data, in dbg("[SAT] SAT PARSER - INPUT_ALPHABET_TYPE_SMS_DEFAULT"); } - if(cmd_data[index]&0x04){ + if(cmd_data[temp_index]&0x04){ sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.inkey_type = INKEY_TYPE_YES_NO_REQUESTED; dbg("[SAT] SAT PARSER - INKEY_TYPE_YES_NO_REQUESTED"); } @@ -2610,26 +2711,34 @@ static enum tcore_sat_result _sat_decode_get_inkey(unsigned char* o_cmd_data, in dbg("[SAT] SAT PARSER - INKEY_TYPE_YES_NO_REQUESTED"); } - if(cmd_data[index]&0x08){ + if(cmd_data[temp_index]&0x08){ sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.immediate_rsp_required = TRUE; dbg("[SAT] SAT PARSER - immediate response requested"); } - if (cmd_data[index] & 0x80) { + if (cmd_data[temp_index] & 0x80) { sat_cmd_ind_data->data.get_inkey.command_detail.cmd_qualifier.get_inkey.help_info = TRUE; dbg("[SAT] SAT PARSER - Help info"); } //device identities - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.get_inkey.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //text - index+=4; - rv = _sat_decode_text_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.get_inkey.text, &data_len_consumed); + temp_index+=4; + + remain_len = o_length-temp_index; + expected_len = tlv_length-5-4; + if(remain_len!=expected_len){ + dbg("[SAT] SAT PARSER - : mismatch!! remain_len=%d, expected_len=%d", remain_len, expected_len); + return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; + } + + rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.get_inkey.text, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; @@ -2639,41 +2748,65 @@ static enum tcore_sat_result _sat_decode_get_inkey(unsigned char* o_cmd_data, in } dbg("[SAT] SAT PARSER text(%s)",sat_cmd_ind_data->data.get_inkey.text.string); - dbg("[SAT] SAT PARSER o_len(%d) index(%d) data_len_consumed(%d)",o_length , index, data_len_consumed); + dbg("[SAT] SAT PARSER o_len(%d) temp_index(%d) data_len_consumed(%d)",o_length , temp_index, data_len_consumed); - if(index+data_len_consumed > o_length){ - err("[SAT] SAT PARSER - Wrong String TLV"); - return TCORE_SAT_BEYOND_ME_CAPABILITY; + if(o_length-temp_index < data_len_consumed){ + dbg("[SAT] SAT PARSER - :wrong text TLV."); + return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - else if(index+data_len_consumed == o_length){ + + if(o_length-temp_index == data_len_consumed){ dbg("[SAT] SAT PARSER - :no more TLVs to decode."); return TCORE_SAT_SUCCESS; } + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV - //icon identifier - index+=data_len_consumed; - if((cmd_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ - data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.get_inkey.icon_id, &data_len_consumed); + //icon identifier - optional + if((cmd_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.get_inkey.icon_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ - return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //SEND TR + return rv; //SEND TR } - if(index+data_len_consumed >= o_length){ - dbg("[SAT] SAT PARSER - no more TLVs to decode."); + if(o_length-temp_index == data_len_consumed){ + dbg("[SAT] SAT PARSER - :no more TLVs to decode."); return TCORE_SAT_SUCCESS; } + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV + } - index+=data_len_consumed; //index pointing to the Tag of next TLV + //time duration - optional + if((cmd_data[temp_index]&0x7F)==SATK_DURATION_TAG){ + rv =_sat_decode_duration_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.get_inkey.duration, &data_len_consumed); + if(rv != TCORE_SAT_SUCCESS){ + return rv; //SEND TR + } + + if(o_length-temp_index == data_len_consumed){ + dbg("[SAT] SAT PARSER - :no more TLVs to decode."); + return TCORE_SAT_SUCCESS; + } + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } - //time duration - if((cmd_data[index]&0x7F)==SATK_DURATION_TAG){ - rv =_sat_decode_duration_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.get_inkey.duration, &data_len_consumed); + //text attribute - optional + if((cmd_data[temp_index]&0x7F)==SATK_TEXT_ATTRIBUTE_TAG){ + rv =_sat_decode_text_attribute_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.get_inkey.text_attribute, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } + + if(o_length-temp_index == data_len_consumed){ + dbg("[SAT] SAT PARSER - :no more TLVs to decode."); + return TCORE_SAT_SUCCESS; + } + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV + } + + if(o_length > temp_index){ + dbg("[SAT] SAT PARSER - : wrong text TLV, remaining data is found!!"); + return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } dbg("[SAT] SAT PARSER - :decoding done!."); @@ -2684,7 +2817,8 @@ static enum tcore_sat_result _sat_decode_get_inkey(unsigned char* o_cmd_data, in static enum tcore_sat_result _sat_decode_get_input(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0; + int temp_index = 0; + int tlv_length = 0, remain_len = 0, expected_len = 0; int data_len_consumed=0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; @@ -2696,12 +2830,13 @@ static enum tcore_sat_result _sat_decode_get_input(unsigned char* o_cmd_data, in } cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.get_input.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.get_input.command_detail.cmd_type = cmd_data[index++]; + tlv_length = cmd_data[curr_offset-1]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.get_input.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.get_input.command_detail.cmd_type = cmd_data[temp_index++]; /* ******decode command qualifier****** */ - if (cmd_data[index] & 0x01) { + if (cmd_data[temp_index] & 0x01) { sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.alphabet_set = TRUE; dbg("[SAT] SAT PARSER - Alphabet set"); } @@ -2710,7 +2845,7 @@ static enum tcore_sat_result _sat_decode_get_input(unsigned char* o_cmd_data, in dbg("[SAT] SAT PARSER - Numeric info"); } - if(cmd_data[index]&0x02){ + if(cmd_data[temp_index]&0x02){ sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.alphabet_type = INPUT_ALPHABET_TYPE_UCS2; dbg("[SAT] SAT PARSER - INPUT_ALPHABET_TYPE_UCS2"); } @@ -2719,7 +2854,7 @@ static enum tcore_sat_result _sat_decode_get_input(unsigned char* o_cmd_data, in dbg("[SAT] SAT PARSER - INPUT_ALPHABET_TYPE_SMS_DEFAULT"); } - if(cmd_data[index]&0x04){ + if(cmd_data[temp_index]&0x04){ sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.me_echo_user_input = FALSE; dbg("[SAT] SAT PARSER - user input not be revealed"); } @@ -2728,7 +2863,7 @@ static enum tcore_sat_result _sat_decode_get_input(unsigned char* o_cmd_data, in dbg("[SAT] SAT PARSER - Me echo user input"); } - if(cmd_data[index]&0x08){ + if(cmd_data[temp_index]&0x08){ sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.user_input_unpacked_format = FALSE; dbg("[SAT] SAT PARSER - packing required"); } @@ -2737,21 +2872,29 @@ static enum tcore_sat_result _sat_decode_get_input(unsigned char* o_cmd_data, in dbg("[SAT] SAT PARSER - unpacked format"); } - if (cmd_data[index] & 0x80) { + if (cmd_data[temp_index] & 0x80) { sat_cmd_ind_data->data.get_input.command_detail.cmd_qualifier.get_input.help_info = TRUE; dbg("[SAT] SAT PARSER - Help info"); } //device identities - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.get_input.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; - //text - index+=4; - rv = _sat_decode_text_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.get_input.text, &data_len_consumed); + //text - mandatory + temp_index+=4; + + remain_len = o_length-temp_index; + expected_len = tlv_length-5-4; + if(remain_len!=expected_len){ + dbg("[SAT] SAT PARSER - : mismatch!! remain_len=%d, expected_len=%d", remain_len, expected_len); + return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; + } + + rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.get_input.text, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; @@ -2759,22 +2902,33 @@ static enum tcore_sat_result _sat_decode_get_input(unsigned char* o_cmd_data, in err("[SAT] SAT PARSER - :string length is 0"); } dbg("[SAT] SAT PARSER text(%s)",sat_cmd_ind_data->data.get_input.text.string); + dbg("[SAT] SAT PARSER o_len(%d) temp_index(%d) data_len_consumed(%d)",o_length , temp_index, data_len_consumed); + + if(o_length-temp_index < data_len_consumed){ + dbg("[SAT] SAT PARSER - :wrong text TLV."); + return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; + } + + if(o_length-temp_index == data_len_consumed){ + dbg("[SAT] SAT PARSER - :no more TLVs to decode."); + return TCORE_SAT_SUCCESS; + } + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV - //response length - index+=data_len_consumed; - rv = _sat_decode_response_length_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.get_input.rsp_len, &data_len_consumed); + //response length - mandatory + rv = _sat_decode_response_length_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.get_input.rsp_len, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - if(index+data_len_consumed >= o_length){ - err("[SAT] SAT PARSER - no more TLVs"); + if(o_length-temp_index == data_len_consumed){ + dbg("[SAT] SAT PARSER - :no more TLVs to decode."); return TCORE_SAT_SUCCESS; } + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV - //default text - index+=data_len_consumed; - if((o_cmd_data[index]&0x7F) == SATK_DEFAULT_TEXT_TAG){ - rv = _sat_decode_text_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.get_input.default_text, &data_len_consumed); + //default text - optional + if((o_cmd_data[temp_index]&0x7F) == SATK_DEFAULT_TEXT_TAG){ + rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.get_input.default_text, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; @@ -2782,24 +2936,45 @@ static enum tcore_sat_result _sat_decode_get_input(unsigned char* o_cmd_data, in err("[SAT] SAT PARSER - :string length is 0"); } dbg("[SAT] SAT PARSER default text(%s)",sat_cmd_ind_data->data.get_input.default_text.string); - index+=data_len_consumed; + if(o_length-temp_index == data_len_consumed){ + dbg("[SAT] SAT PARSER - :no more TLVs to decode."); + return TCORE_SAT_SUCCESS; + } + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } //icon identifier - if((cmd_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ - data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.display_text.icon_id, &data_len_consumed); + if((cmd_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.get_input.icon_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ - return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //SEND TR + return rv; //SEND TR } - if(index+data_len_consumed >= o_length){ - dbg("[SAT] SAT PARSER - no more TLVs to decode."); + if(o_length-temp_index == data_len_consumed){ + dbg("[SAT] SAT PARSER - :no more TLVs to decode."); + return TCORE_SAT_SUCCESS; + } + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV + } + + //text attribute - optional + if((cmd_data[temp_index]&0x7F)==SATK_TEXT_ATTRIBUTE_TAG){ + rv =_sat_decode_text_attribute_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.get_input.text_attribute, &data_len_consumed); + if(rv != TCORE_SAT_SUCCESS){ + return rv; //SEND TR + } + + if(o_length-temp_index == data_len_consumed){ + dbg("[SAT] SAT PARSER - :no more TLVs to decode."); return TCORE_SAT_SUCCESS; } + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV + } - index+=data_len_consumed; //index pointing to the Tag of next TLV + if(o_length > temp_index){ + dbg("[SAT] SAT PARSER - : wrong text TLV, remaining data is found!!"); + return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } dbg("[SAT] SAT PARSER - :decoding done!."); @@ -2810,7 +2985,7 @@ static enum tcore_sat_result _sat_decode_get_input(unsigned char* o_cmd_data, in static enum tcore_sat_result _sat_decode_more_time(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0; + int temp_index = 0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; enum tcore_sat_result rv = TCORE_SAT_SUCCESS; @@ -2822,18 +2997,18 @@ static enum tcore_sat_result _sat_decode_more_time(unsigned char* o_cmd_data, in //command detail cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_type = cmd_data[temp_index++]; //device identifier - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.setup_event_list.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; - index+=4; + temp_index+=4; dbg("[SAT] SAT PARSER - :decoding done!."); return TCORE_SAT_SUCCESS; } @@ -2842,7 +3017,7 @@ static enum tcore_sat_result _sat_decode_more_time(unsigned char* o_cmd_data, in static enum tcore_sat_result _sat_decode_play_tone(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0, data_len_consumed = 0; + int temp_index = 0, data_len_consumed = 0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; enum tcore_sat_result rv = TCORE_SAT_SUCCESS; @@ -2854,33 +3029,33 @@ static enum tcore_sat_result _sat_decode_play_tone(unsigned char* o_cmd_data, in //command detail cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.play_tone.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.play_tone.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.play_tone.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.play_tone.command_detail.cmd_type = cmd_data[temp_index++]; /* ******decode command qualifier****** */ - if (cmd_data[index] & 0x01) + if (cmd_data[temp_index] & 0x01) sat_cmd_ind_data->data.play_tone.command_detail.cmd_qualifier.play_tone.vibration_alert = VIBRATE_ALERT_REQUIRED; else sat_cmd_ind_data->data.play_tone.command_detail.cmd_qualifier.play_tone.vibration_alert = VIBRATE_ALERT_OPTIONAL; //device identifier - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.play_tone.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //alpha id - optional - index+=4; - if((cmd_data[index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ - rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.play_tone.alpha_id, &data_len_consumed); + temp_index+=4; + if((cmd_data[temp_index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ + rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.play_tone.alpha_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); dbg("[SAT] SAT PARSER - default value is set - tone type, duration"); sat_cmd_ind_data->data.play_tone.tone.tone_type = GENERAL_BEEP; @@ -2891,26 +3066,26 @@ static enum tcore_sat_result _sat_decode_play_tone(unsigned char* o_cmd_data, in } //tone - optional - if((cmd_data[index]&0x7F) == SATK_TONE_TAG){ - rv = _sat_decode_tone_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.play_tone.tone, &data_len_consumed); + if((cmd_data[temp_index]&0x7F) == SATK_TONE_TAG){ + rv = _sat_decode_tone_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.play_tone.tone, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; + temp_index+=data_len_consumed; } else{ sat_cmd_ind_data->data.play_tone.tone.tone_type = GENERAL_BEEP; } //time duration - optional - if((cmd_data[index]&0x7F)==SATK_DURATION_TAG){ - rv =_sat_decode_duration_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.play_tone.duration, &data_len_consumed); + if((cmd_data[temp_index]&0x7F)==SATK_DURATION_TAG){ + rv =_sat_decode_duration_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.play_tone.duration, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } @@ -2922,23 +3097,39 @@ static enum tcore_sat_result _sat_decode_play_tone(unsigned char* o_cmd_data, in } //icon identifier - if((cmd_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ + if((cmd_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.play_tone.icon_id, &data_len_consumed); + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.play_tone.icon_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //SEND TR } - if(index+data_len_consumed >= o_length){ + if(temp_index+data_len_consumed >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } - index+=data_len_consumed; //index pointing to the Tag of next TLV + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } -//ToDo: Text Attribute and frames + //text attribute - optional + if((cmd_data[temp_index]&0x7F)==SATK_TEXT_ATTRIBUTE_TAG){ + rv =_sat_decode_text_attribute_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.play_tone.text_attribute, &data_len_consumed); + if(rv != TCORE_SAT_SUCCESS){ + return rv; //SEND TR + } + + if(temp_index+data_len_consumed >= o_length){ + dbg("[SAT] SAT PARSER - no more TLVs to decode."); + return TCORE_SAT_SUCCESS; + } + + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV + } + +//ToDo: frames + dbg("[SAT] SAT PARSER - :decoding done!."); return TCORE_SAT_SUCCESS; } @@ -2947,7 +3138,7 @@ static enum tcore_sat_result _sat_decode_play_tone(unsigned char* o_cmd_data, in static enum tcore_sat_result _sat_decode_refresh(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0, data_len_consumed = 0; + int temp_index = 0, data_len_consumed = 0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; enum tcore_sat_result rv = TCORE_SAT_SUCCESS; @@ -2959,43 +3150,43 @@ static enum tcore_sat_result _sat_decode_refresh(unsigned char* o_cmd_data, int //command detail cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.refresh.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.refresh.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.refresh.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.refresh.command_detail.cmd_type = cmd_data[temp_index++]; /* ******decode command qualifier****** */ - switch(cmd_data[index]){ - case REFRESH_SIM_INIT_AND_FULL_FCN: - case REFRESH_FCN: - case REFRESH_SIM_INIT_AND_FCN: - case REFRESH_SIM_INIT : - case REFRESH_SIM_RESET: - sat_cmd_ind_data->data.refresh.command_detail.cmd_qualifier.refresh.refresh = cmd_data[index]; - dbg("[SAT] SAT PARSER - : refresh mode=[0x%02x]:0-init&FFCN, 1-FCN, 2-init&FCN, 3-init, 4-reset", cmd_data[index]); - break; - - case REFRESH_3G_APPLICATION_RESET: - case REFRESH_3G_SESSION_RESET: - case REFRESH_RESERVED: + switch(cmd_data[temp_index]){ + case SIM_REFRESH_CMD_INIT_AND_FULL_FCN: + case SIM_REFRESH_CMD_FCN: + case SIM_REFRESH_CMD_INIT_AND_FCN: + case SIM_REFRESH_CMD_INIT : + case SIM_REFRESH_CMD_RESET: + sat_cmd_ind_data->data.refresh.command_detail.cmd_qualifier.refresh.refresh = cmd_data[temp_index]; + dbg("[SAT] SAT PARSER - : refresh mode=[0x%02x]:0-init&FFCN, 1-FCN, 2-init&FCN, 3-init, 4-reset", cmd_data[temp_index]); + break; + + case SIM_REFRESH_CMD_3G_APPLICATION_RESET: + case SIM_REFRESH_CMD_3G_SESSION_RESET: + case SIM_REFRESH_CMD_RESERVED: default: - dbg("[SAT] SAT PARSER - : refresh mode=0x%02x Not Supported", cmd_data[index]); + dbg("[SAT] SAT PARSER - : refresh mode=0x%02x Not Supported", cmd_data[temp_index]); return TCORE_SAT_BEYOND_ME_CAPABILITY; break; } //device identifier - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.refresh.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //check file list - index+=4; - if( (sat_cmd_ind_data->data.refresh.command_detail.cmd_qualifier.refresh.refresh == REFRESH_FCN) - || (sat_cmd_ind_data->data.refresh.command_detail.cmd_qualifier.refresh.refresh == REFRESH_SIM_INIT_AND_FCN) ){ + temp_index+=4; + if( (sat_cmd_ind_data->data.refresh.command_detail.cmd_qualifier.refresh.refresh == SIM_REFRESH_CMD_FCN) + || (sat_cmd_ind_data->data.refresh.command_detail.cmd_qualifier.refresh.refresh == SIM_REFRESH_CMD_INIT_AND_FCN) ){ - rv = _sat_decode_file_list_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.refresh.file_list, &data_len_consumed); + rv = _sat_decode_file_list_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.refresh.file_list, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; } @@ -3010,20 +3201,20 @@ static enum tcore_sat_result _sat_decode_refresh(unsigned char* o_cmd_data, int static enum tcore_sat_result _sat_decode_setup_menu(unsigned char* tlv_str, int tlv_len, int curr_offset, struct tcore_sat_proactive_command *pactive_cmd_ind_obj) { - int index = 0; + int temp_index = 0; int data_len_consumed=0; unsigned char dev_id[4]; unsigned char* src_data; enum tcore_sat_result rv = TCORE_SAT_SUCCESS; //access command detail - index = curr_offset+2; //move the index to command detail info +2(tag and length) + temp_index = curr_offset+2; //move the temp_index to command detail info +2(tag and length) src_data = &tlv_str[0]; -// In this time, the point of index is COMMAND NUMBER +// In this time, the point of temp_index is COMMAND NUMBER // [1] insert command detail information into each proactive command data structure. - pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_num = src_data[index++]; - pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_type = src_data[index++]; + pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_num = src_data[temp_index++]; + pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_type = src_data[temp_index++]; // [2] decode COMMAND QUALIFIER /* @@ -3035,7 +3226,7 @@ static enum tcore_sat_result _sat_decode_setup_menu(unsigned char* tlv_str, int */ //[2-1] selection preference - if (src_data[index] & 0x01) { + if (src_data[temp_index] & 0x01) { pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_qualifier.setup_menu.select_preference = SELECTION_PREFERENCE_USING_SOFT_KEY; dbg("[SAT] SAT PARSER - sel_pref=SAT_SELECTION_PREFERENCE_USING_SOFT_KEY."); @@ -3047,7 +3238,7 @@ static enum tcore_sat_result _sat_decode_setup_menu(unsigned char* tlv_str, int } //[2-2] help available - if (src_data[index] & 0x80) { + if (src_data[temp_index] & 0x80) { pactive_cmd_ind_obj->data.setup_menu.command_detail.cmd_qualifier.setup_menu.help_info = TRUE; ;dbg("[SAT] SAT PARSER - : is help Available=TRUE."); @@ -3058,10 +3249,10 @@ static enum tcore_sat_result _sat_decode_setup_menu(unsigned char* tlv_str, int dbg("[SAT] SAT PARSER - is help Available=FALSE."); } -// In this time, the point of index is DEVICE IDENTITIES. +// In this time, the point of temp_index is DEVICE IDENTITIES. //[3] decode DEVICE IDENTITIES TLV - index++; - memcpy(dev_id, &src_data[index], 4); + temp_index++; + memcpy(dev_id, &src_data[temp_index], 4); rv = _sat_decode_device_identities_tlv(dev_id, &pactive_cmd_ind_obj->data.setup_menu.device_id); if (rv != TCORE_SAT_SUCCESS) { //send TR in SatkProcessProactiveCmdInd() @@ -3069,29 +3260,32 @@ static enum tcore_sat_result _sat_decode_setup_menu(unsigned char* tlv_str, int } -// In this time, the point of index is ALPHA IDENTIFIER. 11 or 12. +// In this time, the point of temp_index is ALPHA IDENTIFIER. 11 or 12. //[4] decode ALPHA IDENTIFIER TLV - index+=4; - dbg("[SAT] SAT PARSER - :index=%d",index); - rv = _sat_decode_alpha_identifier_tlv(src_data, tlv_len, index, + temp_index+=4; + dbg("[SAT] SAT PARSER - :temp_index=%d",temp_index); + rv = _sat_decode_alpha_identifier_tlv(src_data, tlv_len, temp_index, &pactive_cmd_ind_obj->data.setup_menu.alpha_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } -// In this time, the point of index is ITEM TLV +// In this time, the point of temp_index is ITEM TLV //[5] decode ITEM LIST (at least one is mandatory) - index+= data_len_consumed; + temp_index+= data_len_consumed; pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt = 0; do{ data_len_consumed=0; - if((src_data[index]&0x7F) == SATK_ITEM_TAG) { - rv = _sat_decode_item_tlv(src_data, tlv_len, index, + if((src_data[temp_index]&0x7F) == SATK_ITEM_TAG) { + rv = _sat_decode_item_tlv(src_data, tlv_len, temp_index, &pactive_cmd_ind_obj->data.setup_menu.menu_item[pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt], &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; + + if(!pactive_cmd_ind_obj->data.setup_menu.menu_item[0].text_len) + break; } else { if(pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt == 0) { @@ -3102,77 +3296,123 @@ static enum tcore_sat_result _sat_decode_setup_menu(unsigned char* tlv_str, int break; //??? } pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt++; - index += data_len_consumed; + temp_index += data_len_consumed; - if(index >= tlv_len) + if(temp_index >= tlv_len) break; }while(pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt < SAT_MENU_ITEM_COUNT_MAX); dbg("[SAT] SAT PARSER - :setup menu item_count=%d",pactive_cmd_ind_obj->data.setup_menu.menu_item_cnt); - if(index >= tlv_len){ + if(temp_index >= tlv_len){ dbg("[SAT] SAT PARSER - :no more TLVs to decode."); //send TR in SatkProcessProactiveCmdInd() return TCORE_SAT_SUCCESS; } //[6] (optional TLV) decode ITEMS NEXT ACTION INDICATOR TLV - if((src_data[index]&0x7F) == SATK_ITEMS_NEXT_ACTION_INDICATOR_TAG) { + if((src_data[temp_index]&0x7F) == SATK_ITEMS_NEXT_ACTION_INDICATOR_TAG) { data_len_consumed = 0; - rv = _sat_decode_item_next_action_indicator_tlv(tlv_str, tlv_len, index, + rv = _sat_decode_item_next_action_indicator_tlv(tlv_str, tlv_len, temp_index, &pactive_cmd_ind_obj->data.setup_menu.next_act_ind_list, &data_len_consumed); if(rv!=TCORE_SAT_SUCCESS) return rv; - if(index+data_len_consumed >= tlv_len) { + if(temp_index+data_len_consumed >= tlv_len) { dbg("[SAT] SAT PARSER - no more TLVs to decode."); //send the data to Noti manager. return TCORE_SAT_SUCCESS; } - index+=data_len_consumed; //index pointing to the Tag of next TLV + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } else { dbg("[SAT] SAT PARSER - ITEMS NEXT ACTION INDICATOR TLV Not present"); } //[7] (optional TLV) decode ICON IDENTIFIER TLV - if((src_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG) { + if((src_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG) { data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(tlv_str, tlv_len, index, + rv = _sat_decode_icon_identifier_tlv(tlv_str, tlv_len, temp_index, &pactive_cmd_ind_obj->data.setup_menu.icon_id, &data_len_consumed); if(rv !=TCORE_SAT_SUCCESS) return rv; - if(index+data_len_consumed >= tlv_len) { + if(temp_index+data_len_consumed >= tlv_len) { dbg("[SAT] SAT PARSER - no more TLVs to decode."); //send the data to Noti manager. return TCORE_SAT_SUCCESS; } - index+=data_len_consumed; //index pointing to the Tag of next TLV + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } else{ dbg("[SAT] SAT PARSER - ICON IDENTIFIER TLV Not present"); } //[8] (optional TLV) decode ICON IDENTIFIER LIST TLV - if((src_data[index]&0x7F) == SATK_ITEM_ICON_IDENTIFIER_LIST_TAG) { + if((src_data[temp_index]&0x7F) == SATK_ITEM_ICON_IDENTIFIER_LIST_TAG) { data_len_consumed = 0; - rv = _sat_decode_icon_identifier_list_tlv(tlv_str, tlv_len, index, + rv = _sat_decode_icon_identifier_list_tlv(tlv_str, tlv_len, temp_index, &pactive_cmd_ind_obj->data.setup_menu.icon_list, &data_len_consumed); if(rv !=TCORE_SAT_SUCCESS) return rv; //SEND TR - if(index+data_len_consumed >= tlv_len){ + if(temp_index+data_len_consumed >= tlv_len){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); //send the data to Noti manager. return TCORE_SAT_SUCCESS; } - index+=data_len_consumed; //index pointing to the Tag of next TLV + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } else { dbg("[SAT] SAT PARSER - ICON IDENTIFIER LIST TLV not present"); } -//ToDo: Text Attribute, Text Attribute list. refer ETSI 102.223. + //text attribute - optional + if((src_data[temp_index]&0x7F)==SATK_TEXT_ATTRIBUTE_TAG){ + rv =_sat_decode_text_attribute_tlv(tlv_str, tlv_len, temp_index, &pactive_cmd_ind_obj->data.setup_menu.text_attribute, &data_len_consumed); + if(rv != TCORE_SAT_SUCCESS){ + return rv; //SEND TR + } + + if(temp_index+data_len_consumed >= tlv_len){ + dbg("[SAT] SAT PARSER - no more TLVs to decode."); + return TCORE_SAT_SUCCESS; + } + + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV + } + + //text attribute list - optional + if((src_data[temp_index]&0x7F) == SATK_TEXT_ATTRIBUTE_LIST_TAG){ + int attr_item_temp_index = 0, item_cnt = 0; + int txt_attr_list_len = 0; + + struct tel_sat_text_attribute_list *txt_attr_list = NULL; + + txt_attr_list = &pactive_cmd_ind_obj->data.setup_menu.text_attribute_list; + + //length + temp_index++; + txt_attr_list_len = src_data[temp_index]; + if(txt_attr_list_len == 0){ + dbg("[SAT] - Text Attribute List is nothing"); + return TCORE_SAT_REQUIRED_VALUE_MISSING; + } + + //item cnt - each text attribute length is 4byte + item_cnt = txt_attr_list_len/4; + txt_attr_list->list_cnt = item_cnt; + dbg("[SAT] - text attribute item cnt(%d)", item_cnt); + + //get attribute data + temp_index++; + for(attr_item_temp_index = 0; attr_item_temp_index < item_cnt; attr_item_temp_index++){ + memcpy(txt_attr_list->text_attribute_list[attr_item_temp_index].text_formatting, &src_data[temp_index], 4); + temp_index += 4; + } + + dbg("[SAT] SAT PARSER - done to decode text attribute list"); + } + dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } @@ -3181,7 +3421,7 @@ static enum tcore_sat_result _sat_decode_setup_menu(unsigned char* tlv_str, int static enum tcore_sat_result _sat_decode_select_item(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0; + int temp_index = 0; int data_len_consumed=0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; @@ -3193,13 +3433,13 @@ static enum tcore_sat_result _sat_decode_select_item(unsigned char* o_cmd_data, } cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.select_item.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.select_item.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.select_item.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.select_item.command_detail.cmd_type = cmd_data[temp_index++]; /* ******decode command qualifier****** */ - if (cmd_data[index] & 0x01) { - if (cmd_data[index] & 0x02) { + if (cmd_data[temp_index] & 0x01) { + if (cmd_data[temp_index] & 0x02) { sat_cmd_ind_data->data.select_item.command_detail.cmd_qualifier.select_item.presentation_type = PRESENTATION_TYPE_NAVIGATION_OPTION; dbg("[SAT] SAT PARSER - PRESENTATION_TYPE_NAVIGATION_OPTION"); } @@ -3213,7 +3453,7 @@ static enum tcore_sat_result _sat_decode_select_item(unsigned char* o_cmd_data, dbg("[SAT] SAT PARSER - PRESENTATION_TYPE_NOT_SPECIFIED"); } - if (cmd_data[index] & 0x04) { + if (cmd_data[temp_index] & 0x04) { sat_cmd_ind_data->data.select_item.command_detail.cmd_qualifier.select_item.select_preference = SELECTION_PREFERENCE_USING_SOFT_KEY; dbg("[SAT] SAT PARSER - SELECTION_PREFERENCE_USING_SOFT_KEY"); } @@ -3222,26 +3462,26 @@ static enum tcore_sat_result _sat_decode_select_item(unsigned char* o_cmd_data, dbg("[SAT] SAT PARSER - SELECTION_PREFERENCE_NONE_REQUESTED"); } - if (cmd_data[index] & 0x80) { + if (cmd_data[temp_index] & 0x80) { sat_cmd_ind_data->data.select_item.command_detail.cmd_qualifier.select_item.help_info = TRUE; dbg("[SAT] SAT PARSER - Help info"); } //device identities - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.select_item.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //alpha identifier - index+=4; - if((cmd_data[index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ - rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.select_item.alpha_id, &data_len_consumed); + temp_index+=4; + if((cmd_data[temp_index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ + rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.select_item.alpha_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; + temp_index+=data_len_consumed; } //item objects @@ -3249,8 +3489,8 @@ static enum tcore_sat_result _sat_decode_select_item(unsigned char* o_cmd_data, do{ data_len_consumed=0; - if((cmd_data[index]&0x7F) == SATK_ITEM_TAG) { - rv = _sat_decode_item_tlv(o_cmd_data, o_length, index, + if((cmd_data[temp_index]&0x7F) == SATK_ITEM_TAG) { + rv = _sat_decode_item_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.select_item.menu_item[sat_cmd_ind_data->data.select_item.menu_item_cnt], &data_len_consumed); @@ -3266,81 +3506,129 @@ static enum tcore_sat_result _sat_decode_select_item(unsigned char* o_cmd_data, break; //??? } sat_cmd_ind_data->data.select_item.menu_item_cnt++; - index += data_len_consumed; + temp_index += data_len_consumed; - if(index >= o_length) + if(temp_index >= o_length) break; }while(sat_cmd_ind_data->data.select_item.menu_item_cnt < SAT_MENU_ITEM_COUNT_MAX); dbg("[SAT] SAT PARSER - select menu item_count=%d",sat_cmd_ind_data->data.select_item.menu_item_cnt); - if(index >= o_length){ + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - :no more TLVs to decode."); return TCORE_SAT_SUCCESS; } //item next action indicator - if((cmd_data[index]&0x7F) == SATK_ITEMS_NEXT_ACTION_INDICATOR_TAG) { + if((cmd_data[temp_index]&0x7F) == SATK_ITEMS_NEXT_ACTION_INDICATOR_TAG) { data_len_consumed = 0; - rv = _sat_decode_item_next_action_indicator_tlv(o_cmd_data, o_length, index, + rv = _sat_decode_item_next_action_indicator_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.select_item.item_next_act_ind_list, &data_len_consumed); if(rv!=TCORE_SAT_SUCCESS) return rv; - if(index+data_len_consumed >= o_length) { + if(temp_index+data_len_consumed >= o_length) { dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } - index+=data_len_consumed; + temp_index+=data_len_consumed; } //item identifier - if((cmd_data[index]&0x7F) == SATK_ITEM_IDENTIFIER_TAG) { + if((cmd_data[temp_index]&0x7F) == SATK_ITEM_IDENTIFIER_TAG) { data_len_consumed = 0; - rv = _sat_decode_item_identifier_tlv(o_cmd_data, o_length, index, + rv = _sat_decode_item_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.select_item.item_identifier, &data_len_consumed); if(rv !=TCORE_SAT_SUCCESS) return rv; - if(index+data_len_consumed >= o_length) { + if(temp_index+data_len_consumed >= o_length) { dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } - index+=data_len_consumed; //index pointing to the Tag of next TLV + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } //icon identifier - if((cmd_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ + if((cmd_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.select_item.icon_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //SEND TR } - if(index+data_len_consumed >= o_length){ + if(temp_index+data_len_consumed >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } - index+=data_len_consumed; //index pointing to the Tag of next TLV + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } - if((cmd_data[index]&0x7F) == SATK_ITEM_ICON_IDENTIFIER_LIST_TAG) { + if((cmd_data[temp_index]&0x7F) == SATK_ITEM_ICON_IDENTIFIER_LIST_TAG) { data_len_consumed = 0; - rv = _sat_decode_icon_identifier_list_tlv(o_cmd_data, o_length, index, + rv = _sat_decode_icon_identifier_list_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.select_item.icon_list, &data_len_consumed); if(rv !=TCORE_SAT_SUCCESS) return rv; //SEND TR - if(index+data_len_consumed >= o_length){ + if(temp_index+data_len_consumed >= o_length){ + dbg("[SAT] SAT PARSER - no more TLVs to decode."); + return TCORE_SAT_SUCCESS; + } + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV + } + + //text attribute - optional + if((cmd_data[temp_index]&0x7F)==SATK_TEXT_ATTRIBUTE_TAG){ + rv =_sat_decode_text_attribute_tlv(o_cmd_data, o_length, temp_index, + &sat_cmd_ind_data->data.select_item.text_attribute, &data_len_consumed); + if(rv != TCORE_SAT_SUCCESS){ + return rv; //SEND TR + } + + if(temp_index+data_len_consumed >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } - index+=data_len_consumed; //index pointing to the Tag of next TLV + + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV + } + + //text attribute list - optional + if((cmd_data[temp_index]&0x7F) == SATK_TEXT_ATTRIBUTE_LIST_TAG){ + int attr_item_temp_index = 0, item_cnt = 0; + int txt_attr_list_len = 0; + + struct tel_sat_text_attribute_list *txt_attr_list = NULL; + + txt_attr_list = &sat_cmd_ind_data->data.select_item.text_attribute_list; + + //length + temp_index++; + txt_attr_list_len = cmd_data[temp_index]; + if(txt_attr_list_len == 0){ + dbg("[SAT] - Text Attribute List is nothing"); + return TCORE_SAT_REQUIRED_VALUE_MISSING; + } + + //item cnt - each text attribute length is 4byte + item_cnt = txt_attr_list_len/4; + txt_attr_list->list_cnt = item_cnt; + dbg("[SAT] - text attribute item cnt(%d)", item_cnt); + + //get attribute data + temp_index++; + for(attr_item_temp_index = 0; attr_item_temp_index < item_cnt; attr_item_temp_index++){ + memcpy(txt_attr_list->text_attribute_list[attr_item_temp_index].text_formatting, &cmd_data[temp_index], 4); + temp_index += 4; + } + + dbg("[SAT] SAT PARSER - done to decode text attribute list"); } dbg("[SAT] SAT PARSER - :decoding done!."); @@ -3351,7 +3639,7 @@ static enum tcore_sat_result _sat_decode_select_item(unsigned char* o_cmd_data, static enum tcore_sat_result _sat_decode_send_sms(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0; + int temp_index = 0; int data_len_consumed=0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; @@ -3363,12 +3651,12 @@ static enum tcore_sat_result _sat_decode_send_sms(unsigned char* o_cmd_data, int } cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.send_sms.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.send_sms.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.send_sms.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.send_sms.command_detail.cmd_type = cmd_data[temp_index++]; /* ******decode command qualifier****** */ - if (cmd_data[index] & 0x01) { + if (cmd_data[temp_index] & 0x01) { sat_cmd_ind_data->data.send_sms.command_detail.cmd_qualifier.send_sms.packing_by_me_required = TRUE; } else { @@ -3377,61 +3665,61 @@ static enum tcore_sat_result _sat_decode_send_sms(unsigned char* o_cmd_data, int } //device identities - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.send_sms.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //alpha identifier - index+=4; - if((cmd_data[index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ + temp_index+=4; + if((cmd_data[temp_index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ data_len_consumed = 0; - rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.send_sms.alpha_id, &data_len_consumed); + rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_sms.alpha_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; + temp_index+=data_len_consumed; } //address - if((cmd_data[index]&0x7F) == SATK_ADDRESS_TAG){ + if((cmd_data[temp_index]&0x7F) == SATK_ADDRESS_TAG){ data_len_consumed = 0; - rv = _sat_decode_address_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.send_sms.address, &data_len_consumed); + rv = _sat_decode_address_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_sms.address, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; + temp_index+=data_len_consumed; } //SMS-TPDU data_len_consumed = 0; - rv = _sat_decode_sms_tpdu_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.send_sms.sms_tpdu, &data_len_consumed); + rv = _sat_decode_sms_tpdu_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_sms.sms_tpdu, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - if(index+data_len_consumed >= o_length){ + if(temp_index+data_len_consumed >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } //icon identifier - index+=data_len_consumed; - if((cmd_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ + temp_index+=data_len_consumed; + if((cmd_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, - &sat_cmd_ind_data->data.select_item.icon_id, &data_len_consumed); + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, + &sat_cmd_ind_data->data.send_sms.icon_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //SEND TR } - if(index+data_len_consumed >= o_length){ + if(temp_index+data_len_consumed >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } - index+=data_len_consumed; //index pointing to the Tag of next TLV + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } dbg("[SAT] SAT PARSER - :decoding done!."); @@ -3442,7 +3730,7 @@ static enum tcore_sat_result _sat_decode_send_sms(unsigned char* o_cmd_data, int static enum tcore_sat_result _sat_decode_send_ss(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0, data_len_consumed = 0; + int temp_index = 0, data_len_consumed = 0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; enum tcore_sat_result rv = TCORE_SAT_SUCCESS; @@ -3453,40 +3741,40 @@ static enum tcore_sat_result _sat_decode_send_ss(unsigned char* o_cmd_data, int } cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.send_ss.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.send_ss.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.send_ss.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.send_ss.command_detail.cmd_type = cmd_data[temp_index++]; /** command detail **/ - index++; //RFU + temp_index++; //RFU //device identities - memcpy(dev_id,&cmd_data[index],4); + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.send_ss.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //alpha identifier - optional - index += 4; - if((cmd_data[index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ - rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.send_ss.alpha_id, &data_len_consumed); + temp_index += 4; + if((cmd_data[temp_index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ + rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_ss.alpha_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; + temp_index+=data_len_consumed; } //ss string - rv = _sat_decode_ss_string_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.send_ss.ss_string, &data_len_consumed); + rv = _sat_decode_ss_string_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_ss.ss_string, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; //icon identifier- optional - index+=data_len_consumed; - if((cmd_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ + temp_index+=data_len_consumed; + if((cmd_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.send_ss.icon_id, &data_len_consumed); + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_ss.icon_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //SEND TR } @@ -3501,7 +3789,7 @@ static enum tcore_sat_result _sat_decode_send_ss(unsigned char* o_cmd_data, int static enum tcore_sat_result _sat_decode_send_ussd(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0, data_len_consumed = 0; + int temp_index = 0, data_len_consumed = 0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; enum tcore_sat_result rv = TCORE_SAT_SUCCESS; @@ -3512,40 +3800,40 @@ static enum tcore_sat_result _sat_decode_send_ussd(unsigned char* o_cmd_data, in } cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.send_ussd.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.send_ussd.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.send_ussd.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.send_ussd.command_detail.cmd_type = cmd_data[temp_index++]; /** command detail **/ - index++; //RFU + temp_index++; //RFU //device identities - memcpy(dev_id,&cmd_data[index],4); + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.send_ussd.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //alpha identifier - optional - index += 4; - if((cmd_data[index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ - rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.send_ussd.alpha_id, &data_len_consumed); + temp_index += 4; + if((cmd_data[temp_index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ + rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_ussd.alpha_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; + temp_index+=data_len_consumed; } //ussd string - rv = _sat_decode_ussd_string_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.send_ussd.ussd_string, &data_len_consumed); + rv = _sat_decode_ussd_string_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_ussd.ussd_string, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; //icon identifier- optional - index+=data_len_consumed; - if((cmd_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ + temp_index+=data_len_consumed; + if((cmd_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.send_ussd.icon_id, &data_len_consumed); + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_ussd.icon_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //SEND TR } @@ -3560,7 +3848,7 @@ static enum tcore_sat_result _sat_decode_send_ussd(unsigned char* o_cmd_data, in static enum tcore_sat_result _sat_decode_setup_call(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0, data_len_consumed = 0; + int temp_index = 0, data_len_consumed = 0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; enum tcore_sat_result rv = TCORE_SAT_SUCCESS; @@ -3572,140 +3860,140 @@ static enum tcore_sat_result _sat_decode_setup_call(unsigned char* o_cmd_data, i //command detail cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.setup_call.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.setup_call.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.setup_call.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.setup_call.command_detail.cmd_type = cmd_data[temp_index++]; /* ******decode command qualifier****** */ - switch(cmd_data[index]){ + switch(cmd_data[temp_index]){ case SETUP_CALL_IF_ANOTHER_CALL_NOT_BUSY: case SETUP_CALL_IF_ANOTHER_CALL_NOT_BUSY_WITH_REDIAL: case SETUP_CALL_PUT_ALL_OTHER_CALLS_ON_HOLD: case SETUP_CALL_PUT_ALL_OTHER_CALLS_ON_HOLD_WITH_REDIAL: case SETUP_CALL_DISCONN_ALL_OTHER_CALLS: case SETUP_CALL_DISCONN_ALL_OTHER_CALLS_WITH_REDIAL: - sat_cmd_ind_data->data.setup_call.command_detail.cmd_qualifier.setup_call.setup_call = cmd_data[index]; + sat_cmd_ind_data->data.setup_call.command_detail.cmd_qualifier.setup_call.setup_call = cmd_data[temp_index]; dbg("[SAT] SAT PARSER - setup_call.cmd_qualifier= 0x%02x", sat_cmd_ind_data->data.setup_call.command_detail.cmd_qualifier.setup_call.setup_call); break; case SETUP_CALL_RESERVED: default: - dbg("[SAT] SAT PARSER - setup_call.cmd_qualifier= 0x%02x", cmd_data[index]); + dbg("[SAT] SAT PARSER - setup_call.cmd_qualifier= 0x%02x", cmd_data[temp_index]); return TCORE_SAT_BEYOND_ME_CAPABILITY; break; } //device identifier - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.setup_call.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //alpha identifier (user confirmation) - optional - index+=4; - if((cmd_data[index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ - rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.setup_call.user_confirm_alpha_id, &data_len_consumed); + temp_index+=4; + if((cmd_data[temp_index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ + rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.setup_call.user_confirm_alpha_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; + temp_index+=data_len_consumed; } //address - rv = _sat_decode_address_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.setup_call.address, &data_len_consumed); + rv = _sat_decode_address_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.setup_call.address, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } //capability configuration parameter - optional - if((cmd_data[index]&0x7F)==SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG){ - rv =_sat_decode_ccp_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.setup_call.ccp, &data_len_consumed); + if((cmd_data[temp_index]&0x7F)==SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG){ + rv =_sat_decode_ccp_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.setup_call.ccp, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //sub address - optional - if((cmd_data[index]&0x7F)==SATK_SUB_ADDRESS_TAG){ - rv =_sat_decode_sub_address_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.setup_call.subaddress, &data_len_consumed); + if((cmd_data[temp_index]&0x7F)==SATK_SUB_ADDRESS_TAG){ + rv =_sat_decode_sub_address_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.setup_call.subaddress, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //time duration - optional - if((cmd_data[index]&0x7F)==SATK_DURATION_TAG){ - rv =_sat_decode_duration_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.setup_call.duration, &data_len_consumed); + if((cmd_data[temp_index]&0x7F)==SATK_DURATION_TAG){ + rv =_sat_decode_duration_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.setup_call.duration, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //icon identifier (user confirmation) - optional - if((cmd_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ + if((cmd_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.setup_call.user_confirm_icon_id, &data_len_consumed); + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.setup_call.user_confirm_icon_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //alpha identifier (call setup) - optional - if((cmd_data[index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ - rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.setup_call.call_setup_alpha_id, &data_len_consumed); + if((cmd_data[temp_index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ + rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.setup_call.call_setup_alpha_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //icon identifier (call setup) - optional - if((cmd_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ + if((cmd_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.setup_call.call_setup_icon_id, &data_len_consumed); + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.setup_call.call_setup_icon_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } @@ -3721,7 +4009,7 @@ static enum tcore_sat_result _sat_decode_setup_call(unsigned char* o_cmd_data, i static enum tcore_sat_result _sat_decode_provide_local_info(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0; + int temp_index = 0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; enum tcore_sat_result rv = TCORE_SAT_SUCCESS; @@ -3733,15 +4021,15 @@ static enum tcore_sat_result _sat_decode_provide_local_info(unsigned char* o_cmd //command detail cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_type = cmd_data[temp_index++]; /* ******decode command qualifier****** */ - switch(cmd_data[index]){ + switch(cmd_data[temp_index]){ case LOCAL_INFO_DATE_TIME_AND_TIMEZONE: case LOCAL_INFO_LANGUAGE: - sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_qualifier.provide_local_info.provide_local_info = cmd_data[index]; + sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_qualifier.provide_local_info.provide_local_info = cmd_data[temp_index]; break; //TODO - Other cases default: @@ -3750,8 +4038,8 @@ static enum tcore_sat_result _sat_decode_provide_local_info(unsigned char* o_cmd } //device identifier - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.setup_event_list.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; @@ -3766,7 +4054,7 @@ static enum tcore_sat_result _sat_decode_provide_local_info(unsigned char* o_cmd static enum tcore_sat_result _sat_decode_setup_event_list(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0, data_len_consumed = 0; + int temp_index = 0, data_len_consumed = 0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; enum tcore_sat_result rv = TCORE_SAT_SUCCESS; @@ -3778,21 +4066,20 @@ static enum tcore_sat_result _sat_decode_setup_event_list(unsigned char* o_cmd_d //command detail cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.setup_event_list.command_detail.cmd_type = cmd_data[temp_index++]; //device identifier - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.setup_event_list.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //event list - index+=4; - rv = _sat_decode_event_list_tlv(o_cmd_data, o_length, index, - &sat_cmd_ind_data->data.setup_event_list.event_list, + temp_index+=4; + rv = _sat_decode_event_list_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.setup_event_list.event_list, &data_len_consumed); dbg("[SAT] SAT PARSER - :decoding done!."); @@ -3803,7 +4090,7 @@ static enum tcore_sat_result _sat_decode_setup_event_list(unsigned char* o_cmd_d static enum tcore_sat_result _sat_decode_setup_idle_mode_text(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0, data_len_consumed = 0; + int temp_index = 0, data_len_consumed = 0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; enum tcore_sat_result rv = TCORE_SAT_SUCCESS; @@ -3815,56 +4102,56 @@ static enum tcore_sat_result _sat_decode_setup_idle_mode_text(unsigned char* o_c //command detail cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.setup_idle_mode_text.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.setup_idle_mode_text.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.setup_idle_mode_text.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.setup_idle_mode_text.command_detail.cmd_type = cmd_data[temp_index++]; //device identifier - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.setup_idle_mode_text.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //text string - index+=4; - rv = _sat_decode_text_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.setup_idle_mode_text.text, &data_len_consumed); + temp_index+=4; + rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.setup_idle_mode_text.text, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - if(sat_cmd_ind_data->data.setup_idle_mode_text.text.string_length <= 0){ - err("[SAT] SAT PARSER - :string length is 0"); + if(sat_cmd_ind_data->data.setup_idle_mode_text.text.string_length < 0){ + err("[SAT] SAT PARSER - :string length is less than 0"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } dbg("[SAT] SAT PARSER text(%s)",sat_cmd_ind_data->data.setup_idle_mode_text.text.string); - dbg("[SAT] SAT PARSER o_len(%d) index(%d) data_len_consumed(%d)",o_length , index, data_len_consumed); + dbg("[SAT] SAT PARSER o_len(%d) temp_index(%d) data_len_consumed(%d)",o_length , temp_index, data_len_consumed); - if(index+data_len_consumed > o_length){ + if(temp_index+data_len_consumed > o_length){ err("[SAT] SAT PARSER - Wrong String TLV"); return TCORE_SAT_BEYOND_ME_CAPABILITY; } - else if(index+data_len_consumed == o_length){ + else if(temp_index+data_len_consumed == o_length){ dbg("[SAT] SAT PARSER - :no more TLVs to decode."); return TCORE_SAT_SUCCESS; } //icon identifier - index+=data_len_consumed; - if((cmd_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ + temp_index+=data_len_consumed; + if((cmd_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.setup_idle_mode_text.icon_id, &data_len_consumed); + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.setup_idle_mode_text.icon_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; //SEND TR } - if(index+data_len_consumed >= o_length){ + if(temp_index+data_len_consumed >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } - index+=data_len_consumed; //index pointing to the Tag of next TLV + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } //ToDo: Text Attribute @@ -3876,7 +4163,7 @@ static enum tcore_sat_result _sat_decode_setup_idle_mode_text(unsigned char* o_c static enum tcore_sat_result _sat_decode_send_dtmf(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0, data_len_consumed = 0; + int temp_index = 0, data_len_consumed = 0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; enum tcore_sat_result rv = TCORE_SAT_SUCCESS; @@ -3888,60 +4175,60 @@ static enum tcore_sat_result _sat_decode_send_dtmf(unsigned char* o_cmd_data, in //command detail cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.send_dtmf.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.send_dtmf.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.send_dtmf.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.send_dtmf.command_detail.cmd_type = cmd_data[temp_index++]; //device identifier - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.send_dtmf.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //alpha identifier - optional - index+=4; - if((cmd_data[index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ - rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.send_dtmf.alpha_id, &data_len_consumed); + temp_index+=4; + if((cmd_data[temp_index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ + rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_dtmf.alpha_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; + temp_index+=data_len_consumed; } // DTMF string - mandatory - if ((cmd_data[index] & 0x7F) == SATK_DTMF_STRING_TAG) { - rv = _sat_decode_dtmf_string_tlv(o_cmd_data, o_length, index, + if ((cmd_data[temp_index] & 0x7F) == SATK_DTMF_STRING_TAG) { + rv = _sat_decode_dtmf_string_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_dtmf.dtmf_string, &data_len_consumed); if (rv != TCORE_SAT_SUCCESS) { return rv; } - if (index + data_len_consumed >= o_length) { + if (temp_index + data_len_consumed >= o_length) { dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } - index += data_len_consumed; + temp_index += data_len_consumed; } else { dbg("[SAT] SAT PARSER - DTMF tlv is missed."); return TCORE_SAT_REQUIRED_VALUE_MISSING; } //icon identifier - optional - if ((cmd_data[index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) { + if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) { data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, - &sat_cmd_ind_data->data.setup_idle_mode_text.icon_id, &data_len_consumed); + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, + &sat_cmd_ind_data->data.send_dtmf.icon_id, &data_len_consumed); if (rv != TCORE_SAT_SUCCESS) { return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - if (index + data_len_consumed >= o_length) { + if (temp_index + data_len_consumed >= o_length) { dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } - index += data_len_consumed; //index pointing to the Tag of next TLV + temp_index += data_len_consumed; //temp_index pointing to the Tag of next TLV } //ToDo: Text Attribute, Frame Identifier @@ -3953,7 +4240,7 @@ static enum tcore_sat_result _sat_decode_send_dtmf(unsigned char* o_cmd_data, in static enum tcore_sat_result _sat_decode_language_notification(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0; + int temp_index = 0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; enum tcore_sat_result rv = TCORE_SAT_SUCCESS; @@ -3965,28 +4252,28 @@ static enum tcore_sat_result _sat_decode_language_notification(unsigned char* o_ //command detail cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.language_notification.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.language_notification.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.language_notification.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.language_notification.command_detail.cmd_type = cmd_data[temp_index++]; /* ******decode command qualifier****** */ - if(cmd_data[index]&0x01) + if(cmd_data[temp_index]&0x01) sat_cmd_ind_data->data.language_notification.command_detail.cmd_qualifier.language_notification.specific_language = TRUE; else sat_cmd_ind_data->data.language_notification.command_detail.cmd_qualifier.language_notification.specific_language = FALSE; //device identifier - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.language_notification.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //language - conditional - index+=4; + temp_index+=4; if (sat_cmd_ind_data->data.language_notification.command_detail.cmd_qualifier.language_notification.specific_language == TRUE) { - if((cmd_data[index]&0x7F) == SATK_LANGUAGE_TAG) { - rv = _sat_decode_language_tlv(cmd_data, o_length, index, &sat_cmd_ind_data->data.language_notification.language); + if((cmd_data[temp_index]&0x7F) == SATK_LANGUAGE_TAG) { + rv = _sat_decode_language_tlv(cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.language_notification.language); if(rv != TCORE_SAT_SUCCESS) return rv; } else { @@ -4006,7 +4293,7 @@ static enum tcore_sat_result _sat_decode_language_notification(unsigned char* o_ static enum tcore_sat_result _sat_decode_launch_browser(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0, data_len_consumed = 0; + int temp_index = 0, data_len_consumed = 0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; enum tcore_sat_result rv = TCORE_SAT_SUCCESS; @@ -4018,12 +4305,12 @@ static enum tcore_sat_result _sat_decode_launch_browser(unsigned char* o_cmd_dat //command detail cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.launch_browser.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.launch_browser.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.launch_browser.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.launch_browser.command_detail.cmd_type = cmd_data[temp_index++]; // decode command qualifier - switch (cmd_data[index]) { + switch (cmd_data[temp_index]) { case 0x00: sat_cmd_ind_data->data.launch_browser.command_detail.cmd_qualifier.launch_browser.launch_browser = LAUNCH_BROWSER_IF_NOT_ALREADY_LAUNCHED; @@ -4051,36 +4338,36 @@ static enum tcore_sat_result _sat_decode_launch_browser(unsigned char* o_cmd_dat } //device identifier - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.language_notification.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; - index += 4; + temp_index += 4; //Browser Identity TLV - Optional - if ((cmd_data[index] & 0x7F) == SATK_BROWSER_IDENTITY_TAG) { - rv = _sat_decode_browser_identity_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.launch_browser.browser_id, &data_len_consumed); + if ((cmd_data[temp_index] & 0x7F) == SATK_BROWSER_IDENTITY_TAG) { + rv = _sat_decode_browser_identity_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.launch_browser.browser_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - index += data_len_consumed; + temp_index += data_len_consumed; } else { dbg("[SAT] SAT PARSER - Browser ID NOT present"); } //URL TLV - Mandatory - if ((cmd_data[index] & 0x7F) == SATK_URL_TAG) { - rv = _sat_decode_url_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.launch_browser.url, &data_len_consumed); + if ((cmd_data[temp_index] & 0x7F) == SATK_URL_TAG) { + rv = _sat_decode_url_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.launch_browser.url, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - if (index + data_len_consumed >= o_length) { + if (temp_index + data_len_consumed >= o_length) { dbg("[SAT] SAT PARSER - No more TLVs to decode, decoding done."); return TCORE_SAT_SUCCESS; } else { dbg("[SAT] SAT PARSER - more TLVs to decode, decoding continue."); - index += data_len_consumed; + temp_index += data_len_consumed; } } else { dbg("[SAT] SAT PARSER - Browser URL NOT present! BUG! this value is mandatory!!!"); @@ -4088,16 +4375,16 @@ static enum tcore_sat_result _sat_decode_launch_browser(unsigned char* o_cmd_dat } //bearer - optional - if ((cmd_data[index] & 0x7F) == SATK_BEARER_TAG) { - rv = _sat_decode_bearer_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.launch_browser.bearer, &data_len_consumed); + if ((cmd_data[temp_index] & 0x7F) == SATK_BEARER_TAG) { + rv = _sat_decode_bearer_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.launch_browser.bearer, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - if (index + data_len_consumed >= o_length) { + if (temp_index + data_len_consumed >= o_length) { dbg("[SAT] SAT PARSER - No more TLVs to decode, decoding done."); return TCORE_SAT_SUCCESS; } else { - index += data_len_consumed; + temp_index += data_len_consumed; } } else { dbg("[SAT] SAT PARSER - Bearer TLV Not present."); @@ -4105,7 +4392,7 @@ static enum tcore_sat_result _sat_decode_launch_browser(unsigned char* o_cmd_dat //Provisioning reference file - optional sat_cmd_ind_data->data.launch_browser.file_ref_count = 0; - while ((cmd_data[index] & 0x7F) == SATK_PROVISIONING_REF_FILE_TAG) { + while ((cmd_data[temp_index] & 0x7F) == SATK_PROVISIONING_REF_FILE_TAG) { if (sat_cmd_ind_data->data.launch_browser.file_ref_count >= SAT_PROVISIONING_REF_MAX_COUNT) { dbg("[SAT] SAT PARSER - More number of PRF entries than can be handled"); return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; @@ -4114,7 +4401,7 @@ static enum tcore_sat_result _sat_decode_launch_browser(unsigned char* o_cmd_dat rv = _sat_decode_provisioning_file_ref_tlv( o_cmd_data, o_length, - index, + temp_index, &sat_cmd_ind_data->data.launch_browser.file_list[sat_cmd_ind_data->data.launch_browser.file_ref_count], &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { @@ -4123,58 +4410,58 @@ static enum tcore_sat_result _sat_decode_launch_browser(unsigned char* o_cmd_dat sat_cmd_ind_data->data.launch_browser.file_ref_count++; } - if (index + data_len_consumed >= o_length) { + if (temp_index + data_len_consumed >= o_length) { dbg("[SAT] SAT PARSER - No more TLVs to decode, decoding done."); return TCORE_SAT_SUCCESS; } else { - index += data_len_consumed; + temp_index += data_len_consumed; } } //text string(gateway/proxy identity) - optional - if ((cmd_data[index] & 0x7F) == SATK_TEXT_STRING_TAG) { - rv = _sat_decode_text_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.launch_browser.gateway_proxy_text, &data_len_consumed); + if ((cmd_data[temp_index] & 0x7F) == SATK_TEXT_STRING_TAG) { + rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.launch_browser.gateway_proxy_text, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - if (index + data_len_consumed >= o_length) { + if (temp_index + data_len_consumed >= o_length) { dbg("[SAT] SAT PARSER - No more TLVs to decode, decoding done."); return TCORE_SAT_SUCCESS; } else { - index += data_len_consumed; + temp_index += data_len_consumed; } } //alpha identifier - optional - if((cmd_data[index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ - rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.launch_browser.user_confirm_alpha_id, &data_len_consumed); + if((cmd_data[temp_index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ + rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.launch_browser.user_confirm_alpha_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - if (index + data_len_consumed >= o_length) { + if (temp_index + data_len_consumed >= o_length) { dbg("[SAT] SAT PARSER - No more TLVs to decode, decoding done."); return TCORE_SAT_SUCCESS; } - index+=data_len_consumed; + temp_index+=data_len_consumed; } else { dbg("[SAT] SAT PARSER - No Alpha ID TLV."); } //icon identifier - optional - if ((cmd_data[index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) { + if ((cmd_data[temp_index] & 0x7F) == SATK_ICON_IDENTIFIER_TAG) { data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.launch_browser.user_confirm_icon_id, &data_len_consumed); if (rv != TCORE_SAT_SUCCESS) { return TCORE_SAT_COMMAND_NOT_UNDERSTOOD; } - if (index + data_len_consumed >= o_length) { + if (temp_index + data_len_consumed >= o_length) { dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } - index += data_len_consumed; //index pointing to the Tag of next TLV + temp_index += data_len_consumed; //temp_index pointing to the Tag of next TLV } //ToDo: Text Attribute, Frame Identifier @@ -4186,7 +4473,7 @@ static enum tcore_sat_result _sat_decode_launch_browser(unsigned char* o_cmd_dat static enum tcore_sat_result _sat_decode_open_channel(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0; + int temp_index = 0; gboolean b_1st_duration = FALSE; int bearer_desc_len =0, data_len_consumed=0; unsigned char dev_id[4]; @@ -4199,59 +4486,59 @@ static enum tcore_sat_result _sat_decode_open_channel(unsigned char* o_cmd_data, } cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.open_channel.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.open_channel.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.open_channel.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.open_channel.command_detail.cmd_type = cmd_data[temp_index++]; /** command detail **/ sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.immediate_link = FALSE; sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.automatic_reconnection = FALSE; sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.background_mode = FALSE; - if(cmd_data[index]&0x01){ + if(cmd_data[temp_index]&0x01){ sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.immediate_link = TRUE; dbg("[SAT] SAT PARSER - Immediate Link Establishment"); } - if(cmd_data[index]&0x02){ + if(cmd_data[temp_index]&0x02){ sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.automatic_reconnection = TRUE; dbg("[SAT] SAT PARSER - Auto Reconnection"); } - if(cmd_data[index]&0x04){ + if(cmd_data[temp_index]&0x04){ sat_cmd_ind_data->data.open_channel.command_detail.cmd_qualifier.open_channel.background_mode = TRUE; dbg("[SAT] SAT PARSER - Background mode"); } //device identities - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.open_channel.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //alpha identifier - optional - index += 4; - if((cmd_data[index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ - rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.alpha_id, &data_len_consumed); + temp_index += 4; + if((cmd_data[temp_index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ + rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.alpha_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; + temp_index+=data_len_consumed; } //icon id - optional - if((cmd_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ + if((cmd_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.icon_id, &data_len_consumed); + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.icon_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; //index pointing to the Tag of next TLV + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } //bearer description - rv =_sat_decode_bearer_description_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_desc, &data_len_consumed); + rv =_sat_decode_bearer_description_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_desc, &data_len_consumed); bearer_desc_len = data_len_consumed; if(rv != TCORE_SAT_SUCCESS) return rv; @@ -4261,35 +4548,35 @@ static enum tcore_sat_result _sat_decode_open_channel(unsigned char* o_cmd_data, case BEARER_CSD: //address - rv = _sat_decode_address_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.address, &data_len_consumed); + rv = _sat_decode_address_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.address, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; + temp_index+=data_len_consumed; //sub address - optional - if((cmd_data[index]&0x7F) == SATK_SUB_ADDRESS_TAG){ + if((cmd_data[temp_index]&0x7F) == SATK_SUB_ADDRESS_TAG){ data_len_consumed = 0; - rv = _sat_decode_subaddress_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.subaddress, &data_len_consumed); + rv = _sat_decode_subaddress_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.subaddress, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; + temp_index+=data_len_consumed; } //time duration 1- optional - if((cmd_data[index]&0x7F)==SATK_DURATION_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_DURATION_TAG){ data_len_consumed = 0; - rv =_sat_decode_duration_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.duration1, &data_len_consumed); + rv =_sat_decode_duration_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.duration1, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; + temp_index+=data_len_consumed; b_1st_duration = TRUE; } //time duration 2- optional - if((cmd_data[index]&0x7F)==SATK_DURATION_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_DURATION_TAG){ if(!b_1st_duration){ dbg("duration 1 does not present!"); @@ -4297,95 +4584,95 @@ static enum tcore_sat_result _sat_decode_open_channel(unsigned char* o_cmd_data, } data_len_consumed = 0; - rv =_sat_decode_duration_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.duration2, &data_len_consumed); + rv =_sat_decode_duration_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.duration2, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; + temp_index+=data_len_consumed; } //bearer description - already did it - index+=bearer_desc_len; + temp_index+=bearer_desc_len; //buffer size - rv =_sat_decode_buffer_size_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.buffer_size, &data_len_consumed); + rv =_sat_decode_buffer_size_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.buffer_size, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } //other address - optional - if((cmd_data[index]&0x7F)==SATK_OTHER_ADDRESS_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_OTHER_ADDRESS_TAG){ data_len_consumed = 0; - rv =_sat_decode_other_address_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.other_address, &data_len_consumed); + rv =_sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.other_address, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //text string - user login - optional - if((cmd_data[index]&0x7F)==SATK_TEXT_STRING_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_TEXT_STRING_TAG){ data_len_consumed = 0; - rv = _sat_decode_text_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.text_user_login, &data_len_consumed); + rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.text_user_login, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //text string - user password - optional - if((cmd_data[index]&0x7F)==SATK_TEXT_STRING_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_TEXT_STRING_TAG){ data_len_consumed = 0; - rv = _sat_decode_text_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.text_user_pwd, &data_len_consumed); + rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.cs_bearer.text_user_pwd, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //UICC/TERMINAL interface transport level - optional - if((cmd_data[index]&0x7F)==SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG){ data_len_consumed = 0; - rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.interface_transport_level, &data_len_consumed); + rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.interface_transport_level, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //destination address - optional - if((cmd_data[index]&0x7F)==SATK_OTHER_ADDRESS_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_OTHER_ADDRESS_TAG){ data_len_consumed = 0; - rv =_sat_decode_other_address_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.data_destination_address, &data_len_consumed); + rv =_sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.data_destination_address, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } @@ -4394,104 +4681,104 @@ static enum tcore_sat_result _sat_decode_open_channel(unsigned char* o_cmd_data, break; case BEARER_GPRS: //bearer description - already did it - index+=bearer_desc_len; + temp_index+=bearer_desc_len; //buffer size - rv =_sat_decode_buffer_size_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.buffer_size, &data_len_consumed); + rv =_sat_decode_buffer_size_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.buffer_size, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } //Network Access Name - optional - if((cmd_data[index]&0x7F)==SATK_NETWORK_ACCESS_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_NETWORK_ACCESS_TAG){ data_len_consumed = 0; - rv =_sat_decode_network_access_name_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.network_access_name, &data_len_consumed); + rv =_sat_decode_network_access_name_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.network_access_name, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //other address - optional - if((cmd_data[index]&0x7F)==SATK_OTHER_ADDRESS_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_OTHER_ADDRESS_TAG){ data_len_consumed = 0; - rv =_sat_decode_other_address_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.other_address, &data_len_consumed); + rv =_sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.other_address, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //text string - user login - optional - if((cmd_data[index]&0x7F)==SATK_TEXT_STRING_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_TEXT_STRING_TAG){ data_len_consumed = 0; - rv = _sat_decode_text_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.text_user_login, &data_len_consumed); + rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.text_user_login, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //text string - user password - optional - if((cmd_data[index]&0x7F)==SATK_TEXT_STRING_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_TEXT_STRING_TAG){ data_len_consumed = 0; - rv = _sat_decode_text_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.text_user_pwd, &data_len_consumed); + rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.ps_bearer.text_user_pwd, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //UICC/TERMINAL interface transport level - optional - if((cmd_data[index]&0x7F)==SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG){ data_len_consumed = 0; - rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.interface_transport_level, &data_len_consumed); + rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.interface_transport_level, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } - dbg("the value (0x%x) after interface transport level", cmd_data[index]&0x7F); + dbg("the value (0x%x) after interface transport level", cmd_data[temp_index]&0x7F); //destination address - optional - if((cmd_data[index]&0x7F)==SATK_OTHER_ADDRESS_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_OTHER_ADDRESS_TAG){ data_len_consumed = 0; - rv =_sat_decode_other_address_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.data_destination_address, &data_len_consumed); + rv =_sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.data_destination_address, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } @@ -4500,87 +4787,87 @@ static enum tcore_sat_result _sat_decode_open_channel(unsigned char* o_cmd_data, break; case BEARER_DEFAULT_BEARER_FROM_TRANSPORT_LAYER: //bearer description - already did it - index+=bearer_desc_len; + temp_index+=bearer_desc_len; //buffer size - rv =_sat_decode_buffer_size_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.buffer_size, &data_len_consumed); + rv =_sat_decode_buffer_size_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.buffer_size, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } //other address - optional - if((cmd_data[index]&0x7F)==SATK_OTHER_ADDRESS_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_OTHER_ADDRESS_TAG){ data_len_consumed = 0; - rv =_sat_decode_other_address_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.default_bearer.other_address, &data_len_consumed); + rv =_sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.default_bearer.other_address, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //text string - user login - optional - if((cmd_data[index]&0x7F)==SATK_TEXT_STRING_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_TEXT_STRING_TAG){ data_len_consumed = 0; - rv = _sat_decode_text_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.default_bearer.text_user_login, &data_len_consumed); + rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.default_bearer.text_user_login, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //text string - user password - optional - if((cmd_data[index]&0x7F)==SATK_TEXT_STRING_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_TEXT_STRING_TAG){ data_len_consumed = 0; - rv = _sat_decode_text_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.default_bearer.text_user_pwd, &data_len_consumed); + rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.default_bearer.text_user_pwd, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //UICC/TERMINAL interface transport level - optional - if((cmd_data[index]&0x7F)==SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG){ data_len_consumed = 0; - rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.interface_transport_level, &data_len_consumed); + rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.interface_transport_level, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //destination address - optional - if((cmd_data[index]&0x7F)==SATK_OTHER_ADDRESS_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_OTHER_ADDRESS_TAG){ data_len_consumed = 0; - rv =_sat_decode_other_address_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.data_destination_address, &data_len_consumed); + rv =_sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.data_destination_address, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } @@ -4590,18 +4877,18 @@ static enum tcore_sat_result _sat_decode_open_channel(unsigned char* o_cmd_data, case BEARER_LOCAL_LINK_TECHNOLOGY_INDEPENDENT: //time duration 1- optional - if((cmd_data[index]&0x7F)==SATK_DURATION_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_DURATION_TAG){ data_len_consumed = 0; - rv =_sat_decode_duration_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.duration1, &data_len_consumed); + rv =_sat_decode_duration_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.duration1, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; + temp_index+=data_len_consumed; b_1st_duration = TRUE; } //time duration 2- optional - if((cmd_data[index]&0x7F)==SATK_DURATION_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_DURATION_TAG){ if(!b_1st_duration){ dbg("duration 1 does not present!"); @@ -4609,81 +4896,81 @@ static enum tcore_sat_result _sat_decode_open_channel(unsigned char* o_cmd_data, } data_len_consumed = 0; - rv =_sat_decode_duration_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.duration2, &data_len_consumed); + rv =_sat_decode_duration_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.duration2, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; + temp_index+=data_len_consumed; } //bearer description - already did it - index+=bearer_desc_len; + temp_index+=bearer_desc_len; //buffer size - rv =_sat_decode_buffer_size_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.buffer_size, &data_len_consumed); + rv =_sat_decode_buffer_size_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.buffer_size, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } //text string - user password - optional - if((cmd_data[index]&0x7F)==SATK_TEXT_STRING_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_TEXT_STRING_TAG){ data_len_consumed = 0; - rv = _sat_decode_text_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.text_user_pwd, &data_len_consumed); + rv = _sat_decode_text_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.text_user_pwd, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //UICC/TERMINAL interface transport level - optional - if((cmd_data[index]&0x7F)==SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_USIM_ME_INTERFACE_TRANSPORT_LEVEL_TAG){ data_len_consumed = 0; - rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.interface_transport_level, &data_len_consumed); + rv = _sat_decode_uicc_terminal_interface_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.interface_transport_level, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) return rv; - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //destination address - optional - if((cmd_data[index]&0x7F)==SATK_OTHER_ADDRESS_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_OTHER_ADDRESS_TAG){ data_len_consumed = 0; - rv =_sat_decode_other_address_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.data_destination_address, &data_len_consumed); + rv =_sat_decode_other_address_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.data_destination_address, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } } //remote entity address - optional - if((cmd_data[index]&0x7F)==SATK_REMOTE_ENTITY_ADDRESS_TAG){ + if((cmd_data[temp_index]&0x7F)==SATK_REMOTE_ENTITY_ADDRESS_TAG){ data_len_consumed = 0; - rv =_sat_decode_remote_entity_address_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.remote_entity_address, &data_len_consumed); + rv =_sat_decode_remote_entity_address_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.open_channel.bearer_detail.local_bearer.remote_entity_address, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; - if(index >= o_length){ + temp_index+=data_len_consumed; + if(temp_index >= o_length){ dbg("[SAT] SAT PARSER - no more TLVs to decode."); return TCORE_SAT_SUCCESS; } @@ -4702,7 +4989,7 @@ static enum tcore_sat_result _sat_decode_open_channel(unsigned char* o_cmd_data, static enum tcore_sat_result _sat_decode_close_channel(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0; + int temp_index = 0; int data_len_consumed=0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; @@ -4714,37 +5001,37 @@ static enum tcore_sat_result _sat_decode_close_channel(unsigned char* o_cmd_data } cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.close_channel.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.close_channel.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.close_channel.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.close_channel.command_detail.cmd_type = cmd_data[temp_index++]; /** command detail **/ - index++; //RFU + temp_index++; //RFU //device identities - memcpy(dev_id,&cmd_data[index],4); + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.close_channel.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //alpha identifier - optional - index += 4; - if((cmd_data[index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ - rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.close_channel.alpha_id, &data_len_consumed); + temp_index += 4; + if((cmd_data[temp_index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ + rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.close_channel.alpha_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; + temp_index+=data_len_consumed; } //icon id - optional - if((cmd_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ + if((cmd_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.close_channel.icon_id, &data_len_consumed); + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.close_channel.icon_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; //index pointing to the Tag of next TLV + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } //ToDo: Text Attribute and frames @@ -4757,7 +5044,7 @@ static enum tcore_sat_result _sat_decode_close_channel(unsigned char* o_cmd_data static enum tcore_sat_result _sat_decode_receive_data(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0; + int temp_index = 0; int data_len_consumed=0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; @@ -4769,41 +5056,41 @@ static enum tcore_sat_result _sat_decode_receive_data(unsigned char* o_cmd_data, } cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.receive_data.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.receive_data.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.receive_data.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.receive_data.command_detail.cmd_type = cmd_data[temp_index++]; /** command detail **/ - index++; //RFU + temp_index++; //RFU //device identities - memcpy(dev_id,&cmd_data[index],4); + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.receive_data.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //alpha identifier - optional - index += 4; - if((cmd_data[index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ - rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.receive_data.alpha_id, &data_len_consumed); + temp_index += 4; + if((cmd_data[temp_index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ + rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.receive_data.alpha_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; + temp_index+=data_len_consumed; } //icon id - optional - if((cmd_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ + if((cmd_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.receive_data.icon_id, &data_len_consumed); + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.receive_data.icon_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; //index pointing to the Tag of next TLV + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } //channel data length - rv =_sat_decode_channel_data_length_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.receive_data.channel_data_len, &data_len_consumed); + rv =_sat_decode_channel_data_length_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.receive_data.channel_data_len, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } @@ -4818,7 +5105,7 @@ static enum tcore_sat_result _sat_decode_receive_data(unsigned char* o_cmd_data, static enum tcore_sat_result _sat_decode_send_data(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0; + int temp_index = 0; int data_len_consumed=0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; @@ -4830,46 +5117,46 @@ static enum tcore_sat_result _sat_decode_send_data(unsigned char* o_cmd_data, in } cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.send_data.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.send_data.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.send_data.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.send_data.command_detail.cmd_type = cmd_data[temp_index++]; /** command detail **/ sat_cmd_ind_data->data.send_data.command_detail.cmd_qualifier.send_data.send_data_immediately = FALSE; - if(cmd_data[index]&0x01){ + if(cmd_data[temp_index]&0x01){ sat_cmd_ind_data->data.send_data.command_detail.cmd_qualifier.send_data.send_data_immediately = TRUE; dbg("[SAT] SAT PARSER - Send data immediately"); } //device identities - index++; - memcpy(dev_id,&cmd_data[index],4); + temp_index++; + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.send_data.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; //alpha identifier - optional - index += 4; - if((cmd_data[index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ - rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.send_data.alpha_id, &data_len_consumed); + temp_index += 4; + if((cmd_data[temp_index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ + rv = _sat_decode_alpha_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_data.alpha_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS) { return rv; } - index+=data_len_consumed; + temp_index+=data_len_consumed; } //icon id - optional - if((cmd_data[index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ + if((cmd_data[temp_index]&0x7F) == SATK_ICON_IDENTIFIER_TAG){ data_len_consumed = 0; - rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.send_data.icon_id, &data_len_consumed); + rv = _sat_decode_icon_identifier_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_data.icon_id, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } - index+=data_len_consumed; //index pointing to the Tag of next TLV + temp_index+=data_len_consumed; //temp_index pointing to the Tag of next TLV } //channel data - rv =_sat_decode_channel_data_tlv(o_cmd_data, o_length, index, &sat_cmd_ind_data->data.send_data.channel_data, &data_len_consumed); + rv =_sat_decode_channel_data_tlv(o_cmd_data, o_length, temp_index, &sat_cmd_ind_data->data.send_data.channel_data, &data_len_consumed); if(rv != TCORE_SAT_SUCCESS){ return rv; //SEND TR } @@ -4884,7 +5171,7 @@ static enum tcore_sat_result _sat_decode_send_data(unsigned char* o_cmd_data, in static enum tcore_sat_result _sat_decode_get_channel_status(unsigned char* o_cmd_data, int o_length, int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) { - int index = 0; + int temp_index = 0; unsigned char dev_id[4]; unsigned char* cmd_data = NULL; enum tcore_sat_result rv = TCORE_SAT_SUCCESS; @@ -4895,15 +5182,15 @@ static enum tcore_sat_result _sat_decode_get_channel_status(unsigned char* o_cmd } cmd_data = &o_cmd_data[0]; - index = curr_offset+2; - sat_cmd_ind_data->data.get_channel_status.command_detail.cmd_num = cmd_data[index++]; - sat_cmd_ind_data->data.get_channel_status.command_detail.cmd_type = cmd_data[index++]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.get_channel_status.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.get_channel_status.command_detail.cmd_type = cmd_data[temp_index++]; /** command detail **/ - index++; //RFU + temp_index++; //RFU //device identities - memcpy(dev_id,&cmd_data[index],4); + memcpy(dev_id,&cmd_data[temp_index],4); rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.get_channel_status.device_id); if(rv != TCORE_SAT_SUCCESS) return rv; @@ -4912,10 +5199,42 @@ static enum tcore_sat_result _sat_decode_get_channel_status(unsigned char* o_cmd return TCORE_SAT_SUCCESS; } +//6.4.XX Unsupported Command +static enum tcore_sat_result _sat_decode_unsupported_command(unsigned char* o_cmd_data, int o_length, + int curr_offset, struct tcore_sat_proactive_command *sat_cmd_ind_data) +{ + int temp_index = 0; + unsigned char dev_id[4]; + unsigned char* cmd_data = NULL; + enum tcore_sat_result rv = TCORE_SAT_SUCCESS; + + if(o_cmd_data == NULL){ + dbg("[SAT] SAT PARSER - o_cmd_data == NULL"); + return TCORE_SAT_ERROR_FATAL; + } + + cmd_data = &o_cmd_data[0]; + temp_index = curr_offset+2; + sat_cmd_ind_data->data.unsupport_cmd.command_detail.cmd_num = cmd_data[temp_index++]; + sat_cmd_ind_data->data.unsupport_cmd.command_detail.cmd_type = cmd_data[temp_index++]; + + /** command detail **/ + temp_index++; //RFU + + //device identities + memcpy(dev_id,&cmd_data[temp_index],4); + rv = _sat_decode_device_identities_tlv(dev_id, &sat_cmd_ind_data->data.unsupport_cmd.device_id); + if(rv != TCORE_SAT_SUCCESS) + return rv; + + dbg("[SAT] SAT PARSER - :decoding done!."); + return TCORE_SAT_SUCCESS; +} + int tcore_sat_decode_proactive_command(unsigned char* tlv_origin, unsigned int tlv_length, struct tcore_sat_proactive_command* decoded_tlv) { - unsigned int index = 0; + unsigned int temp_index = 0; int length_field_len = 0; enum tcore_sat_result rv = TCORE_SAT_SUCCESS; @@ -4925,149 +5244,278 @@ int tcore_sat_decode_proactive_command(unsigned char* tlv_origin, unsigned int t } //tag - if(tlv_origin[index++]!= SATK_PROACTIVE_CMD_TAG) { - dbg("[SAT] SAT PARSER - Did not find Proactive command tag.tag=%d", tlv_origin[index-1]); + if(tlv_origin[temp_index++]!= SATK_PROACTIVE_CMD_TAG) { + dbg("[SAT] SAT PARSER - Did not find Proactive command tag.tag=%d", tlv_origin[temp_index-1]); return TCORE_SAT_ERROR_FATAL; } //length - length_field_len = _get_length_filed_size(tlv_origin[index]); + length_field_len = _get_length_filed_size(tlv_origin[temp_index]); if(length_field_len == 0) { dbg("[SAT] SAT PARSER - Invalid length."); return TCORE_SAT_ERROR_FATAL; } - - index+=length_field_len; + //length + dbg("[SAT] SAT PARSER - tlv_length=%d", tlv_length); + temp_index+=length_field_len; //check command validation - if(tlv_length < index+5+4)//command detail(5) and device identities(4) + if(tlv_length < temp_index+5+4)//command detail(5) and device identities(4) return TCORE_SAT_ERROR_FATAL; //check comprehensive value - if((tlv_origin[index] | 0x7F) != 0x7F){ - dbg("comprehensive value 0x%x", tlv_origin[index] | 0x7F); + if((tlv_origin[temp_index] | 0x7F) != 0x7F){ + dbg("comprehensive value 0x%x", tlv_origin[temp_index] | 0x7F); b_comprehensive = TRUE; } - if( (tlv_origin[index] & 0x7F) != SATK_COMMAND_DETAILS_TAG){ + if( (tlv_origin[temp_index] & 0x7F) != SATK_COMMAND_DETAILS_TAG){ err("[SAT] no command detail info"); return TCORE_SAT_ERROR_FATAL; } - if( tlv_origin[index+1] != SATK_COMMAND_DETAILS_LENGTH){ + if( tlv_origin[temp_index+1] != SATK_COMMAND_DETAILS_LENGTH){ err("[SAT] invalid command detail length"); return TCORE_SAT_ERROR_FATAL; } - decoded_tlv->cmd_num= tlv_origin[index+2]; - decoded_tlv->cmd_type = tlv_origin[index+3]; + decoded_tlv->cmd_num= tlv_origin[temp_index+2]; + decoded_tlv->cmd_type = tlv_origin[temp_index+3]; switch(decoded_tlv->cmd_type) { case SAT_PROATV_CMD_DISPLAY_TEXT: //6.4.1 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_DISPLAY_TEXT"); - rv = _sat_decode_display_text(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_display_text(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_GET_INKEY: //6.4.2 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_GET_INKEY"); - rv = _sat_decode_get_inkey(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_get_inkey(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_GET_INPUT: //6.4.3 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_GET_INPUT"); - rv = _sat_decode_get_input(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_get_input(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_MORE_TIME: //6.4.4 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_MORE_TIME"); - rv = _sat_decode_more_time(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_more_time(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_PLAY_TONE: //6.4.5 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_PLAY TONE"); - rv = _sat_decode_play_tone(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_play_tone(tlv_origin, tlv_length, temp_index, decoded_tlv); break; //case POLL INTERVAL //6.4.6 processing by cp case SAT_PROATV_CMD_REFRESH: //6.4.7 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_REFRESH"); - rv = _sat_decode_refresh(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_refresh(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_SETUP_MENU: //6.4.8 dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_SETUP_MENU"); - rv = _sat_decode_setup_menu(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_setup_menu(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_SELECT_ITEM: //6.4.9 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SELECT_ITEM"); - rv = _sat_decode_select_item(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_select_item(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_SEND_SMS: //6.4.10 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SEND_SMS"); - rv = _sat_decode_send_sms(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_send_sms(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_SEND_SS: //6.4.11 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SEND_SS"); - rv = _sat_decode_send_ss(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_send_ss(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_SEND_USSD: //6.4.12 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SEND_USSD"); - rv = _sat_decode_send_ussd(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_send_ussd(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_SETUP_CALL: //6.4.13 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SETUP_CALL"); - rv = _sat_decode_setup_call(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_setup_call(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_PROVIDE_LOCAL_INFO: //6.4.15 dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_PROVIDE_LOCAL_INFO"); - rv = _sat_decode_provide_local_info(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_provide_local_info(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_SETUP_EVENT_LIST: //6.4.16 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SETUP_EVENT_LIST"); - rv = _sat_decode_setup_event_list(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_setup_event_list(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT: //6.4.22 dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_SETUP_IDLE_MODE_TEXT"); - rv = _sat_decode_setup_idle_mode_text(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_setup_idle_mode_text(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_SEND_DTMF: //6.4.24 dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_SEND_DTMF"); - rv = _sat_decode_send_dtmf(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_send_dtmf(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_LANGUAGE_NOTIFICATION: //6.4.25 dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_LANGUAGE_NOTIFICATION"); - rv = _sat_decode_language_notification(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_language_notification(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_LAUNCH_BROWSER: //6.4.26 dbg("[SAT] SAT PARSER - SAT_PROATV_CMD_LAUNCH_BROWSER"); - rv = _sat_decode_launch_browser(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_launch_browser(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_OPEN_CHANNEL://6.4.27 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_OPEN_CHANNEL"); - rv = _sat_decode_open_channel(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_open_channel(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_CLOSE_CHANNEL://6.4.28 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_CLOSE_CHANNEL"); - rv = _sat_decode_close_channel(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_close_channel(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_RECEIVE_DATA://6.4.29 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_RECEIVE_DATA"); - rv = _sat_decode_receive_data(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_receive_data(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_SEND_DATA://6.4.30 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_SEND_DATA"); - rv = _sat_decode_send_data(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_send_data(tlv_origin, tlv_length, temp_index, decoded_tlv); break; case SAT_PROATV_CMD_GET_CHANNEL_STATUS://6.4.31 dbg("[SAT] SAT PARSER - SAT_CMD_TYPE_GET_CHANNEL_STATUS"); - rv = _sat_decode_get_channel_status(tlv_origin, tlv_length, index, decoded_tlv); + rv = _sat_decode_get_channel_status(tlv_origin, tlv_length, temp_index, decoded_tlv); break; default: dbg("[SAT] SAT PARSER - ME cannot perform this command =0x[%02x]", decoded_tlv->cmd_type); - //SEND TR with command not understood by ME, those command that are defined but not implemented by ME should be sent as beyond me's capability. - rv = TCORE_SAT_BEYOND_ME_CAPABILITY; + rv = _sat_decode_unsupported_command(tlv_origin, tlv_length, temp_index, decoded_tlv); break; } - //return value will be success if the proactive command has been successfuly decoded, then send it to clients. dbg("[SAT] SAT PARSER - each command parsing done."); return rv; } +int tcore_sat_decode_call_control_result(unsigned char* tlv_origin, unsigned int tlv_length, struct tnoti_sat_call_control_result_ind* call_ctrl_result_tlv) +{ + unsigned int temp_index = 0; + int length = 0, data_len = 0, data_len_consumed = 0; + enum tcore_sat_result rv = TCORE_SAT_SUCCESS; + + if(tlv_origin == NULL || tlv_length <=2) { + dbg("[SAT] SAT PARSER - pointer pData passed is NULL or invalid length."); + return TCORE_SAT_ERROR_FATAL; + } + + //call conrol result + call_ctrl_result_tlv->cc_result = tlv_origin[temp_index++]; + length = _get_length_filed_size(tlv_origin[temp_index]); + if(length == 0){ + dbg("[SAT] fail to get the call control result length"); + return TCORE_SAT_ERROR_FATAL; + } + temp_index = temp_index+length-1; + data_len = tlv_origin[temp_index]; + dbg("[SAT] call control result (%d), data len(%d)",call_ctrl_result_tlv->cc_result, data_len); + if(data_len == 0){ + dbg("no more call control result - decoding done"); + return rv; + } + temp_index++; + + //address - optional (voice call) + if((tlv_origin[temp_index]&0x7F) == SATK_ADDRESS_TAG){ + rv = _sat_decode_address_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->address, &data_len_consumed); + if(rv != TCORE_SAT_SUCCESS) { + return rv; + } + temp_index+=data_len_consumed; + + if(temp_index >= tlv_length){ + dbg("[SAT] call control decoding done"); + return TCORE_SAT_SUCCESS; + } + } + + //ss string - optional (ss) + if((tlv_origin[temp_index]&0x7F) == SATK_SS_STRING_TAG){ + rv = _sat_decode_ss_string_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->ss_string, &data_len_consumed); + if(rv != TCORE_SAT_SUCCESS) { + return rv; + } + temp_index+=data_len_consumed; + + if(temp_index >= tlv_length){ + dbg("[SAT] call control decoding done"); + return TCORE_SAT_SUCCESS; + } + } + + //ccp1 - optional + if((tlv_origin[temp_index]&0x7F)==SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG){ + rv =_sat_decode_ccp_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->ccp1, &data_len_consumed); + if(rv != TCORE_SAT_SUCCESS){ + return rv; //SEND TR + } + temp_index+=data_len_consumed; + + if(temp_index >= tlv_length){ + dbg("[SAT] call control decoding done"); + return TCORE_SAT_SUCCESS; + } + } + + //sub address + if((tlv_origin[temp_index]&0x7F) == SATK_SUB_ADDRESS_TAG){ + rv = _sat_decode_sub_address_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->sub_address, &data_len_consumed); + if(rv != TCORE_SAT_SUCCESS) { + return rv; + } + temp_index+=data_len_consumed; + + if(temp_index >= tlv_length){ + dbg("[SAT] call control decoding done"); + return TCORE_SAT_SUCCESS; + } + } + + //alpha id + if((tlv_origin[temp_index]&0x7F) == SATK_ALPHA_IDENTIFIER_TAG){ + rv = _sat_decode_alpha_identifier_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->alpha_id, &data_len_consumed); + if(rv != TCORE_SAT_SUCCESS) { + return rv; + } + temp_index+=data_len_consumed; + + if(temp_index >= tlv_length){ + dbg("[SAT] call control decoding done"); + return TCORE_SAT_SUCCESS; + } + } + + //bc repeated indicator + if((tlv_origin[temp_index]&0x7F) == SATK_BC_REPEAT_INDICATOR_TAG){ + int tag = 0; + int bc_repeat_ind_len = 0; + + tag = tlv_origin[temp_index++]; + bc_repeat_ind_len = tlv_origin[temp_index++]; + call_ctrl_result_tlv->bc_repeat_type.bc_indi_repeat_type = tlv_origin[temp_index++]; + + dbg("bc repeated indication tag(%x) len(%x) type(%x)", tag, bc_repeat_ind_len, call_ctrl_result_tlv->bc_repeat_type.bc_indi_repeat_type); + if(temp_index >= tlv_length){ + dbg("[SAT] call control decoding done"); + return TCORE_SAT_SUCCESS; + } + } + + //ccp2 + if((tlv_origin[temp_index]&0x7F)==SATK_CAPABILITY_CONFIGURATION_PARAMETERS_TAG){ + rv =_sat_decode_ccp_tlv(tlv_origin, tlv_length, temp_index, &call_ctrl_result_tlv->ccp2, &data_len_consumed); + if(rv != TCORE_SAT_SUCCESS){ + return rv; //SEND TR + } + temp_index+=data_len_consumed; + + if(temp_index >= tlv_length){ + dbg("[SAT] call control decoding done"); + return TCORE_SAT_SUCCESS; + } + } + + return rv; +} + static unsigned char _sat_encode_dcs_tlv(const struct data_coding_scheme* src) { unsigned char rv = 0x00; @@ -5098,15 +5546,15 @@ static unsigned char _sat_encode_dcs_tlv(const struct data_coding_scheme* src) //alphabet format switch(src->a_format) { - case ALPHABET_FROMAT_SMS_DEFAULT: + case ALPHABET_FORMAT_SMS_DEFAULT: rv &= 0xF3; break; - case ALPHABET_FROMAT_8BIT_DATA: + case ALPHABET_FORMAT_8BIT_DATA: rv |= 0x04; break; - case ALPHABET_FROMAT_UCS2: + case ALPHABET_FORMAT_UCS2: rv |= 0x08; break; @@ -5118,66 +5566,66 @@ static unsigned char _sat_encode_dcs_tlv(const struct data_coding_scheme* src) return rv; } -static int _sat_encode_command_detail_tlv(const struct tel_sat_cmd_detail_info* src, char *dst, int current_index) +static int _sat_encode_command_detail_tlv(const struct tel_sat_cmd_detail_info* src, char *dst, int current_temp_index) { - dst[current_index++] = (b_comprehensive ? (SATK_COMMAND_DETAILS_TAG | 0x80) : SATK_COMMAND_DETAILS_TAG); - dst[current_index++] = SATK_COMMAND_DETAILS_LENGTH; - dst[current_index++] = src->cmd_num; - dst[current_index++] = src->cmd_type; - dst[current_index] = 0x00; + dst[current_temp_index++] = (b_comprehensive ? (SATK_COMMAND_DETAILS_TAG | 0x80) : SATK_COMMAND_DETAILS_TAG); + dst[current_temp_index++] = SATK_COMMAND_DETAILS_LENGTH; + dst[current_temp_index++] = src->cmd_num; + dst[current_temp_index++] = src->cmd_type; + dst[current_temp_index] = 0x00; switch(src->cmd_type){ case SAT_PROATV_CMD_DISPLAY_TEXT:{ //command detail text priority if (src->cmd_qualifier.display_text.text_priority == TEXT_PRIORITY_HIGH) - dst[current_index] += 0x01; + dst[current_temp_index] += 0x01; //command detail text clear type if (src->cmd_qualifier.display_text.text_clear_type == TEXT_WAIT_FOR_USER_TO_CLEAR_MSG) - dst[current_index] += 0x80; + dst[current_temp_index] += 0x80; }break; case SAT_PROATV_CMD_GET_INKEY:{ //command detail alphabet set if(src->cmd_qualifier.get_inkey.alphabet_set) - dst[current_index] += 0x01; + dst[current_temp_index] += 0x01; //command detail alphabet type if(src->cmd_qualifier.get_inkey.alphabet_type == INPUT_ALPHABET_TYPE_UCS2) - dst[current_index] += 0x02; + dst[current_temp_index] += 0x02; //command detail get inkey type if(src->cmd_qualifier.get_inkey.inkey_type == INKEY_TYPE_YES_NO_REQUESTED) - dst[current_index] += 0x04; + dst[current_temp_index] += 0x04; //command detail immediate response required if(src->cmd_qualifier.get_inkey.immediate_rsp_required) - dst[current_index] += 0x08; + dst[current_temp_index] += 0x08; //command detail help available if (src->cmd_qualifier.get_inkey.help_info) - dst[current_index] += 0x80; + dst[current_temp_index] += 0x80; }break; case SAT_PROATV_CMD_GET_INPUT:{ //command detail alphabet set if(src->cmd_qualifier.get_input.alphabet_set) - dst[current_index] += 0x01; + dst[current_temp_index] += 0x01; //command detail alphabet type if(src->cmd_qualifier.get_input.alphabet_type == INPUT_ALPHABET_TYPE_UCS2) - dst[current_index] += 0x02; + dst[current_temp_index] += 0x02; //command detail echo user input if(!src->cmd_qualifier.get_input.me_echo_user_input) - dst[current_index] += 0x04; + dst[current_temp_index] += 0x04; //command detail user input unpacked format if(!src->cmd_qualifier.get_input.user_input_unpacked_format) - dst[current_index] += 0x08; + dst[current_temp_index] += 0x08; //command detail help available if (src->cmd_qualifier.get_input.help_info) - dst[current_index] += 0x80; + dst[current_temp_index] += 0x80; }break; case SAT_PROATV_CMD_MORE_TIME:{ dbg("more time : 1bit RFU") @@ -5185,56 +5633,71 @@ static int _sat_encode_command_detail_tlv(const struct tel_sat_cmd_detail_info* case SAT_PROATV_CMD_PLAY_TONE:{ //command detail vibration alert if(src->cmd_qualifier.play_tone.vibration_alert == VIBRATE_ALERT_REQUIRED) - dst[current_index] += 0x01; + dst[current_temp_index] += 0x01; }break; case SAT_PROATV_CMD_REFRESH:{ //command detail refresh command - dst[current_index] += src->cmd_qualifier.refresh.refresh; + dst[current_temp_index] += src->cmd_qualifier.refresh.refresh; }break; case SAT_PROATV_CMD_SETUP_MENU:{ //command detail preferences if (src->cmd_qualifier.setup_menu.select_preference == SELECTION_PREFERENCE_USING_SOFT_KEY) - dst[current_index] += 0x01; + dst[current_temp_index] += 0x01; //command detail help available if (src->cmd_qualifier.setup_menu.help_info) - dst[current_index] += 0x80; + dst[current_temp_index] += 0x80; }break; case SAT_PROATV_CMD_SELECT_ITEM:{ //command detail presentation - dst[current_index] += src->cmd_qualifier.select_item.presentation_type; + if(src->cmd_qualifier.select_item.presentation_type != PRESENTATION_TYPE_NOT_SPECIFIED){ + dst[current_temp_index] += 0x01; + if(src->cmd_qualifier.select_item.presentation_type == PRESENTATION_TYPE_NAVIGATION_OPTION){ + dst[current_temp_index] += PRESENTATION_TYPE_NAVIGATION_OPTION; + } + } //command detail selection preference if(src->cmd_qualifier.select_item.select_preference == SELECTION_PREFERENCE_USING_SOFT_KEY) - dst[current_index] += 0x04; + dst[current_temp_index] += 0x04; //command detail help available if (src->cmd_qualifier.select_item.help_info) - dst[current_index] += 0x80; + dst[current_temp_index] += 0x80; }break; case SAT_PROATV_CMD_SEND_SMS:{ //command detail sms packing by me required if(src->cmd_qualifier.send_sms.packing_by_me_required) - dst[current_index] += 0x01; + dst[current_temp_index] += 0x01; }break; case SAT_PROATV_CMD_SETUP_CALL:{ //command detail setup call command; - dst[current_index] += src->cmd_qualifier.setup_call.setup_call; + dst[current_temp_index] += src->cmd_qualifier.setup_call.setup_call; }break; case SAT_PROATV_CMD_SETUP_EVENT_LIST:{ dbg("setup evnet list : 1bit RFU") }break; case SAT_PROATV_CMD_OPEN_CHANNEL:{ if(src->cmd_qualifier.open_channel.immediate_link) - dst[current_index] += 0x01; + dst[current_temp_index] += 0x01; if(src->cmd_qualifier.open_channel.automatic_reconnection) - dst[current_index] += 0x02; + dst[current_temp_index] += 0x02; if(src->cmd_qualifier.open_channel.background_mode) - dst[current_index] += 0x04; + dst[current_temp_index] += 0x04; }break; case SAT_PROATV_CMD_SEND_DATA:{ if(src->cmd_qualifier.send_data.send_data_immediately) - dst[current_index] += 0x01; + dst[current_temp_index] += 0x01; + }break; + case SAT_PROATV_CMD_PROVIDE_LOCAL_INFO:{ + dst[current_temp_index] += src->cmd_qualifier.provide_local_info.provide_local_info; + }break; + case SAT_PROATV_CMD_LANGUAGE_NOTIFICATION:{ + if(src->cmd_qualifier.language_notification.specific_language) + dst[current_temp_index] += 0x01; + }break; + case SAT_PROATV_CMD_LAUNCH_BROWSER:{ + dst[current_temp_index] += src->cmd_qualifier.launch_browser.launch_browser; }break; default: err("no matched cmd type(%d)", src->cmd_type); @@ -5244,185 +5707,205 @@ static int _sat_encode_command_detail_tlv(const struct tel_sat_cmd_detail_info* return 5; } -static int _sat_encode_device_identities_tlv(const struct tel_sat_device_identities* src, char *dst, int current_index) +static int _sat_encode_device_identities_tlv(const struct tel_sat_device_identities* src, char *dst, int current_temp_index) { - dst[current_index++] = (b_comprehensive ? (SATK_DEVICE_IDENTITY_TAG | 0x80) : SATK_DEVICE_IDENTITY_TAG); - dst[current_index++] =SATK_DEVICE_IDENTITY_LENGTH; - dst[current_index++] = src->src; - dst[current_index++] = src->dest; + dst[current_temp_index++] = SATK_DEVICE_IDENTITY_TAG; + dst[current_temp_index++] = SATK_DEVICE_IDENTITY_LENGTH; + dst[current_temp_index++] = src->src; + dst[current_temp_index++] = src->dest; //device identities total len 4 return 4; } -static int _sat_encode_item_identifier_tlv(const struct tel_sat_item_identifier* src, char *dst, int current_index) +static int _sat_encode_item_identifier_tlv(const struct tel_sat_item_identifier* src, char *dst, int current_temp_index) { - dst[current_index++] =SATK_ITEM_IDENTIFIER_TAG; - dst[current_index++] =SATK_ITEM_IDENTIFIER_LENGTH; - dst[current_index++] = src->item_identifier; + dst[current_temp_index++] =SATK_ITEM_IDENTIFIER_TAG; + dst[current_temp_index++] =SATK_ITEM_IDENTIFIER_LENGTH; + dst[current_temp_index++] = src->item_identifier; //item identifier total len 3 return 3; } -static int _sat_encode_duration_tlv(const struct tel_sat_duration* src, char *dst, int current_index) +/*static int _sat_encode_duration_tlv(const struct tel_sat_duration* src, char *dst, int current_temp_index) { - dst[current_index++] =SATK_DURATION_TAG; - dst[current_index++] =SATK_DURATION_LENGTH; - dst[current_index++] = src->time_unit; - dst[current_index++] = src->time_interval; + dst[current_temp_index++] =SATK_DURATION_TAG; + dst[current_temp_index++] =SATK_DURATION_LENGTH; + dst[current_temp_index++] = src->time_unit; + dst[current_temp_index++] = src->time_interval; //duration total len 4 return 4; -} +}*/ -static int _sat_encode_text_tlv(const struct tel_sat_text_string_object* src, char *dst, int current_index, gboolean raw_dcs) +static int _sat_encode_text_tlv(const struct tel_sat_text_string_object* src, char *dst, int current_temp_index, gboolean raw_dcs) { int total_len = 0; - int length_index = 0; + int length_temp_index = 0; //tag - dst[current_index++] =SATK_TEXT_STRING_TAG; + dst[current_temp_index++] =SATK_TEXT_STRING_TAG; //length if(src->string_length <= 0x7F){ - dst[current_index++] =SATK_DCS_LENGTH+src->string_length; - length_index = 1; + dst[current_temp_index++] =SATK_DCS_LENGTH+src->string_length; + length_temp_index = 1; } else{ - dst[current_index++] = 0x81; - dst[current_index++] =SATK_DCS_LENGTH+src->string_length; - length_index = 2; + dst[current_temp_index++] = 0x81; + dst[current_temp_index++] =SATK_DCS_LENGTH+src->string_length; + length_temp_index = 2; } //dcs if(raw_dcs) - dst[current_index++] = src->dcs.raw_dcs; + dst[current_temp_index++] = src->dcs.raw_dcs; else - dst[current_index++] =_sat_encode_dcs_tlv(&(src->dcs)); + dst[current_temp_index++] =_sat_encode_dcs_tlv(&(src->dcs)); //value if(src->string_length > 0){ - memcpy(&(dst[current_index]), src->string, src->string_length); + memcpy(&(dst[current_temp_index]), src->string, src->string_length); } - //tag+index+dcs+data - total_len = 1+length_index+1+src->string_length; + //tag+temp_index+dcs+data + total_len = 1+length_temp_index+1+src->string_length; return total_len; } -static int _sat_encode_eventlist_tlv(const enum event_list src, char *dst, int current_index) +static int _sat_encode_eventlist_tlv(const enum event_list src, char *dst, int current_temp_index) { - dst[current_index++] =SATK_EVENT_LIST_TAG; - dst[current_index++] =0x01; - dst[current_index++] =src; + dst[current_temp_index++] =SATK_EVENT_LIST_TAG; + dst[current_temp_index++] =0x01; + dst[current_temp_index++] =src; return 3; } -static int _sat_encode_date_time_and_timezone_tlv(const struct tel_sat_date_time_and_timezone *src, char *dst, int current_index) +static int _sat_encode_date_time_and_timezone_tlv(const struct tel_sat_date_time_and_timezone *src, char *dst, int current_temp_index) { - dst[current_index++] = SATK_DATE_TIME_AND_TIME_ZONE_TAG; - dst[current_index++] = SATK_DATE_TIME_AND_TIME_ZONE_LENGTH; - dst[current_index++] = src->year; - dst[current_index++] = src->month; - dst[current_index++] = src->day; - dst[current_index++] = src->hour; - dst[current_index++] = src->minute; - dst[current_index++] = src->second; - dst[current_index++] = src->timeZone; + dst[current_temp_index++] = SATK_DATE_TIME_AND_TIME_ZONE_TAG; + dst[current_temp_index++] = SATK_DATE_TIME_AND_TIME_ZONE_LENGTH; + dst[current_temp_index++] = src->year; + dst[current_temp_index++] = src->month; + dst[current_temp_index++] = src->day; + dst[current_temp_index++] = src->hour; + dst[current_temp_index++] = src->minute; + dst[current_temp_index++] = src->second; + dst[current_temp_index++] = src->timeZone; return 1+1+SATK_DATE_TIME_AND_TIME_ZONE_LENGTH; //tag length+len field length+value length; } -static int _sat_encode_language_tlv(const enum tel_sim_language_type src, char *dst, int current_index) +static int _sat_encode_language_tlv(const enum tel_sim_language_type src, char *dst, int current_temp_index) { - dst[current_index++] =SATK_LANGUAGE_TAG; - dst[current_index++] =SATK_LANGUAGE_LENGTH; + dst[current_temp_index++] =SATK_LANGUAGE_TAG; + dst[current_temp_index++] =SATK_LANGUAGE_LENGTH; dbg("language (%d)", src); switch(src){ case SIM_LANG_GERMAN : - dst[current_index++] = 'd'; - dst[current_index++] = 'e'; + dst[current_temp_index++] = 'd'; + dst[current_temp_index++] = 'e'; break; case SIM_LANG_ENGLISH : - dst[current_index++] = 'e'; - dst[current_index++] = 'n'; + dst[current_temp_index++] = 'e'; + dst[current_temp_index++] = 'n'; break; case SIM_LANG_ITALIAN : - dst[current_index++] = 'i'; - dst[current_index++] = 't'; + dst[current_temp_index++] = 'i'; + dst[current_temp_index++] = 't'; break; case SIM_LANG_FRENCH : - dst[current_index++] = 'f'; - dst[current_index++] = 'r'; + dst[current_temp_index++] = 'f'; + dst[current_temp_index++] = 'r'; break; case SIM_LANG_SPANISH : - dst[current_index++] = 'e'; - dst[current_index++] = 's'; + dst[current_temp_index++] = 'e'; + dst[current_temp_index++] = 's'; break; case SIM_LANG_DUTCH : - dst[current_index++] = 'n'; - dst[current_index++] = 'l'; + dst[current_temp_index++] = 'n'; + dst[current_temp_index++] = 'l'; break; case SIM_LANG_SWEDISH : - dst[current_index++] = 's'; - dst[current_index++] = 'v'; + dst[current_temp_index++] = 's'; + dst[current_temp_index++] = 'v'; break; case SIM_LANG_DANISH : - dst[current_index++] = 'd'; - dst[current_index++] = 'a'; + dst[current_temp_index++] = 'd'; + dst[current_temp_index++] = 'a'; break; case SIM_LANG_PORTUGUESE : - dst[current_index++] = 'p'; - dst[current_index++] = 't'; + dst[current_temp_index++] = 'p'; + dst[current_temp_index++] = 't'; break; case SIM_LANG_FINNISH : - dst[current_index++] = 'f'; - dst[current_index++] = 'i'; + dst[current_temp_index++] = 'f'; + dst[current_temp_index++] = 'i'; break; case SIM_LANG_NORWEGIAN : - dst[current_index++] = 'n'; - dst[current_index++] = 'b'; + dst[current_temp_index++] = 'n'; + dst[current_temp_index++] = 'b'; break; case SIM_LANG_GREEK : - dst[current_index++] = 'e'; - dst[current_index++] = 'l'; + dst[current_temp_index++] = 'e'; + dst[current_temp_index++] = 'l'; break; case SIM_LANG_TURKISH : - dst[current_index++] = 't'; - dst[current_index++] = 'k'; + dst[current_temp_index++] = 't'; + dst[current_temp_index++] = 'k'; break; case SIM_LANG_HUNGARIAN : - dst[current_index++] = 'h'; - dst[current_index++] = 'u'; + dst[current_temp_index++] = 'h'; + dst[current_temp_index++] = 'u'; break; case SIM_LANG_POLISH : - dst[current_index++] = 'p'; - dst[current_index++] = 'l'; + dst[current_temp_index++] = 'p'; + dst[current_temp_index++] = 'l'; + break; + + case SIM_LANG_KOREAN : + dst[current_temp_index++] = 'k'; + dst[current_temp_index++] = 'o'; + break; + + case SIM_LANG_CHINESE : + dst[current_temp_index++] = 'z'; + dst[current_temp_index++] = 'h'; + break; + + case SIM_LANG_RUSSIAN : + dst[current_temp_index++] = 'r'; + dst[current_temp_index++] = 'u'; + break; + + case SIM_LANG_JAPANESE: + dst[current_temp_index++] = 'j'; + dst[current_temp_index++] = 'a'; break; default:{ - dst[current_index++] = 'e'; - dst[current_index++] = 'n'; + dst[current_temp_index++] = 'e'; + dst[current_temp_index++] = 'n'; dbg("[SAT] SAT PARSER - Unknown Language: 0x%x",src); break; } @@ -5430,41 +5913,41 @@ static int _sat_encode_language_tlv(const enum tel_sim_language_type src, char * return 4; } -static int _sat_encode_browser_termination_tlv(const enum browser_termination_cause src, char *dst, int current_index) +static int _sat_encode_browser_termination_tlv(const enum browser_termination_cause src, char *dst, int current_temp_index) { - dst[current_index++] =SATK_BROWSER_TERMINATION_CAUSE_TAG; - dst[current_index++] =SATK_BROWSER_TERMINATION_CAUSE_LENGTH; - dst[current_index++] =src; + dst[current_temp_index++] =SATK_BROWSER_TERMINATION_CAUSE_TAG; + dst[current_temp_index++] =SATK_BROWSER_TERMINATION_CAUSE_LENGTH; + dst[current_temp_index++] =src; return 3; } - -static int _sat_encode_bearer_desc_tlv(const struct tel_sat_bearer_description* src, char *dst, int current_index) +#if 0 +static int _sat_encode_bearer_desc_tlv(const struct tel_sat_bearer_description* src, char *dst, int current_temp_index) { int total_len = 0; - int length_index = 0; + int length_temp_index = 0; - dst[current_index++] =SATK_BEARER_DISCRIPTION_TAG; + dst[current_temp_index++] =SATK_BEARER_DISCRIPTION_TAG; - //length index - length_index = current_index++; + //length temp_index + length_temp_index = current_temp_index++; //bearer type - dst[current_index++] = src->bearer_type; + dst[current_temp_index++] = src->bearer_type; switch(src->bearer_type){ case BEARER_CSD:{ - dst[current_index++] = src->bearer_parameter.cs_bearer_param.data_rate; - dst[current_index++] = src->bearer_parameter.cs_bearer_param.service_type; - dst[current_index++] = src->bearer_parameter.cs_bearer_param.connection_element_type; + dst[current_temp_index++] = src->bearer_parameter.cs_bearer_param.data_rate; + dst[current_temp_index++] = src->bearer_parameter.cs_bearer_param.service_type; + dst[current_temp_index++] = src->bearer_parameter.cs_bearer_param.connection_element_type; }break; case BEARER_GPRS:{ - dst[current_index++] = src->bearer_parameter.ps_bearer_param.precedence_class; - dst[current_index++] = src->bearer_parameter.ps_bearer_param.delay_class; - dst[current_index++] = src->bearer_parameter.ps_bearer_param.reliability_class; - dst[current_index++] = src->bearer_parameter.ps_bearer_param.peak_throughput_class; - dst[current_index++] = src->bearer_parameter.ps_bearer_param.mean_throughput_class; - dst[current_index++] = src->bearer_parameter.ps_bearer_param.pdp_type; + dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.precedence_class; + dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.delay_class; + dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.reliability_class; + dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.peak_throughput_class; + dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.mean_throughput_class; + dst[current_temp_index++] = src->bearer_parameter.ps_bearer_param.pdp_type; }break; case BEARER_DEFAULT_BEARER_FROM_TRANSPORT_LAYER: case BEARER_LOCAL_LINK_TECHNOLOGY_INDEPENDENT: @@ -5472,178 +5955,178 @@ static int _sat_encode_bearer_desc_tlv(const struct tel_sat_bearer_description* break; } - dst[length_index] = (current_index-1) - length_index; - total_len = (current_index-1) - length_index + 2; //tag and length + dst[length_temp_index] = (current_temp_index-1) - length_temp_index; + total_len = (current_temp_index-1) - length_temp_index + 2; //tag and length return total_len; } -static int _sat_encode_buffer_size_tlv(const struct tel_sat_buffer_size* src, char *dst, int current_index) +static int _sat_encode_buffer_size_tlv(const struct tel_sat_buffer_size* src, char *dst, int current_temp_index) { - dst[current_index++] = SATK_BUFFER_SIZE_TAG; - dst[current_index++] = SATK_BUFFER_SIZE_LENGTH; - dst[current_index++] = src->size[0]; - dst[current_index++] = src->size[1]; + dst[current_temp_index++] = SATK_BUFFER_SIZE_TAG; + dst[current_temp_index++] = SATK_BUFFER_SIZE_LENGTH; + dst[current_temp_index++] = src->size[0]; + dst[current_temp_index++] = src->size[1]; return 4; } - -static int _sat_encode_channel_data_tlv(const struct tel_sat_channel_data* src, char *dst, int current_index) +#endif +static int _sat_encode_channel_data_tlv(const struct tel_sat_channel_data* src, char *dst, int current_temp_index) { int total_len = 0; - int length_index = 0; + int length_temp_index = 0; - dst[current_index++] = SATK_CHANNEL_DATA_TAG; + dst[current_temp_index++] = SATK_CHANNEL_DATA_TAG; if(src->data_string_len <= 0x7F){ - dst[current_index++] = src->data_string_len; - length_index = 1; + dst[current_temp_index++] = src->data_string_len; + length_temp_index = 1; } else{ - dst[current_index++] = 0x81; - dst[current_index++] = src->data_string_len; - length_index = 2; + dst[current_temp_index++] = 0x81; + dst[current_temp_index++] = src->data_string_len; + length_temp_index = 2; } - memcpy(&(dst[current_index]), src->data_string, src->data_string_len); + memcpy(&(dst[current_temp_index]), src->data_string, src->data_string_len); - total_len = 1+length_index+src->data_string_len; + total_len = 1+length_temp_index+src->data_string_len; return total_len; } -static int _sat_encode_channel_data_length_tlv(const struct tel_sat_channel_data_len* src, char *dst, int current_index) +static int _sat_encode_channel_data_length_tlv(const struct tel_sat_channel_data_len* src, char *dst, int current_temp_index) { - dst[current_index++] = SATK_CHANNEL_DATA_LEN_TAG; - dst[current_index++] = SATK_CHANNEL_DATA_LENGTH_VALUE_LENGTH; - dst[current_index++] = src->data_len; + dst[current_temp_index++] = SATK_CHANNEL_DATA_LEN_TAG; + dst[current_temp_index++] = SATK_CHANNEL_DATA_LENGTH_VALUE_LENGTH; + dst[current_temp_index++] = src->data_len; return 3; } -static int _sat_encode_channel_status_tlv(const struct tel_sat_channel_status* src, char *dst, int current_index) +static int _sat_encode_channel_status_tlv(const struct tel_sat_channel_status* src, char *dst, int current_temp_index) { - dst[current_index++] = SATK_CHANNEL_STATUS_TAG; - dst[current_index++] = SATK_CHANNEL_STATUS_LENGTH; + dst[current_temp_index++] = SATK_CHANNEL_STATUS_TAG; + dst[current_temp_index++] = SATK_CHANNEL_STATUS_LENGTH; if(src->status == link_or_packet_service_activated) //(bit 8) - dst[current_index] += 0x80; + dst[current_temp_index] += 0x80; - dst[current_index++] += src->channel_id; //(bit 1~3) - dst[current_index++] = src->status_info; + dst[current_temp_index++] += src->channel_id; //(bit 1~3) + dst[current_temp_index++] = src->status_info; return 4; } static int _sat_encode_download_event(const struct tel_sat_envelop_event_download_tlv *evt_dl, char *dst_envelop) { - int index = 2; + int temp_index = 2; int encoded_len = 0; dbg("event type(%d)", evt_dl->event); //event list - encoded_len = _sat_encode_eventlist_tlv(evt_dl->event, dst_envelop, index); - index += encoded_len; + encoded_len = _sat_encode_eventlist_tlv(evt_dl->event, dst_envelop, temp_index); + temp_index += encoded_len; //device id - len 4 - encoded_len =_sat_encode_device_identities_tlv(&(evt_dl->device_identitie), dst_envelop, index); - index += encoded_len; + encoded_len =_sat_encode_device_identities_tlv(&(evt_dl->device_identitie), dst_envelop, temp_index); + temp_index += encoded_len; switch(evt_dl->event){ case EVENT_LANGUAGE_SELECTION: - encoded_len = _sat_encode_language_tlv(evt_dl->language, dst_envelop, index); - index += encoded_len; + encoded_len = _sat_encode_language_tlv(evt_dl->language, dst_envelop, temp_index); + temp_index += encoded_len; break; case EVENT_BROWSER_TERMINATION: - encoded_len = _sat_encode_browser_termination_tlv(evt_dl->browser_termination, dst_envelop, index); - index += encoded_len; + encoded_len = _sat_encode_browser_termination_tlv(evt_dl->browser_termination, dst_envelop, temp_index); + temp_index += encoded_len; break; case EVENT_DATA_AVAILABLE: - encoded_len = _sat_encode_channel_status_tlv(&(evt_dl->channel_status), dst_envelop, index); - index += encoded_len; + encoded_len = _sat_encode_channel_status_tlv(&(evt_dl->channel_status), dst_envelop, temp_index); + temp_index += encoded_len; - encoded_len = _sat_encode_channel_data_length_tlv(&(evt_dl->channel_data_len), dst_envelop, index); - index += encoded_len; + encoded_len = _sat_encode_channel_data_length_tlv(&(evt_dl->channel_data_len), dst_envelop, temp_index); + temp_index += encoded_len; break; case EVENT_CHANNEL_STATUS: - encoded_len = _sat_encode_channel_status_tlv(&(evt_dl->channel_status), dst_envelop, index); - index += encoded_len; + encoded_len = _sat_encode_channel_status_tlv(&(evt_dl->channel_status), dst_envelop, temp_index); + temp_index += encoded_len; break; default: break; } dst_envelop[0] = SATK_EVENT_DOWNLOAD_TAG; - dst_envelop[1] = index-2; + dst_envelop[1] = temp_index-2; - dbg("download envelop cmd len(%d)", index); + dbg("download envelop cmd len(%d)", temp_index); - if(index-2 > 0x7F){ + if(temp_index-2 > 0x7F){ int idx = 0; - for(idx = index; idx > 0; idx--){ + for(idx = temp_index; idx > 0; idx--){ dst_envelop[idx] = dst_envelop[idx+1]; } dst_envelop[1] = 0x81; - index += 1; - dbg("download envelop added cmd len(%d)", index); + temp_index += 1; + dbg("download envelop added cmd len(%d)", temp_index); } - return index; + return temp_index; } int tcore_sat_encode_envelop_cmd(const struct treq_sat_envelop_cmd_data *src_envelop, char *dst_envelop) { - int index = 0, encoded_len= 0; + int temp_index = 0, encoded_len= 0; if(!dst_envelop) return 0; if(src_envelop->sub_cmd == ENVELOP_MENU_SELECTION){ - index = 2; //set the cursor to device identity + temp_index = 2; //set the cursor to device identity dbg("item id(%d)", src_envelop->envelop_data.menu_select.item_identifier.item_identifier); - encoded_len =_sat_encode_device_identities_tlv(&(src_envelop->envelop_data.menu_select.device_identitie), dst_envelop, index); - index += encoded_len; + encoded_len =_sat_encode_device_identities_tlv(&(src_envelop->envelop_data.menu_select.device_identitie), dst_envelop, temp_index); + temp_index += encoded_len; //item identifier - encoded_len = _sat_encode_item_identifier_tlv(&(src_envelop->envelop_data.menu_select.item_identifier), dst_envelop, index); - index += encoded_len; + encoded_len = _sat_encode_item_identifier_tlv(&(src_envelop->envelop_data.menu_select.item_identifier), dst_envelop, temp_index); + temp_index += encoded_len; if(src_envelop->envelop_data.menu_select.help_request){ encoded_len = 2;//help request - dst_envelop[index++] = SATK_HELP_REQUEST_TAG; - dst_envelop[index++] = SATK_HELP_REQUEST_LENGTH; + dst_envelop[temp_index++] = SATK_HELP_REQUEST_TAG; + dst_envelop[temp_index++] = SATK_HELP_REQUEST_LENGTH; } - dbg("menu selection cmd len(%d)", index); + dbg("menu selection cmd len(%d)", temp_index); //main cmd dst_envelop[0] = SATK_MENU_SELECTION_TAG; - dst_envelop[1] = index-2; + dst_envelop[1] = temp_index-2; } else if(src_envelop->sub_cmd == ENVELOP_EVENT_DOWNLOAD){ - index = _sat_encode_download_event(&(src_envelop->envelop_data.event_download),dst_envelop); + temp_index = _sat_encode_download_event(&(src_envelop->envelop_data.event_download),dst_envelop); } - return index; + return temp_index; } static int _sat_encode_display_text(const struct tel_sat_tr_display_text_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG); + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG); switch(src_tr->result_type){ case RESULT_SUCCESS: case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION: @@ -5657,49 +6140,49 @@ static int _sat_encode_display_text(const struct tel_sat_tr_display_text_tlv *sr case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_FRAMES_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_get_inkey(const struct tel_sat_tr_get_inkey_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION: case RESULT_SUCCESS_WITH_MISSING_INFO: case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; - encoded_len = _sat_encode_text_tlv(&(src_tr->text), dst_tr, index, FALSE); - index += encoded_len; + encoded_len = _sat_encode_text_tlv(&(src_tr->text), dst_tr, temp_index, FALSE); + temp_index += encoded_len; break; case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER: case RESULT_BACKWARD_MOVE_BY_USER: @@ -5709,56 +6192,50 @@ static int _sat_encode_get_inkey(const struct tel_sat_tr_get_inkey_tlv *src_tr, case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; - break; case RESULT_NO_RESPONSE_FROM_USER: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; - - encoded_len = _sat_encode_duration_tlv(&(src_tr->duration), dst_tr, index); - index += encoded_len; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_FRAMES_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_get_input(const struct tel_sat_tr_get_input_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION: case RESULT_SUCCESS_WITH_MISSING_INFO: case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; - encoded_len = _sat_encode_text_tlv(&(src_tr->text), dst_tr, index, FALSE); - index += encoded_len; + encoded_len = _sat_encode_text_tlv(&(src_tr->text), dst_tr, temp_index, FALSE); + temp_index += encoded_len; break; case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER: case RESULT_BACKWARD_MOVE_BY_USER: @@ -5769,38 +6246,38 @@ static int _sat_encode_get_input(const struct tel_sat_tr_get_input_tlv *src_tr, case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_FRAMES_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index =0; + temp_index =0; break; } - return index; + return temp_index; } static int _sat_encode_more_time(const struct tel_sat_tr_more_time_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: @@ -5811,37 +6288,37 @@ static int _sat_encode_more_time(const struct tel_sat_tr_more_time_tlv *src_tr, case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_play_tone(const struct tel_sat_tr_play_tone_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: @@ -5855,38 +6332,38 @@ static int _sat_encode_play_tone(const struct tel_sat_tr_play_tone_tlv *src_tr, case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_FRAMES_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_refresh(const struct tel_sat_tr_refresh_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: @@ -5899,37 +6376,37 @@ static int _sat_encode_refresh(const struct tel_sat_tr_refresh_tlv *src_tr, char case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_setup_menu(const struct tel_sat_tr_setup_menu_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION: @@ -5940,97 +6417,97 @@ static int _sat_encode_setup_menu(const struct tel_sat_tr_setup_menu_tlv *src_tr case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_select_item(const struct tel_sat_tr_select_item_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION: case RESULT_SUCCESS_WITH_MISSING_INFO: case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; - encoded_len = _sat_encode_item_identifier_tlv(&(src_tr->item_identifier), dst_tr, index); - index += encoded_len; + case RESULT_HELP_INFO_REQUIRED_BY_USER: + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; + encoded_len = _sat_encode_item_identifier_tlv(&(src_tr->item_identifier), dst_tr, temp_index); + temp_index += encoded_len; break; case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER: case RESULT_BACKWARD_MOVE_BY_USER: case RESULT_NO_RESPONSE_FROM_USER: - case RESULT_HELP_INFO_REQUIRED_BY_USER: case RESULT_BEYOND_ME_CAPABILITIES: case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_FRAMES_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_send_sms(const struct tel_sat_tr_send_sms_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION: case RESULT_SUCCESS_WITH_MISSING_INFO: case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND: @@ -6038,34 +6515,39 @@ static int _sat_encode_send_sms(const struct tel_sat_tr_send_sms_tlv *src_tr, ch case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_SMS_RP_ERROR: + case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; + break; case RESULT_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->cc_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_send_ss(const struct tel_sat_tr_send_ss_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: @@ -6074,48 +6556,60 @@ static int _sat_encode_send_ss(const struct tel_sat_tr_send_ss_tlv *src_tr, char case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED: case RESULT_SUCCESS_BUT_MODIFIED_BY_CALL_CONTROL_BY_SIM: case RESULT_USSD_OR_SS_TRANSACTION_TERMINATED_BY_USER: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1+src_tr->text.string_length; + dst_tr[temp_index++] = src_tr->result_type; + + memcpy(&(dst_tr[temp_index]), src_tr->text.string, src_tr->text.string_length); + encoded_len = src_tr->text.string_length; + temp_index += encoded_len; + break; + case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; case RESULT_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->cc_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->cc_problem_type; break; case RESULT_SS_RETURN_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->ss_problem; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->ss_problem; + break; + case RESULT_BEYOND_ME_CAPABILITIES: + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_send_ussd(const struct tel_sat_tr_send_ussd_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: @@ -6124,48 +6618,56 @@ static int _sat_encode_send_ussd(const struct tel_sat_tr_send_ussd_tlv *src_tr, case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED: case RESULT_SUCCESS_BUT_MODIFIED_BY_CALL_CONTROL_BY_SIM: case RESULT_USSD_OR_SS_TRANSACTION_TERMINATED_BY_USER: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; + + encoded_len = _sat_encode_text_tlv(&(src_tr->text), dst_tr, temp_index, TRUE); + temp_index += encoded_len; + break; + case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: + case RESULT_BEYOND_ME_CAPABILITIES: + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; case RESULT_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->cc_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->cc_problem_type; break; case RESULT_USSD_RETURN_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->ussd_problem; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->ussd_problem; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_setup_call(const struct tel_sat_tr_setup_call_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: @@ -6180,106 +6682,106 @@ static int _sat_encode_setup_call(const struct tel_sat_tr_setup_call_tlv *src_tr case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: case RESULT_SS_RETURN_ERROR: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_USER_DID_NOT_ACCEPT_CALL_SETUP_REQ: case RESULT_USER_CLEAR_DOWN_CALL_BEFORE_CONN: case RESULT_FRAMES_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->network_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->network_problem_type; break; case RESULT_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->cc_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->cc_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_provide_local_info(const struct tel_sat_tr_provide_local_info_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION: case RESULT_SUCCESS_WITH_MISSING_INFO: case RESULT_SUCCESS_LIMITED_SERVICE: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; switch(src_tr->command_detail.cmd_qualifier.provide_local_info.provide_local_info){ case LOCAL_INFO_DATE_TIME_AND_TIMEZONE: - encoded_len = _sat_encode_date_time_and_timezone_tlv(&(src_tr->other.date_time_and_timezone), dst_tr, index); + encoded_len = _sat_encode_date_time_and_timezone_tlv(&(src_tr->other.date_time_and_timezone), dst_tr, temp_index); break; case LOCAL_INFO_LANGUAGE: - encoded_len = _sat_encode_language_tlv(src_tr->other.language, dst_tr, index); + encoded_len = _sat_encode_language_tlv(src_tr->other.language, dst_tr, temp_index); break; default: dbg("local info type[%d] is not handled", src_tr->command_detail.cmd_qualifier.provide_local_info.provide_local_info); break; } - index += encoded_len; + temp_index += encoded_len; break; case RESULT_BEYOND_ME_CAPABILITIES: case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_setup_event_list(const struct tel_sat_tr_setup_event_list_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION: @@ -6289,79 +6791,80 @@ static int _sat_encode_setup_event_list(const struct tel_sat_tr_setup_event_list case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_setup_idle_mode_text(const struct tel_sat_tr_setup_idle_mode_text_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION: case RESULT_SUCCESS_WITH_MISSING_INFO: + case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED: case RESULT_BEYOND_ME_CAPABILITIES: case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_FRAMES_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_send_dtmf(const struct tel_sat_tr_send_dtmf_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: @@ -6374,37 +6877,37 @@ static int _sat_encode_send_dtmf(const struct tel_sat_tr_send_dtmf_tlv *src_tr, case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_language_notification(const struct tel_sat_tr_language_notification_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: @@ -6415,97 +6918,101 @@ static int _sat_encode_language_notification(const struct tel_sat_tr_language_no case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_FRAMES_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_launch_browser(const struct tel_sat_tr_launch_browser_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION: case RESULT_SUCCESS_WITH_MISSING_INFO: + case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER: + case RESULT_BACKWARD_MOVE_BY_USER: + case RESULT_NO_RESPONSE_FROM_USER: case RESULT_BEYOND_ME_CAPABILITIES: case RESULT_COMMAND_TYPE_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED: + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND: case RESULT_FRAMES_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; case RESULT_LAUNCH_BROWSER_GENERIC_ERROR_CODE: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->browser_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->browser_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_open_channel(const struct tel_sat_tr_open_channel_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION: case RESULT_SUCCESS_WITH_MISSING_INFO: case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED: case RESULT_SUCCESS_WITH_MODIFICATION: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; //set channel status - encoded_len = _sat_encode_channel_status_tlv(&(src_tr->channel_status), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_channel_status_tlv(&(src_tr->channel_status), dst_tr, temp_index); + temp_index += encoded_len; break; case RESULT_REFRESH_PRFRMD_BUT_INDICATED_USIM_NOT_ACTIVE: case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER: @@ -6516,20 +7023,20 @@ static int _sat_encode_open_channel(const struct tel_sat_tr_open_channel_tlv *sr case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: case RESULT_USER_DID_NOT_ACCEPT_CALL_SETUP_REQ: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND: case RESULT_FRAMES_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; case RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->bip_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->bip_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); @@ -6537,31 +7044,23 @@ static int _sat_encode_open_channel(const struct tel_sat_tr_open_channel_tlv *sr break; } - //set buffer desc - encoded_len = _sat_encode_bearer_desc_tlv(&(src_tr->bearer_desc), dst_tr, index); - index += encoded_len; - - //set buffer size - encoded_len = _sat_encode_buffer_size_tlv(&(src_tr->buffer_size), dst_tr, index); - index += encoded_len; - - return index; + return temp_index; } static int _sat_encode_close_channel(const struct tel_sat_tr_close_channel_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION: @@ -6573,43 +7072,43 @@ static int _sat_encode_close_channel(const struct tel_sat_tr_close_channel_tlv * case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_FRAMES_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; case RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->bip_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->bip_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_send_data(const struct tel_sat_tr_send_data_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION: @@ -6621,47 +7120,47 @@ static int _sat_encode_send_data(const struct tel_sat_tr_send_data_tlv *src_tr, case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; - encoded_len = _sat_encode_channel_data_length_tlv(&(src_tr->channel_data_len), dst_tr, index); - index += encoded_len; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; + encoded_len = _sat_encode_channel_data_length_tlv(&(src_tr->channel_data_len), dst_tr, temp_index); + temp_index += encoded_len; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND: case RESULT_FRAMES_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; case RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->bip_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->bip_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_receive_data(const struct tel_sat_tr_receive_data_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION: @@ -6673,57 +7172,57 @@ static int _sat_encode_receive_data(const struct tel_sat_tr_receive_data_tlv *sr case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; - encoded_len = _sat_encode_channel_data_tlv(&(src_tr->channel_data), dst_tr, index); - index += encoded_len; - encoded_len = _sat_encode_channel_data_length_tlv(&(src_tr->channel_data_len), dst_tr, index); - index += encoded_len; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; + encoded_len = _sat_encode_channel_data_tlv(&(src_tr->channel_data), dst_tr, temp_index); + temp_index += encoded_len; + encoded_len = _sat_encode_channel_data_length_tlv(&(src_tr->channel_data_len), dst_tr, temp_index); + temp_index += encoded_len; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_FRAMES_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; case RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->bip_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->bip_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; } static int _sat_encode_get_channel_status(const struct tel_sat_tr_get_channel_status_tlv *src_tr, char *dst_tr) { - int index = 0, encoded_len = 0; + int temp_index = 0, encoded_len = 0; //set command detail info - encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; //set device identities info - encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, index); - index += encoded_len; + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; //set result info - dst_tr[index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; switch(src_tr->result_type){ case RESULT_SUCCESS: case RESULT_SUCCESS_WITH_PARTIAL_COMPREHENSION: case RESULT_SUCCESS_WITH_MISSING_INFO: case RESULT_SUCCESS_BUT_REQUESTED_ICON_NOT_DISPLAYED: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; - encoded_len = _sat_encode_channel_status_tlv(&(src_tr->channel_status), dst_tr, index); - index += encoded_len; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; + encoded_len = _sat_encode_channel_status_tlv(&(src_tr->channel_status), dst_tr, temp_index); + temp_index += encoded_len; break; case RESULT_PROACTIVE_SESSION_TERMINATED_BY_USER: case RESULT_BEYOND_ME_CAPABILITIES: @@ -6731,27 +7230,47 @@ static int _sat_encode_get_channel_status(const struct tel_sat_tr_get_channel_st case RESULT_COMMAND_DATA_NOT_UNDERSTOOD_BY_ME: case RESULT_COMMAND_NUMBER_NOT_KNOWN_BY_ME: case RESULT_ERROR_REQUIRED_VALUES_ARE_MISSING: - dst_tr[index++] = 1; - dst_tr[index++] = src_tr->result_type; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; break; case RESULT_ME_UNABLE_TO_PROCESS_COMMAND: case RESULT_NETWORK_UNABLE_TO_PROCESS_COMMAND: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->me_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->me_problem_type; break; case RESULT_BEARER_INDEPENDENT_PROTOCOL_ERROR: - dst_tr[index++] = 2; - dst_tr[index++] = src_tr->result_type; - dst_tr[index++] = src_tr->bip_problem_type; + dst_tr[temp_index++] = 2; + dst_tr[temp_index++] = src_tr->result_type; + dst_tr[temp_index++] = src_tr->bip_problem_type; break; default: dbg("invalid response value[0x%x] in current TR",src_tr->result_type); - index = 0; + temp_index = 0; break; } - return index; + return temp_index; +} + +static int _sat_encode_unsupport_command(const struct tel_sat_tr_unsupport_command_tlv *src_tr, char *dst_tr) +{ + int temp_index = 0, encoded_len = 0; + + //set command detail info + encoded_len = _sat_encode_command_detail_tlv(&(src_tr->command_detail), dst_tr, temp_index); + temp_index += encoded_len; + + //set device identities info + encoded_len = _sat_encode_device_identities_tlv(&(src_tr->device_id), dst_tr, temp_index); + temp_index += encoded_len; + + //set result info + dst_tr[temp_index++] = (b_comprehensive ? (SATK_RESULT_TAG | 0x80) : SATK_RESULT_TAG);; + dst_tr[temp_index++] = 1; + dst_tr[temp_index++] = src_tr->result_type; + + return temp_index; } int tcore_sat_encode_terminal_response(const struct treq_sat_terminal_rsp_data *src_tr, char *dst_tr){ @@ -6830,9 +7349,9 @@ int tcore_sat_encode_terminal_response(const struct treq_sat_terminal_rsp_data * case SAT_PROATV_CMD_GET_CHANNEL_STATUS:{ tr_len = _sat_encode_get_channel_status(&(src_tr->terminal_rsp_data.get_channel_status), dst_tr); }break; - default: - err("no matched cmd type(%d)", src_tr->cmd_type); - break; + default:{ + tr_len = _sat_encode_unsupport_command(&(src_tr->terminal_rsp_data.unsupport_cmd), dst_tr); + }break; } return tr_len; @@ -6851,7 +7370,7 @@ CoreObject *tcore_sat_new(TcorePlugin *p, const char *name, if (!o) return NULL; - po = calloc(sizeof(struct private_object_data), 1); + po = calloc(1, sizeof(struct private_object_data)); if (!po) { tcore_object_free(o); return NULL; @@ -6870,14 +7389,21 @@ CoreObject *tcore_sat_new(TcorePlugin *p, const char *name, void tcore_sat_free(CoreObject *o) { + CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAT); + + tcore_object_free(o); +} + +void tcore_sat_set_ops(CoreObject *o, struct tcore_sat_operations *ops) +{ struct private_object_data *po = NULL; CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SAT); - po = tcore_object_ref_object(o); - if (!po) + po = (struct private_object_data *)tcore_object_ref_object(o); + if (!po) { return; + } - free(po); - tcore_object_free(o); + po->ops = ops; } diff --git a/src/co_sim.c b/src/co_sim.c index 8c0b967..6fd0618 100644 --- a/src/co_sim.c +++ b/src/co_sim.c @@ -39,15 +39,100 @@ struct private_object_data { struct tel_sim_imsi imsi; /**< Provides IMSI information*/ gboolean b_sim_changed; /**< Provides SIM card Identification- 0:no changed, 1:changed*/ gboolean b_cphs; /**< Whether current SIM is for CPHS or not*/ + struct tel_sim_service_table *svct; /**< (U)SIM Service Table information*/ + struct tel_sim_ecc_list *ecc_list; + struct tel_sim_msisdn_list *msisdn_list; + struct tel_sim_spn *spn; + struct tel_sim_cphs_netname *cphs_netname; + struct tel_sim_iccid *iccid; + struct tel_sim_cphs_csp *csp; + void *userdata; /**< free use data*/ +}; - enum tel_sim_file_id language_file; /**ops->update_file) return TCORE_RETURN_ENOSYS; @@ -141,6 +231,7 @@ static TReturn _dispatcher(CoreObject *o, UserRequest *ur) case TREQ_SIM_GET_CALLFORWARDING: case TREQ_SIM_GET_MESSAGEWAITING: case TREQ_SIM_GET_CPHS_INFO: + case TREQ_SIM_GET_SERVICE_TABLE: case TREQ_SIM_GET_MSISDN: case TREQ_SIM_GET_SPN: case TREQ_SIM_GET_SPDI: @@ -148,6 +239,8 @@ static TReturn _dispatcher(CoreObject *o, UserRequest *ur) case TREQ_SIM_GET_PNN: case TREQ_SIM_GET_CPHS_NETNAME: case TREQ_SIM_GET_OPLMNWACT: + case TREQ_SIM_GET_ICON: + case TREQ_SIM_GET_GID: if (!po->ops->read_file) return TCORE_RETURN_ENOSYS; @@ -161,7 +254,15 @@ static TReturn _dispatcher(CoreObject *o, UserRequest *ur) return po->ops->req_authentication(o, ur); break; + case TREQ_SIM_SET_POWERSTATE: + if (!po->ops->set_powerstate) + return TCORE_RETURN_ENOSYS; + + return po->ops->set_powerstate(o, ur); + break; + default: + warn("unhandled request command[%d]", command); break; } @@ -176,7 +277,7 @@ static void _clone_hook(CoreObject *src, CoreObject *dest) if (!src || !dest) return; - dest_po = calloc(sizeof(struct private_object_data), 1); + dest_po = calloc(1, sizeof(struct private_object_data)); if (!dest_po) { tcore_object_link_object(dest, NULL); return; @@ -196,6 +297,20 @@ static void _free_hook(CoreObject *o) po = tcore_object_ref_object(o); if (po) { + if (po->svct) + free(po->svct); + if (po->ecc_list) + free(po->ecc_list); + if (po->msisdn_list) + free(po->msisdn_list); + if (po->spn) + free(po->spn); + if (po->cphs_netname) + free(po->cphs_netname); + if (po->iccid) + free(po->iccid); + if (po->csp) + free(po->csp); free(po); tcore_object_link_object(o, NULL); } @@ -509,6 +624,166 @@ static int _ucs2_to_utf8(int in_length, unsigned char *in_data, int *out_length, return TRUE; } +static int _decode_cdma_imsi_util(char *imsi, unsigned short *mcc, unsigned char *mnc, + unsigned long *min1, unsigned short *min2) +{ + unsigned short country_code = *mcc; + unsigned char nw_code = *mnc; + unsigned long imsi_min1 = *min1; + unsigned short imsi_min2 = *min2; + unsigned short second_three = 0; + unsigned char thousands = 0; + unsigned short last_three = 0; + unsigned char min_to_digit[] = {'1','2','3','4','5','6','7','8','9','0'}; + unsigned char bcd_to_num[] = {0xFF,'1','2','3','4','5','6','7','8','9','0',0xFF,0xFF,0xFF,0xFF,0xFF}; + int p_digit = 0; + int digit = 0; + + /* Convert Country code of IMSI */ + if(country_code <= 999) { + digit = min_to_digit[country_code/100]; + imsi[p_digit++] = digit; + country_code %= 100; + + digit = min_to_digit[country_code / 10]; + imsi[p_digit++] = digit; + + digit = min_to_digit[country_code % 10]; + imsi[p_digit++] = digit; + + } else { + err("Invalid Country code"); + return -1; + } + + /* Convert Network code of IMSI */ + if(nw_code <= 99) { + digit = min_to_digit[nw_code / 10]; + imsi[p_digit++] = digit; + + digit = min_to_digit[nw_code % 10]; + imsi[p_digit++] = digit; + } else { + err("Invalid Network code"); + return -1; + } + + /* Convert First Three Digits of IMSI */ + if (imsi_min2 <= 999) { + digit = min_to_digit[imsi_min2 / 100]; + imsi[p_digit++] = digit; + imsi_min2 %= 100; + + digit = min_to_digit[imsi_min2 / 10]; + imsi[p_digit++] = digit; + + digit = min_to_digit[imsi_min2 % 10]; + imsi[p_digit++] = digit; + } else { + err("Invalid IMSI_MIN2 code"); + return -1; + } + + /* Convert Last Seven digits of IMSI */ + second_three = (imsi_min1 & 0x00FFC000) >> 14; + thousands = (imsi_min1 & 0x00003C00) >> 10; + last_three = (imsi_min1 & 0x000003FF) >> 0; + + thousands = bcd_to_num[thousands]; + if ((thousands != 0xFF) && (second_three <= 999) && (last_three <= 999)) { + digit = min_to_digit[second_three / 100]; + imsi[p_digit++] = digit; + + second_three %= 100; + + digit = min_to_digit[second_three / 10]; + imsi[p_digit++] = digit; + + digit = min_to_digit[second_three % 10]; + imsi[p_digit++] = digit; + + imsi[p_digit++] = thousands; + + digit = min_to_digit[last_three / 100]; + imsi[p_digit++] = digit; + + last_three %= 100; + + digit = min_to_digit[last_three / 10]; + imsi[p_digit++] = digit; + + digit = min_to_digit[last_three % 10]; + imsi[p_digit++] = digit; + } else { + err("Invalid IMSI_MIN1 code"); + return -1; + } + return p_digit; +} + +/** + * This function is used to decode 3 bytes of plmn string encoded as TS 24.008 to 6 bytes char string. + * + * @return void . + * @param[out] out decoded output string (must be 6 + 1 bytes) + * @param[in] in encoded input string (must be 3 bytes) + * @remark + */ +static void _decode_plmn(const unsigned char* in, unsigned char* out) +{ + unsigned char temp[6 + 1] = {0,}; + int i; + unsigned char higher, lower; + + for (i = 0; i < 3; i++) { + higher = (in[i] >> 4) & 0x0F; // get high nibble + if (higher < 0x0A) { + // if it is a number + temp[i*2] = higher + 0x30; + } else if (higher == 0x0D) { + // 0x0D (BCD digit) is regarded as wild character by TS 24.008 + temp[i*2] = 'D'; + } else { + temp[i*2] = 0x00; + } + + lower = in[i] & 0x0F; // get low nibble + if (lower < 0x0A) { + // if it is a number + temp[i*2 + 1] = lower + 0x30; + } else if (lower == 0x0D) { + // 0x0D (BCD digit) is regarded as wild character by TS 24.008 + temp[i*2 + 1] = 'D'; + } else { + temp[i*2 + 1] = 0x00; + } + } + + // according to PLMN digits order by TS 24.008 + // MCC + out[0] = temp[1]; + out[1] = temp[0]; + out[2] = temp[3]; + // MNC + out[3] = temp[5]; + out[4] = temp[4]; + out[5] = temp[2]; + + out[6] = '\0'; + + /* + * [14.08.21] + * As NA Operators requested, + * for NA operators (MCC 310 ~ 316), + * if 6th digit of MNC is 'F' then should be regarded as '0'. + */ + if (out[5] == 0x00 && + strncmp((const char*)out, "31", 2) == 0 && + ('0' <= out[2] && out[2] <= '6')){ + out[5] = '0'; + } +} + /** * According to ETSI 102.221 ( 3GPP specification refers it ), EF-ICCID is coded by BCD, left justified and padded with 'F'. * This EF is mandatory and byte length is fixed with 10 bytes. So actual maximum length of ICCID is 20 digits. @@ -527,10 +802,8 @@ gboolean tcore_sim_decode_iccid(struct tel_sim_iccid *p_out, unsigned char *p_in memset((void*) p_out->iccid, 0, SIM_ICCID_LEN_MAX+1); bcd_byte = _get_valid_bcd_byte(p_in, in_length); - dbg( "ICCID valid bcd byte is[%d]", bcd_byte); - char_length = _bcd_to_digit(p_out->iccid, (char*) p_in, bcd_byte); - dbg( "ICCID string length is[%d]", char_length); + dbg( "bcd byte:[%d] string length:[%d]", bcd_byte, char_length); *(p_out->iccid+char_length) = '\0'; @@ -582,22 +855,25 @@ gboolean tcore_sim_decode_lp(struct tel_sim_language *p_out, unsigned char *p_in */ char* tcore_sim_encode_lp( int *out_length, struct tel_sim_language *p_in) { - int i = 0; - char *tmp_out = NULL; + int i = 0; + char *tmp_out = NULL; + + if ( out_length == NULL || p_in == NULL ){ + dbg("out_length or p_in is null"); + return NULL; + } - if ( out_length == NULL || p_in == NULL ){ - dbg("out_length or p_in is null"); - return NULL; - } + tmp_out = (char*)malloc(p_in->language_count); + if (!tmp_out) + return NULL; - tmp_out = (char*)malloc(p_in->language_count); - memset((void*) tmp_out, 0xff, p_in->language_count); + memset((void*) tmp_out, 0xff, p_in->language_count); - for (i = 0; i < p_in->language_count; i++) - tmp_out[i] = p_in->language[i]; + for (i = 0; i < p_in->language_count; i++) + tmp_out[i] = p_in->language[i]; - *out_length = i; - return tmp_out; + *out_length = i; + return tmp_out; } /** @@ -656,6 +932,9 @@ gboolean tcore_sim_decode_li(enum tel_sim_file_id file_id, struct tel_sim_langua case 'l': p_out->language[p_out->language_count] = SIM_LANG_GREEK; break; + default: + warn("invalid language"); + break; } } else if (tempLi[0] == 'd') { switch (tempLi[1]) { @@ -666,6 +945,9 @@ gboolean tcore_sim_decode_li(enum tel_sim_file_id file_id, struct tel_sim_langua case 'a': p_out->language[p_out->language_count] = SIM_LANG_DANISH; break; + default: + warn("invalid language"); + break; } } else if (tempLi[0] == 'i' && tempLi[1] == 't') { p_out->language[p_out->language_count] = SIM_LANG_ITALIAN; @@ -691,6 +973,9 @@ gboolean tcore_sim_decode_li(enum tel_sim_file_id file_id, struct tel_sim_langua case 't': p_out->language[p_out->language_count] = SIM_LANG_PORTUGUESE; break; + default: + warn("invalid language"); + break; } } else if (tempLi[0] == 'k' && tempLi[1] == 'o') { p_out->language[p_out->language_count] = SIM_LANG_KOREAN; @@ -721,17 +1006,19 @@ gboolean tcore_sim_decode_li(enum tel_sim_file_id file_id, struct tel_sim_langua char* tcore_sim_encode_li( int *out_length, struct tel_sim_language *p_in) { int i = 0; - char *tmp_out = NULL; - char *LanguageCode[] = { "de", "en", "it", "fr", "es", "nl", "sv", "da", "pt", "fi", "no", "el", + char *tmp_out = NULL; + const char *LanguageCode[] = { "de", "en", "it", "fr", "es", "nl", "sv", "da", "pt", "fi", "no", "el", "tr", "hu", "pl", "ko", "zh", "ru", "ja" }; - if ( out_length == NULL || p_in == NULL ){ - dbg("out_length or p_in is null"); - return NULL; - } + if ( out_length == NULL || p_in == NULL ){ + dbg("out_length or p_in is null"); + return NULL; + } - tmp_out = (char*)malloc((p_in->language_count) *2); - memset((void*) tmp_out, 0xff, (p_in->language_count)*2); + tmp_out = (char*)malloc((p_in->language_count) *2); + if (!tmp_out) + return NULL; + memset((void*) tmp_out, 0xff, (p_in->language_count)*2); for (i = 0; i < p_in->language_count; i++) { if (p_in->language[i] < SIM_LANG_UNSPECIFIED) { @@ -745,10 +1032,10 @@ char* tcore_sim_encode_li( int *out_length, struct tel_sim_language *p_in) gboolean tcore_sim_decode_imsi(struct tel_sim_imsi *p_out, unsigned char *p_in, int in_length) { - int i,j=0; + int i = 0, j = 0; char imsi_raw[16]; - - dbg( "Func Entrance"); + char *plmn = NULL; + int plmn_digits = 5; if ((NULL == p_out) || (NULL == p_in)) return FALSE; @@ -762,7 +1049,6 @@ gboolean tcore_sim_decode_imsi(struct tel_sim_imsi *p_out, unsigned char *p_in, dbg("No valid IMSI present to convert - length:[%x]", in_length); return FALSE; } - dbg("imsi length[%d], input data length[%d]", p_in[0], in_length); /* Decode IMSI value from nibbles */ for (i = 1; i < in_length; i++) { @@ -777,16 +1063,88 @@ gboolean tcore_sim_decode_imsi(struct tel_sim_imsi *p_out, unsigned char *p_in, imsi_raw[j++] = ((p_in[i] & 0xF0) >> 4) + '0'; } } + + /* Determine # of PLMN digits (5 or 6) */ + plmn = g_strndup(imsi_raw, 6 + 1); + if (plmn) { + plmn[6] = '\0'; + if(tcore_sim_check_plmn_having_3digits_mnc(plmn)) { + plmn_digits = 6; + } + g_free(plmn); + } + /* Terminate string */ imsi_raw[j] = '\0'; - dbg("imsi_raw[%s], size[%d]", imsi_raw, strlen(imsi_raw)); + memcpy(p_out->plmn, imsi_raw, plmn_digits); + p_out->plmn[plmn_digits] = '\0'; + memcpy(p_out->msin, imsi_raw + plmn_digits, strlen(imsi_raw) - plmn_digits); + p_out->msin[strlen(imsi_raw) - plmn_digits] = '\0'; + + dbg("plmn in imsi = [%s]", p_out->plmn); + + return TRUE; +} + +gboolean tcore_sim_decode_cdma_imsi(struct tel_sim_imsi *p_out, unsigned char *p_in, int in_length) +{ + char imsi_raw[16]={0,}; + int digits = 0; + unsigned short mcc; + unsigned char mnc; + unsigned long min1; + unsigned short min2; + char *plmn = NULL; + int plmn_digits = 5; + + if ((NULL == p_out) || (NULL == p_in)) + return FALSE; + + /* + According to 3GPP2 specification, the length of raw IMSI data is 10 bytes. + byte Description + 1 Class assignment of IMSI_M + 2-3 IMSI_M_S2 : MSIN2 + 4-6 IMSI_M_S1 : MSIN1 + 7 IMSI_M_11_12 : MNC + 8 IMSI_M_ADDR_NUM : No of IMSI_M address digits. + 9-10 MCC_M : MCC + + */ + if ((in_length == 0) || (in_length == 0xff) || (4 > in_length) || (10 < in_length)) { + dbg("No valid IMSI present to convert - length:[%x]", in_length); + return FALSE; + } + + /* Decode IMSI value from nibbles */ + mcc = (p_in[9] << 8) | p_in[8]; + mnc = p_in[6]; + min1 = (p_in[5] << 16) | (p_in[4] << 8) | (p_in[3]); + min2 = (p_in[2] << 8) | p_in[1]; + + digits = _decode_cdma_imsi_util(imsi_raw, &mcc, &mnc, &min1, &min2); + + if (digits < 0) + return FALSE; - memcpy(p_out->plmn, imsi_raw, 5); - p_out->plmn[5] = '\0'; - memcpy(p_out->msin, imsi_raw+5, strlen(imsi_raw)-5); - p_out->msin[strlen(imsi_raw)-5] = '\0'; + /* Determine # of PLMN digits (5 or 6) */ + plmn = g_strndup(imsi_raw, 6 + 1); + if (plmn) { + plmn[6] = '\0'; + if(tcore_sim_check_plmn_having_3digits_mnc(plmn)) { + plmn_digits = 6; + } + g_free(plmn); + } + + /* Terminate string */ + imsi_raw[digits] = '\0'; + memcpy(p_out->plmn, imsi_raw, plmn_digits); + p_out->plmn[plmn_digits] = '\0'; + memcpy(p_out->msin, imsi_raw + plmn_digits, strlen(imsi_raw) - plmn_digits); + p_out->msin[strlen(imsi_raw) - plmn_digits] = '\0'; - dbg("p_out->plmn[%s], p_out->msin[%s]", p_out->plmn, p_out->msin); + dbg("plmn in imsi = [%s]", p_out->plmn); return TRUE; } @@ -806,7 +1164,7 @@ gboolean tcore_sim_decode_sst(struct tel_sim_sst *p_sst, unsigned char *p_in, in // get count of SIM service id. one byte has four service status. svc_count = in_length * 4; - /*3GPP 11.11 SST shows 50 kinds of service types. current sim_ss_s has also 50 elements*/ + /*3GPP 51.011 SST shows 56 kinds of service types. current tel_sim_sst has also 56 elements*/ if (svc_count > SIM_SST_SERVICE_CNT_MAX) svc_count = SIM_SST_SERVICE_CNT_MAX; @@ -829,6 +1187,66 @@ gboolean tcore_sim_decode_sst(struct tel_sim_sst *p_sst, unsigned char *p_in, in case 0: mask = 0x80; break; + default: + warn("invalid rast"); + break; + } + + if (sstByte & mask) + *p_index = 1; + else + *p_index = 0; + + p_index += sizeof(char); + simServiceID++; // next service id + } + return TRUE; +} + +gboolean tcore_sim_decode_cdma_st(struct tel_sim_cst *p_cdma_st, unsigned char *p_in, int in_length) +{ + unsigned char sstByte, rast, mask = 0; + char simServiceID = 1; // set "CHV1 disable function" + int i, svc_count; + char *p_index; + + memset((void*)p_cdma_st, 0, sizeof(struct tel_sim_cst)); + + if (in_length == 0 || in_length > SIM_CDMA_ST_SERVICE_LEN_MAX) + return FALSE; + + // get count of SIM service id. one byte has four service status. + svc_count = in_length * 4; + + /*CDMA_ST service is described to 47(1 byte includes 4 service status) in C.S0023 3.4.18. + Current tel_sim_cst.serivce.cdma_service has 47 services. so in_length should be under 12 byte. */ + if (svc_count > SIM_CDMA_ST_SERVICE_CNT_MAX) + svc_count = SIM_CDMA_ST_SERVICE_CNT_MAX; + + p_cdma_st->cdma_svc_table = SIM_CDMA_SVC_TABLE; + + p_index = (char*)p_cdma_st->service.cdma_service; + + for (i = 0; i < svc_count; i++) { + sstByte = p_in[(simServiceID - 1) / 4]; + rast = simServiceID - 4 * (simServiceID / 4); + + switch (rast) { + case 1: + mask = 0x02; + break; + case 2: + mask = 0x08; + break; + case 3: + mask = 0x20; + break; + case 0: + mask = 0x80; + break; + default: + warn("invalid rast"); + break; } if (sstByte & mask) @@ -842,6 +1260,35 @@ gboolean tcore_sim_decode_sst(struct tel_sim_sst *p_sst, unsigned char *p_in, in return TRUE; } +gboolean tcore_sim_decode_csim_st(struct tel_sim_cst *p_csim_st, unsigned char *p_in, int in_length) +{ + int i, j; + char mask; + char *p_index; + memset((void*) p_csim_st, 0, sizeof(struct tel_sim_cst)); + + p_csim_st->cdma_svc_table = SIM_CSIM_SVC_TABLE; + p_index = (char*)p_csim_st->service.csim_service; + + /*CSIM_ST service is described to 41(1 byte includes 8 service status) in C.S0065 5.2.18. + Current tel_sim_cst.serivce.csim_service has 41 services. so in_length should be under 6 byte. */ + if (in_length > SIM_CSIM_ST_SERVICE_LEN_MAX) + in_length = SIM_CSIM_ST_SERVICE_LEN_MAX; + + for (i = 0; i < in_length; i++) { + mask = 0x01; // reset mask to check first bit + + for (j = 0; j < 8; j++) { + if (p_in[i] & mask) { + *p_index = 1; + } + p_index += sizeof(char); + mask = mask << 1; + } + } + return TRUE; +} + gboolean tcore_sim_decode_spn(struct tel_sim_spn *p_spn, unsigned char *p_in, int in_length) { int i; @@ -849,18 +1296,43 @@ gboolean tcore_sim_decode_spn(struct tel_sim_spn *p_spn, unsigned char *p_in, in if (in_length == 0) return FALSE; - p_spn->display_condition = p_in[0]; - dbg( "The display condition is [%d]", p_spn->display_condition); + p_spn->display_condition = p_in[0] & 0x3; for (i = 1; i < SIM_SPN_LEN_MAX + 1; i++) { if (p_in[i] == 0xFF) break; /* loop break*/ p_spn->spn[i - 1] = p_in[i]; - dbg( "EF-SPN name[%d][%c]", i, p_in[i]); } p_spn->spn[i-1] = '\0'; + dbg( "spn:[%s] display condition : [%d]", p_spn->spn, p_spn->display_condition); + + return TRUE; +} + +gboolean tcore_sim_decode_cdma_spn(struct tel_sim_spn *p_spn, unsigned char *p_in, int in_length) +{ + int i=0; + + if (in_length == 0) + return FALSE; + + p_spn->display_condition = p_in[0] & 0x1; + + /*Note : Character Encoding (1 byte) and Language Indicator (1 byte) + are ignored, will be added later if required by Application */ + + for (i = 3; i < SIM_CDMA_SPN_LEN_MAX + 1; i++) { + if (p_in[i] == 0xFF) + break; /* loop break*/ + + p_spn->spn[i - 3] = p_in[i]; + } + p_spn->spn[i-3] = '\0'; + + dbg( "spn:[%s] display condition : [%d]", p_spn->spn, p_spn->display_condition); + return TRUE; } @@ -881,6 +1353,7 @@ gboolean tcore_sim_decode_spdi(struct tel_sim_spdi *p_spdi, unsigned char *p_in, //Display info tag('A3') if (p_in[0] == 0xA3) { total_data_len = p_in[1]; + dbg("total_data_len=[%d]", total_data_len); //PLMN list tag('80') if (p_in[2] == 0x80) { p_spdi->plmn_count = p_in[3] / 3; @@ -898,11 +1371,7 @@ gboolean tcore_sim_decode_spdi(struct tel_sim_spdi *p_spdi, unsigned char *p_in, dbg( "p_spdi->num_of_plmn_entries[%d]", p_spdi->plmn_count); for (i = 0; i < p_spdi->plmn_count; i++) { - unsigned char packetInDigit[3 * 2 + 1]; - _bcd_to_digit((char*) packetInDigit, (char*) &p_in[Src_plmn_start_len], 3); - // get MCC (mobile country code) - memcpy(p_spdi->list[i].plmn, &(packetInDigit[0]), 6); - p_spdi->list[i].plmn[6] = '\0'; + _decode_plmn(&p_in[Src_plmn_start_len], p_spdi->list[i].plmn); dbg( "SPDI PLMN[%d][%s]", i, p_spdi->list[i].plmn); Src_plmn_start_len = Src_plmn_start_len + 3; @@ -918,14 +1387,17 @@ gboolean tcore_sim_decode_spdi(struct tel_sim_spdi *p_spdi, unsigned char *p_in, gboolean tcore_sim_decode_msisdn(struct tel_sim_msisdn *p_msisdn, unsigned char *p_in, int in_length) { - int X; // alpha id max length - int value_length; - int bcd_byte; // dialing number max length + int X = 0; // alpha id max length + int alpha_id_length = 0; + int value_length = 0; + int bcd_byte = 0; // dialing number max length memset((void*) p_msisdn, 0, sizeof(struct tel_sim_msisdn)); - if (in_length == 0) + if (in_length < 14) { + err("invalid in_length[%d]", in_length); return FALSE; + } if (_is_empty(p_in, in_length) == TRUE) { memset(p_msisdn, 0, sizeof(struct tel_sim_msisdn)); @@ -935,7 +1407,12 @@ gboolean tcore_sim_decode_msisdn(struct tel_sim_msisdn *p_msisdn, unsigned char X = in_length - 14; // get alpha id max length if (X != 0) { - value_length = _get_string((unsigned char *)p_msisdn->name, p_in, X); + alpha_id_length = X; + dbg("alpha_id_length[%d]", alpha_id_length); + if(alpha_id_length > SIM_XDN_ALPHA_ID_LEN_MAX) + alpha_id_length = SIM_XDN_ALPHA_ID_LEN_MAX; + + value_length = _get_string((unsigned char *)p_msisdn->name, p_in, alpha_id_length); p_msisdn->name[value_length] = '\0'; } @@ -955,11 +1432,46 @@ gboolean tcore_sim_decode_msisdn(struct tel_sim_msisdn *p_msisdn, unsigned char // get dialing number/SSC string value_length = _bcd_to_digit((char*) p_msisdn->num, (char*) &p_in[X + 2], bcd_byte); // actual dialing number length in BCD. p_msisdn->num[value_length] = '\0'; + p_msisdn->next_record = p_in[X+13]; dbg( "p_msisdn->num[%s]", p_msisdn->num); } return TRUE; } +gboolean tcore_sim_decode_mdn(struct tel_sim_msisdn *p_msisdn, unsigned char *p_in, int in_length) +{ + int value_length = 0; + int bcd_byte = 0; // dialing number max length + + memset((void*) p_msisdn, 0, sizeof(struct tel_sim_msisdn)); + + if (in_length == 0) + return FALSE; + + if (_is_empty(p_in, in_length) == TRUE) { + return FALSE; + } + + /*Note : Alpha identifier is not present in EF-MDN file.*/ + if (p_in[0] != 0xFF) { + dbg( "Dialing number Length %d, BCD length 0x%x ", (p_in[0] - 1) * 2, p_in[0]); + + // get TON and NPI + p_msisdn->ton = (p_in[9] >> 4) & 0x07; + + // get actual dialing number length + bcd_byte = _get_valid_bcd_byte(&p_in[1], 8); + dbg( "bcd_byte[%x]", bcd_byte); + + // get dialing number/SSC string + value_length = _bcd_to_digit((char*) p_msisdn->num, (char*) &p_in[1], bcd_byte); // actual dialing number length in BCD. + p_msisdn->num[value_length] = '\0'; + /*p_msisdn->next_record = p_in[];*/ //Need to check with next_record field + dbg("p_msisdn->num[%s]", p_msisdn->num); + } + return TRUE; +} + gboolean tcore_sim_decode_xdn(struct tel_sim_dialing_number *p_xdn, unsigned char *p_in, int in_length) { int X; // alpha id max length @@ -977,19 +1489,18 @@ gboolean tcore_sim_decode_xdn(struct tel_sim_dialing_number *p_xdn, unsigned cha X = in_length - 14; // get alpha id max length if (X != 0) { - p_xdn->AlphaIdLength = _get_string((unsigned char *)p_xdn->AlphaId, p_in, X); - p_xdn->AlphaIDMaxLength = X; + _get_string((unsigned char *)p_xdn->alpha_id, p_in, X); + p_xdn->alpha_id_max_len = X; } // get dialing number length // p_in[X] is BCD length of dialing number length plus TON/NPI 1 bytes. // Convert to digit length and subtract TON/NPI length. if (p_in[X] != 0xFF) { - p_xdn->DiallingNumMaxLength = (p_in[X] - 1) * 2; - dbg( "Dialing number Length %d, BCD length 0x%x ", p_xdn->DiallingNumMaxLength, p_in[X]); + dbg( "Dialing number Length %d, BCD length 0x%x ", (p_in[X] - 1) * 2, p_in[X]); + +/* if (p_xdn->num_max_len > SIM_XDN_NUMBER_LEN_MAX) { - if (p_xdn->DiallingNumMaxLength > SIM_XDN_NUMBER_LEN_MAX) { - /* this may be broken record. p_xdn->b_used = FALSE; memset((void*)p_xdn, 0, sizeof(tapi_sim_dialing_number_info_t)); @@ -1005,73 +1516,98 @@ gboolean tcore_sim_decode_xdn(struct tel_sim_dialing_number *p_xdn, unsigned cha Anyway we are doing this check @ bcd_byte = _get_valid_bcd_byte (&p_in[X+2], TAPI_SIM_XDN_DIALING_NUMBER_LEN/2); by using the 20/2; so don`t return false. - */ + if (p_in[X] == 0x00) - p_xdn->DiallingNumMaxLength = 0; + p_xdn->num_max_len = 0; else - p_xdn->DiallingNumMaxLength = SIM_XDN_NUMBER_LEN_MAX; - } + p_xdn->num_max_len = SIM_XDN_NUMBER_LEN_MAX; + }*/ // get TON and NPI - p_xdn->TypeOfNumber = (p_in[X + 1] >> 4) & 0x07; - p_xdn->NumberingPlanIdent = p_in[X + 1] & 0x0F; + p_xdn->ton = (p_in[X + 1] >> 4) & 0x07; + p_xdn->npi = p_in[X + 1] & 0x0F; // get actual dialing number length bcd_byte = _get_valid_bcd_byte(&p_in[X + 2], SIM_XDN_NUMBER_LEN_MAX / 2); dbg( "bcd_byte[%x]", bcd_byte); // get dialing number/SSC string - p_xdn->DiallingnumLength = _bcd_to_digit((char*) p_xdn->DiallingNum, (char*) &p_in[X + 2], bcd_byte); // actual dialing number length in BCD. - dbg( "p_xdn->DiallingnumLength[%x]", p_xdn->DiallingnumLength); - dbg( "p_xdn->DiallingNum[%s]", p_xdn->DiallingNum); + _bcd_to_digit((char*) p_xdn->num, (char*) &p_in[X + 2], bcd_byte); // actual dialing number length in BCD. + dbg( "p_xdn->DiallingNum[%s]", p_xdn->num); // get Capability/Configuration id - p_xdn->CapaConfigId = p_in[X + 12]; + p_xdn->cc_id = p_in[X + 12]; // get Extension1 id - p_xdn->Ext1RecordId = p_in[X + 13]; + p_xdn->ext1_id = p_in[X + 13]; } return TRUE; } -gboolean tcore_sim_encode_xdn(char *p_out, int out_length, struct tel_sim_dialing_number *p_xdn) +char* tcore_sim_encode_xdn(int in_length, struct tel_sim_dialing_number *p_xdn) { - int X; + int alpha_id_space =0, digit_len =0, str_len = 0; char bcdCode[SIM_XDN_NUMBER_LEN_MAX / 2]; + char * p_out = NULL; - memset((void*) p_out, 0xFF, out_length); + if (in_length < 14) { + dbg("in_length[%d] should be greater than or equal to 14.", in_length) + return NULL; + } + + p_out = calloc(1, in_length + 1); + if (!p_out) + return NULL; + memset((void*) p_out, 0xFF, in_length); - X = out_length - 14; // get alpha id max length + // get alpha id max length + alpha_id_space = in_length - 14; - if (X < p_xdn->AlphaIdLength) - return FALSE; // alpha id is too big + // alpha id is too big + str_len = strlen(p_xdn->alpha_id); + if (alpha_id_space < str_len) { + dbg("SIM space for alpha_id is [%d] but input alpha_id length is [%d]. so we will use [%d] byte", + alpha_id_space, str_len, alpha_id_space); + str_len = alpha_id_space; + } - if (p_xdn->DiallingnumLength > SIM_XDN_NUMBER_LEN_MAX) // this is digit length - return FALSE; // dialing number is too big + digit_len = strlen(p_xdn->num); + // this is digit length + if ( digit_len > SIM_XDN_NUMBER_LEN_MAX) { + dbg("SIM space for number is [%d] but input number length is [%d]. so we will use [%d] byte", + SIM_XDN_NUMBER_LEN_MAX, digit_len, SIM_XDN_NUMBER_LEN_MAX); + digit_len = SIM_XDN_NUMBER_LEN_MAX; + } - _set_string((unsigned char *)p_out, (unsigned char *)p_xdn->AlphaId, p_xdn->AlphaIdLength); + _set_string((unsigned char *)p_out, (unsigned char *)p_xdn->alpha_id, str_len); // set length of BCD number/SSC contents // p_xdn->diallingnumLen is maximum digit length. = 20 bytes. // convert to BCD length and add 1 byte. - p_out[X] = ((p_xdn->DiallingnumLength + 1) / 2) + 1; + p_out[alpha_id_space] = ( (digit_len + 1) / 2 ) + 1; // set TON and NPI - p_out[X + 1] = 0x80; - p_out[X + 1] |= (p_xdn->TypeOfNumber & 0x07) << 4; - p_out[X + 1] |= p_xdn->NumberingPlanIdent & 0x0F; + p_out[alpha_id_space + 1] = 0x80; + p_out[alpha_id_space + 1] |= (p_xdn->ton & 0x07) << 4; + p_out[alpha_id_space + 1] |= p_xdn->npi & 0x0F; // set dialing number/SSC string memset((void*) bcdCode, 0xFF, SIM_XDN_NUMBER_LEN_MAX / 2); - _digit_to_bcd((char*) bcdCode, (char*) p_xdn->DiallingNum, p_xdn->DiallingnumLength); + _digit_to_bcd((char*) bcdCode, (char*) p_xdn->num, digit_len); - memcpy((void*) &p_out[X + 2], bcdCode, SIM_XDN_NUMBER_LEN_MAX / 2); + memcpy((void*) &p_out[alpha_id_space + 2], bcdCode, SIM_XDN_NUMBER_LEN_MAX / 2); // set Capability/Configuration Identifier - p_out[X + 12] = (unsigned char) p_xdn->CapaConfigId; + if (p_xdn->cc_id == 0x00) + p_out[alpha_id_space + 12] = 0xff; + else + p_out[alpha_id_space + 12] = (unsigned char) p_xdn->cc_id; // set extension1 record Identifier - p_out[X + 13] = (unsigned char) p_xdn->Ext1RecordId; + if (p_xdn->ext1_id == 0x00) + p_out[alpha_id_space + 13] = 0xff; + else + p_out[alpha_id_space + 13] = (unsigned char) p_xdn->ext1_id; - return TRUE; + return p_out; } gboolean tcore_sim_decode_ecc(struct tel_sim_ecc_list *p_ecc, unsigned char *p_in, int in_length) @@ -1098,11 +1634,32 @@ gboolean tcore_sim_decode_ecc(struct tel_sim_ecc_list *p_ecc, unsigned char *p_i return TRUE; } -gboolean tcore_sim_decode_ust(struct tel_sim_ust *p_ust, unsigned char *p_in, int in_length) +gboolean tcore_sim_decode_ext(struct tel_sim_ext *p_ext, unsigned char *p_in, int in_length) { - int i, j; - char mask; - char *p_index; + int bcd_byte; // dialing number max length + gboolean res = FALSE; + memset((void*)p_ext, 0x00, sizeof(struct tel_sim_ext)); + + if(*p_in & 0x01) { + dbg("Record type - Called Party Subaddress - NOT SUPPORTED"); + } else if(*p_in & 0x02) { + dbg("Record type - Additional data"); + bcd_byte = _get_valid_bcd_byte(&p_in[2], SIM_XDN_NUMBER_LEN_MAX / 2); + p_ext->ext_len = _bcd_to_digit((char*) p_ext->ext, (char*) &p_in[2], bcd_byte); // actual dialing number length in BCD. + p_ext->next_record = p_in[12]; + dbg( "Dialing number Length[%d]", p_ext->ext_len); + res = TRUE; + } else { + dbg("Record type - Invalid"); + } + return res; +} + +gboolean tcore_sim_decode_ust(struct tel_sim_ust *p_ust, unsigned char *p_in, int in_length) +{ + int i, j; + char mask; + char *p_index; memset((void*) p_ust, 0, sizeof(struct tel_sim_ust)); p_index = (char*)p_ust; @@ -1158,7 +1715,7 @@ gboolean tcore_sim_decode_uecc(struct tel_sim_ecc *p_ecc, unsigned char* p_in, i //get the alpha identifier of ECC ( _get_string((unsigned char*) p_ecc->ecc_string, (unsigned char*) &p_in[3], in_length - 3); - eccServiceCategory = p_in[in_length - 1] & 0x1F; // Check for the first 5 bits + eccServiceCategory = p_in[in_length - 1]; /* Assign the service category @@ -1175,26 +1732,13 @@ gboolean tcore_sim_decode_uecc(struct tel_sim_ecc *p_ecc, unsigned char* p_in, i Bit 7 automatically initiated eCall Bit 8 is spare and set to "0" */ - switch (eccServiceCategory) { - case 0x01: - p_ecc->ecc_category = SIM_ECC_POLICE; - break; - case 0x02: - p_ecc->ecc_category = SIM_ECC_AMBULANCE; - break; - case 0x04: - p_ecc->ecc_category = SIM_ECC_FIREBRIGADE; - break; - case 0x08: - p_ecc->ecc_category = SIM_ECC_MARAINEGUARD; - break; - case 0x10: - p_ecc->ecc_category = SIM_ECC_MOUTAINRESCUE; - break; - default: - p_ecc->ecc_category = SIM_ECC_SPARE; - break; + + if (eccServiceCategory == 0xFF) { // if category vaule is unused (unchecked) then just return 0xff + p_ecc->ecc_category = eccServiceCategory; + } else { + p_ecc->ecc_category = eccServiceCategory & 0x1F; // Check for the first 5 bits } + return TRUE; } @@ -1223,11 +1767,6 @@ gboolean tcore_sim_decode_gid( struct tel_sim_gid *p_gid, unsigned char* p_in, i gboolean tcore_sim_decode_mbi(struct tel_sim_mbi *p_mbi, unsigned char *p_in, int in_length) { - int i; - for (i = 0; i < in_length; i++) { - dbg( " \t0x%04X.", p_in[i]); - } - /* EF-MBI is defined 4 mandatory, 1 optional byte in 31.102 */ if (in_length == 0 || in_length > SIM_MAIL_BOX_IDENTIFIER_LEN_MAX) return FALSE; @@ -1236,35 +1775,44 @@ gboolean tcore_sim_decode_mbi(struct tel_sim_mbi *p_mbi, unsigned char *p_in, in return FALSE; // this is empty record } - p_mbi->VoiceMailBoxIdentifier = p_in[0]; - p_mbi->FaxMailBoxIdentifier = p_in[1]; - p_mbi->EmailMailBoxIdentifier = p_in[2]; - p_mbi->OtherMailBoxIdentifier = p_in[3]; + p_mbi->voice_index = p_in[0]; + p_mbi->fax_index = p_in[1]; + p_mbi->email_index = p_in[2]; + p_mbi->other_index = p_in[3]; // 5th byte is optional if (in_length == 5) - p_mbi->VideoMailBoxIdentifier = p_in[4]; + p_mbi->video_index = p_in[4]; return TRUE; } -gboolean tcore_sim_encode_mbi(char *p_out, int out_length, struct tel_sim_mbi *p_mbi) +char* tcore_sim_encode_mbi(const struct tel_sim_mbi *p_mbi, int in_length) { - p_out[0] = p_mbi->VoiceMailBoxIdentifier; - p_out[1] = p_mbi->FaxMailBoxIdentifier; - p_out[2] = p_mbi->EmailMailBoxIdentifier; - p_out[3] = p_mbi->OtherMailBoxIdentifier; + char *p_out = NULL; - if (out_length == 5) - p_out[4] = p_mbi->VideoMailBoxIdentifier; + if (in_length < 4) { + dbg("in_length[%d] should be greater than or equal to 4.", in_length) + return NULL; + } - return TRUE; + p_out = calloc(1, in_length); + if (!p_out) + return NULL; + + p_out[0] = p_mbi->voice_index; + p_out[1] = p_mbi->fax_index; + p_out[2] = p_mbi->email_index; + p_out[3] = p_mbi->other_index; + + if (in_length == 5) + p_out[4] = p_mbi->video_index; + + return p_out; } -gboolean tcore_sim_decode_cff(struct tel_sim_callforwarding *cfis, unsigned char *p_in, int in_length) +gboolean tcore_sim_decode_cff(struct tel_sim_cphs_cf *p_cff, unsigned char *p_in, int in_length) { - struct tel_sim_cphs_cf p_cff = {0,}; - if (in_length == 0) return FALSE; @@ -1272,34 +1820,30 @@ gboolean tcore_sim_decode_cff(struct tel_sim_callforwarding *cfis, unsigned char dbg( "flag(1)=%x", p_in[1]); if ((p_in[0] & 0x0F) == 0x0A) { - p_cff.bCallForwardUnconditionalLine1 = TRUE; - cfis->voice1 = TRUE; + p_cff->b_line1 = TRUE; } if ((p_in[0] & 0xF0) == 0xA0) { - p_cff.bCallForwardUnconditionalLine2 = TRUE; - cfis->voice2 = TRUE; + p_cff->b_line2 = TRUE; } if (in_length > 1) { if ((p_in[1] & 0x0F) == 0x0A) { - p_cff.bCallForwardUnconditionalFax = TRUE; - cfis->fax = TRUE; + p_cff->b_fax = TRUE; } if ((p_in[1] & 0xF0) == 0xA0) { - p_cff.bCallForwardUnconditionalData = TRUE; - cfis->data = TRUE; + p_cff->b_data = TRUE; } } dbg("Line1 = %d, line2 = %d, Fax = %d, Data = %d ", - p_cff.bCallForwardUnconditionalLine1, - p_cff.bCallForwardUnconditionalLine2, - p_cff.bCallForwardUnconditionalFax, - p_cff.bCallForwardUnconditionalData); + p_cff->b_line1, + p_cff->b_line2, + p_cff->b_fax, + p_cff->b_data); return TRUE; } -char* tcore_sim_encode_cff(const struct tel_sim_callforwarding *cff) +char* tcore_sim_encode_cff(const struct tel_sim_cphs_cf *cff, int in_length) { int i, j = 0; char *p_out = NULL; @@ -1307,9 +1851,17 @@ char* tcore_sim_encode_cff(const struct tel_sim_callforwarding *cff) unsigned char present = 0x0A; unsigned char absent = 0x05; - p_out = calloc(SIM_CPHS_CALL_FORWARDING_LEN_MAX+1, 1); + if (in_length < SIM_CPHS_CALL_FORWARDING_LEN_MIN) { + err("in_length[%d] is smaller than SIM_CPHS_CALL_FORWARDING_LEN_MIN[%d]", in_length, SIM_CPHS_CALL_FORWARDING_LEN_MIN); + return NULL; + } + + p_out = calloc(1, SIM_CPHS_CALL_FORWARDING_LEN_MIN+1); + if (!p_out) { + return NULL; + } - for (i = 0; i < SIM_CPHS_CALL_FORWARDING_LEN_MAX; i++) { + for (i = 0; i < SIM_CPHS_CALL_FORWARDING_LEN_MIN; i++) { present = 0x0A; absent = 0x05; @@ -1324,7 +1876,8 @@ char* tcore_sim_encode_cff(const struct tel_sim_callforwarding *cff) absent = absent << 4; } } - p_out[SIM_CPHS_CALL_FORWARDING_LEN_MAX] = '\0'; + + p_out[SIM_CPHS_CALL_FORWARDING_LEN_MIN] = '\0'; return p_out; } @@ -1339,30 +1892,30 @@ gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_i memset((void*) p_csp, 0, sizeof(struct tel_sim_cphs_csp)); -/* current telephony supports 22 byte cphs-csp data. 18 byte is mandatory, the other is optional. */ - for (i = 0, j = 0; i < SIM_CPHS_CSP_LEN_MAX || j < SIM_CPHS_CSP_LEN_MAX; i++, j++) { - p_csp->ServiceProfileEntry[j].CustomerServiceGroup = (enum tel_sim_cphs_csp_group) p_in[i]; + /* current telephony supports 22 byte cphs-csp data. 18 byte is mandatory, the other is optional. */ + for (i = 0, j = 0; i < SIM_CPHS_CSP_LEN_MAX && j < SIM_CPHS_CSP_ENTRY_CNT_MAX; i++, j++) { + p_csp->service_profile_entry[j].customer_service_group = (enum tel_sim_cphs_csp_group) p_in[i]; byteSignificance = p_in[++i]; mask = 0x80; - switch (p_csp->ServiceProfileEntry[j].CustomerServiceGroup) { + switch (p_csp->service_profile_entry[j].customer_service_group) { case 0x01: for (k = 0; k < 5; k++) { switch (byteSignificance & mask) { case 0x80: - p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingUnconditional = TRUE; + p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_unconditional = TRUE; break; case 0x40: - p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingOnUserBusy = TRUE; + p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_user_busy = TRUE; break; case 0x20: - p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingOnNoReply = TRUE; + p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_no_reply = TRUE; break; case 0x10: - p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingOnUserNotReachable = TRUE; + p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_user_not_reachable = TRUE; break; case 0x08: - p_csp->ServiceProfileEntry[j].u.CallOffering.bCallTransfer = TRUE; + p_csp->service_profile_entry[j].service.call_offering.b_call_transfer = TRUE; break; default: break; @@ -1375,19 +1928,19 @@ gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_i for (k = 0; k < 5; k++) { switch (byteSignificance & mask) { case 0x80: - p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfAllOutgoingCalls = TRUE; + p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_all_outgoing_calls = TRUE; break; case 0x40: - p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfOutgoingInternationalCalls = TRUE; + p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_outgoing_international_calls = TRUE; break; case 0x20: - p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfOutgoingInternationalCallsExceptHplmn = TRUE; + p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_outgoing_international_calls_except_hplmn = TRUE; break; case 0x10: - p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfAllIncomingCallsRoamingOutsideHplmn = TRUE; + p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_all_incoming_calls_roaming_outside_hplmn = TRUE; break; case 0x08: - p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfIncomingCallsWhenRoaming = TRUE; + p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_incoming_calls_when_roaming = TRUE; break; default: break; @@ -1400,19 +1953,19 @@ gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_i for (k = 0; k < 5; k++) { switch (byteSignificance & mask) { case 0x80: - p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bMultiPartyService = TRUE; + p_csp->service_profile_entry[j].service.other_supp_services.b_multi_party_service = TRUE; break; case 0x40: - p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bClosedUserGroup = TRUE; + p_csp->service_profile_entry[j].service.other_supp_services.b_closed_user_group = TRUE; break; case 0x20: - p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bAdviceOfCharge = TRUE; + p_csp->service_profile_entry[j].service.other_supp_services.b_advice_of_charge = TRUE; break; case 0x10: - p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bPreferentialClosedUserGroup = TRUE; + p_csp->service_profile_entry[j].service.other_supp_services.b_preferential_closed_user_group = TRUE; break; case 0x08: - p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bClosedUserGroupOutgoingAccess = TRUE; + p_csp->service_profile_entry[j].service.other_supp_services.b_closed_user_group_outgoing_access = TRUE; break; default: break; @@ -1425,16 +1978,16 @@ gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_i for (k = 0; k < 4; k++) { switch (byteSignificance & mask) { case 0x80: - p_csp->ServiceProfileEntry[j].u.CallComplete.bCallHold = TRUE; + p_csp->service_profile_entry[j].service.call_complete.b_call_hold = TRUE; break; case 0x40: - p_csp->ServiceProfileEntry[j].u.CallComplete.bCallWaiting = TRUE; + p_csp->service_profile_entry[j].service.call_complete.b_call_waiting = TRUE; break; case 0x20: - p_csp->ServiceProfileEntry[j].u.CallComplete.bCompletionOfCallToBusySubscriber = TRUE; + p_csp->service_profile_entry[j].service.call_complete.b_completion_of_call_to_busy_subscriber = TRUE; break; case 0x10: - p_csp->ServiceProfileEntry[j].u.CallComplete.bUserUserSignalling = TRUE; + p_csp->service_profile_entry[j].service.call_complete.b_user_user_signalling = TRUE; break; default: break; @@ -1447,25 +2000,25 @@ gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_i for (k = 0; k < 7; k++) { switch (byteSignificance & mask) { case 0x80: - p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageMobileTerminated = TRUE; + p_csp->service_profile_entry[j].service.teleservices.b_short_message_mobile_terminated = TRUE; break; case 0x40: - p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageMobileOriginated = TRUE; + p_csp->service_profile_entry[j].service.teleservices.b_short_message_mobile_originated = TRUE; break; case 0x20: - p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageCellBroadcast = TRUE; + p_csp->service_profile_entry[j].service.teleservices.b_short_message_cell_broadcast = TRUE; break; case 0x10: - p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageReplyPath = TRUE; + p_csp->service_profile_entry[j].service.teleservices.b_short_message_reply_path = TRUE; break; case 0x08: - p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageDeliveryConf = TRUE; + p_csp->service_profile_entry[j].service.teleservices.b_short_message_delivery_conf = TRUE; break; case 0x04: - p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageProtocolIdentifier = TRUE; + p_csp->service_profile_entry[j].service.teleservices.b_short_message_protocol_identifier = TRUE; break; case 0x02: - p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageValidityPeriod = TRUE; + p_csp->service_profile_entry[j].service.teleservices.b_short_message_validity_period = TRUE; break; default: break; @@ -1478,7 +2031,7 @@ gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_i for (k = 0; k < 1; k++) { switch (byteSignificance & mask) { case 0x80: - p_csp->ServiceProfileEntry[j].u.CphsTeleservices.bAlternativeLineService = TRUE; + p_csp->service_profile_entry[j].service.cphs_teleservices.b_alternative_line_service = TRUE; break; default: break; @@ -1491,7 +2044,7 @@ gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_i for (k = 0; k < 1; k++) { switch (byteSignificance & mask) { case 0x80: - p_csp->ServiceProfileEntry[j].u.CphsFeatures.bStringServiceTable = TRUE; + p_csp->service_profile_entry[j].service.cphs_features.b_string_service_table = TRUE; break; default: break; @@ -1504,22 +2057,22 @@ gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_i for (k = 0; k < 8; k++) { switch (byteSignificance & mask) { case 0x80: - p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bCallingLineIdentificationPresent = TRUE; + p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_present = TRUE; break; case 0x20: - p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bConnectedLineIdentificationRestrict = TRUE; + p_csp->service_profile_entry[j].service.number_identifiers.b_connected_line_identification_restrict = TRUE; break; case 0x10: - p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bConnectedLineIdentificationPresent = TRUE; + p_csp->service_profile_entry[j].service.number_identifiers.b_connected_line_identification_present = TRUE; break; case 0x08: - p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bMaliciousCallIdentifier = TRUE; + p_csp->service_profile_entry[j].service.number_identifiers.b_malicious_call_identifier = TRUE; break; case 0x02: - p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bCallingLineIdentificationSend = TRUE; + p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_send = TRUE; break; case 0x01: - p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bCallingLineIdentificationBlock = TRUE; + p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_block = TRUE; break; default: break; @@ -1532,22 +2085,22 @@ gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_i for (k = 0; k < 6; k++) { switch (byteSignificance & mask) { case 0x80: - p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForGprs = TRUE; + p_csp->service_profile_entry[j].service.phase_services.b_menu_for_gprs = TRUE; break; case 0x40: - p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForHighSpeedCsd = TRUE; + p_csp->service_profile_entry[j].service.phase_services.b_menu_for_high_speed_csd = TRUE; break; case 0x20: - p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForVoiceGroupCall = TRUE; + p_csp->service_profile_entry[j].service.phase_services.b_menu_for_voice_group_call = TRUE; break; case 0x10: - p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForVoiceBroadcastService = TRUE; + p_csp->service_profile_entry[j].service.phase_services.b_menu_for_voice_broadcast_service = TRUE; break; case 0x08: - p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForMultipleSubscriberProfile = TRUE; + p_csp->service_profile_entry[j].service.phase_services.b_menu_for_multiple_subscriber_profile = TRUE; break; case 0x04: - p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForMultipleBand = TRUE; + p_csp->service_profile_entry[j].service.phase_services.b_menu_for_multiple_band = TRUE; break; default: break; @@ -1560,25 +2113,25 @@ gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_i for (k = 0; k < 8; k++) { switch (byteSignificance & mask) { case 0x80: - p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForManualSelection = TRUE; + p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_manual_selection = TRUE; break; case 0x40: - p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForVoiceMail = TRUE; + p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_voice_mail = TRUE; break; case 0x20: - p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForMoSmsAndPaging = TRUE; + p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_mo_sms_and_paging = TRUE; break; case 0x10: - p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForMoSmsWithEmialType = TRUE; + p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_mo_sms_with_emial_type = TRUE; break; case 0x08: - p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForFaxCalls = TRUE; + p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_fax_calls = TRUE; break; case 0x04: - p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForDataCalls = TRUE; + p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_data_calls = TRUE; break; case 0x01: - p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForChangeLanguage = TRUE; + p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_change_language = TRUE; break; default: break; @@ -1598,7 +2151,7 @@ gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_i case 0x04: case 0x02: case 0x01: - p_csp->ServiceProfileEntry[j].u.InformationNumbers.bInformationNumbers = TRUE; + p_csp->service_profile_entry[j].service.information_numbers.b_information_numbers = TRUE; break; default: break; @@ -1624,88 +2177,88 @@ gboolean tcore_sim_encode_csp(unsigned char *p_out, int out_length, struct tel_s memset((void*) p_out, 0xFF, out_length); /* current telephony supports 22 byte cphs-csp data. 18 byte is mandatory, the other is optional.*/ - for (i = 0, j = 0; i < 22 || j < 22; i++, j++) { - p_out[i] = (unsigned char) p_csp->ServiceProfileEntry[j].CustomerServiceGroup; + for (i = 0, j = 0; i < SIM_CPHS_CSP_LEN_MAX && j < SIM_CPHS_CSP_ENTRY_CNT_MAX; i++, j++) { + p_out[i] = (unsigned char) p_csp->service_profile_entry[j].customer_service_group; switch (p_out[i]) { case 0x01: - p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingUnconditional) << 7) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingOnUserBusy) << 6) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingOnNoReply) << 5) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingOnUserNotReachable) << 4) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallOffering.bCallTransfer) << 3); + p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_unconditional) << 7) + + (((unsigned char) p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_user_busy) << 6) + + (((unsigned char) p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_no_reply) << 5) + + (((unsigned char) p_csp->service_profile_entry[j].service.call_offering.b_call_forwarding_on_user_not_reachable) << 4) + + (((unsigned char) p_csp->service_profile_entry[j].service.call_offering.b_call_transfer) << 3); break; case 0x02: - p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfAllOutgoingCalls) << 7) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfOutgoingInternationalCalls) << 6) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfOutgoingInternationalCallsExceptHplmn) << 5) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfAllIncomingCallsRoamingOutsideHplmn) << 4) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfIncomingCallsWhenRoaming) << 3); + p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_all_outgoing_calls) << 7) + + (((unsigned char) p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_outgoing_international_calls) << 6) + + (((unsigned char) p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_outgoing_international_calls_except_hplmn) << 5) + + (((unsigned char) p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_all_incoming_calls_roaming_outside_hplmn) << 4) + + (((unsigned char) p_csp->service_profile_entry[j].service.call_restriction.b_barring_of_incoming_calls_when_roaming) << 3); break; case 0x03: - p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bMultiPartyService) << 7) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bClosedUserGroup) << 6) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bAdviceOfCharge) << 5) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bPreferentialClosedUserGroup) << 4) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bClosedUserGroupOutgoingAccess) << 3); + p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.other_supp_services.b_multi_party_service) << 7) + + (((unsigned char) p_csp->service_profile_entry[j].service.other_supp_services.b_closed_user_group) << 6) + + (((unsigned char) p_csp->service_profile_entry[j].service.other_supp_services.b_advice_of_charge) << 5) + + (((unsigned char) p_csp->service_profile_entry[j].service.other_supp_services.b_preferential_closed_user_group) << 4) + + (((unsigned char) p_csp->service_profile_entry[j].service.other_supp_services.b_closed_user_group_outgoing_access) << 3); break; case 0x04: - p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallComplete.bCallHold) << 7) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallComplete.bCallWaiting) << 6) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallComplete.bCompletionOfCallToBusySubscriber) << 5) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallComplete.bUserUserSignalling) << 4); + p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.call_complete.b_call_hold) << 7) + + (((unsigned char) p_csp->service_profile_entry[j].service.call_complete.b_call_waiting) << 6) + + (((unsigned char) p_csp->service_profile_entry[j].service.call_complete.b_completion_of_call_to_busy_subscriber) << 5) + + (((unsigned char) p_csp->service_profile_entry[j].service.call_complete.b_user_user_signalling) << 4); break; case 0x05: - p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageMobileTerminated) << 7) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageMobileOriginated) << 6) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageCellBroadcast) << 5) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageReplyPath) << 4) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageDeliveryConf) << 3) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageProtocolIdentifier) << 2) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageValidityPeriod) << 1); + p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_mobile_terminated) << 7) + + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_mobile_originated) << 6) + + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_cell_broadcast) << 5) + + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_reply_path) << 4) + + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_delivery_conf) << 3) + + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_protocol_identifier) << 2) + + (((unsigned char) p_csp->service_profile_entry[j].service.teleservices.b_short_message_validity_period) << 1); break; case 0x06: - p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.CphsTeleservices.bAlternativeLineService) << 7); + p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.cphs_teleservices.b_alternative_line_service) << 7); break; case 0x07: - p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.CphsFeatures.bStringServiceTable) << 7); + p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.cphs_features.b_string_service_table) << 7); break; case 0x08: - p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bCallingLineIdentificationPresent) << 7) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bConnectedLineIdentificationRestrict) << 5) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bConnectedLineIdentificationPresent) << 4) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bMaliciousCallIdentifier) << 3) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bCallingLineIdentificationSend) << 1) - + ((unsigned char) p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bCallingLineIdentificationBlock); + p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_present) << 7) + + (((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_connected_line_identification_restrict) << 5) + + (((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_connected_line_identification_present) << 4) + + (((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_malicious_call_identifier) << 3) + + (((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_send) << 1) + + ((unsigned char) p_csp->service_profile_entry[j].service.number_identifiers.b_calling_line_identification_block); break; case 0x09: - p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForGprs) << 7) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForHighSpeedCsd) << 6) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForVoiceGroupCall) << 5) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForVoiceBroadcastService) << 4) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForMultipleSubscriberProfile) << 3) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForMultipleBand) << 2); + p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_gprs) << 7) + + (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_high_speed_csd) << 6) + + (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_voice_group_call) << 5) + + (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_voice_broadcast_service) << 4) + + (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_multiple_subscriber_profile) << 3) + + (((unsigned char) p_csp->service_profile_entry[j].service.phase_services.b_menu_for_multiple_band) << 2); break; case 0xC0: - p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForManualSelection) << 7) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForVoiceMail) << 6) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForMoSmsAndPaging) << 5) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForMoSmsWithEmialType) << 4) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForFaxCalls) << 3) - + (((unsigned char) p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForDataCalls) << 2) - + ((unsigned char) p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForChangeLanguage); + p_out[++i] = (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_manual_selection) << 7) + + (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_voice_mail) << 6) + + (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_mo_sms_and_paging) << 5) + + (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_mo_sms_with_emial_type) << 4) + + (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_fax_calls) << 3) + + (((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_data_calls) << 2) + + ((unsigned char) p_csp->service_profile_entry[j].service.value_added_services.b_restrict_menu_for_change_language); break; case 0xD5: - if (p_csp->ServiceProfileEntry[j].u.InformationNumbers.bInformationNumbers) + if (p_csp->service_profile_entry[j].service.information_numbers.b_information_numbers) p_out[++i] = 0xFF; else p_out[++i] = 0x00; @@ -1718,32 +2271,6 @@ gboolean tcore_sim_encode_csp(unsigned char *p_out, int out_length, struct tel_s return TRUE; } -gboolean tcore_sim_decode_vmwf(struct tel_sim_cphs_mw *p_vmwf, unsigned char* p_in, unsigned long in_length) -{ - int i, j = 0; - unsigned char* pTemp = (unsigned char*) p_vmwf; - unsigned char mask = 0x0F; - unsigned char voiceMsgFlg = 0; - - if (in_length == 0) - return FALSE; - -/* current telephony supports 2 byte cphs-vmwf data*/ - for (i = 0; i < SIM_CPHS_VMWF_LEN_MAX; i++) { - voiceMsgFlg = p_in[i]; - for (j = 0; j < 2; j++) { - if ((voiceMsgFlg & mask) == 0x0A) { - *pTemp = 1; //TRUE - } else if ((voiceMsgFlg & mask) == 0x05) { - *pTemp = 0; // FALSE - } - pTemp += sizeof(gboolean); - voiceMsgFlg = voiceMsgFlg >> 4; - } - } - return TRUE; -} - gboolean tcore_sim_decode_mwis(struct tel_sim_mw *pMwis, unsigned char *p_in, int in_length) { int i; @@ -1761,22 +2288,22 @@ gboolean tcore_sim_decode_mwis(struct tel_sim_mw *pMwis, unsigned char *p_in, in for (i = 0; i < 5; i++) { switch (type & mask) { case 0x01: - pMwis->IndicatorType = pMwis->IndicatorType | SIM_MWIS_VOICE; + pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_VOICE; break; case 0x02: - pMwis->IndicatorType = pMwis->IndicatorType | SIM_MWIS_FAX; + pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_FAX; break; case 0x04: - pMwis->IndicatorType = pMwis->IndicatorType | SIM_MWIS_EMAIL; + pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_EMAIL; break; case 0x08: - pMwis->IndicatorType = pMwis->IndicatorType | SIM_MWIS_OTHER; + pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_OTHER; break; case 0x10: - pMwis->IndicatorType = pMwis->IndicatorType | SIM_MWIS_VIDEO; + pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_VIDEO; break; default: - pMwis->IndicatorType = pMwis->IndicatorType | SIM_MWIS_NONE; + pMwis->indicator_status = pMwis->indicator_status | SIM_MWIS_NONE; break; } mask = mask << 1; @@ -1793,37 +2320,102 @@ gboolean tcore_sim_decode_mwis(struct tel_sim_mw *pMwis, unsigned char *p_in, in return TRUE; } -gboolean tcore_sim_encode_mwis( char *p_out, int out_length, struct tel_sim_mw *pMwis) +char* tcore_sim_encode_mwis( int *out_length, const struct tel_sim_mw *pMwis, int in_length) { + char *p_out = NULL; + int i = 0; + int encoded_size = 0; + if (out_length == 0) return FALSE; - memset((void*) p_out, 0xFF, out_length); - p_out[0] = 0x00; + /* + * by 3GPP spec (31.102), + * EF-MWIS record length should be <= 6. (5 or 6) + */ + if (in_length > 6) { + encoded_size = 6; + } else { + encoded_size = in_length; + } - p_out[0] = (unsigned char) pMwis->IndicatorType; - p_out[1] = pMwis->voice_count; - p_out[2] = pMwis->fax_count; - p_out[3] = pMwis->email_count; - p_out[4] = pMwis->other_count; + p_out = calloc(1, encoded_size); + if (!p_out) + return NULL; - if (out_length == 6) - p_out[5] = pMwis->video_count; + for(i = 0; i < encoded_size; i++) { + switch (i) { + case 0: + p_out[0] = (unsigned char) pMwis->indicator_status; + break; + case 1: + p_out[1] = pMwis->voice_count; + break; + case 2: + p_out[2] = pMwis->fax_count; + break; + case 3: + p_out[3] = pMwis->email_count; + break; + case 4: + p_out[4] = pMwis->other_count; + break; + case 5: + p_out[5] = pMwis->video_count; + break; + default: + break; + } + } + + *out_length = encoded_size; + return p_out; +} +gboolean tcore_sim_decode_vmwf(struct tel_sim_cphs_mw *p_vmwf, unsigned char* p_in, unsigned long in_length) +{ + int i, j = 0; + unsigned char* pTemp = (unsigned char*) p_vmwf; + unsigned char mask = 0x0F; + unsigned char voiceMsgFlg = 0; + + if (in_length == 0){ + dbg("fail - input length is zero"); + return FALSE; + } + +/* current telephony supports 2 byte cphs-vmwf data*/ + for (i = 0; i < SIM_CPHS_VMWF_LEN_MAX; i++) { + voiceMsgFlg = p_in[i]; + for (j = 0; j < 2; j++) { + if ((voiceMsgFlg & mask) == 0x0A) { + *pTemp = 1; //TRUE + } else if ((voiceMsgFlg & mask) == 0x05) { + *pTemp = 0; // FALSE + } + pTemp += sizeof(gboolean); + voiceMsgFlg = voiceMsgFlg >> 4; + } + } return TRUE; } -gboolean tcore_sim_encode_vmwf(char *p_out, int out_length, struct tel_sim_cphs_mw *p_vmwf) +char* tcore_sim_encode_vmwf(int *out_length, const struct tel_sim_cphs_mw *p_vmwf, int in_length) { int i, j = 0; + char *p_out = NULL; unsigned char* pTemp = (unsigned char*) p_vmwf; unsigned char present = 0x0A; unsigned char absent = 0x05; if (out_length == 0) - return FALSE; + return NULL; - for (i = 0; i < 2; i++) { + p_out = calloc(1, in_length); + if (!p_out) + return NULL; + + for (i = 0; i < in_length; i++) { present = 0x0A; absent = 0x05; @@ -1840,7 +2432,8 @@ gboolean tcore_sim_encode_vmwf(char *p_out, int out_length, struct tel_sim_cphs_ absent = absent << 4; } } - return TRUE; + *out_length = in_length; + return p_out; } gboolean tcore_sim_decode_ons(unsigned char* p_out,unsigned char* p_in, int in_length) @@ -1866,12 +2459,11 @@ gboolean tcore_sim_decode_ons(unsigned char* p_out,unsigned char* p_in, int in_ return TRUE; } -gboolean tcore_sim_decode_cfis(struct tel_sim_callforwarding *cfis, unsigned char *p_in, int in_length) +gboolean tcore_sim_decode_cfis(struct tel_sim_cfis *p_cfis, unsigned char *p_in, int in_length) { int bcd_byte; // dialing number max length + int digit_len; int i = 0; - struct tel_sim_cfis p_cfis = {0,}; - if (in_length == 0) return FALSE; @@ -1880,53 +2472,81 @@ gboolean tcore_sim_decode_cfis(struct tel_sim_callforwarding *cfis, unsigned cha return TRUE; // this is empty record } - p_cfis.MspNumber = p_in[i++]; - p_cfis.Status = p_in[i++]; + p_cfis->msp_num = p_in[i++]; + p_cfis->cfu_status = p_in[i++]; // get TON and NPI - p_cfis.TypeOfNumber = (p_in[++i] >> 4) & 0x07; - p_cfis.NumberingPlanIdent = p_in[i++] & 0x0F; + p_cfis->ton = (p_in[++i] >> 4) & 0x07; + p_cfis->npi = p_in[i++] & 0x0F; // get actual dialing number length /* current telephony supports 20 byte dialing number format. */ bcd_byte = _get_valid_bcd_byte(&p_in[i], SIM_XDN_NUMBER_LEN_MAX / 2); // get dialing number/SSC string - p_cfis.DiallingnumLen = _bcd_to_digit((char*) p_cfis.DiallingNum, (char*) &p_in[i], bcd_byte); // actual dialing number length in BCD. - dbg( "Dialing number Length %d \n", p_cfis.DiallingnumLen); + digit_len = _bcd_to_digit((char*) p_cfis->cfu_num, (char*) &p_in[i], bcd_byte); // actual dialing number length in BCD. + dbg( "Dialing number Length[%d]", digit_len); i = i + SIM_XDN_NUMBER_LEN_MAX / 2; // get Capability/Configuration id - // p_cfis.CapaConfig2Id = p_in[i++]; + p_cfis->cc2_id = p_in[i++]; // get Extension1 id - // p_cfis.Ext7RecordId = p_in[i]; - - dbg( "MspNumber 0x%x", p_cfis.MspNumber); - dbg( "Status 0x%x", p_cfis.Status); - dbg( "DiallingnumLen %d", p_cfis.DiallingnumLen); - dbg( "TypeOfNumber %d", p_cfis.TypeOfNumber); - dbg( "NumberingPlanIdent %d", p_cfis.NumberingPlanIdent); - dbg( "Dialing number[%s]", p_cfis.DiallingNum); - - if(p_cfis.Status & 0x01) - cfis->voice1 = TRUE; - if(p_cfis.Status & 0x02) - cfis->fax = TRUE; - if(p_cfis.Status & 0x04) - cfis->data = TRUE; - if(p_cfis.Status & 0x08) - cfis->sms = TRUE; - if(p_cfis.Status & 0x0a) - cfis->allbearer = TRUE; + p_cfis->ext7_id = p_in[i]; + + dbg( "MspNumber 0x%x", p_cfis->msp_num); + dbg( "Status 0x%x", p_cfis->cfu_status); + dbg( "TypeOfNumber %d", p_cfis->ton); + dbg( "NumberingPlanIdent %d", p_cfis->npi); + dbg( "Dialing number[%s]", p_cfis->cfu_num); + + return TRUE; +} + +gboolean tcore_sim_decode_img(struct tel_sim_img *p_out, unsigned char *p_in, int in_length) +{ + int i = 1; + + dbg( "Func Entrance"); + + if ((NULL == p_out) || (NULL == p_in)) { + return FALSE; + } + + if ((in_length == 0) || (in_length == 0xff) || (10 > in_length)) { + dbg("No valid IMG data present - length:[%x]", in_length); + return FALSE; + } + + if (_is_empty(p_in, in_length) == TRUE) { + dbg("empty record. all data is set 0xff"); + return FALSE; // this is empty record + } + + /*We are trying to decode only the 1st valid image data property and ignoring other for time being*/ + p_out->width = p_in[i++]; + p_out->height = p_in[i++]; + p_out->ics = p_in[i++]; + p_out->iidf_fileid = (*(p_in+4) << 8) | (*(p_in+5) & 0x00ff);/*index is 4 and 5 because the 1st byte is number of actual image instance*/ + p_out->offset = (*(p_in+6) << 8) | (*(p_in+7) & 0x00ff); + p_out->length = (*(p_in+8) << 8) | (*(p_in+9) & 0x00ff); + + dbg("p_out->width[%d], p_out->height[%d], p_out->ics[%d], p_out->offset[%d], p_out->length[%d], p_out->iidf_fileid[0x%02x]", + p_out->width, p_out->height, p_out->ics, p_out->offset, p_out->length, p_out->iidf_fileid); + return TRUE; } -char* tcore_sim_encode_cfis(int *out_length, const struct tel_sim_callforwarding *p_cfis) +char* tcore_sim_encode_cfis(int *out_length, const struct tel_sim_cfis *p_cfis) { char *encoded_o = NULL; - encoded_o = calloc(16, 1); // EF-CFIS record length is 16 + char bcd[10]; + + encoded_o = calloc(1, 16); // EF-CFIS record length is 16 + if (!encoded_o) + return NULL; + memset(bcd, 0xff, 10); /* Bytes Description M/O Length @@ -1934,24 +2554,25 @@ char* tcore_sim_encode_cfis(int *out_length, const struct tel_sim_callforwarding 2 CFU indicator status M 1 byte 3 Length of BCD number M 1 byte 4 TON and NPI M 1 byte - 5 to 14 Dialing Number M 10 bytes + 5 to 14 Dialing Number M 10 bytes. unused byte should be set with 'F' 15 Capability/Configuration2 Record Identifier M 1 byte 16 Extension 7 Record Identifier M 1 byte */ - encoded_o[0] = 0x01; //default profile + encoded_o[0] = p_cfis->msp_num; + encoded_o[1] = p_cfis->cfu_status; + + encoded_o[2] = (strlen(p_cfis->cfu_num) +1) /2; + + // set TON and NPI + encoded_o[3] = 0x80; + encoded_o[3] |= (p_cfis->ton & 0x07) << 4; + encoded_o[3] |= p_cfis->npi & 0x0F; - if(p_cfis->voice1 ) - encoded_o[1] = encoded_o[1] | 0x01; - if(p_cfis->fax ) - encoded_o[1] = encoded_o[1] | 0x02; - if(p_cfis->data ) - encoded_o[1] = encoded_o[1] | 0x04; - if(p_cfis->sms ) - encoded_o[1] = encoded_o[1] | 0x08; - if(p_cfis->allbearer ) - encoded_o[1] = encoded_o[1] | 0x0a; + _digit_to_bcd(bcd, (char*)&p_cfis->cfu_num, strlen(p_cfis->cfu_num)); + memcpy(&encoded_o[4], bcd, 10); - memset(&encoded_o[2], 0xff, 14); + encoded_o[14] = p_cfis->cc2_id; + encoded_o[15] = p_cfis->ext7_id; *out_length = 16; return encoded_o; @@ -1972,10 +2593,11 @@ gboolean tcore_sim_decode_dynamic_flag(struct tel_sim_cphs_dflag *p_df, unsigned case 0x01: p_df->DynamicFlags = SIM_DYNAMIC_FLAGS_LINE1; break; - default: - break; + warn("invalid input"); + break; } + return TRUE; } @@ -1990,12 +2612,15 @@ gboolean tcore_sim_decode_dynamic2_flag(struct tel_sim_cphs_dflag2 *p_d2f, unsig case 0x00: p_d2f->Dynamic2Flag = SIM_PIN2_ACCESSIBLE_FLAGS_UNLOCKED; break; + case 0x01: p_d2f->Dynamic2Flag = SIM_PIN2_ACCESSIBLE_FLAGS_LOCKED; break; default: - break; + warn("invalid input"); + break; } + return TRUE; } @@ -2127,33 +2752,23 @@ gboolean tcore_sim_decode_information_number(struct tel_sim_cphs_info_number *p_ gboolean tcore_sim_decode_opl(struct tel_sim_opl *p_opl, unsigned char *p_in, int in_length) { - unsigned char packetInDigit[3 * 2 + 1]; - if (_is_empty(p_in, in_length) == TRUE) { memset(p_opl, 0x00, sizeof(struct tel_sim_opl)); return FALSE; // this is empty record } - _bcd_to_digit((char*) packetInDigit, (char*) &p_in[0], 3); - dbg( "AFTER _bcd_to_digit 4th[0x%x]", packetInDigit[3]); - - // get MCC - memcpy(&p_opl->plmn, &(packetInDigit[0]), 3); - // get MNC - if (packetInDigit[3] == 0x00){ - memcpy(&(p_opl->plmn[3]), &(packetInDigit[3 + 1]), 2); - p_opl->plmn[5] = '\0'; - } else{ - memcpy(&(p_opl->plmn[3]), &(packetInDigit[3]), 3); - p_opl->plmn[6] = '\0'; - } + _decode_plmn(p_in, p_opl->plmn); dbg( " PLMN Code[%s]", p_opl->plmn); + p_opl->lac_from = (*(p_in+3) << 8) | (*(p_in+4) & 0x00ff); dbg( " Start value of the LAC range[%x]", p_opl->lac_from); + p_opl->lac_to = (*(p_in+5) << 8) | (*(p_in+6) & 0x00ff); dbg( " End value of the LAC range[%x]", p_opl->lac_to); + p_opl->rec_identifier = p_in[7]; dbg( " PNN Record identifier[%x]", p_opl->rec_identifier); + return TRUE; } @@ -2185,14 +2800,14 @@ gboolean tcore_sim_decode_pnn(struct tel_sim_pnn *p_pnn, unsigned char* p_in, in 0 1 0 to reserved 1 1 1 to reserved */ - if ((p_in[2] & 0x01110000) >> 4 == 0) { + if ((p_in[2] & 0x70) >> 4 == 0) { dbg( "DCS:GSM7"); // In case of GSM7, 35byte packing data will be converted 40 bytes unpacking string. if (f_name_len > (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8) f_name_len = (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8; _unpack_7bit28bit(p_in + 3, f_name_len, (unsigned char *) (p_pnn->full_name)); - } else if ((p_in[2] & 0x01110000) >> 4 == 1) { + } else if ((p_in[2] & 0x70) >> 4 == 1) { dbg( "DCS:UCS2"); /* current telephony supports 40 bytes network name string */ if (f_name_len > SIM_NW_FULL_NAME_LEN_MAX) @@ -2214,14 +2829,14 @@ gboolean tcore_sim_decode_pnn(struct tel_sim_pnn *p_pnn, unsigned char* p_in, in //s_name_part includes information byte. s_name_len = p_in[s_name_base +1] -1; - if ((p_in[s_name_base + 2] & 0x01110000) >> 4 == 0) { + if ((p_in[s_name_base + 2] & 0x70) >> 4 == 0) { dbg( "DCS:GSM7"); // In case of GSM7, 35byte packing data will be converted 40 bytes unpacking string. if (s_name_len > (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8) s_name_len = (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8; _unpack_7bit28bit(p_in + s_name_base + 3, s_name_len, (unsigned char *) (p_pnn->short_name)); - } else if ((p_in[s_name_base +2] & 0x01110000) >> 4 == 1) { + } else if ((p_in[s_name_base +2] & 0x70) >> 4 == 1) { dbg( "DCS:UCS2"); if (s_name_len > SIM_NW_FULL_NAME_LEN_MAX) s_name_len = SIM_NW_FULL_NAME_LEN_MAX; @@ -2255,7 +2870,6 @@ gboolean tcore_sim_decode_oplmnwact(struct tel_sim_oplmnwact_list *p_list, unsig dbg( "rawOplmnWactCount[%d]", rawOplmnWactCount); for (i = 0; i < rawOplmnWactCount; i++) { - unsigned char packetInDigit[3 * 2 + 1]; //Regarding current IPC data, even if there`s no OPLMN value, IPC data is sending with 'ff ff ff 00 00'. so we should check for validation. if (p_in[m] == 0xff) { @@ -2264,19 +2878,7 @@ gboolean tcore_sim_decode_oplmnwact(struct tel_sim_oplmnwact_list *p_list, unsig return TRUE; } - _bcd_to_digit((char*) packetInDigit, (char*) &p_in[m], 3); - dbg( "AFTER _bcd_to_digit 4th[0x%x]", packetInDigit[3]); - - // get MCC - memcpy(&p_list->opwa[i].plmn, &(packetInDigit[0]), 3); - // get MNC - if (packetInDigit[3] == 0x00){ - memcpy(&(p_list->opwa[i].plmn[3]), &(packetInDigit[3 + 1]), 2); - p_list->opwa[i].plmn[5] = '\0'; - } else{ - memcpy(&(p_list->opwa[i].plmn[3]), &(packetInDigit[3]), 3); - p_list->opwa[i].plmn[6] = '\0'; - } + _decode_plmn(&p_in[m], p_list->opwa[i].plmn); dbg( "[%d] OPLMN PLMN Code[%s]", i, p_list->opwa[i].plmn); if(p_in[m+3] & 0x80) @@ -2374,12 +2976,15 @@ struct tel_sim_imsi* tcore_sim_get_imsi(CoreObject *o) dbg("po access fail"); return NULL; } - tmp_imsi = calloc(sizeof(struct tel_sim_imsi), 1); + tmp_imsi = calloc(1, sizeof(struct tel_sim_imsi)); + if (!tmp_imsi) + return NULL; + memcpy(tmp_imsi, &po->imsi, sizeof(struct tel_sim_imsi)); return tmp_imsi; } -gboolean tcore_sim_set_imsi(CoreObject *o, struct tel_sim_imsi *imsi) +gboolean tcore_sim_set_imsi(CoreObject *o, const struct tel_sim_imsi *imsi) { struct private_object_data *po = NULL; po = tcore_object_ref_object(o); @@ -2391,6 +2996,153 @@ gboolean tcore_sim_set_imsi(CoreObject *o, struct tel_sim_imsi *imsi) return TRUE; } +struct tel_sim_msisdn_list* tcore_sim_get_msisdn_list(CoreObject *o) +{ + struct tel_sim_msisdn_list *tmp_msisdn_list; + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return NULL; + } else if (!po->msisdn_list) { + dbg("po->msisdn_list is NULL"); + return NULL; + } + tmp_msisdn_list = calloc(1, sizeof(struct tel_sim_msisdn_list)); + if (!tmp_msisdn_list) { + err("tmp_msisdn_list allocation failed!"); + return NULL; + } + memcpy(tmp_msisdn_list, po->msisdn_list, sizeof(struct tel_sim_msisdn_list)); + return tmp_msisdn_list; +} + +gboolean tcore_sim_set_msisdn_list(CoreObject *o, const struct tel_sim_msisdn_list *msisdn_list) +{ + struct tel_sim_msisdn_list *empty_msisdn_list = NULL; + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return FALSE; + } + if (!msisdn_list) { + empty_msisdn_list = calloc(1, sizeof(struct tel_sim_msisdn_list)); + if (!empty_msisdn_list) + return FALSE; + + msisdn_list = empty_msisdn_list; + } + + if (po->msisdn_list) { + memcpy(po->msisdn_list, msisdn_list, sizeof(struct tel_sim_msisdn_list)); + } else { + struct tel_sim_msisdn_list *tmp_msisdn_list = NULL; + tmp_msisdn_list = calloc(1, sizeof(struct tel_sim_msisdn_list)); + if (!tmp_msisdn_list) { + if (empty_msisdn_list) + free(empty_msisdn_list); + return FALSE; + } + memcpy(tmp_msisdn_list, msisdn_list, sizeof(struct tel_sim_msisdn_list)); + po->msisdn_list = tmp_msisdn_list; + } + + if (empty_msisdn_list) + free(empty_msisdn_list); + + return TRUE; +} + +enum tcore_return tcore_sim_delete_msisdn_list(CoreObject *o) +{ + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return TCORE_RETURN_EINVAL; + } + + if (po->msisdn_list) { + free(po->msisdn_list); + po->msisdn_list = NULL; + } + + return TCORE_RETURN_SUCCESS; +} + +struct tel_sim_service_table* tcore_sim_get_service_table(CoreObject *o) +{ + struct tel_sim_service_table *tmp_svct; + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return NULL; + } else if (!po->svct) { + dbg("po->svct is NULL."); + return NULL; + } + tmp_svct = calloc(1, sizeof(struct tel_sim_service_table)); + if (!tmp_svct) + return NULL; + memcpy(tmp_svct, po->svct, sizeof(struct tel_sim_service_table)); + return tmp_svct; +} + +gboolean tcore_sim_set_service_table(CoreObject *o, const struct tel_sim_service_table *svct) +{ + struct private_object_data *po = NULL; + struct tel_sim_service_table *empty_svct = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return FALSE; + } + if (!svct) { + empty_svct = calloc(1, sizeof(struct tel_sim_service_table)); + if (!empty_svct) + return FALSE; + svct = empty_svct; + } + + if (po->svct) { + memcpy(po->svct, svct, sizeof(struct tel_sim_service_table)); + } else { + struct tel_sim_service_table *tmp_svct = NULL; + tmp_svct = calloc(1, sizeof(struct tel_sim_service_table)); + if (!tmp_svct) { + if(empty_svct) + free(empty_svct); + return FALSE; + } + memcpy(tmp_svct, svct, sizeof(struct tel_sim_service_table)); + po->svct = tmp_svct; + } + + if(empty_svct) + free(empty_svct); + + return TRUE; +} + +enum tcore_return tcore_sim_delete_service_table(CoreObject *o) +{ + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return TCORE_RETURN_EINVAL; + } + + if (po->svct) { + free(po->svct); + po->svct = NULL; + } + + return TCORE_RETURN_SUCCESS; +} + gboolean tcore_sim_get_cphs_status(CoreObject *o){ struct private_object_data *po = NULL; po = tcore_object_ref_object(o); @@ -2412,6 +3164,373 @@ gboolean tcore_sim_set_cphs_status(CoreObject *o, gboolean b_support){ return TRUE; } +struct tel_sim_cphs_csp* tcore_sim_get_csp(CoreObject *o) +{ + struct tel_sim_cphs_csp *tmp_csp; + struct private_object_data *po = NULL; + + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return NULL; + } else if (!po->csp) { + dbg("po->csp is NULL"); + return NULL; + } + tmp_csp = calloc(1, sizeof(struct tel_sim_cphs_csp)); + if (!tmp_csp) { + err("memory allocation failed"); + return NULL; + } + memcpy(tmp_csp, po->csp, sizeof(struct tel_sim_cphs_csp)); + return tmp_csp; +} + +gboolean tcore_sim_set_csp(CoreObject *o, const struct tel_sim_cphs_csp *csp) +{ + struct tel_sim_cphs_csp *empty_csp = NULL; + struct private_object_data *po = NULL; + + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return FALSE; + } + if (!csp) { + empty_csp = calloc(1, sizeof(struct tel_sim_cphs_csp)); + if (!empty_csp) { + err("memory allocation failed"); + return FALSE; + } + csp = empty_csp; + } + + if (!(po->csp)) { + po->csp = calloc(1, sizeof(struct tel_sim_cphs_csp)); + if (!(po->csp)) { + err("memory allocation failed"); + if (empty_csp) + free(empty_csp); + return FALSE; + } + } + memcpy(po->csp, csp, sizeof(struct tel_sim_cphs_csp)); + if (empty_csp) + free(empty_csp); + + return TRUE; +} + +gboolean tcore_sim_delete_csp(CoreObject *o) +{ + struct private_object_data *po = NULL; + + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return FALSE; + } + + if (po->csp) { + free(po->csp); + po->csp = NULL; + } + + return TRUE; +} + +struct tel_sim_ecc_list* tcore_sim_get_ecc_list(CoreObject *o) +{ + struct tel_sim_ecc_list *tmp_ecc_list; + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return NULL; + } else if (!po->ecc_list) { + dbg("po->ecc_list is NULL"); + return NULL; + } + tmp_ecc_list = calloc(1, sizeof(struct tel_sim_ecc_list)); + if (!tmp_ecc_list) { + err("memory allocation failed"); + return NULL; + } + memcpy(tmp_ecc_list, po->ecc_list, sizeof(struct tel_sim_ecc_list)); + return tmp_ecc_list; +} + +gboolean tcore_sim_set_ecc_list(CoreObject *o, const struct tel_sim_ecc_list *ecc_list) +{ + struct tel_sim_ecc_list *empty_ecc_list = NULL; + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return FALSE; + } + if (!ecc_list) { + empty_ecc_list = calloc(1, sizeof(struct tel_sim_ecc_list)); + if (!empty_ecc_list) + return FALSE; + + ecc_list = empty_ecc_list; + } + + if (po->ecc_list) { + memcpy(po->ecc_list, ecc_list, sizeof(struct tel_sim_ecc_list)); + } else { + struct tel_sim_ecc_list *tmp_ecc_list = NULL; + tmp_ecc_list = calloc(1, sizeof(struct tel_sim_ecc_list)); + if (!tmp_ecc_list) { + if (empty_ecc_list) + free(empty_ecc_list); + return FALSE; + } + memcpy(tmp_ecc_list, ecc_list, sizeof(struct tel_sim_ecc_list)); + po->ecc_list = tmp_ecc_list; + } + + if (empty_ecc_list) + free(empty_ecc_list); + + return TRUE; +} + +enum tcore_return tcore_sim_delete_ecc_list(CoreObject *o) +{ + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return TCORE_RETURN_EINVAL; + } + + if (po->ecc_list) { + free(po->ecc_list); + po->ecc_list = NULL; + } + + return TCORE_RETURN_SUCCESS; +} + +struct tel_sim_spn* tcore_sim_get_spn(CoreObject *o) +{ + struct tel_sim_spn *tmp_spn; + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return NULL; + } else if (!po->spn) { + dbg("po->spn is NULL"); + return NULL; + } + tmp_spn = calloc(1, sizeof(struct tel_sim_spn)); + if (!tmp_spn) + return NULL; + memcpy(tmp_spn, po->spn, sizeof(struct tel_sim_spn)); + return tmp_spn; +} + +gboolean tcore_sim_set_spn(CoreObject *o, const struct tel_sim_spn *spn) +{ + struct tel_sim_spn *empty_spn = NULL; + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return FALSE; + } + if (!spn) { + empty_spn = calloc(1, sizeof(struct tel_sim_spn)); + if (!empty_spn) + return FALSE; + spn = empty_spn; + } + + if (po->spn) { + memcpy(po->spn, spn, sizeof(struct tel_sim_spn)); + } else { + struct tel_sim_spn *tmp_spn = NULL; + tmp_spn = calloc(1, sizeof(struct tel_sim_spn)); + if (!tmp_spn) { + if (empty_spn) + free(empty_spn); + return FALSE; + } + memcpy(tmp_spn, spn, sizeof(struct tel_sim_spn)); + po->spn = tmp_spn; + } + + if (empty_spn) + free(empty_spn); + + return TRUE; +} + +enum tcore_return tcore_sim_delete_spn(CoreObject *o) +{ + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return TCORE_RETURN_EINVAL; + } + + if (po->spn) { + free(po->spn); + po->spn = NULL; + } + + return TCORE_RETURN_SUCCESS; +} + +struct tel_sim_cphs_netname* tcore_sim_get_cphs_netname(CoreObject *o) +{ + struct tel_sim_cphs_netname *tmp_cphs_netname; + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return NULL; + } else if (!po->cphs_netname) { + dbg("po->cphs_netname is NULL"); + return NULL; + } + tmp_cphs_netname = calloc(1, sizeof(struct tel_sim_cphs_netname)); + if (!tmp_cphs_netname) + return NULL; + memcpy(tmp_cphs_netname, po->cphs_netname, sizeof(struct tel_sim_cphs_netname)); + return tmp_cphs_netname; +} + +gboolean tcore_sim_set_cphs_netname(CoreObject *o, const struct tel_sim_cphs_netname *cphs_netname) +{ + struct tel_sim_cphs_netname *empty_cphs_netname = NULL; + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return FALSE; + } + if (!cphs_netname) { + empty_cphs_netname = calloc(1, sizeof(struct tel_sim_cphs_netname)); + if (!empty_cphs_netname) + return FALSE; + cphs_netname = empty_cphs_netname; + } + + if (po->cphs_netname) { + memcpy(po->cphs_netname, cphs_netname, sizeof(struct tel_sim_cphs_netname)); + } else { + struct tel_sim_cphs_netname *tmp_cphs_netname = NULL; + tmp_cphs_netname = calloc(1, sizeof(struct tel_sim_cphs_netname)); + if (!tmp_cphs_netname) { + if (empty_cphs_netname) + free(empty_cphs_netname); + return FALSE; + } + memcpy(tmp_cphs_netname, cphs_netname, sizeof(struct tel_sim_cphs_netname)); + po->cphs_netname = tmp_cphs_netname; + } + + if (empty_cphs_netname) + free(empty_cphs_netname); + + return TRUE; +} + +enum tcore_return tcore_sim_delete_cphs_netname(CoreObject *o) +{ + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return TCORE_RETURN_EINVAL; + } + + if (po->cphs_netname) { + free(po->cphs_netname); + po->cphs_netname = NULL; + } + + return TCORE_RETURN_SUCCESS; +} + +struct tel_sim_iccid* tcore_sim_get_iccid(CoreObject *o) +{ + struct tel_sim_iccid *tmp_iccid; + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return NULL; + } else if (!po->iccid) { + dbg("po->iccid is NULL"); + return NULL; + } + tmp_iccid = calloc(1, sizeof(struct tel_sim_iccid)); + if (!tmp_iccid) + return NULL; + + memcpy(tmp_iccid, po->iccid, sizeof(struct tel_sim_iccid)); + return tmp_iccid; +} + +gboolean tcore_sim_set_iccid(CoreObject *o, const struct tel_sim_iccid *iccid) +{ + struct tel_sim_iccid *empty_iccid = NULL; + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return FALSE; + } + if (!iccid) { + empty_iccid = calloc(1, sizeof(struct tel_sim_iccid)); + if (!empty_iccid) + return FALSE; + iccid = empty_iccid; + } + + if (po->iccid) { + memcpy(po->iccid, iccid, sizeof(struct tel_sim_iccid)); + } else { + struct tel_sim_iccid *tmp_iccid = NULL; + tmp_iccid = calloc(1, sizeof(struct tel_sim_iccid)); + if (!tmp_iccid) { + if (empty_iccid) + free(empty_iccid); + return FALSE; + } + memcpy(tmp_iccid, iccid, sizeof(struct tel_sim_iccid)); + po->iccid = tmp_iccid; + } + + if (empty_iccid) + free(empty_iccid); + + return TRUE; +} + +enum tcore_return tcore_sim_delete_iccid(CoreObject *o) +{ + struct private_object_data *po = NULL; + po = tcore_object_ref_object(o); + if (!po) { + dbg("po access fail"); + return TCORE_RETURN_EINVAL; + } + + if (po->iccid) { + free(po->iccid); + po->iccid = NULL; + } + + return TCORE_RETURN_SUCCESS; +} + gboolean tcore_sim_link_userdata(CoreObject *o, void *userdata) { struct private_object_data *po = NULL; @@ -2446,19 +3565,9 @@ static void tcore_sim_initialize_context(CoreObject *o) } tmp_ops = po->ops; - -/* if(!po->p_cache) - free(po->p_cache);*/ - memset(po, 0x00, sizeof(struct private_object_data)); - po->ops = tmp_ops; - po->sim_status = SIM_STATUS_UNKNOWN; - po->language_file = SIM_EF_INVALID; - po->cf_file = SIM_EF_INVALID; - po->mw_file = SIM_EF_INVALID; - po->mb_file = SIM_EF_INVALID; } CoreObject *tcore_sim_new(TcorePlugin *p, const char *name, @@ -2474,7 +3583,7 @@ CoreObject *tcore_sim_new(TcorePlugin *p, const char *name, if (!o) return NULL; - po = calloc(sizeof(struct private_object_data), 1); + po = calloc(1, sizeof(struct private_object_data)); if (!po) { tcore_object_free(o); return NULL; @@ -2495,14 +3604,20 @@ CoreObject *tcore_sim_new(TcorePlugin *p, const char *name, void tcore_sim_free(CoreObject *o) { + CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SIM); + tcore_object_free(o); +} + +void tcore_sim_set_ops(CoreObject *o, struct tcore_sim_operations *ops) +{ struct private_object_data *po = NULL; CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SIM); - po = tcore_object_ref_object(o); - if (!po) + po = (struct private_object_data *)tcore_object_ref_object(o); + if (!po) { return; + } - free(po); - tcore_object_free(o); + po->ops = ops; } diff --git a/src/co_sms.c b/src/co_sms.c index 2fd96dc..e7d30bf 100644 --- a/src/co_sms.c +++ b/src/co_sms.c @@ -34,16 +34,6 @@ struct private_object_data { gboolean b_readyStatus; }; -/** - * This function is used to encode SMS Parameters to TPDU on EFsmsp - * - * @return length of string - * @param[in] incoming - telephony_sms_Params_t - * @param[in] data - TPDU data - * @Interface Synchronous. - * @remark - * @Refer - */ int _tcore_util_sms_encode_smsParameters(const struct telephony_sms_Params *incoming, unsigned char *data, int SMSPRecordLen) { struct telephony_sms_Params *smsParams = (struct telephony_sms_Params *)incoming; @@ -129,6 +119,1006 @@ int _tcore_util_sms_encode_smsParameters(const struct telephony_sms_Params *inco } +void tcore_util_sms_semioctet_to_octect(int* nScLength) { + if (*nScLength % 2) { + *nScLength = (*nScLength / 2) + 1; + } else { + *nScLength = *nScLength / 2; + } + + return; +} + +TReturn tcore_util_sms_encode_submit_message(const struct telephony_sms_CdmaMsgInfo *pMsgInfo, uint8_t *output, uint32_t *pos) +{ + TReturn api_err = TCORE_RETURN_SUCCESS; + + struct telephony_sms_Is637OutSubmit *pSubmit = NULL; + uint32_t temp_index = 0; + int i = 0; + + // 1. check null pointer + if(pMsgInfo == NULL || output == NULL || pos == NULL) + return TCORE_RETURN_EINVAL; + + // 2. check manatory parameter in the TelSmsMsgInfo_t + if(!((pMsgInfo->ParamMask & SMS_PARAM_TELESERVICE_MASK) && + (pMsgInfo->ParamMask & SMS_PARAM_ADDRESS_MASK) && + (pMsgInfo->ParamMask & SMS_PARAM_MESSAGE_ID_MASK) )) + return TCORE_RETURN_EINVAL; + + pSubmit = (struct telephony_sms_Is637OutSubmit *)&(pMsgInfo->MsgData.outSubmit); + + dbg("SMS_PARAMID_TELESERVICE_ID\n"); + dbg("teleservice msg=%x\n", pSubmit->TeleService); + // 3. teleservice + output[temp_index++] = SMS_PARAMID_TELESERVICE_ID; + output[temp_index++] = 2; + memcpy(output+temp_index, &(pSubmit->TeleService), sizeof(unsigned short)); + temp_index += sizeof(unsigned short); + + dbg("SMS_PARAMID_ADDRESS\n"); + // 4. Destination address + output[temp_index++] = SMS_PARAMID_ADDRESS; + output[temp_index++] = pSubmit->DstAddr.szAddrLength + 5; + output[temp_index++] = (uint8_t)pSubmit->DstAddr.Digit; + output[temp_index++] = (uint8_t)pSubmit->DstAddr.NumberMode; + output[temp_index++] = (uint8_t)pSubmit->DstAddr.NumberType; + output[temp_index++] = (uint8_t)pSubmit->DstAddr.NumberPlan; + output[temp_index++] = (uint8_t)pSubmit->DstAddr.szAddrLength; + if(pSubmit->DstAddr.szAddrLength > SMS_MAXLENGTH_SMS_ADDRESS) + api_err = TCORE_RETURN_EINVAL; + else{ + memcpy(output+ temp_index, pSubmit->DstAddr.szAddress, pSubmit->DstAddr.szAddrLength); + temp_index += pSubmit->DstAddr.szAddrLength; + } + + dbg("SMS_PARAMID_SUBADDRESS\n"); + // 5. Subaddress (optional) + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_SUBADDRESS_MASK)){ + output[temp_index++] = SMS_PARAMID_SUBADDRESS; + output[temp_index++] = pSubmit->DstSubAddr.szAddrLength + 3; + output[temp_index++] = pSubmit->DstSubAddr.SubType; + output[temp_index++] = pSubmit->DstSubAddr.Odd; + output[temp_index++] = pSubmit->DstSubAddr.szAddrLength; + if(pSubmit->DstSubAddr.szAddrLength > SMS_MAXLENGTH_SMS_ADDRESS) + api_err = TCORE_RETURN_EINVAL; + else{ + memcpy(output+ temp_index, pSubmit->DstSubAddr.szAddress, pSubmit->DstSubAddr.szAddrLength); + temp_index += pSubmit->DstSubAddr.szAddrLength; + } + } + + dbg("SMS_PARAMID_BEARER_REPLY\n"); + // 6. Bearer Reply Option + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_BEARER_REPLY_MASK)){ + output[temp_index++] = SMS_PARAMID_BEARER_REPLY; + output[temp_index++] = 1; + if(pSubmit->ReplySeqNumber >= 64) + api_err = TCORE_RETURN_EINVAL; + else output[temp_index++] = pSubmit->ReplySeqNumber; + } + + dbg("SMS_PARAMID_MESSAGE_ID\n"); + dbg("Message ID msg=%x\n",pSubmit->MsgId); + // 7. Message Id + if((api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_MESSAGE_ID_MASK)){ + output[temp_index++] = SMS_PARAMID_MESSAGE_ID; + output[temp_index++] = 3; + output[temp_index++] = SMS_MESSAGETYPE_SUBMIT; + memcpy(output+ temp_index, &(pSubmit->MsgId), sizeof(unsigned short)); + temp_index += sizeof(unsigned short); + } + + dbg("SMS_PARAMID_USER_DATA\n"); + // 8. User Data + if((api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_USER_DATA_MASK)){ + output[temp_index++] = SMS_PARAMID_USER_DATA; + output[temp_index++] = 2 + pSubmit->MsgLength; + output[temp_index++] = pSubmit->MsgEncoding; + output[temp_index++] = pSubmit->MsgLength; + if(pSubmit->MsgLength > SMS_MAXLENGTH_SMS_MO_USER_DATA) + api_err = TCORE_RETURN_EINVAL; + else{ + memcpy(output+ temp_index, pSubmit->szData, pSubmit->MsgLength); + temp_index += pSubmit->MsgLength; + } + } + + // 9. Deferred DeliveryTime Absolute + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_DEFERRED_DELIVERY_ABS_MASK)){ + output[temp_index++] = SMS_PARAMID_DEFERRED_DELIVERY_ABS; + output[temp_index++] = 6; + output[temp_index++] = (uint8_t)pSubmit->DeferredDelTimeAbs.year; + output[temp_index++] = (uint8_t)pSubmit->DeferredDelTimeAbs.month; + output[temp_index++] = (uint8_t)pSubmit->DeferredDelTimeAbs.day; + output[temp_index++] = (uint8_t)pSubmit->DeferredDelTimeAbs.hours; + output[temp_index++] = (uint8_t)pSubmit->DeferredDelTimeAbs.minutes; + output[temp_index++] = (uint8_t)pSubmit->DeferredDelTimeAbs.seconds; + } + + // 10. Deferred DeliveryTime Relative + if((api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_DEFERRED_DELIVERY_REL_MASK)){ + output[temp_index++] = SMS_PARAMID_DEFERRED_DELIVERY_REL; + output[temp_index++] = 1; + output[temp_index++] = (uint8_t)pSubmit->DeferredDelTimeRel; + } + + // 11. Priority Indicator + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_PRIORITY_MASK)){ + output[temp_index++] = SMS_PARAMID_PRIORITY; + output[temp_index++] = 1; + if((int)pSubmit->Privacy < SMS_PRIVACY_NOT_RESTRICTED || pSubmit->Privacy > SMS_PRIVACY_SECRET) + api_err = TCORE_RETURN_EINVAL; + else output[temp_index++] = pSubmit->Priority; + } + + // 12. Privacy Indicator + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_PRIVACY_MASK)){ + output[temp_index++] = SMS_PARAMID_PRIVACY; + output[temp_index++] = 1; + if((int)pSubmit->Priority < SMS_PRIORITY_NORMAL || pSubmit->Priority > SMS_PRIORITY_EMERGENCY) + api_err = TCORE_RETURN_EINVAL; + else output[temp_index++] = pSubmit->Privacy; + } + + // 13. Reply Option + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_REPLY_OPTION_MASK)){ + output[temp_index++] = SMS_PARAMID_REPLY_OPTION; + output[temp_index++] = 2; + if(pSubmit->bUserAckRequest == 0 && pSubmit->bDeliveryAckRequest == 0) + api_err = TCORE_RETURN_EINVAL; + else { + output[temp_index++] = (uint8_t)(pSubmit->bUserAckRequest); + output[temp_index++] = (uint8_t)(pSubmit->bDeliveryAckRequest); + } + } + + // 14. Alert on Message Delivery + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_ALERT_ON_DELIVERY_MASK)){ + output[temp_index++] = SMS_PARAMID_ALERT_ON_DELIVERY; + output[temp_index++] = 1; + if((int)pSubmit->AlertPriority< SMS_ALERT_PRIORITY_DEFAULT || pSubmit->AlertPriority > SMS_ALERT_PRIORITY_HIGH) + api_err = TCORE_RETURN_EINVAL; + else output[temp_index++] = pSubmit->AlertPriority; + } + + // 15. Language Indicator + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_LANGUAGE_MASK)){ + output[temp_index++] = SMS_PARAMID_LANGUAGE; + output[temp_index++] = 1; + if((int)pSubmit->MsgLang< SMS_LANG_UNKNOWN || pSubmit->MsgLang > SMS_LANG_HEBREW) + api_err = TCORE_RETURN_EINVAL; + else output[temp_index++] = pSubmit->MsgLang; + } + + dbg("SMS_PARAMID_CALLBACK\n"); + // 16. Callback Number + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_CALLBACK_MASK)){ + output[temp_index++] = SMS_PARAMID_CALLBACK; + output[temp_index++] = 4 + pSubmit->CallBackNumber.szAddrLength; + output[temp_index++] = pSubmit->CallBackNumber.Digit; + output[temp_index++] = pSubmit->CallBackNumber.NumberType; + output[temp_index++] = pSubmit->CallBackNumber.NumberPlan; + output[temp_index++] = (uint8_t)pSubmit->CallBackNumber.szAddrLength; + dbg("temp_index before =%d, value=%x", (int)temp_index, output[temp_index-1]); + if(pSubmit->CallBackNumber.szAddrLength > SMS_MAXLENGTH_SMS_ADDRESS) + api_err = TCORE_RETURN_EINVAL; + else{ + memcpy(output+ temp_index, pSubmit->CallBackNumber.szAddress, pSubmit->CallBackNumber.szAddrLength); + + dbg("index after =%d, value=%x\n", (int)temp_index, output[temp_index]); + + for (i=0;i<11;i++) + dbg("szAddr[%d]=%x\n", i, output[temp_index+i]); + temp_index += pSubmit->CallBackNumber.szAddrLength; + } + } + + dbg("output index: (0)=%x, (-1)=%x, (+1)=%x\n", output[temp_index], output[temp_index-1],output[temp_index+1]); + + *pos = temp_index; + + return api_err; +} + +TReturn tcore_util_sms_encode_cancel_message(const struct telephony_sms_CdmaMsgInfo *pMsgInfo, uint8_t *output, uint32_t *pos) +{ + TReturn api_err = TCORE_RETURN_SUCCESS; + struct telephony_sms_Is637OutCancel *pCancel = NULL; + uint32_t temp_index = 0; + + // 1. check null pointer + if(pMsgInfo == NULL || output == NULL || pos == NULL) + return TCORE_RETURN_EINVAL; + + // 2. check manatory parameter in the TelSmsMsgInfo_t + if(!((pMsgInfo->ParamMask & SMS_PARAM_TELESERVICE_MASK) && + (pMsgInfo->ParamMask & SMS_PARAM_ADDRESS_MASK) && + (pMsgInfo->ParamMask & SMS_PARAM_MESSAGE_ID_MASK) )) + return TCORE_RETURN_EINVAL; + + pCancel = (struct telephony_sms_Is637OutCancel *)&(pMsgInfo->MsgData.outCancel); + + // 3. teleservice + output[temp_index++] = SMS_PARAMID_TELESERVICE_ID; + output[temp_index++] = 2; + memcpy(output+temp_index, &pCancel->TeleService, sizeof(unsigned short)); + temp_index += sizeof(unsigned short); + + + // 4. Destination address + output[temp_index++] = SMS_PARAMID_ADDRESS; + output[temp_index++] = pCancel->DstAddr.szAddrLength + 5; + output[temp_index++] = (uint8_t)pCancel->DstAddr.Digit; + output[temp_index++] = (uint8_t)pCancel->DstAddr.NumberMode; + output[temp_index++] = (uint8_t)pCancel->DstAddr.NumberType; + output[temp_index++] = (uint8_t)pCancel->DstAddr.NumberPlan; + output[temp_index++] = (uint8_t)pCancel->DstAddr.szAddrLength; + if(pCancel->DstAddr.szAddrLength > SMS_MAXLENGTH_SMS_ADDRESS) + api_err = TCORE_RETURN_EINVAL; + else{ + memcpy(output+ temp_index, pCancel->DstAddr.szAddress, pCancel->DstAddr.szAddrLength); + temp_index += pCancel->DstAddr.szAddrLength; + } + + // 5. Subaddress (optional) + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_SUBADDRESS_MASK)){ + output[temp_index++] = SMS_PARAMID_SUBADDRESS; + output[temp_index++] = pCancel->DstSubAddr.szAddrLength + 3; + output[temp_index++] = pCancel->DstSubAddr.SubType; + output[temp_index++] = pCancel->DstSubAddr.Odd; + output[temp_index++] = pCancel->DstSubAddr.szAddrLength; + if(pCancel->DstSubAddr.szAddrLength > SMS_MAXLENGTH_SMS_ADDRESS) + api_err = TCORE_RETURN_EINVAL; + else{ + memcpy(output+ temp_index, pCancel->DstSubAddr.szAddress, pCancel->DstSubAddr.szAddrLength); + temp_index += pCancel->DstSubAddr.szAddrLength; + } + } + + // 6. Bearer Reply Option + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_BEARER_REPLY_MASK)){ + output[temp_index++] = SMS_PARAMID_BEARER_REPLY; + output[temp_index++] = 1; + if(pCancel->ReplySeqNumber >= 64) + api_err = TCORE_RETURN_EINVAL; + else output[temp_index++] = pCancel->ReplySeqNumber; + } + + // 7. Message Id + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_MESSAGE_ID_MASK)){ + output[temp_index++] = SMS_PARAMID_MESSAGE_ID; + output[temp_index++] = 3; + output[temp_index++] = SMS_MESSAGETYPE_CANCEL; + memcpy(output+ temp_index, &pCancel->MsgId, sizeof(unsigned short)); + temp_index += sizeof(unsigned short); + } + + *pos = temp_index; + + return api_err; +} + +TReturn tcore_util_sms_encode_user_ack_message(const struct telephony_sms_CdmaMsgInfo *pMsgInfo, uint8_t *output, uint32_t *pos) +{ + TReturn api_err = TCORE_RETURN_SUCCESS; + struct telephony_sms_Is637OutAck *pUserAck = NULL; + uint32_t temp_index = 0; + + // 1. check null pointer + if(pMsgInfo == NULL || output == NULL || pos == NULL) + return TCORE_RETURN_EINVAL; + + if(!((pMsgInfo->ParamMask & SMS_PARAM_TELESERVICE_MASK) && + (pMsgInfo->ParamMask & SMS_PARAM_ADDRESS_MASK) && + (pMsgInfo->ParamMask & SMS_PARAM_MESSAGE_ID_MASK) )) + return TCORE_RETURN_EINVAL; + + pUserAck = (struct telephony_sms_Is637OutAck *)&(pMsgInfo->MsgData.outAck); + + // 3. teleservice + output[temp_index++] = SMS_PARAMID_TELESERVICE_ID; + output[temp_index++] = 2; + memcpy(output+temp_index, &pUserAck->TeleService, sizeof(unsigned short)); + temp_index += sizeof(unsigned short); + + + // 4. Destination address + output[temp_index++] = SMS_PARAMID_ADDRESS; + output[temp_index++] = pUserAck->DstAddr.szAddrLength + 5; + output[temp_index++] = (uint8_t)pUserAck->DstAddr.Digit; + output[temp_index++] = (uint8_t)pUserAck->DstAddr.NumberMode; + output[temp_index++] = (uint8_t)pUserAck->DstAddr.NumberType; + output[temp_index++] = (uint8_t)pUserAck->DstAddr.NumberPlan; + output[temp_index++] = (uint8_t)pUserAck->DstAddr.szAddrLength; + if(pUserAck->DstAddr.szAddrLength > SMS_MAXLENGTH_SMS_ADDRESS) + api_err = TCORE_RETURN_EINVAL; + else{ + memcpy(output+ temp_index, pUserAck->DstAddr.szAddress, pUserAck->DstAddr.szAddrLength); + temp_index += pUserAck->DstAddr.szAddrLength; + } + + // 5. Subaddress (optional) + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_SUBADDRESS_MASK)){ + output[temp_index++] = SMS_PARAMID_SUBADDRESS; + output[temp_index++] = pUserAck->DstSubAddr.szAddrLength + 3; + output[temp_index++] = pUserAck->DstSubAddr.SubType; + output[temp_index++] = pUserAck->DstSubAddr.Odd; + output[temp_index++] = pUserAck->DstSubAddr.szAddrLength; + if(pUserAck->DstSubAddr.szAddrLength > SMS_MAXLENGTH_SMS_ADDRESS) + api_err = TCORE_RETURN_EINVAL; + else{ + memcpy(output+ temp_index, pUserAck->DstSubAddr.szAddress, pUserAck->DstSubAddr.szAddrLength); + temp_index += pUserAck->DstSubAddr.szAddrLength; + } + } + + // 6. Bearer Reply Option + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_BEARER_REPLY_MASK)){ + output[temp_index++] = SMS_PARAMID_BEARER_REPLY; + output[temp_index++] = 1; + if(pUserAck->ReplySeqNumber >= 64) + api_err = TCORE_RETURN_EINVAL; + else output[temp_index++] = pUserAck->ReplySeqNumber; + } + + // 7. Message Id + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_MESSAGE_ID_MASK)){ + output[temp_index++] = SMS_PARAMID_MESSAGE_ID; + output[temp_index++] = 3; + output[temp_index++] = SMS_MESSAGETYPE_USER_ACK; + memcpy(output+ temp_index, &pUserAck->MsgId, sizeof(unsigned short)); + temp_index += sizeof(unsigned short); + } + + // 8. User Data + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_USER_DATA_MASK)){ + output[temp_index++] = SMS_PARAMID_USER_DATA; + output[temp_index++] = 2 + pUserAck->MsgEncoding; + output[temp_index++] = pUserAck->MsgLength; + if(pUserAck->MsgLength > SMS_MAXLENGTH_SMS_MO_USER_DATA) + api_err = TCORE_RETURN_EINVAL; + else{ + memcpy(output+ temp_index, pUserAck->szData, pUserAck->MsgLength); + temp_index += pUserAck->MsgLength; + } + } + + // 9. User Response Code + if( (api_err == TCORE_RETURN_SUCCESS) && (pMsgInfo->ParamMask & SMS_PARAM_USER_RESPONSE_CODE_MASK)){ + output[temp_index++] = SMS_PARAMID_USER_RESPONSE_CODE; + output[temp_index++] = 1; + output[temp_index++] = pUserAck->UserResponseCode; + } + + *pos = temp_index; + + return api_err; +} + +int tcore_util_sms_decode_inDeliver_message(uint8_t *incoming, uint32_t length, struct telephony_sms_CdmaMsgInfo *pMsgInfo) +{ + int rtn = TRUE; + uint32_t temp_index = 0; + struct telephony_sms_Is637InDeliver *InDeliver = NULL; + + dbg("Parsing Bearer Data below, Total length[0x%x]", (unsigned int)length); + + if(incoming == NULL || pMsgInfo == NULL) + return FALSE; + + InDeliver = &(pMsgInfo->MsgData.inDeliver); + + do{ + if(incoming[temp_index] == SMS_PARAMID_USER_DATA){ + int i=0; + dbg("ParamID[SMS_PARAMID_USER_DATA=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + temp_index++; //ignore param length + InDeliver->MsgEncoding = incoming[++temp_index]; + InDeliver->MsgLength = incoming[++temp_index]; + memcpy(InDeliver->szData, incoming+ ++temp_index, InDeliver->MsgLength); + temp_index += InDeliver->MsgLength; + pMsgInfo->ParamMask |= SMS_PARAM_USER_DATA_MASK; + dbg("MsgEnconding[0x%x], MsgLength[%d]", + InDeliver->MsgEncoding, InDeliver->MsgLength); + + for(i = 0 ; i < InDeliver->MsgLength ; i++) + { + dbg("Index[%d] Char[0x%x]", i, InDeliver->szData[i]); + } + dbg("Final Index[0x%x]", (unsigned int)temp_index); + + + } + else if(incoming[temp_index] == SMS_PARAMID_VALIDITY_PERIOD_ABS){ + dbg("ParamID[SMS_PARAMID_VALIDITY_PERIOD_ABS=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + temp_index++; //ignore param length + InDeliver->ValidityPeriodAbs.year = incoming[++temp_index]; + InDeliver->ValidityPeriodAbs.month = incoming[++temp_index]; + InDeliver->ValidityPeriodAbs.day = incoming[++temp_index]; + InDeliver->ValidityPeriodAbs.hours = incoming[++temp_index]; + InDeliver->ValidityPeriodAbs.minutes = incoming[++temp_index]; + InDeliver->ValidityPeriodAbs.seconds = incoming[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_VALIDITY_PERIOD_ABS_MASK; + } + else if(incoming[temp_index] == SMS_PARAMID_VALIDITY_PERIOD_REL){ + dbg("ParamID[SMS_PARAMID_VALIDITY_PERIOD_REL=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + temp_index++; //ignore param length + InDeliver->ValidityPeriodRel = incoming[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_VALIDITY_PERIOD_REL_MASK; + } + else if(incoming[temp_index] == SMS_PARAMID_MC_TIME_STAMP){ + dbg("ParamID[SMS_PARAMID_MC_TIME_STAMP=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + temp_index++; //ignore param length + InDeliver->MessageCenterTimeStamp.year = incoming[++temp_index]; + InDeliver->MessageCenterTimeStamp.month = incoming[++temp_index]; + InDeliver->MessageCenterTimeStamp.day = incoming[++temp_index]; + InDeliver->MessageCenterTimeStamp.hours = incoming[++temp_index]; + InDeliver->MessageCenterTimeStamp.minutes = incoming[++temp_index]; + InDeliver->MessageCenterTimeStamp.seconds = incoming[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_MC_TIME_STAMP_MASK; + } + + else if(incoming[temp_index] == SMS_PARAMID_PRIORITY){ + dbg("ParamID[SMS_PARAMID_PRIORITY=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + temp_index++; //ignore param length + InDeliver->Priority = incoming[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_PRIORITY_MASK; + } + else if(incoming[temp_index] == SMS_PARAMID_PRIVACY){ + dbg("ParamID[SMS_PARAMID_PRIVACY=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + temp_index++; //ignore param length + InDeliver->Privacy = incoming[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_PRIVACY_MASK; + } + else if(incoming[temp_index] == SMS_PARAMID_NUMBER_OF_MESSAGE){ + dbg("ParamID[SMS_PARAMID_NUMBER_OF_MESSAGE=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + temp_index++; //ignore param length + InDeliver->NumMsg = incoming[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_NUMBER_OF_MESSAGE_MASK; + } + else if(incoming[temp_index] == SMS_PARAMID_ALERT_ON_DELIVERY){ + dbg("ParamID[SMS_PARAMID_ALERT_ON_DELIVERY=0x%x], ParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + temp_index++; //ignore param length + InDeliver->AlertPriority = incoming[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_ALERT_ON_DELIVERY_MASK; + } + else if(incoming[temp_index] == SMS_PARAMID_LANGUAGE){ + dbg("ParamID[SMS_PARAMID_LANGUAGE=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + temp_index++; //ignore param length + InDeliver->MsgLang = incoming[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_LANGUAGE_MASK; + } + else if(incoming[temp_index] == SMS_PARAMID_REPLY_OPTION){ + dbg("ParamID[SMS_PARAMID_REPLY_OPTION=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + temp_index++; //ignore param length + InDeliver->bUserAckRequest = (int)incoming[++temp_index]; + InDeliver->bDeliveryAckRequest = (int)incoming[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_REPLY_OPTION_MASK; + } + else if(incoming[temp_index] == SMS_PARAMID_CALLBACK){ + dbg("ParamID[SMS_PARAMID_CALLBACK=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + temp_index++; //ignore param length + InDeliver->CallBackNumer.Digit = incoming[++temp_index]; + InDeliver->CallBackNumer.NumberType= incoming[++temp_index]; + InDeliver->CallBackNumer.NumberPlan = incoming[++temp_index]; + InDeliver->CallBackNumer.szAddrLength = incoming[++temp_index]; + memcpy(InDeliver->CallBackNumer.szAddress, incoming+ ++temp_index, InDeliver->CallBackNumer.szAddrLength); + temp_index+= InDeliver->CallBackNumer.szAddrLength; + pMsgInfo->ParamMask |= SMS_PARAMID_CALLBACK; + } + else if(incoming[temp_index] == SMS_PARAMID_DISPLAY_MODE){ + dbg("ParamID[SMS_PARAMID_DISPLAY_MODE=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + temp_index++; //ignore param length + InDeliver->Display= incoming[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_DISPLAY_MODE_MASK; + } + else + { + dbg("Undefined SMS Parameter ID [0x%x] in the Bearer Data", incoming[temp_index]); + rtn = FALSE; + break; + } + }while(!(temp_index == length)); + + return rtn; +} + +int tcore_util_sms_decode_inAck_message(uint8_t *incoming, uint32_t length, struct telephony_sms_CdmaMsgInfo *pMsgInfo) +{ + int rtn = TRUE; + struct telephony_sms_Is637InAck *InAck = NULL; + uint32_t temp_index = 0; + + if(incoming == NULL || pMsgInfo == NULL) + return FALSE; + + InAck = &(pMsgInfo->MsgData.inAck); + do{ + if(incoming[temp_index] == SMS_PARAMID_USER_DATA){ + temp_index++; //ignore param length + InAck->MsgEncoding = incoming[++temp_index]; + InAck->MsgLength = incoming[++temp_index]; + memcpy(InAck->szData, incoming+ ++temp_index, InAck->MsgLength); + temp_index += InAck->MsgLength; + pMsgInfo->ParamMask |= SMS_PARAM_USER_DATA_MASK; + } + else if(incoming[temp_index] == SMS_PARAMID_USER_RESPONSE_CODE){ + temp_index++; //ignore param length + InAck->MsgEncoding = incoming[++temp_index]; + InAck->UserResponseCode = incoming[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_USER_RESPONSE_CODE_MASK; + } + else if(incoming[temp_index] == SMS_PARAMID_MC_TIME_STAMP){ + temp_index++; //ignore param length + InAck->MessageCenterTimeStamp.year = incoming[++temp_index]; + InAck->MessageCenterTimeStamp.month = incoming[++temp_index]; + InAck->MessageCenterTimeStamp.day = incoming[++temp_index]; + InAck->MessageCenterTimeStamp.hours = incoming[++temp_index]; + InAck->MessageCenterTimeStamp.minutes = incoming[++temp_index]; + InAck->MessageCenterTimeStamp.seconds = incoming[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_MC_TIME_STAMP_MASK; + } + else{ + rtn = FALSE; + break; + } + }while(!(temp_index == length)); + + return rtn; +} + +int tcore_util_sms_decode_inDeliverAck_message(uint8_t *incoming, uint32_t length, struct telephony_sms_CdmaMsgInfo *pMsgInfo) +{ + int rtn = TRUE; + struct telephony_sms_Is637InDeliverAck *InDelAck = NULL; + uint32_t temp_index = 0; + + if(incoming == NULL || pMsgInfo == NULL) + return FALSE; + + InDelAck = &(pMsgInfo->MsgData.inDeliverAck); + do{ + if(incoming[temp_index] == SMS_PARAMID_USER_DATA){ + temp_index++; //ignore param length + InDelAck->MsgEncoding = incoming[++temp_index]; + InDelAck->MsgLength = incoming[++temp_index]; + memcpy(InDelAck->szData, incoming+ ++temp_index, InDelAck->MsgLength); + temp_index += InDelAck->MsgLength; + pMsgInfo->ParamMask |= SMS_PARAM_USER_DATA_MASK; + } + else if(incoming[temp_index] == SMS_PARAMID_MC_TIME_STAMP){ + temp_index++; //ignore param length + InDelAck->MessageCenterTimeStamp.year = incoming[++temp_index]; + InDelAck->MessageCenterTimeStamp.month = incoming[++temp_index]; + InDelAck->MessageCenterTimeStamp.day = incoming[++temp_index]; + InDelAck->MessageCenterTimeStamp.hours = incoming[++temp_index]; + InDelAck->MessageCenterTimeStamp.minutes = incoming[++temp_index]; + InDelAck->MessageCenterTimeStamp.seconds = incoming[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_MC_TIME_STAMP_MASK; + } + else{ + rtn = FALSE; + break; + } + }while(!(temp_index == length)); + + return rtn; +} + +int tcore_util_sms_decode_ptp_message(uint8_t *incoming, uint32_t length, struct telephony_sms_CdmaMsgInfo *pMsgInfo) +{ + int rtn = TRUE; + uint32_t temp_index = 0; + uint32_t ParamLen = 0; + struct telephony_sms_Is637InDeliver *pCommon = NULL; + enum telephony_sms_CdmaMsgType type; + + if(incoming == NULL || pMsgInfo == NULL) + return FALSE; + + pCommon = &(pMsgInfo->MsgData.inDeliver); + + do{ + if(incoming[temp_index] == SMS_PARAMID_TELESERVICE_ID) + { + dbg("ParamID[SMS_PARAMID_TELESERVICE_ID=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + ParamLen = incoming[++temp_index]; //parameter length + memcpy(&pCommon->TeleService, incoming+ ++temp_index, ParamLen); + temp_index += ParamLen; + pMsgInfo->ParamMask |= SMS_PARAM_TELESERVICE_MASK; + } + else if(incoming[temp_index] == SMS_PARAMID_ADDRESS) + { + dbg("ParamID[SMS_PARAMID_ADDRESS=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + ParamLen = incoming[++temp_index]; //parameter length + pCommon->OrigAddr.Digit = incoming[++temp_index]; + pCommon->OrigAddr.NumberMode = incoming[++temp_index]; + pCommon->OrigAddr.NumberType = incoming[++temp_index]; + pCommon->OrigAddr.NumberPlan = incoming[++temp_index]; + pCommon->OrigAddr.szAddrLength = incoming[++temp_index]; + memcpy(pCommon->OrigAddr.szAddress, incoming+ ++temp_index, pCommon->OrigAddr.szAddrLength); + temp_index += pCommon->OrigAddr.szAddrLength; + pMsgInfo->ParamMask |= SMS_PARAM_ADDRESS_MASK; + } + else if(incoming[temp_index] == SMS_PARAMID_SUBADDRESS) + { + dbg("ParamID[SMS_PARAMID_SUBADDRESS=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + ParamLen = incoming[++temp_index]; //parameter length + pCommon->OrigSubAddr.SubType = incoming[++temp_index]; + pCommon->OrigSubAddr.Odd = incoming[++temp_index]; + pCommon->OrigSubAddr.szAddrLength = incoming[++temp_index]; + memcpy(pCommon->OrigSubAddr.szAddress, incoming+ ++temp_index, pCommon->OrigSubAddr.szAddrLength); + temp_index += pCommon->OrigSubAddr.szAddrLength; + pMsgInfo->ParamMask |= SMS_PARAM_SUBADDRESS_MASK; + } + else if(incoming[temp_index] == SMS_PARAMID_BEARER_REPLY) + { + dbg("ParamID[SMS_PARAMID_BEARER_REPLY=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + ParamLen = incoming[++temp_index]; //parameter length + pCommon->bBearerReplySeqRequest = (int)TRUE; + pCommon->ReplySeqNumber = incoming[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_BEARER_REPLY_MASK; + } + else if(incoming[temp_index] == SMS_PARAMID_MESSAGE_ID) + { + dbg("ParamID[SMS_PARAMID_MESSAGE_ID=0x%x]\tParamLen[%d]", incoming[temp_index], incoming[temp_index+1]); + ParamLen = incoming[++temp_index]; //parameter length + type = incoming[++temp_index]; + pMsgInfo->MsgType = type; + memcpy(&pCommon->MsgId, incoming+ ++temp_index, sizeof(unsigned short)); + temp_index += sizeof(unsigned short); + pMsgInfo->ParamMask |= SMS_PARAM_MESSAGE_ID_MASK; + switch(type) + { + case SMS_MESSAGETYPE_DELIVER: + dbg("SubParamID[SMS_MESSAGETYPE_DELIVER=0x%x]", type); + dbg("Current Index[0x%x], Parsing Length[0x%x], ParamLen[0x%x]", (unsigned int)temp_index, (unsigned int)length, (unsigned int)ParamLen); + + rtn = tcore_util_sms_decode_inDeliver_message(incoming+temp_index, length - temp_index, pMsgInfo); + + break; + case SMS_MESSAGETYPE_DELIVERY_ACK: + dbg("SubParamID[SMS_MESSAGETYPE_DELIVERY_ACK=0x%x]", type); + + rtn = tcore_util_sms_decode_inAck_message(incoming+temp_index, length - temp_index, pMsgInfo); + + break; + case SMS_MESSAGETYPE_USER_ACK: + dbg("SubParamID[SMS_MESSAGETYPE_USER_ACK=0x%x]", type); + + rtn = tcore_util_sms_decode_inDeliverAck_message(incoming+temp_index, length - temp_index, pMsgInfo); + + break; + default: + dbg("Unknown Incoming Message Type = %d", type); + rtn = FALSE; + break; + } + temp_index = length; + } + else + { + dbg("ParamID[Undefined]"); + //rtn = FALSE; + break; + } + + }while(!(temp_index == length)); + + return rtn; +} + +int tcore_util_sms_decode_broadcast_message(uint8_t *bcmsg, uint32_t length, struct telephony_sms_CdmaMsgInfo *pMsgInfo) +{ + int rtn = TRUE; + uint32_t temp_index = 0; + uint32_t ParamLen = 0; + struct telephony_sms_Is637InBroadCast *pOutput = NULL; + + if(bcmsg == NULL || pMsgInfo == NULL) + return FALSE; + + pOutput = &(pMsgInfo->MsgData.inBc); + + do{ + if(bcmsg[temp_index] == SMS_PARAMID_SERVICE_CATEGORY){ + ParamLen = bcmsg[++temp_index]; //parameter length + memcpy(&pOutput->ServiceCategory, bcmsg+ ++temp_index, ParamLen); + temp_index += ParamLen; + pMsgInfo->ParamMask |= SMS_PARAM_SERVICE_CATEGORY_MASK; + } + else if(bcmsg[temp_index] == SMS_PARAMID_BEARER_REPLY){ + ParamLen = bcmsg[++temp_index]; //parameter length + pOutput->bBearerReplySeqRequest = (int)TRUE; + pOutput->ReplySeqNumber = bcmsg[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_BEARER_REPLY_MASK; + } + else if(bcmsg[temp_index] == SMS_PARAMID_MESSAGE_ID){ + ParamLen = bcmsg[++temp_index]; //parameter length + memcpy(&pOutput->MsgId, bcmsg+ ++temp_index, ParamLen); + temp_index += ParamLen; + pMsgInfo->ParamMask |= SMS_PARAM_MESSAGE_ID_MASK; + } + else if(bcmsg[temp_index] == SMS_PARAMID_VALIDITY_PERIOD_ABS){ + ParamLen = bcmsg[++temp_index]; //parameter length + pOutput->ValidityPeriodAbs.year = bcmsg[++temp_index]; + pOutput->ValidityPeriodAbs.month = bcmsg[++temp_index]; + pOutput->ValidityPeriodAbs.day = bcmsg[++temp_index]; + pOutput->ValidityPeriodAbs.hours = bcmsg[++temp_index]; + pOutput->ValidityPeriodAbs.minutes = bcmsg[++temp_index]; + pOutput->ValidityPeriodAbs.seconds = bcmsg[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_VALIDITY_PERIOD_ABS_MASK; + } + else if(bcmsg[temp_index] == SMS_PARAMID_VALIDITY_PERIOD_REL){ + ParamLen = bcmsg[++temp_index]; //parameter length + pOutput->ValidityPeriodRel = bcmsg[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_VALIDITY_PERIOD_REL_MASK; + } + else if(bcmsg[temp_index] == SMS_PARAMID_MC_TIME_STAMP){ + ParamLen = bcmsg[++temp_index]; //parameter length + pOutput->MessageCenterTimeStamp.year = bcmsg[++temp_index]; + pOutput->MessageCenterTimeStamp.month = bcmsg[++temp_index]; + pOutput->MessageCenterTimeStamp.day = bcmsg[++temp_index]; + pOutput->MessageCenterTimeStamp.hours = bcmsg[++temp_index]; + pOutput->MessageCenterTimeStamp.minutes = bcmsg[++temp_index]; + pOutput->MessageCenterTimeStamp.seconds = bcmsg[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_MC_TIME_STAMP_MASK; + } + else if(bcmsg[temp_index] == SMS_PARAMID_PRIORITY){ + ParamLen = bcmsg[++temp_index]; //parameter length + pOutput->Priority= bcmsg[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_PRIORITY_MASK; + } + else if(bcmsg[temp_index] == SMS_PARAMID_ALERT_ON_DELIVERY){ + ParamLen = bcmsg[++temp_index]; //parameter length + pOutput->AlertPriority = bcmsg[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_ALERT_ON_DELIVERY_MASK; + } + else if(bcmsg[temp_index] == SMS_PARAMID_LANGUAGE){ + ParamLen = bcmsg[++temp_index]; //parameter length + pOutput->MsgLang = bcmsg[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_LANGUAGE_MASK; + } + else if(bcmsg[temp_index] == SMS_PARAMID_DISPLAY_MODE){ + ParamLen = bcmsg[++temp_index]; //parameter length + pOutput->Display = bcmsg[++temp_index]; + temp_index++; + pMsgInfo->ParamMask |= SMS_PARAM_DISPLAY_MODE_MASK; + } + else if(bcmsg[temp_index] == SMS_PARAMID_USER_DATA){ + ParamLen = bcmsg[++temp_index]; //parameter length + pOutput->MsgEncoding = bcmsg[++temp_index]; + pOutput->MsgLength = bcmsg[++temp_index]; + memcpy(pOutput->szData, bcmsg+ ++temp_index, pOutput->MsgLength); + temp_index += pOutput->MsgLength; + pMsgInfo->ParamMask |= SMS_PARAM_USER_DATA_MASK; + } + else{ + rtn = FALSE; + break; + } + + }while(!(temp_index == length)); + + return rtn; +} + +int tcore_util_sms_decode_smsParameters(uint8_t *incoming, uint32_t length, struct telephony_sms_Params *params) +{ + int alpha_id_len = 0; + int i = 0; + int nOffset = 0; + + dbg(" RecordLen = %d", length); + + if(incoming == NULL || params == NULL) + return FALSE; + + alpha_id_len = length -SMS_SMSP_PARAMS_MAX_LEN; + + if ( alpha_id_len > 0 ) + { + if(alpha_id_len > SMS_SMSP_ALPHA_ID_LEN_MAX) + { + alpha_id_len = SMS_SMSP_ALPHA_ID_LEN_MAX; + } + + for( i=0 ; i < alpha_id_len ; i++) + { + if( 0xff == incoming[i]) + { + dbg(" found"); + break; + } + } + + memcpy(params->szAlphaId, incoming, i); + + params->alphaIdLen = i; + + dbg(" Alpha id length = %d", i); + + } + else + { + params->alphaIdLen = 0; + dbg(" Alpha id length is zero"); + } + + //dongil01.park - start parse from here. + params->paramIndicator = incoming[alpha_id_len]; + + dbg(" Param Indicator = %02x", params->paramIndicator); + + //dongil01.park(2008/12/26) - DestAddr + if( (params->paramIndicator & SMSPValidDestAddr) == 0) + { + nOffset = nDestAddrOffset; + + if( 0x00 == incoming[alpha_id_len + nOffset] || 0xff == incoming[alpha_id_len + nOffset]) + { + params->tpDestAddr.dialNumLen = 0; + + dbg("DestAddr Length is 0"); + } + else + { + if ( 0 < (int)incoming[alpha_id_len + nOffset] ) + { + params->tpDestAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1 ); + + if(params->tpDestAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN) + params->tpDestAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN; + } + else + { + params->tpDestAddr.dialNumLen = 0; + } + + params->tpDestAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ; + params->tpDestAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70 )>>4 ; + + memcpy( params->tpDestAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpDestAddr.dialNumLen)) ; + + dbg("Dest TON is %d",params->tpDestAddr.typeOfNum); + dbg("Dest NPI is %d",params->tpDestAddr.numPlanId); + dbg("Dest Length = %d",params->tpDestAddr.dialNumLen); + dbg("Dest Addr = %s",params->tpDestAddr.diallingNum); + + } + } + + //dongil01.park(2008/12/26) - SvcAddr + if( (params->paramIndicator & SMSPValidSvcAddr) == 0) + { + nOffset = nSCAAddrOffset; + + if( 0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset] ) + { + params->tpSvcCntrAddr.dialNumLen = 0; + + dbg(" SCAddr Length is 0"); + } + else + { + if ( 0 < (int)incoming[alpha_id_len + nOffset] ) + { + params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1); + + if(params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN) + params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN; + + params->tpSvcCntrAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ; + params->tpSvcCntrAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70) >>4 ; + + memcpy( params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], (params->tpSvcCntrAddr.dialNumLen)); + + dbg("SCAddr Length = %d ",params->tpSvcCntrAddr.dialNumLen); + dbg("SCAddr TON is %d",params->tpSvcCntrAddr.typeOfNum); + dbg("SCAddr NPI is %d",params->tpSvcCntrAddr.numPlanId); + + for( i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i ++) + dbg("SCAddr = %d [%02x]",i,params->tpSvcCntrAddr.diallingNum[i]); + } + else + { + params->tpSvcCntrAddr.dialNumLen = 0; + } + } + } + else if ( (0x00 < (int)incoming[alpha_id_len +nSCAAddrOffset] && (int)incoming[alpha_id_len +nSCAAddrOffset] <= 12 ) + || 0xff != (int)incoming[alpha_id_len +nSCAAddrOffset]) + { + nOffset = nSCAAddrOffset; + + if( 0x00 == (int)incoming[alpha_id_len + nOffset] || 0xff == (int)incoming[alpha_id_len + nOffset] ) + { + params->tpSvcCntrAddr.dialNumLen = 0; + dbg("SCAddr Length is 0"); + } + else + { + + if ( 0 < (int)incoming[alpha_id_len + nOffset] ) + { + params->tpSvcCntrAddr.dialNumLen = (int)(incoming[alpha_id_len + nOffset] - 1); + + params->tpSvcCntrAddr.dialNumLen = incoming[alpha_id_len + nOffset] -1; + + if(params->tpSvcCntrAddr.dialNumLen > SMS_SMSP_ADDRESS_LEN) + params->tpSvcCntrAddr.dialNumLen = SMS_SMSP_ADDRESS_LEN; + + params->tpSvcCntrAddr.numPlanId= incoming[alpha_id_len + (++nOffset)] & 0x0f ; + params->tpSvcCntrAddr.typeOfNum= (incoming[alpha_id_len + nOffset] & 0x70) >>4 ; + + memcpy( params->tpSvcCntrAddr.diallingNum, &incoming[alpha_id_len + (++nOffset)], + (params->tpSvcCntrAddr.dialNumLen)) ; + + dbg("SCAddr Length = %d ",params->tpSvcCntrAddr.dialNumLen); + dbg("SCAddr TON is %d",params->tpSvcCntrAddr.typeOfNum); + dbg("SCAddr NPI is %d",params->tpSvcCntrAddr.numPlanId); + + for( i = 0 ; i < (int)params->tpSvcCntrAddr.dialNumLen ; i ++) + dbg("SCAddr = %d [%02x]",i,params->tpSvcCntrAddr.diallingNum[i]); + } + else + { + params->tpSvcCntrAddr.dialNumLen = 0; + } + } + + } + + if( (params->paramIndicator & SMSPValidPID) == 0 && (alpha_id_len + nPIDOffset) < SMS_MAX_EFSMSP_RECORD_LENGTH) + { + params->tpProtocolId = incoming[alpha_id_len + nPIDOffset]; + } + if( (params->paramIndicator & SMSPValidDCS) == 0 && (alpha_id_len + nDCSOffset) < SMS_MAX_EFSMSP_RECORD_LENGTH) + { + params->tpDataCodingScheme = incoming[alpha_id_len + nDCSOffset]; + } + if( (params->paramIndicator & SMSPValidVP) == 0 && (alpha_id_len + nVPOffset) < SMS_MAX_EFSMSP_RECORD_LENGTH) + { + params->tpValidityPeriod = incoming[alpha_id_len + nVPOffset]; + } + + dbg(" Alpha Id(Len) = %d",(int)params->alphaIdLen); + + for (i=0; i< (int)params->alphaIdLen ; i++) + { + dbg(" Alpha Id = [%d] [%c]",i,params->szAlphaId[i]); + } + dbg(" PID = %d",params->tpProtocolId); + dbg(" DCS = %d",params->tpDataCodingScheme); + dbg(" VP = %d",params->tpValidityPeriod); + + return TRUE; +} + + static TReturn _dispatcher(CoreObject *o, UserRequest *ur) { enum tcore_request_command command; @@ -360,7 +1350,7 @@ static void _clone_hook(CoreObject *src, CoreObject *dest) if (!src || !dest) return; - dest_po = calloc(sizeof(struct private_object_data), 1); + dest_po = calloc(1, sizeof(struct private_object_data)); if (!dest_po) { tcore_object_link_object(dest, NULL); return; @@ -411,7 +1401,7 @@ CoreObject *tcore_sms_new(TcorePlugin *p, const char *name, if (!o) return NULL; - po = calloc(sizeof(struct private_object_data), 1); + po = calloc(1, sizeof(struct private_object_data)); if (!po) { tcore_object_free(o); return NULL; @@ -430,16 +1420,20 @@ CoreObject *tcore_sms_new(TcorePlugin *p, const char *name, void tcore_sms_free(CoreObject *o) { + CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SMS); + tcore_object_free(o); +} + +void tcore_sms_set_ops(CoreObject *o, struct tcore_sms_operations *ops) +{ struct private_object_data *po = NULL; CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SMS); - po = tcore_object_ref_object(o); - if (!po) + po = (struct private_object_data *)tcore_object_ref_object(o); + if (!po) { return; + } - free(po); - tcore_object_free(o); + po->ops = ops; } - - diff --git a/src/co_ss.c b/src/co_ss.c index a3b4a07..cdf77a4 100644 --- a/src/co_ss.c +++ b/src/co_ss.c @@ -64,74 +64,135 @@ static TReturn _dispatcher(CoreObject *o, UserRequest *ur) command = tcore_user_request_get_command(ur); switch (command) { case TREQ_SS_BARRING_ACTIVATE: + if (!po->ops->barring_activate) + return TCORE_RETURN_ENOSYS; + ret = po->ops->barring_activate(o, ur); break; case TREQ_SS_BARRING_DEACTIVATE: + if (!po->ops->barring_deactivate) + return TCORE_RETURN_ENOSYS; + ret = po->ops->barring_deactivate(o, ur); break; case TREQ_SS_BARRING_CHANGE_PASSWORD: + if (!po->ops->barring_change_password) + return TCORE_RETURN_ENOSYS; + ret = po->ops->barring_change_password(o, ur); break; case TREQ_SS_BARRING_GET_STATUS: + if (!po->ops->barring_get_status) + return TCORE_RETURN_ENOSYS; + ret = po->ops->barring_get_status(o, ur); break; case TREQ_SS_FORWARDING_ACTIVATE: + if (!po->ops->forwarding_activate) + return TCORE_RETURN_ENOSYS; + ret = po->ops->forwarding_activate(o, ur); break; case TREQ_SS_FORWARDING_DEACTIVATE: + if (!po->ops->forwarding_deactivate) + return TCORE_RETURN_ENOSYS; + ret = po->ops->forwarding_deactivate(o, ur); break; case TREQ_SS_FORWARDING_REGISTER: + if (!po->ops->forwarding_register) + return TCORE_RETURN_ENOSYS; + ret = po->ops->forwarding_register(o, ur); break; case TREQ_SS_FORWARDING_DEREGISTER: + if (!po->ops->forwarding_deregister) + return TCORE_RETURN_ENOSYS; + ret = po->ops->forwarding_deregister(o, ur); break; case TREQ_SS_FORWARDING_GET_STATUS: + if (!po->ops->forwarding_get_status) + return TCORE_RETURN_ENOSYS; + ret = po->ops->forwarding_get_status(o, ur); break; case TREQ_SS_WAITING_ACTIVATE: + if (!po->ops->waiting_activate) + return TCORE_RETURN_ENOSYS; + ret = po->ops->waiting_activate(o, ur); break; case TREQ_SS_WAITING_DEACTIVATE: + if (!po->ops->waiting_deactivate) + return TCORE_RETURN_ENOSYS; + ret = po->ops->waiting_deactivate(o, ur); break; case TREQ_SS_WAITING_GET_STATUS: + if (!po->ops->waiting_get_status) + return TCORE_RETURN_ENOSYS; + ret = po->ops->waiting_get_status(o, ur); break; case TREQ_SS_CLI_ACTIVATE: + if (!po->ops->cli_activate) + return TCORE_RETURN_ENOSYS; + ret = po->ops->cli_activate(o, ur); break; case TREQ_SS_CLI_DEACTIVATE: + if (!po->ops->cli_deactivate) + return TCORE_RETURN_ENOSYS; + ret = po->ops->cli_deactivate(o, ur); break; + case TREQ_SS_CLI_SET_STATUS: + if (!po->ops->cli_set_status) + return TCORE_RETURN_ENOSYS; + + ret = po->ops->cli_set_status(o, ur); + break; + case TREQ_SS_CLI_GET_STATUS: + if (!po->ops->cli_get_status) + return TCORE_RETURN_ENOSYS; + ret = po->ops->cli_get_status(o, ur); break; case TREQ_SS_SEND_USSD: + if (!po->ops->send_ussd) + return TCORE_RETURN_ENOSYS; + ret = po->ops->send_ussd(o, ur); break; case TREQ_SS_SET_AOC: + if (!po->ops->set_aoc) + return TCORE_RETURN_ENOSYS; + ret = po->ops->set_aoc(o, ur); break; case TREQ_SS_GET_AOC: + if (!po->ops->get_aoc) + return TCORE_RETURN_ENOSYS; + ret = po->ops->get_aoc(o, ur); break; @@ -150,7 +211,7 @@ static void _clone_hook(CoreObject *src, CoreObject *dest) if (!src || !dest) return; - dest_po = calloc(sizeof(struct private_object_data), 1); + dest_po = calloc(1, sizeof(struct private_object_data)); if (!dest_po) { tcore_object_link_object(dest, NULL); return; @@ -280,6 +341,21 @@ int tcore_ss_ussd_get_session_data(struct ussd_session* ussd_s, void **data) } } +void tcore_ss_ussd_set_session_data(struct ussd_session* ussd_s, void *data, int data_len) +{ + if (!ussd_s || !ussd_s->session) { + dbg("[ error ] there is no session"); + return ; + + } + else { + + ussd_s->data = data; + ussd_s->data_len = data_len; + } +} + + CoreObject *tcore_ss_new(TcorePlugin *p, const char *name, struct tcore_ss_operations *ops, TcoreHal *hal) { @@ -293,7 +369,7 @@ CoreObject *tcore_ss_new(TcorePlugin *p, const char *name, if (!o) return NULL; - po = calloc(sizeof(struct private_object_data), 1); + po = calloc(1, sizeof(struct private_object_data)); if (!po) { tcore_object_free(o); return NULL; @@ -318,3 +394,18 @@ void tcore_ss_free(CoreObject *o) tcore_object_free(o); } + +void tcore_ss_set_ops(CoreObject *o, struct tcore_ss_operations *ops) +{ + struct private_object_data *po = NULL; + + CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SS); + + po = (struct private_object_data *)tcore_object_ref_object(o); + if (!po) { + return; + } + + po->ops = ops; +} + diff --git a/src/communicator.c b/src/communicator.c index fe72f62..f2534d2 100644 --- a/src/communicator.c +++ b/src/communicator.c @@ -44,7 +44,7 @@ Communicator* tcore_communicator_new(TcorePlugin *plugin, const char *name, { Communicator *comm; - comm = calloc(sizeof(struct tcore_communicator_type), 1); + comm = calloc(1, sizeof(struct tcore_communicator_type)); if (!comm) return NULL; @@ -123,7 +123,7 @@ TReturn tcore_communicator_send_response(Communicator *comm, UserRequest *ur, if (!comm || !comm->ops || !comm->ops->send_response) return TCORE_RETURN_EINVAL; - dbg("ur = 0x%x", ur); + dbg("ur = 0x%x", (unsigned int)ur); return comm->ops->send_response(comm, ur, command, data_len, data); } diff --git a/src/core_object.c b/src/core_object.c index 52f6bc1..af929cc 100644 --- a/src/core_object.c +++ b/src/core_object.c @@ -25,11 +25,24 @@ #include #include "tcore.h" +#include "server.h" #include "plugin.h" #include "core_object.h" #include "hal.h" #include "at.h" +#include "co_call.h" +#include "co_modem.h" +#include "co_ps.h" +#include "co_network.h" +#include "co_ss.h" +#include "co_sim.h" +#include "co_sat.h" +#include "co_sap.h" +#include "co_sms.h" +#include "co_phonebook.h" +#include "co_gps.h" + struct callback_type { CoreObject *co; char *event; @@ -50,24 +63,69 @@ struct tcore_object_type { CoreObjectCloneHook clone_hook; CoreObjectDispatcher dispatcher; GSList *callbacks; + GHashTable *property; + + TcoreHal *hal; +}; + +/* Mapping Table */ +struct tcore_object_mapping_tbl { TcoreHal *hal; + GSList *object_type; }; -static CoreObject *_object_new(TcorePlugin *plugin, const char *name, unsigned int type) +static void _util_print_mapping_tbl_entry(object_mapping_table_t *tbl_entry) +{ + GSList *co_list; + + msg("------> Table Entry - HAL: [0x%x]", tbl_entry->hal); + + co_list = tbl_entry->object_type; + if (co_list == NULL) { + err("No Core Objects defined for this Mapping Table Entry"); + return; + } + + /* Search all the Table entries with matching 'type' */ + for ( ; co_list ; co_list = co_list->next) { + if (co_list->data == NULL) + continue; + + msg(" Core Object type: [0x%x]", co_list->data); + } +} + +static void _free_tbl_entry(gpointer data) +{ + object_mapping_table_t *tbl_entry; + + if (data == NULL) + return; + + tbl_entry = data; + + dbg("Removing Mapping Table Entry - HAL: [0x%x]", tbl_entry->hal); + _util_print_mapping_tbl_entry(tbl_entry); + + /* Free Core Object types list */ + g_slist_free(tbl_entry->object_type); + + /* Free Table entry */ + g_free(tbl_entry); +} +static CoreObject *_object_new(TcorePlugin *plugin, unsigned int type) { CoreObject *co; - co = calloc(sizeof(struct tcore_object_type), 1); + co = calloc(1, sizeof(struct tcore_object_type)); if (!co) return NULL; co->parent_plugin = plugin; - if (name) - co->name = strdup(name); - co->type = type; + co->property = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); return co; } @@ -91,16 +149,319 @@ static void _remove_at_callback(TcoreAT *at, struct callback_type *cb) tcore_at_remove_notification_full(at, cb->event, _on_at_event, cb); } +static object_mapping_table_t *_object_search_mapping_tbl_entry(GSList *mapping_tbl_list, + TcoreHal *hal) +{ + GSList *list; + object_mapping_table_t *tbl_entry = NULL; + + for (list = mapping_tbl_list; list ; list = list->next) { + tbl_entry = list->data; + if (tbl_entry == NULL) + continue; + + /* Search for Table entry with matching 'hal' */ + if (tbl_entry->hal == hal) { + return tbl_entry; + } + } + + return NULL; +} + +static object_mapping_table_t *_object_search_mapping_tbl_entry_by_type( + GSList *mapping_tbl_list, unsigned int type) +{ + GSList *list; + GSList *co_list; + object_mapping_table_t *tbl_entry = NULL; + + for (list = mapping_tbl_list; list ; list = list->next) { + tbl_entry = list->data; + if (tbl_entry == NULL) + continue; + + /* Search all the Table entries with matching 'type' */ + for (co_list = tbl_entry->object_type ; co_list ; co_list = co_list->next) { + if (co_list->data == NULL) + continue; + + if (type == (unsigned int)co_list->data) { + return tbl_entry; + } + } + } + + return tbl_entry; +} + +static CoreObject *_create_core_object_by_type(guint type, + TcorePlugin *plugin, TcoreHal *hal) +{ + CoreObject *co = NULL; + + switch (type) { + case CORE_OBJECT_TYPE_MODEM: + /* Create Core Object */ + co = tcore_modem_new(plugin, "modem", NULL, hal); + break; + + case CORE_OBJECT_TYPE_CALL: + /* Create Core Object */ + co = tcore_call_new(plugin, "call", NULL, hal); + break; + + case CORE_OBJECT_TYPE_SS: + /* Create Core Object */ + co = tcore_ss_new(plugin, "ss", NULL, hal); + break; + + case CORE_OBJECT_TYPE_NETWORK: + /* Create Core Object */ + co = tcore_network_new(plugin, "network", NULL, hal); + break; + + case CORE_OBJECT_TYPE_PS: + /* Create Core Object */ + co = tcore_ps_new(plugin, "ps", NULL, hal); + break; + + case CORE_OBJECT_TYPE_SIM: + /* Create Core Object */ + co = tcore_sim_new(plugin, "sim", NULL, hal); + break; + + case CORE_OBJECT_TYPE_SAT: + /* Create Core Object */ + co = tcore_sat_new(plugin, "sat", NULL, hal); + break; + + case CORE_OBJECT_TYPE_SAP: + /* Create Core Object */ + co = tcore_sap_new(plugin, "sap", NULL, hal); + break; + + case CORE_OBJECT_TYPE_SMS: + /* Create Core Object */ + co = tcore_sms_new(plugin, "sms", NULL, hal); + break; + + case CORE_OBJECT_TYPE_PHONEBOOK: + /* Create Core Object */ + co = tcore_phonebook_new(plugin, "phonebook", NULL, hal); + break; + + case CORE_OBJECT_TYPE_GPS: + /* Create Core Object */ + co = tcore_gps_new(plugin, "gps", NULL, hal); + break; + + case CORE_OBJECT_TYPE_CUSTOM: /* Fall through */ + default: + err("Unsupport/Invalid Core Object Type [0x%x]", type); + } + + return co; +} + + +static gboolean _init_core_object_by_type(unsigned int type, + TcorePlugin *plugin, struct object_initializer *initializer_list) +{ + gboolean ret = FALSE; + CoreObject *co = tcore_plugin_ref_core_object(plugin, type); + if (co == NULL) { + err("No Core Object of type: [0x%x]", type); + return FALSE; + } + + switch (type) { + case CORE_OBJECT_TYPE_MODEM: { + /* Invoke initializer */ + if (initializer_list->modem_init) + ret = initializer_list->modem_init(plugin, co); + } break; + + case CORE_OBJECT_TYPE_CALL: { + /* Invoke initializer */ + if (initializer_list->call_init) + ret = initializer_list->call_init(plugin, co); + } break; + + case CORE_OBJECT_TYPE_SS: { + /* Invoke initializer */ + if (initializer_list->ss_init) + ret = initializer_list->ss_init(plugin, co); + } break; + + case CORE_OBJECT_TYPE_NETWORK: { + /* Invoke initializer */ + if (initializer_list->network_init) + ret = initializer_list->network_init(plugin, co); + } break; + + case CORE_OBJECT_TYPE_PS: { + /* Invoke initializer */ + if (initializer_list->ps_init) + ret = initializer_list->ps_init(plugin, co); + } break; + + case CORE_OBJECT_TYPE_SIM: { + /* Invoke initializer */ + if (initializer_list->sim_init) + ret = initializer_list->sim_init(plugin, co); + } break; + + case CORE_OBJECT_TYPE_SAT: { + /* Invoke initializer */ + if (initializer_list->sat_init) + ret = initializer_list->sat_init(plugin, co); + } break; + + case CORE_OBJECT_TYPE_SAP: { + /* Invoke initializer */ + if (initializer_list->sap_init) + ret = initializer_list->sap_init(plugin, co); + } break; + + case CORE_OBJECT_TYPE_SMS:{ + /* Invoke initializer */ + if (initializer_list->sms_init) + ret = initializer_list->sms_init(plugin, co); + } break; + + case CORE_OBJECT_TYPE_PHONEBOOK: { + /* Invoke initializer */ + if (initializer_list->phonebook_init) + ret = initializer_list->phonebook_init(plugin, co); + } break; + + case CORE_OBJECT_TYPE_GPS:{ + /* Invoke initializer */ + if (initializer_list->gps_init) + ret = initializer_list->gps_init(plugin, co); + } break; + + case CORE_OBJECT_TYPE_CUSTOM: /* Fall through */ + default: + dbg("Unsupport/Invalid Core Object Type [0x%x]", type); + } + + return ret; +} + + +static void _deinit_core_object_by_type(unsigned int type, + TcorePlugin *plugin, struct object_deinitializer *deinitializer_list) +{ + CoreObject *co; + + co = tcore_plugin_ref_core_object(plugin, type); + if (co == NULL) { + err("No Core Object of type: [0x%x]", type); + return; + } + + switch (type) { + case CORE_OBJECT_TYPE_MODEM: { + if (deinitializer_list->modem_deinit) { + /* Invoke deinitializer */ + deinitializer_list->modem_deinit(plugin, co); + } + } break; + + case CORE_OBJECT_TYPE_CALL: { + if (deinitializer_list->call_deinit) { + /* Invoke deinitializer */ + deinitializer_list->call_deinit(plugin, co); + } + } break; + + case CORE_OBJECT_TYPE_SS: { + if (deinitializer_list->ss_deinit) { + /* Invoke deinitializer */ + deinitializer_list->ss_deinit(plugin, co); + } + } break; + + case CORE_OBJECT_TYPE_NETWORK: { + if (deinitializer_list->network_deinit) { + /* Invoke deinitializer */ + deinitializer_list->network_deinit(plugin, co); + } + } break; + + case CORE_OBJECT_TYPE_PS: { + if (deinitializer_list->ps_deinit) { + /* Invoke deinitializer */ + deinitializer_list->ps_deinit(plugin, co); + } + } break; + + case CORE_OBJECT_TYPE_SIM: { + if (deinitializer_list->sim_deinit) { + /* Invoke deinitializer */ + deinitializer_list->sim_deinit(plugin, co); + } + } break; + + case CORE_OBJECT_TYPE_SAT: { + if (deinitializer_list->sat_deinit) { + /* Invoke deinitializer */ + deinitializer_list->sat_deinit(plugin, co); + } + } break; + + case CORE_OBJECT_TYPE_SAP: { + if (deinitializer_list->sap_deinit) { + /* Invoke deinitializer */ + deinitializer_list->sap_deinit(plugin, co); + } + } break; + + case CORE_OBJECT_TYPE_SMS:{ + if (deinitializer_list->sms_deinit) { + /* Invoke deinitializer */ + deinitializer_list->sms_deinit(plugin, co); + } + } break; + + case CORE_OBJECT_TYPE_PHONEBOOK: { + if (deinitializer_list->phonebook_deinit) { + /* Invoke deinitializer */ + deinitializer_list->phonebook_deinit(plugin, co); + } + } break; + + case CORE_OBJECT_TYPE_GPS:{ + if (deinitializer_list->gps_deinit) { + /* Invoke deinitializer */ + deinitializer_list->gps_deinit(plugin, co); + } + } break; + + case CORE_OBJECT_TYPE_CUSTOM: /* Fall through */ + default: + dbg("Unsupport/Invalid Core Object Type [0x%x]", type); + return; + } + + /* Free Core Object */ + tcore_object_free(co); +} + + CoreObject *tcore_object_new(TcorePlugin *plugin, const char *name, TcoreHal *hal) { CoreObject *co; - co = _object_new(plugin, name, CORE_OBJECT_TYPE_DEFAULT); + co = _object_new(plugin, CORE_OBJECT_TYPE_DEFAULT); if (!co) return NULL; tcore_object_set_hal(co, hal); + tcore_object_set_name(co, name); if (plugin) tcore_plugin_add_core_object(plugin, co); @@ -120,37 +481,46 @@ void tcore_object_free(CoreObject *co) if (co->free_hook) co->free_hook(co); + else { + if (co->object) + warn("free_hook is null, private-object couldn't be freed!!"); + } + + if (co->property) { + g_hash_table_destroy(co->property); + } if (co->callbacks) { for (l = co->callbacks; l; l = l->next) { - if (!l) - continue; - cb = l->data; if (!cb) continue; if (cb->event) - g_free(cb->event); + free(cb->event); - g_free(cb); + free(cb); } g_slist_free(co->callbacks); co->callbacks = NULL; } + if (co->parent_plugin) + tcore_plugin_remove_core_object(co->parent_plugin, co); + if (co->name) - g_free(co->name); + free(co->name); - g_free(co); + memset(co, 0, sizeof(CoreObject)); + free(co); } -CoreObject *tcore_object_clone(CoreObject *src, TcorePlugin *new_parent, const char *new_name) +CoreObject *tcore_object_clone(CoreObject *src, TcorePlugin *new_parent) { CoreObject *dest; TcorePlugin *p; - const char *name; + GSList *l = NULL; struct callback_type *cb = NULL; @@ -162,12 +532,7 @@ CoreObject *tcore_object_clone(CoreObject *src, TcorePlugin *new_parent, const c else p = src->parent_plugin; - if (new_name) - name = new_name; - else - name = src->name; - - dest = _object_new(p, name, src->type); + dest = _object_new(p, src->type); if (!dest) return NULL; @@ -179,9 +544,6 @@ CoreObject *tcore_object_clone(CoreObject *src, TcorePlugin *new_parent, const c dest->hal = src->hal; for (l = src->callbacks; l; l = l->next) { - if (!l) - continue; - cb = l->data; if (!cb) continue; @@ -197,6 +559,19 @@ CoreObject *tcore_object_clone(CoreObject *src, TcorePlugin *new_parent, const c return dest; } +CoreObject *tcore_object_clone_template_object(TcorePlugin *p, + unsigned int co_type) +{ + CoreObject *template_co; + + template_co = tcore_server_find_template_object(tcore_plugin_ref_server(p), co_type); + if(template_co == NULL) + return NULL; + + return tcore_object_clone(template_co, p); + +} + const char *tcore_object_ref_name(CoreObject *co) { if (!co) @@ -302,9 +677,6 @@ TReturn tcore_object_set_hal(CoreObject *co, TcoreHal *hal) if (tcore_hal_get_mode(co->hal) == TCORE_HAL_MODE_AT) { at = tcore_hal_get_at(co->hal); for (l = co->callbacks; l; l = l->next) { - if (!l) - continue; - cb = l->data; if (!cb) continue; @@ -322,9 +694,6 @@ TReturn tcore_object_set_hal(CoreObject *co, TcoreHal *hal) if (tcore_hal_get_mode(hal) == TCORE_HAL_MODE_AT) { at = tcore_hal_get_at(hal); for (l = co->callbacks; l; l = l->next) { - if (!l) - continue; - cb = l->data; if (!cb) continue; @@ -389,6 +758,43 @@ TReturn tcore_object_set_dispatcher(CoreObject *co, return TCORE_RETURN_SUCCESS; } +TReturn tcore_object_override_callback(CoreObject *co, + const char *event, tcore_object_callback callback, void *user_data) +{ + struct callback_type *cb = NULL; + GSList *l = NULL; + TcoreAT *at = NULL; + + if ((co == NULL) || (event == NULL) || (callback == NULL)) + return TCORE_RETURN_EINVAL; + + if (strlen(event) < 1) + return TCORE_RETURN_EINVAL; + + if (co->hal) { + if (tcore_hal_get_mode(co->hal) == TCORE_HAL_MODE_AT) + at = tcore_hal_get_at(co->hal); + } + + for (l = co->callbacks; l; l = l->next) { + cb = l->data; + if (cb == NULL) + continue; + + if (g_strcmp0(cb->event, event) != 0) + continue; + + if (at) + _remove_at_callback(at, cb); + + g_free(cb->event); + co->callbacks = g_slist_remove(co->callbacks, cb); + g_free(cb); + } + + return tcore_object_add_callback(co, event, callback, user_data); +} + TReturn tcore_object_add_callback(CoreObject *co, const char *event, CoreObjectCallback callback, void *user_data) @@ -402,7 +808,7 @@ TReturn tcore_object_add_callback(CoreObject *co, if (strlen(event) < 1) return TCORE_RETURN_EINVAL; - cb = calloc(sizeof(struct callback_type), 1); + cb = calloc(1, sizeof(struct callback_type)); if (!cb) return TCORE_RETURN_ENOMEM; @@ -437,7 +843,7 @@ TReturn tcore_object_del_callback(CoreObject *co, if (!co || !event || !callback || !co->callbacks) return TCORE_RETURN_EINVAL; - if (strlen(event) < 1) + if (strlen(event) == 0) return TCORE_RETURN_EINVAL; if (co->hal) { @@ -445,25 +851,30 @@ TReturn tcore_object_del_callback(CoreObject *co, at = tcore_hal_get_at(co->hal); } - for (l = co->callbacks; l; l = l->next) { - if (!l) - continue; - + l = co->callbacks; + while (l) { cb = l->data; - if (!cb) + if (!cb) { + l = l->next; continue; + } - if (cb->callback != callback) + if (cb->callback != callback) { + l = l->next; continue; + } - if (g_strcmp0(cb->event, event) != 0) + if (g_strcmp0(cb->event, event) != 0) { + l = l->next; continue; + } if (at) _remove_at_callback(at, cb); - free(cb->event); + l = l->next; co->callbacks = g_slist_remove(co->callbacks, cb); + free(cb->event); free(cb); } @@ -507,3 +918,347 @@ TReturn tcore_object_emit_callback(CoreObject *co, return TCORE_RETURN_SUCCESS; } + +static GSList *_set_property_real (CoreObject *co, const char *key, + const char *value, GSList *list) +{ + char *prev; + + if (!co || !key) + return list; + + if (!value) { + g_hash_table_remove (co->property, key); + return g_slist_append (list, (char *)key); + } + + prev = g_hash_table_lookup(co->property, key); + if (prev != NULL) { + /* + * If same data, no change & no callback emit + */ + if (strcmp (prev, value) == 0) + return list; + + g_hash_table_replace(co->property, strdup(key), strdup(value)); + } + else { + g_hash_table_insert(co->property, strdup(key), strdup(value)); + } + + return g_slist_append (list, (char *)key); +} + +TReturn tcore_object_set_property_full(CoreObject *co, const char *first_property, ...) +{ + va_list argptr; + GSList *list = NULL; + const char *k; + const char *v; + + if (!co || !first_property) + return TCORE_RETURN_EINVAL; + + va_start (argptr, first_property); + + k = first_property; + v = va_arg (argptr, char *); + list = _set_property_real (co, k, v, list); + + while (1) { + k = va_arg (argptr, char *); + if (!k) + break; + + v = va_arg (argptr, char *); + list = _set_property_real (co, k, v, list); + } + + va_end (argptr); + + if (!list) + return TCORE_RETURN_SUCCESS; + + if (g_slist_length(list) > 0) + tcore_object_emit_callback (co, + CORE_OBJECT_EVENT_PROPERTY_CHANGED, list); + + g_slist_free (list); + + return TCORE_RETURN_SUCCESS; +} + +const char *tcore_object_ref_property(CoreObject *co, const char *key) +{ + if (!co || !key) + return NULL; + + return g_hash_table_lookup(co->property, key); +} + +GHashTable *tcore_object_ref_property_hash(CoreObject *co) +{ + if (!co) + return NULL; + + return co->property; +} +void *tcore_object_add_mapping_tbl_entry(void *mapping_tbl, + unsigned int object_type, TcoreHal *hal) +{ + GSList *mapping_tbl_list = mapping_tbl; + object_mapping_table_t *tbl_entry; + + if (hal == NULL) { + err("Mapping Table: [0x%x] HAL: [0x%x]", mapping_tbl, hal); + return mapping_tbl; + } + + /* + * Search 'hal' across all the Table entries of the Mapping Table + * + * Table entry MAY NOT be found as - + * 1. Mapping Table is NOT yet created + * 2. Table entry for corresponding 'hal' is NOT present + * + * In each of the above cases, the new Mapping Table entry should be added + * to the Mapping Table. + */ + tbl_entry = _object_search_mapping_tbl_entry(mapping_tbl_list, hal); + if (tbl_entry == NULL) { + dbg("Creating New Table entry for HAL: [0x%x]", hal); + /* + * If there is NO previously added Table entry for the 'hal' then + * new Table entry is created + */ + + tbl_entry = g_try_new0(object_mapping_table_t, 1); + if (tbl_entry != NULL) + tbl_entry->hal = hal; + else { + err("Failed to allocate memory"); + return mapping_tbl_list; + } + + /* Add the Mapping Table entry to Mapping Table */ + mapping_tbl_list = g_slist_append(mapping_tbl_list, tbl_entry); + } + + /* + * Appending the Core Object type to the list of Core Objects types + */ + tbl_entry->object_type = g_slist_append(tbl_entry->object_type, (gpointer)object_type); + dbg("Added Mapping Table entry - HAL: [0x%x] Object type: [0x%x]", hal, object_type); + + return mapping_tbl_list; +} + +void tcore_object_remove_mapping_tbl(void *mapping_tbl) +{ + GSList *mapping_tbl_list = mapping_tbl; + + if (mapping_tbl_list == NULL) { + err("Mapping Table is NULL"); + return; + } + + /* Freeing Mapping Table */ + g_slist_free_full(mapping_tbl_list, _free_tbl_entry); +} + +void *tcore_object_remove_mapping_tbl_entry(void *mapping_tbl, TcoreHal *hal) +{ + GSList *mapping_tbl_list = mapping_tbl; + object_mapping_table_t *tbl_entry; + + if (mapping_tbl_list == NULL) { + err("Mapping Table is NULL"); + return mapping_tbl; + } + + tbl_entry = _object_search_mapping_tbl_entry(mapping_tbl_list, hal); + if (tbl_entry == NULL) { + err("Table entry is NOT available"); + return mapping_tbl_list; + } + + dbg("Removing Mapping Table Entry - HAL: [0x%x]", hal); + _util_print_mapping_tbl_entry(tbl_entry); + + /* Free Core Object types list */ + g_slist_free(tbl_entry->object_type); + + /* Remove mapping Table entry */ + mapping_tbl_list = g_slist_remove(mapping_tbl_list, tbl_entry); + + /* Free Table entry */ + g_free(tbl_entry); + + return mapping_tbl_list; +} + +void tcore_object_remove_mapping_tbl_entry_by_type(void *mapping_tbl, + unsigned int co_type) +{ + GSList *mapping_tbl_list; + object_mapping_table_t *tbl_entry; + + if (mapping_tbl == NULL) { + err("Mapping Table is NULL"); + return; + } + + mapping_tbl_list = mapping_tbl; + + tbl_entry = + _object_search_mapping_tbl_entry_by_type(mapping_tbl_list, co_type); + if (tbl_entry == NULL) { + err("Table entry is NOT available"); + return; + } + + /* Remove the Core Object type from the list */ + tbl_entry->object_type = g_slist_remove(tbl_entry->object_type, (gconstpointer)co_type); +} + +void tcore_object_print_mapping_tbl(void *mapping_tbl) +{ + GSList *mapping_tbl_list; + object_mapping_table_t *tbl_entry = NULL; + + + if (mapping_tbl == NULL) { + err("Mapping Table is NULL"); + return; + } + + mapping_tbl_list = mapping_tbl; + + for ( ; mapping_tbl_list ; mapping_tbl_list = mapping_tbl_list->next) { + tbl_entry = mapping_tbl_list->data; + if (tbl_entry == NULL) + continue; + + _util_print_mapping_tbl_entry(tbl_entry); + } +} + +/* Initialize Core Objects */ +TReturn tcore_object_init_objects(TcorePlugin *plugin, + struct object_initializer *initializer_list) +{ + GSList *mapping_tbl_list; + gboolean ret = FALSE; + + /* Refer mapping_tbl from Server's Modem list */ + mapping_tbl_list = tcore_server_get_cp_mapping_tbl(plugin); + + /* + * Mapping Table is a MUST + * If Mapping Table is NOT NULL, then initialization would be guided by the + * Mapping Table entries, + * else, it is treated as a Failure. + */ + if (mapping_tbl_list != NULL) { + object_mapping_table_t *tbl_entry; + GSList *mtbl_list; + GSList *object_type_list; + unsigned int type; + + /* Create each Core Object based on the Mapping Table entries */ + mtbl_list = mapping_tbl_list; + for ( ; mtbl_list ; mtbl_list = mtbl_list->next) { + tbl_entry = mtbl_list->data; + if (tbl_entry != NULL) { + CoreObject *co; + + object_type_list = tbl_entry->object_type; + for ( ; object_type_list ; object_type_list = object_type_list->next) { + type = (guint)object_type_list->data; + + co = _create_core_object_by_type(type, plugin, tbl_entry->hal); + if (co == NULL) { + err("Failed to create Core Object - Type: [0x%x]", type); + return TCORE_RETURN_FAILURE; + } + dbg("Created Core Object - Type: [0x%x]", type); + } + } + } + + + /* Initialize each Core Object based on the Mapping Table entries */ + mtbl_list = mapping_tbl_list; + for ( ; mtbl_list ; mtbl_list = mtbl_list->next) { + tbl_entry = mtbl_list->data; + if (tbl_entry != NULL) { + /* To handle NULL 'init' function case */ + ret = FALSE; + + object_type_list = tbl_entry->object_type; + + for ( ; object_type_list ; object_type_list = object_type_list->next) { + type = (unsigned int)object_type_list->data; + dbg("Core Object type: [0x%x]", type); + + ret = _init_core_object_by_type(type, plugin, initializer_list); + if (ret == FALSE) { + err("Failed to initialize Core Object Type [0x%x]", type); + return TCORE_RETURN_FAILURE; + } + dbg("Initialized Core Object - Type: [0x%x]", type); + } + } + } + } else { + err("Mapping Table is NOT present"); + } + if (ret == FALSE) { + err("Failed to create/initialize Core Objects"); + return TCORE_RETURN_FAILURE; + } + + dbg("Successfully initialized Core Objects"); + return TCORE_RETURN_SUCCESS; +} + +/* De-initialize Core Objects */ +void tcore_object_deinit_objects(TcorePlugin *plugin, + struct object_deinitializer *deinitializer_list) +{ + GSList *mapping_tbl_list; + + /* Refer mapping_tbl from Server's Modem list */ + mapping_tbl_list = tcore_server_get_cp_mapping_tbl(plugin); + + /* + * Mapping Table is a MUST + * If Mapping Table is NOT NULL, then de-initialization would be guided by the + * Mapping Table entries, + * else, + * just return with an Error log. + */ + if (mapping_tbl_list != NULL) { + object_mapping_table_t *tbl_entry; + GSList *object_type_list; + unsigned int type; + + /* De-initialize each Core Object based on the Mapping Table entries */ + for ( ; mapping_tbl_list ; mapping_tbl_list = mapping_tbl_list->next) { + tbl_entry = mapping_tbl_list->data; + if (tbl_entry == NULL) + continue; + + object_type_list = tbl_entry->object_type; + + for ( ; object_type_list ; object_type_list = object_type_list->next) { + type = (unsigned int)object_type_list->data; + dbg("Core Object type: [0x%x]", type); + + _deinit_core_object_by_type(type, plugin, deinitializer_list); + } + } + dbg("Successfully de-initialized Core Objects"); + } else + err("Mapping Table is NOT present"); +} diff --git a/src/hal.c b/src/hal.c old mode 100755 new mode 100644 index 9e7be96..75993e1 --- a/src/hal.c +++ b/src/hal.c @@ -73,21 +73,22 @@ static gboolean _hal_idle_send(void *user_data) void *data = NULL; unsigned int data_len = 0; gboolean renew = FALSE; - if (!h) return FALSE; - +#ifdef TCORE_HAL_DEBUG msg("--[Queue SEND]-------------------"); - +#endif p = tcore_queue_ref_next_pending(h->queue); if (!p) { +#ifdef TCORE_HAL_DEBUG dbg("next pending is NULL. no send, queue len=%d", tcore_queue_get_length(h->queue)); +#endif goto out; } data = tcore_pending_ref_request_data(p, &data_len); - dbg("queue len=%d, pending=0x%x, id=0x%x, data_len=%d", - tcore_queue_get_length(h->queue), (unsigned int)p, tcore_pending_get_id(p), data_len); + dbg("queue(%p) len=%d, pending(%p) id=0x%x data_len=%d", + h->queue, tcore_queue_get_length(h->queue), p, tcore_pending_get_id(p), data_len); if (h->mode == TCORE_HAL_MODE_AT) { ret = tcore_at_set_request(h->at, data, TRUE); @@ -98,6 +99,7 @@ static gboolean _hal_idle_send(void *user_data) if (ret == TCORE_RETURN_SUCCESS) { tcore_pending_emit_send_callback(p, TRUE); + tcore_pending_start_timer(p); } else { tcore_pending_emit_send_callback(p, FALSE); @@ -122,9 +124,10 @@ static gboolean _hal_idle_send(void *user_data) } } } - out: +#ifdef TCORE_HAL_DEBUG msg("--[Queue SEND FINISH]------------\n"); +#endif return renew; } @@ -137,7 +140,7 @@ TcoreHal *tcore_hal_new(TcorePlugin *plugin, const char *name, if (!name) return NULL; - h = calloc(sizeof(struct tcore_hal_type), 1); + h = calloc(1, sizeof(struct tcore_hal_type)); if (!h) return NULL; @@ -153,6 +156,8 @@ TcoreHal *tcore_hal_new(TcorePlugin *plugin, const char *name, if (plugin) tcore_server_add_hal(tcore_plugin_ref_server(plugin), h); + dbg("HAL [%s] <==> Queue [%p]", h->name, h->queue); + return h; } @@ -163,6 +168,10 @@ void tcore_hal_free(TcoreHal *hal) dbg("hal=%s", hal->name); + /* Remove HAL from Server */ + if (hal->parent_plugin) + tcore_server_remove_hal(tcore_plugin_ref_server(hal->parent_plugin), hal); + if (hal->name) free(hal->name); @@ -225,7 +234,7 @@ TReturn tcore_hal_set_mode(TcoreHal *hal, enum tcore_hal_mode mode) { if (!hal) return TCORE_RETURN_EINVAL; - + hal->mode = mode; return TCORE_RETURN_SUCCESS; @@ -275,14 +284,20 @@ TReturn tcore_hal_send_data(TcoreHal *hal, unsigned int data_len, void *data) /* Send data by Queue */ TReturn tcore_hal_send_request(TcoreHal *hal, TcorePending *pending) { - int qlen = 0; + int ret = 0; enum tcore_pending_priority priority; if (!hal || !pending) return TCORE_RETURN_EINVAL; - qlen = tcore_queue_get_length(hal->queue); - tcore_queue_push(hal->queue, pending); + if (hal->power_state == FALSE) + return TCORE_RETURN_FAILURE; + + ret = tcore_queue_push(hal->queue, pending); + if( ret != TCORE_RETURN_SUCCESS ) { + dbg("Pushing pending fails : return [ %d ]", ret); + return ret; + } tcore_pending_get_priority(pending, &priority); if (priority == TCORE_PENDING_PRIORITY_IMMEDIATELY) { @@ -290,7 +305,7 @@ TReturn tcore_hal_send_request(TcoreHal *hal, TcorePending *pending) _hal_idle_send(hal); } else { - if (tcore_queue_get_length(hal->queue) == 1) { + if (tcore_queue_get_normal_length(hal->queue) <= 1) { g_idle_add_full(IDLE_SEND_PRIORITY, _hal_idle_send, hal, NULL); } } @@ -308,6 +323,50 @@ TReturn tcore_hal_send_force(TcoreHal *hal) return TCORE_RETURN_SUCCESS; } +TReturn tcore_hal_free_timeout_pending_request(TcoreHal *hal, TcorePending *p, + unsigned int data_len, const void *data) +{ + if (!hal) + return TCORE_RETURN_EINVAL; + + if (data_len > 0 && data == NULL) + return TCORE_RETURN_EINVAL; + + if (hal->mode == TCORE_HAL_MODE_AT) { + dbg("TCORE_HAL_MODE_AT"); + tcore_free_pending_timeout_at_request(hal->at); + p = tcore_queue_pop_by_pending(hal->queue, p); + if (!p) { + dbg("no pending"); + } + tcore_user_request_free(tcore_pending_ref_user_request(p)); + tcore_pending_free(p); + } + else { + if(hal->mode == TCORE_HAL_MODE_CUSTOM) { + dbg("TCORE_HAL_MODE_CUSTOM"); + p = tcore_queue_pop_by_pending(hal->queue, p); + if (!p) { + dbg("no pending"); + } + tcore_user_request_free(tcore_pending_ref_user_request(p)); + tcore_pending_free(p); + } + else if(hal->mode == TCORE_HAL_MODE_TRANSPARENT) { + dbg("TCORE_HAL_MODE_TRANSPARENT"); + + /* TODO : Need to free resources */ + + /* Invoke CMUX receive API for decoding */ + tcore_cmux_rcv_from_hal(hal, (unsigned char *)data, data_len); + } + } + /* Send next request in queue */ + g_idle_add_full(IDLE_SEND_PRIORITY, _hal_idle_send, hal, NULL ); + + return TCORE_RETURN_SUCCESS; +} + TReturn tcore_hal_dispatch_response_data(TcoreHal *hal, int id, unsigned int data_len, const void *data) { @@ -321,6 +380,9 @@ TReturn tcore_hal_dispatch_response_data(TcoreHal *hal, int id, if (hal->mode == TCORE_HAL_MODE_AT) { gboolean ret; +#ifdef TCORE_HAL_DEBUG + dbg("TCORE_HAL_MODE_AT"); +#endif ret = tcore_at_process(hal->at, data_len, data); if (ret) { /* Send next request in queue */ @@ -342,9 +404,9 @@ TReturn tcore_hal_dispatch_response_data(TcoreHal *hal, int id, } else if(hal->mode == TCORE_HAL_MODE_TRANSPARENT) { dbg("TCORE_HAL_MODE_TRANSPARENT"); - + /* Invoke CMUX receive API for decoding */ - tcore_cmux_rcv_from_hal((unsigned char *)data, data_len); + tcore_cmux_rcv_from_hal(hal, (unsigned char *)data, data_len); } /* Send next request in queue */ g_idle_add_full(IDLE_SEND_PRIORITY, _hal_idle_send, hal, NULL ); @@ -361,7 +423,7 @@ TReturn tcore_hal_add_recv_callback(TcoreHal *hal, TcoreHalReceiveCallback func, if (!hal) return TCORE_RETURN_EINVAL; - item = calloc(sizeof(struct recv_callback_item_type), 1); + item = calloc(1, sizeof(struct recv_callback_item_type)); if (!item) return TCORE_RETURN_ENOMEM; @@ -390,6 +452,9 @@ TReturn tcore_hal_remove_recv_callback(TcoreHal *hal, TcoreHalReceiveCallback fu if (item->func == func) { hal->callbacks = g_slist_remove(hal->callbacks, item); free(item); + if (!hal->callbacks) + break; + list = hal->callbacks; } } @@ -425,7 +490,7 @@ TReturn tcore_hal_add_send_hook(TcoreHal *hal, TcoreHalSendHook func, void *user if (!hal || !func) return TCORE_RETURN_EINVAL; - hook = calloc(sizeof(struct hook_send_type), 1); + hook = calloc(1, sizeof(struct hook_send_type)); if (!hook) return TCORE_RETURN_ENOMEM; @@ -502,3 +567,13 @@ TReturn tcore_hal_set_power(TcoreHal *hal, gboolean flag) return hal->ops->power(hal, flag); } +TReturn tcore_hal_setup_netif(TcoreHal *hal, CoreObject *co, + TcoreHalSetupNetifCallback func, + void *user_data, unsigned int cid, + gboolean enable) +{ + if ((hal == NULL) || (hal->ops == NULL) || (hal->ops->setup_netif == NULL)) + return TCORE_RETURN_EINVAL; + + return hal->ops->setup_netif(co, func, user_data, cid, enable); +} diff --git a/src/mux.c b/src/mux.c index d69b972..d75b88e 100644 --- a/src/mux.c +++ b/src/mux.c @@ -22,89 +22,87 @@ #include #include +#include + #include #include "tcore.h" #include "hal.h" +#include "core_object.h" #include "plugin.h" #include "user_request.h" #include "server.h" +#include "at.h" #include "mux.h" -#include "core_object.h" -/* Maximum Core objects per Logical HAL (indirectly per Channel) */ -#define MAX_CMUX_CORE_OBJECTS 3 +/* Channel name maximum length */ +#define CMUX_MAX_CHANNEL_NAME 16 -/* Max CMUX Buffer size */ -#define MAX_CMUX_BUFFER_SIZE 4096 +/* CMUX Commands */ +#define CMUX_COMMAND_SABM 0x2F +#define CMUX_COMMAND_UA 0x63 +#define CMUX_COMMAND_DM 0x0F +#define CMUX_COMMAND_DISC 0x43 +#define CMUX_COMMAND_UIH 0xEF +#define CMUX_COMMAND_UI 0x03 -/* Max muber of CMUX Channels */ -#define MAX_CMUX_CHANNELS_SUPPORTED 8 +/* CMUX Delimiter Byte */ +#define CMUX_FRAME_DELIMITER 0xF9 -/* CMUX Commands */ -#define CMUX_COMMAND_SABM 0x2F -#define CMUX_COMMAND_UA 0x63 -#define CMUX_COMMAND_DM 0x0F -#define CMUX_COMMAND_DISC 0x43 -#define CMUX_COMMAND_UIH 0xEF -#define CMUX_COMMAND_UI 0x03 - -/* MUX CONTROL COMMANDS - * We are supporting only MSC command for phase 1 - */ -#define CMUX_COMMAND_MSC 0xE3 // Modem Status Command -#define CMUX_COMMAND_CLD 0xC3 // Multiplexer close down - -/* CMUX Channels [0-7] - - * Channel 0 - Control Channel for CMUX - * Channel 1 - CALL - * Channel 2 - SIM - * Channel 3 - SAT - * Channel 4 - SMS - * Channel 5 - SS - * Channel 6 - NETWORK - * Channel 7 - MODEM & PS - */ -typedef enum CMUX_Channels { - CMUX_CHANNEL_0, - CMUX_CHANNEL_1, - CMUX_CHANNEL_2, - CMUX_CHANNEL_3, - CMUX_CHANNEL_4, - CMUX_CHANNEL_5, - CMUX_CHANNEL_6, - CMUX_CHANNEL_7 -} CMUX_Channels; - -/* MUX Channel States */ -typedef enum MuxChannelState { - MUX_CHANNEL_CLOSED, - MUX_CHANNEL_SABM_SEND_WAITING_FOR_UA, - MUX_CHANNEL_ESTABLISHED, - MUX_CHANNEL_UA_NOT_RECEIVED_RETRY, - MUX_CHANNEL_DM_RECEIVED_CLOSING, - MUX_CHANNEL_DM_SEND, - MUX_CHANNEL_DISC_RECEIVED_CLOSING, - MUX_CHANNEL_DISC_SEND_WAITING_FOR_UA, - MUX_CHANNEL_UA_SEND_CLOSING, - MUX_CHANNEL_UA_RECEIVED, - MUX_CHANNEL_UA_SENDING, -} MuxChannelState; - -/* MUX State */ -typedef enum MuxState { - MUX_NOT_INITIALIZED, - MUX_INITIALIZED, - MUX_CLOSED -} MuxState; +/* + * CMUX Channels [0-64] - + * + * CMUX_CHANNEL_0 is dedicated CMUX Control Channnel. + */ +typedef enum { + CMUX_CHANNEL_NONE = -1, /* No CMUX */ + CMUX_CHANNEL_0 = 0, /* CMUX Control Channel */ + + CMUX_CHANNEL_MAX = 65 /* Based on #GPP 27.010 */ +} tcore_cmux_channel_id; + +/* + * CMUX Channel States + * + * Only Internal CMUX Channel states are managed, + * Kernel CMUX Channel states are managed by Kernel directly. + */ +typedef enum { + CMUX_CHANNEL_CLOSED, + CMUX_CHANNEL_SABM_SEND_WAITING_FOR_UA, + CMUX_CHANNEL_ESTABLISHED, + CMUX_CHANNEL_UA_NOT_RECEIVED_RETRY, + CMUX_CHANNEL_DM_RECEIVED_CLOSING, + CMUX_CHANNEL_DM_SEND, + CMUX_CHANNEL_DISC_RECEIVED_CLOSING, + CMUX_CHANNEL_DISC_SEND_WAITING_FOR_UA, + CMUX_CHANNEL_UA_SEND_CLOSING, + CMUX_CHANNEL_UA_RECEIVED, + CMUX_CHANNEL_UA_SENDING, +} tcore_cmux_channel_state; + +/* CMUX State */ +typedef enum { + CMUX_NOT_INITIALIZED, + CMUX_INITIALIZED, + CMUX_CLOSED +} tcore_cmux_state; + +/* + * CMUX CONTROL COMMANDS + * We are supporting only MSC and CLD commands for phase 1 + */ +/* Modem Status Command */ +#define CMUX_COMMAND_MSC 0xE3 +/* Multiplexer close down */ +#define CMUX_COMMAND_CLD 0xC3 #define FIND_LENGTH(buf, header_length, total_length) do { \ if (*buf & 0x01) { \ total_length = *buf++ >> 1; \ header_length = 6; \ - } \ - else { \ + } else { \ total_length = *(buf + 0x01) << 7; \ total_length = total_length | (*buf & 0xFE) >> 1; \ header_length = 7; \ @@ -112,837 +110,1085 @@ typedef enum MuxState { } while (0) /*================= CRC TABLE=========================*/ -const unsigned char crc_table[256] = { // reversed, 8-bit, poly=0x07 - 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, - 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, - 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, - 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, - 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, - 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, - 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, - 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, - 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, - 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, - 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, - 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, - 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, - 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, - 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, - 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF +const unsigned char crc_table[256] = { /* reversed, 8-bit, poly=0x07 */ + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, + 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, + 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, + 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, + 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, + 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, + 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, + 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, + 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, + 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, + 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, + 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, + 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, + 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, + 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, + 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, + 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF }; /*================= CRC TABLE=========================*/ /* CMUX Channel */ -typedef struct cmux_channel { - GSList *co; +struct cmux_channel { TcoreHal *hal; - MuxChannelState state; - CMUX_Channels channel_id; + + tcore_cmux_channel_state channel_state; + tcore_cmux_channel_id channel_id; + int frame_type; unsigned char ext_bit; unsigned char cr_bit; unsigned char poll_final_bit; -} CHANNEL; +}; -/* CMUX callback prototype */ -typedef gboolean (*mux_cb_func)(CHANNEL *channel_ptr); +/* CMUX structure - Internal */ +struct cmux_internal { + tcore_cmux_channel *channel_info[CMUX_CHANNEL_MAX]; -/* CMUX structure */ -typedef struct cmux { - MuxState state; - CHANNEL *channel_info[MAX_CMUX_CHANNELS_SUPPORTED]; int is_waiting; + int msg_len; int cur_main_buf_len; - TcorePlugin *plugin; - TcoreHal *phy_hal; - CoreObject *modem_co; - mux_cb_func cb_func; - int info_field_len; - unsigned char *info_field; -} MUX; - -/* Global pointer MUX Object pointer */ -MUX *g_mux_obj_ptr = NULL; -/* CMUX mode of operation */ -int g_mux_mode = 0; /* BASIC mode */ + /* Channel Setup callbacks */ + cmux_setup_cb_func channel_setup_cb; + gpointer channel_setup_user_data; -struct cmux_channel_object { - char *channel_id_name; - char *core_object_name[MAX_CMUX_CORE_OBJECTS]; -}; + /* Channel Setup complete callback */ + cmux_setup_complete_cb_func setup_complete_cb; + gpointer setup_complete_user_data; -/* Core Object names need to be verified, define a MACRO globally */ -struct cmux_channel_object cmux_channel_core_object[] = { - {"channel_0", {"control", NULL, NULL}}, - {"channel_1", {"call", NULL, NULL}}, - {"channel_2", {"sim", NULL, NULL}}, - {"channel_3", {"sat", NULL, NULL}}, - {"channel_4", {"umts_sms", NULL, NULL}}, - {"channel_5", {"ss", NULL, NULL}}, - {"channel_6", {"umts_network", NULL, NULL}}, - {"channel_7", {"modem", "umts_ps", NULL}}, + int info_field_len; + unsigned char *info_field; }; -/* All the local functions declared below */ -static unsigned char calc_crc(unsigned char *header, int length); -static int rcv_crc_check(unsigned char *data, unsigned char len, unsigned char rcv_FCS); -MUX* tcore_cmux_new(void); -static void tcore_cmux_free(void); -void tcore_cmux_link_core_object_hal(CMUX_Channels channel_id, TcorePlugin *plugin); -static gboolean tcore_cmux_recv_mux_data(CHANNEL *channel_ptr); -static void tcore_cmux_process_rcv_frame(unsigned char *data, int len); -static void tcore_cmux_process_channel_data(CHANNEL *channel_info_ptr); -static void tcore_cmux_control_channel_handle(void); -static void tcore_cmux_flush_channel_data(void); -static void tcore_cmux_channel_init(CMUX_Channels channel_id); -static void tcore_cmux_close_channel(int channel_id); -static unsigned char* tcore_encode_cmux_frame(unsigned char *data, int length, int channel_id, int frame_type, unsigned char EA_bit, unsigned char CR_bit, unsigned char PF_bit, int *out_data_len); -static TReturn tcore_cmux_send_data(int data_len, unsigned char *data); - -static TReturn tcore_cmux_hal_power(TcoreHal *h, gboolean flag) -{ - TcorePlugin *p = NULL; - struct custom_data *user_data = NULL; - - dbg("Entry"); - - p = tcore_hal_ref_plugin(h); - if (!p) { - err("Plugin is undefined"); - return TCORE_RETURN_FAILURE; - } - - user_data = tcore_hal_ref_user_data(h); - if (!user_data) { - err("User data is undefined"); - return TCORE_RETURN_FAILURE; - } +/* Global CMUX Object */ +struct cmux_obj { + /* Physical HAL */ + TcoreHal *phy_hal; - tcore_hal_set_power_state(h, TRUE); + /* Modem Interface Plug-in */ + TcorePlugin *plugin; - dbg("Exit"); - return TCORE_RETURN_SUCCESS; -} + tcore_cmux_state cmux_state; -static TReturn tcore_cmux_hal_send(TcoreHal *h, unsigned int data_len, void *data) -{ - unsigned char *send_data = NULL; - char *channel_name = NULL; - int channel_id = MAX_CMUX_CHANNELS_SUPPORTED; - int len = 0; - int i = 0; - int ret; + tcore_cmux_mode cmux_mode; + int max_cmux_channels; + unsigned int max_cmux_buf_size; - dbg("Entry"); + /* CMUX frame processing buffer */ + unsigned char *cmux_buffer; - /* Check if Logical HAL is Powered ON */ - if (tcore_hal_get_power_state(h) == FALSE) { - err("HAL is not Powered UP"); - return TCORE_RETURN_FAILURE; - } + /* Only Internal MUX is managed by libtcore */ + struct cmux_internal internal_mux; +}; - channel_name = tcore_hal_get_name(h); - dbg("HAL name: %s", channel_name) - if (channel_name) { - while (i < MAX_CMUX_CHANNELS_SUPPORTED) { - if (0 == strcmp((char *) cmux_channel_core_object[i].channel_id_name, (char *) channel_name)) { - channel_id = i; - dbg("Found Channel ID: %d", channel_id); +/* CMUX Object */ +static GSList *g_cmux_obj = NULL; - /* Free memory */ - free(channel_name); - break; - } - i++; - } - } else { - err("No name defined for HAL"); - return TCORE_RETURN_FAILURE; - } +/* All the local functions declared below */ +static void _cmux_on_confirmation_message_send(TcorePending *plugin, + gboolean result, void *user_data); - if (channel_id > MAX_CMUX_CHANNELS_SUPPORTED) { - err("Failed to find Channel ID"); - return TCORE_RETURN_FAILURE; - } +tcore_cmux_object *_cmux_new(int max_channels, unsigned int buffer_size); +static void _cmux_free(tcore_cmux_object *cmux_obj); - /* Muxing operation and Frame creation */ - /* Encoding frame */ - send_data = tcore_encode_cmux_frame(data, data_len, channel_id, CMUX_COMMAND_UIH, 1, 1, 0, &len); - if (0 == len) { - err("Failed to encode"); - return TCORE_RETURN_FAILURE; - } +static void _cmux_channel_init(tcore_cmux_object *cmux_obj, int channel_id); +static void _cmux_close_channel(tcore_cmux_object *cmux_obj, int channel_id); - /* Send CMUX data */ - ret = tcore_cmux_send_data(len, send_data); +static TcoreHal *_cmux_create_logical_hal(tcore_cmux_object *cmux_obj, + tcore_cmux_channel *channel); - dbg("Exit"); - return TCORE_RETURN_SUCCESS; -} +static gboolean _cmux_recv_cmux_data(tcore_cmux_object *cmux_obj, + tcore_cmux_channel *channel); +static void _cmux_process_rcv_frame(tcore_cmux_object *cmux_obj, int length); +static void _cmux_process_channel_data(tcore_cmux_object *cmux_obj, + tcore_cmux_channel *channel); -/* CMUX supported HAL (Logical HAL) operations */ -static struct tcore_hal_operations mux_hops = { - .power = tcore_cmux_hal_power, - .send = tcore_cmux_hal_send, -}; +static void _cmux_control_channel_handle(tcore_cmux_object *cmux_obj); +static void _cmux_flush_channel_data(tcore_cmux_object *cmux_obj); -static TReturn tcore_cmux_send_data(int data_len, unsigned char *data) -{ - TReturn ret = TCORE_RETURN_SUCCESS; +static TReturn _cmux_send_data(TcoreHal *hal, int data_len, unsigned char *data); +static unsigned char *_cmux_encode_cmux_frame(tcore_cmux_object *cmux_obj, + unsigned char *data, unsigned int length, int channel_id, + int frame_type, unsigned char EA_bit, unsigned char CR_bit, + unsigned char PF_bit, int *out_data_len); - dbg("Entry"); +static tcore_cmux_object *_cmux_get_cmux_object(TcorePlugin *plugin); - /* Directly send to Physical HAL */ - ret = tcore_hal_send_data(g_mux_obj_ptr->phy_hal, data_len, (void *) data); - if (TCORE_RETURN_SUCCESS != ret) { - err("Failed to send CMUX data"); - } else { - dbg("Successfully sent CMUX data"); - } +static unsigned char _cmux_calc_crc(unsigned char *header, int length); +static int _cmux_check_recv_crc(unsigned char *data, + unsigned char length, + unsigned char rcv_fcs); - dbg("Exit"); - return ret; -} -static gboolean tcore_cmux_recv_mux_data(CHANNEL *channel_ptr) +static unsigned char _cmux_calc_crc(unsigned char *header, int length) { - TcoreHal *hal = NULL; - - dbg("Entry"); + unsigned char fcs = 0xFF; /* Init */ + unsigned char crc = 0x00; - /* Dereferencing HAL from Channel Pointer */ - hal = channel_ptr->hal; + /* + * 'length' is the number of bytes in the message, + * 'header' points to message + */ + while (length--) + fcs = crc_table[fcs ^ *header++]; - dbg("Dispatching to logical HAL - hal: %x", hal); - tcore_hal_dispatch_response_data(hal, 0, g_mux_obj_ptr->info_field_len, g_mux_obj_ptr->info_field); + /* Ones complement */ + crc = (0xFF - fcs); - dbg("Exit"); - return TRUE; + dbg("Exit - CRC: [0x%02x]", crc); + return crc; } -void tcore_cmux_link_core_object_hal(CMUX_Channels channel_id, TcorePlugin *plugin) +static int _cmux_check_recv_crc(unsigned char *data, + unsigned char length, + unsigned char rcv_fcs) { - TcoreHal *hal = NULL; - CoreObject *co = NULL; - int index; - - dbg("Entry"); + unsigned char fcs = 0xFF; /* Init */ - if (CMUX_CHANNEL_0 != channel_id) { - dbg("Normal channel [%d]", channel_id); + /* + * 'length' is the number of bytes in the message, + * 'data' points to message + */ + while (length--) + fcs = crc_table[fcs ^ *data++]; - /* Creating Logical HAL for Core Object - Mode - 'AT mode' */ - hal = tcore_hal_new(plugin, cmux_channel_core_object[channel_id].channel_id_name, &mux_hops, TCORE_HAL_MODE_AT); - dbg("hal: %p", hal); - - /* Update Logical HAL of CMUX Channel */ - g_mux_obj_ptr->channel_info[channel_id]->hal = hal; - - index = 0; - while (NULL != cmux_channel_core_object[channel_id].core_object_name[index]) { - /* Retrieving Core Object */ - dbg("Core Object: '%s'", cmux_channel_core_object[channel_id].core_object_name[index]); - co = tcore_plugin_ref_core_object(plugin, cmux_channel_core_object[channel_id].core_object_name[index]); - dbg("co: %p", co); - - if (0 == strcmp((const char *) cmux_channel_core_object[channel_id].core_object_name[index], "modem")) { - g_mux_obj_ptr->modem_co = co; - dbg("'modem' Core object reference is stored"); - } + /* Ones complement */ + fcs = crc_table[fcs ^ rcv_fcs]; - /* Set Logical HAL to Core objects */ - tcore_object_set_hal(co, hal); - - /* Update Core Object list of CMUX Channel */ - g_mux_obj_ptr->channel_info[channel_id]->co = g_slist_append(g_mux_obj_ptr->channel_info[channel_id]->co, co); - - /* Next Core Object of the channel */ - index++; - } - } else { - /* Control Channel */ - dbg("Control channel"); - - /* Creating Logical HAL for Core Object - Mode - 'AT mode' */ - hal = tcore_hal_new(plugin, cmux_channel_core_object[channel_id].channel_id_name, &mux_hops, TCORE_HAL_MODE_AT); - dbg("hal: %p", hal); - - /* Update Logical HAL of CMUX Channel */ - g_mux_obj_ptr->channel_info[channel_id]->hal = hal; - } - - /* Set Logical HAL Power State to TRUE */ - tcore_hal_set_power_state(hal, TRUE); - dbg("HAL Power is SET"); - - dbg("Exit"); - return; + /* 0xCF is the reversed order of 11110011 */ + if (fcs == 0xCF) /* FCS is OK */ + return 1; + else /* FCS is NOT OK */ + return 0; } -MUX* tcore_cmux_new(void) +static tcore_cmux_object *_cmux_get_cmux_object(TcorePlugin *plugin) { - MUX *mux = NULL; - int i = 0; - - /* Allocating memory for mux */ - mux = (MUX *) calloc(sizeof(MUX), 1); - if (!mux) { - err("Failed to allocate memory"); - return NULL; - } - - /* Allocating memory for info_field */ - mux->info_field = (unsigned char *) calloc(MAX_CMUX_BUFFER_SIZE, 1); - if (!mux->info_field) { - err("Failed to allocate memory for info field"); - goto ERROR; - } - - /* MUX State initialize to MUX_NOT_INITIALIZED */ - mux->state = MUX_NOT_INITIALIZED; - - /* Allocating memory for channel_info */ - for (i = 0; i < MAX_CMUX_CHANNELS_SUPPORTED; i++) { - mux->channel_info[i] = (CHANNEL *) calloc(sizeof(CHANNEL), 1); - /* Check for Memory allocation failure */ - if (!mux->channel_info[i]) { - err("Failed to allocate memory for channel_info of channel: %d", i); - goto ERROR; - } - } - - return mux; + tcore_cmux_object *cmux_obj; + GSList *tmp_obj; + dbg("Entry"); -ERROR: - /* Free allocated memory */ - if (mux) { - if (mux->info_field) { - free(mux->info_field); - } + /* Check across CMUX Objects list for specific CMUX Object */ + for (tmp_obj = g_cmux_obj ; tmp_obj ; tmp_obj = tmp_obj->next) { + cmux_obj = tmp_obj->data; + if (cmux_obj == NULL) + continue; - for (i = 0; i < MAX_CMUX_CHANNELS_SUPPORTED; i++) { - if (mux->channel_info[i]) { - free(mux->channel_info[i]); - } + /* Check for matching 'plugin' */ + if (plugin == cmux_obj->plugin) { + dbg("Found CMUX object"); + return cmux_obj; } - - free(mux); } - err("Exit"); return NULL; } -static unsigned char calc_crc(unsigned char *header, int length) -{ - unsigned char FCS = 0xFF; /*Init*/ - unsigned char crc = 0x00; - - /* 'length' is the number of bytes in the message, 'header' points to message */ - while (length--) { - FCS = crc_table[FCS ^ *header++]; - } - - /*Ones complement*/ - crc = (0xFF - FCS); - - dbg("Exit - crc: 0x%02x", crc) - return crc; -} - -static unsigned char* tcore_encode_cmux_frame(unsigned char *data, - int length, - int channel_id, - int frame_type, - unsigned char EA_bit, - unsigned char CR_bit, - unsigned char PF_bit, - int *out_data_len) +static unsigned char *_cmux_encode_cmux_frame(tcore_cmux_object *cmux_obj, + unsigned char *data, unsigned int length, int channel_id, + int frame_type, unsigned char EA_bit, unsigned char CR_bit, + unsigned char PF_bit, int *out_data_len) { int frame_length = 0; int total_frame_length = 0; int crc_len = 0; - dbg("Entry"); /* Flush channel data */ - tcore_cmux_flush_channel_data(); + _cmux_flush_channel_data(cmux_obj); - if (length > MAX_CMUX_BUFFER_SIZE) { + if (length > cmux_obj->max_cmux_buf_size) { err("Length - %d exceeds the limit", length); return NULL; } /* Flag Octet */ - g_mux_obj_ptr->info_field[frame_length++] = (char) 0xF9; + cmux_obj->internal_mux.info_field[frame_length++] = CMUX_FRAME_DELIMITER; /* Mode of Operation */ - if (0x00 == g_mux_mode) { /* BASIC */ - /* EA: Extension Bit - * C/R: Command Response - */ - g_mux_obj_ptr->info_field[frame_length] = g_mux_obj_ptr->info_field[frame_length] | ((EA_bit & 0x01) | ((CR_bit << 1) & 0x02)); + if (cmux_obj->cmux_mode == CMUX_MODE_BASIC) { /* BASIC */ + /* + * EA: Extension Bit + * C/R: Command Response + */ + cmux_obj->internal_mux.info_field[frame_length] = + (cmux_obj->internal_mux.info_field[frame_length] + | ((EA_bit & 0x01) | ((CR_bit << 1) & 0x02))); /* DLCI: Data Link Connection Identifier */ /* Check if the channel is within range */ - if (channel_id < MAX_CMUX_CHANNELS_SUPPORTED && channel_id >= 0) { - dbg("Channel ID: %d", channel_id); - g_mux_obj_ptr->info_field[frame_length] = g_mux_obj_ptr->info_field[frame_length] | ((unsigned char) channel_id << 2); + if (channel_id < cmux_obj->max_cmux_channels && channel_id >= 0) { + dbg("Channel ID: [%d]", channel_id); + cmux_obj->internal_mux.info_field[frame_length] = + (cmux_obj->internal_mux.info_field[frame_length] + | ((unsigned char)channel_id << 2)); } else { - err("Channel is out of range[0-8]"); + err("Channel ID [%d] is out of range [0-%d]", + channel_id, cmux_obj->max_cmux_channels); return NULL; } frame_length++; - /* Control Field - * The content of the control field defines the type of frame. - * **************************************************************** - * Frame Type 0 1 2 3 4 5 6 7 - * SABM (Set Asynchronous Balanced Mode) 1 1 1 1 P/F 1 0 0 - * UA (Unnumbered Acknowledgement) 1 1 0 0 P/F 1 1 0 - * DM (Disconnected Mode) 1 1 1 1 P/F 0 0 0 - * DISC (Disconnect) 1 1 0 0 P/F 0 1 0 - * UIH (Unnumbered Information with Header check) 1 1 1 1 P/F 1 1 1 - *****************************************************************/ - if (PF_bit) { - g_mux_obj_ptr->info_field[frame_length++] = frame_type | 0x10; - } else { - g_mux_obj_ptr->info_field[frame_length++] = frame_type; - } + /* + * Control Field + * + * The content of the control field defines the type of frame. + * **************************************************************** + * Frame Type 0 1 2 3 4 5 6 7 + * SABM (Set Asynchronous Balanced Mode) 1 1 1 1 P/F 1 0 0 + * UA (Unnumbered Acknowledgement) 1 1 0 0 P/F 1 1 0 + * DM (Disconnected Mode) 1 1 1 1 P/F 0 0 0 + * DISC (Disconnect) 1 1 0 0 P/F 0 1 0 + * UIH (Unnumbered Information with Header check) 1 1 1 1 P/F 1 1 1 + ******************************************************************/ + if (PF_bit) + cmux_obj->internal_mux.info_field[frame_length++] = + frame_type | 0x10; + else + cmux_obj->internal_mux.info_field[frame_length++] = frame_type; /* 5.2.1.5 Length Indicator */ if (length < 128) { - g_mux_obj_ptr->info_field[frame_length++] = (char) length << 1 | 0x01; + cmux_obj->internal_mux.info_field[frame_length++] = + (char) length << 1 | 0x01; /* CRC calculatable length */ crc_len = 3; } else { - g_mux_obj_ptr->info_field[frame_length++] = (char) (length << 1); // Need to change - g_mux_obj_ptr->info_field[frame_length++] = (char) (length >> 7); // Need to change + cmux_obj->internal_mux.info_field[frame_length++] = + (char) (length << 1); + cmux_obj->internal_mux.info_field[frame_length++] = + (char) (length >> 7); /* CRC calculatable length */ crc_len = 4; } - /* We need to divide the frames into maximum frame length supported by IMC. - * If IMC supports length according to 27.010 , we can send max of 16,384 bytes. - * Need to discuss with IMC. - */ + /* + * We need to divide the frames into maximum frame length supported by IMC. + * If IMC supports length according to 27.010 , we can send max of 16,384 bytes. + * Need to discuss with IMC. + */ - /* 5.2.1.4 Information Field*/ + /* 5.2.1.4 Information Field */ if (length > 0) { - memcpy((g_mux_obj_ptr->info_field + frame_length), data, length); + memcpy((cmux_obj->internal_mux.info_field + frame_length), + data, length); frame_length += length; - } else { + } else dbg("info field length is zero"); - } - /*5.2.1.6 Frame Checking Sequence Field (FCS)*/ - g_mux_obj_ptr->info_field[frame_length++] = calc_crc(g_mux_obj_ptr->info_field + 1, crc_len); + /* 5.2.1.6 Frame Checking Sequence Field (FCS) */ + cmux_obj->internal_mux.info_field[frame_length++] = + _cmux_calc_crc(cmux_obj->internal_mux.info_field + 1, crc_len); - /*Flag Octet*/ - g_mux_obj_ptr->info_field[frame_length++] = 0xF9; + /* Flag Octet */ + cmux_obj->internal_mux.info_field[frame_length++] = CMUX_FRAME_DELIMITER; total_frame_length = frame_length; - } else if (0x01 == g_mux_mode) { /* TBD MUX_MODE_ADVANCE */ - dbg("Advanced MUX mode : TBD"); + } else if (cmux_obj->cmux_mode == CMUX_MODE_ADVANCED) { + /* TBD CMUX_MODE_ADVANCE */ + dbg("Advanced CMUX mode : TBD"); } *out_data_len = total_frame_length; - dbg("*out_data_len: %d", *out_data_len); - - dbg("Exit total_frame_length: %d", total_frame_length); - return g_mux_obj_ptr->info_field; -} - -static int rcv_crc_check(unsigned char *data, unsigned char len, unsigned char rcv_FCS) -{ - unsigned char FCS = 0xFF; + dbg("Data (Frame) Length: [%d]", *out_data_len); - /* 'len' is the number of bytes in the message, 'data' points to message */ - while (len--) { - FCS = crc_table[FCS ^ *data++]; - } - - /*Ones complement*/ - FCS = crc_table[FCS ^ rcv_FCS]; - - /* 0xCF is the reversed order of 11110011 */ - if (0xCF == FCS) { /* FCS is OK */ - return 1; - } else { /* FCS is NOT OK */ - return 0; - } + return cmux_obj->internal_mux.info_field; } -static void tcore_cmux_flush_channel_data(void) -{ - dbg("Entry"); - - g_mux_obj_ptr->info_field_len = 0x0; - memset(g_mux_obj_ptr->info_field, 0x0, MAX_CMUX_BUFFER_SIZE); - - dbg("Exit"); - return; -} - -static void tcore_cmux_control_channel_handle(void) +static void _cmux_control_channel_handle(tcore_cmux_object *cmux_obj) { unsigned char cmd_type; int msg_len = 0; - unsigned char *msg_start_ptr = NULL; - + unsigned char *msg_start_ptr; dbg("Entry"); - /* 5.4.6.1 Message format - * All messages sent between the multiplexers conform to the following type, length, value format: - * Type Length Value 1 Value2 \85 - */ - if (g_mux_obj_ptr->info_field_len > 0) { - msg_start_ptr = g_mux_obj_ptr->info_field; - cmd_type = g_mux_obj_ptr->info_field[0]; - - /* The EA bit is an extension bit. The EA bit is set to 1 in the last octet of the sequence; - * in other octets EA is set to 0. - * - * Search for the last octet - */ - while ((*msg_start_ptr++ & 0x01)) { // TBD + /* + * 5.4.6.1 Message format + * All messages sent between the multiplexers conform to the following + * type, length, value format: + * Type Length Value 1 Value2 \85 + */ + if (cmux_obj->internal_mux.info_field_len > 0) { + msg_start_ptr = cmux_obj->internal_mux.info_field; + cmd_type = cmux_obj->internal_mux.info_field[0]; + + /* + * The EA bit is an extension bit. The EA bit is set to 1 in the last octet + * of the sequence; in other octets EA is set to 0. + * + * Search for the last octet + */ + while ((*msg_start_ptr++ & 0x01)) msg_len++; - } - if ((cmd_type & 0x02) == 0x02) { // This is a command Request + if ((cmd_type & 0x02) == 0x02) { /* This is a command Request */ switch (cmd_type) { - case CMUX_COMMAND_MSC: - { - dbg("Modem Status Command"); - break; - } - - case CMUX_COMMAND_CLD: - { - dbg("Multiplexer close down"); - tcore_cmux_close(); - break; - } - - default: - { - /* We will be supporting these commands in Phase 2 */ - dbg("Default"); - break; - } + case CMUX_COMMAND_MSC: + dbg("Modem Status Command"); + break; + case CMUX_COMMAND_CLD: + dbg("Multiplexer close down"); + + cmux_obj->cmux_state = CMUX_CLOSED; + + /* TODO - Need to notify regarding CMUX closure */ + tcore_cmux_close(cmux_obj->phy_hal, NULL, NULL); + break; + default: + /* We will be supporting these commands in Phase 2 */ + dbg("Default"); + break; } } - } else { + } else err("Frame length is less than ZERO"); - } dbg("Exit"); - return; } -static void tcore_cmux_process_channel_data(CHANNEL *channel_info_ptr) +static void _cmux_process_channel_data(tcore_cmux_object *cmux_obj, + tcore_cmux_channel *channel) { int frame_type; int channel_id; int len; - unsigned char *send_data = NULL; + unsigned char *send_data; static int count = 0; int ret; - dbg("Entry"); - channel_id = channel_info_ptr->channel_id; - dbg("Channel ID: %d", channel_id); + channel_id = channel->channel_id; + dbg("Channel ID: [%d]", channel_id); - frame_type = channel_info_ptr->frame_type & 0xEF; - dbg("frame_type: 0x%x", frame_type); + frame_type = channel->frame_type & 0xEF; + dbg("Frame Type: [0x%02x]", frame_type); switch (frame_type) { - case CMUX_COMMAND_UI: - case CMUX_COMMAND_UIH: - { - dbg("Received UI/UIH Frame"); - if (0 == channel_id) { /* This is control info */ - dbg("Control information"); - tcore_cmux_control_channel_handle(); - } else { - dbg("Normal information"); - // put in the logical HAL queue, this goes to the Cobject - tcore_cmux_recv_mux_data(channel_info_ptr); - } - break; - } + case CMUX_COMMAND_UI: + case CMUX_COMMAND_UIH: + dbg("Received UI/UIH Frame"); + if (channel_id == CMUX_CHANNEL_0) { /* This is control info */ + dbg("Control information"); + _cmux_control_channel_handle(cmux_obj); + } else { + dbg("Normal information"); - case CMUX_COMMAND_UA: - { - dbg("Received UA Frame"); - dbg("channel_info_ptr->state: %d", channel_info_ptr->state); - if (MUX_CHANNEL_SABM_SEND_WAITING_FOR_UA == channel_info_ptr->state) { - channel_info_ptr->state = MUX_CHANNEL_ESTABLISHED; - - count++; - dbg("Count: %d", count); - if (MAX_CMUX_CHANNELS_SUPPORTED == count) { - /* Indicate to CoreObject */ - CoreObject *co = NULL; - - /* 'modem' Core Object */ - co = g_mux_obj_ptr->modem_co; - if (NULL == co) { - err("'modem' Core object is not present"); - return; + /* Put in the logical HAL queue, this goes to the Cobject */ + if (FALSE == _cmux_recv_cmux_data(cmux_obj, channel)) + err("Failed receive callback"); + } + break; + case CMUX_COMMAND_UA: + dbg("Received UA Frame - Channel State: [%d]", channel->channel_state); + if (CMUX_CHANNEL_SABM_SEND_WAITING_FOR_UA == channel->channel_state) { + channel->channel_state = CMUX_CHANNEL_ESTABLISHED; + + if (channel->channel_id != CMUX_CHANNEL_0) { + TcoreHal *hal; + + /* Create Logical HAL */ + hal = _cmux_create_logical_hal(cmux_obj, channel); + if (hal != NULL) { + dbg("Invoking CMUX Channel Setup callback for [%d] channel", + channel->channel_id); + /* + * 'channel_setup_cb' cannot be NULL as it is MANDATED during + * CMUX setup operation. + */ + cmux_obj->internal_mux.channel_setup_cb(channel->channel_id, hal, + cmux_obj->internal_mux.channel_setup_user_data); + } else + err("Failed to Create Logical HAL"); } - /* Emit callback */ - dbg("Emit Core object callback"); - tcore_object_emit_callback(co, "CMUX-UP", NULL); - dbg("Emitted Core object callback"); + count++; + dbg("Count: [%d]", count); + if (cmux_obj->max_cmux_channels == count) { + dbg("Invoking CMUX Channel Setup Complete callback - Total Channels: [%d]", + count); + /* + * 'setup_complete_cb' cannot be NULL as it is MANDATED during + * CMUX setup operation. + */ + cmux_obj->internal_mux.setup_complete_cb( + cmux_obj->internal_mux.setup_complete_user_data); + + /* Reset 'count' */ + count = 0; + } + } else if (CMUX_CHANNEL_DISC_SEND_WAITING_FOR_UA == + channel->channel_state) { + channel->channel_state = CMUX_CHANNEL_CLOSED; - /* Reset 'count' */ - count = 0; - } - } else if (MUX_CHANNEL_DISC_SEND_WAITING_FOR_UA == channel_info_ptr->state) { - channel_info_ptr->state = MUX_CHANNEL_CLOSED; + if (channel_id == CMUX_CHANNEL_0) { + cmux_obj->cmux_state = CMUX_CLOSED; - if (0 == channel_id) { - g_mux_obj_ptr->state = MUX_CLOSED; - tcore_cmux_close(); + /* TODO - Need to notify regarding CMUX closure */ + tcore_cmux_close(cmux_obj->phy_hal, NULL, NULL); + } + } else + err("Received UA in wrong state!!!"); + + break; + case CMUX_COMMAND_DM: + /* + * 5.4.1 DLC Establishment : If the responding station is not ready or unwilling + * to establish the particular DLC it will reply with a DM frame with the + * F-bit set to 1. + */ + dbg("Received DM Frame"); + if ((channel->channel_state == CMUX_CHANNEL_ESTABLISHED) + || (channel->channel_state == + CMUX_CHANNEL_SABM_SEND_WAITING_FOR_UA)) { + /* Channel State set to Close */ + channel->channel_state = CMUX_CHANNEL_CLOSED; } - } else { - err("Received UA in wrong state!!!"); - } - break; - } - - case CMUX_COMMAND_DM: - { - /* 5.4.1 DLC Establishment : If the responding station is not ready or unwilling - * to establish the particular DLC it will reply with a DM frame with the - * F-bit set to 1. - */ - dbg("Received DM Frame"); - if ((MUX_CHANNEL_ESTABLISHED == channel_info_ptr->state) - || (MUX_CHANNEL_SABM_SEND_WAITING_FOR_UA == channel_info_ptr->state)) { - /* Channel State set to Close */ - channel_info_ptr->state = MUX_CHANNEL_CLOSED; - } - - /* Flush the Channel data */ - tcore_cmux_flush_channel_data(); - - break; - } - - case CMUX_COMMAND_DISC: - { - dbg("Received DISC Frame"); - if (0 == channel_info_ptr->poll_final_bit) { - /* In the case where a CMUX_COMMAND_SABM or CMUX_COMMAND_DISC command with - * the P bit set to 0 is received then the received frame shall be discarded. - */ /* Flush the Channel data */ - tcore_cmux_flush_channel_data(); - } else { - if (MUX_CHANNEL_CLOSED == channel_info_ptr->state) { - /* If a CMUX_COMMAND_DISC command is received while in disconnected mode - * a CMUX_COMMAND_DM response should be sent - */ + _cmux_flush_channel_data(cmux_obj); + break; + case CMUX_COMMAND_DISC: + dbg("Received DISC Frame"); + if (channel->poll_final_bit == 0) { + /* + * In the case where a CMUX_COMMAND_SABM or + * CMUX_COMMAND_DISC command with + * the P bit set to 0 is received then the received frame shall be + * discarded. + */ + + /* Flush the Channel data */ + _cmux_flush_channel_data(cmux_obj); + } else { + if (channel->channel_state == CMUX_CHANNEL_CLOSED) { + /* + * If a CMUX_COMMAND_DISC command is received while in + * disconnected mode a CMUX_COMMAND_DM response should + * be sent + */ + + /* Encoding frame */ + send_data = _cmux_encode_cmux_frame(cmux_obj, NULL, + 0, channel_id, CMUX_COMMAND_DM, + 0x01, 0x01, 0x01, &len); + } else { /* Send Unnumbered Acknowledgement */ + /* Encoding frame */ + send_data = _cmux_encode_cmux_frame(cmux_obj, NULL, + 0, channel_id, CMUX_COMMAND_UA, + 0x01, 0x01, 0x01, &len); + } - /* Encoding frame */ - send_data = tcore_encode_cmux_frame(NULL, 0, channel_id, CMUX_COMMAND_DM, 1, 1, 1, &len); - } else { // send Unnumbered Acknowledgement - send_data = tcore_encode_cmux_frame(NULL, 0, channel_id, CMUX_COMMAND_UA, 1, 1, 1, &len); - } + if (len == 0) { + err("Failed to encode"); + return; + } - if (0 == len) { - err("Failed to encode"); - return; + /* Send CMUX data */ + ret = _cmux_send_data(cmux_obj->phy_hal, len, send_data); + dbg("return %d", ret); + + /* Flush the Channel data */ + _cmux_flush_channel_data(cmux_obj); + + /* + * 5.3.4 Disconnect (DISC) command: CMUX_COMMAND_DISC + * command sent at DLCI 0 have the same meaning as the + * Multiplexer Close Down command. + */ + if (channel_id == CMUX_CHANNEL_0) { + cmux_obj->cmux_state = CMUX_CLOSED; + + /* Close CMUX */ + /* TODO - Need to notify regarding CMUX closure */ + tcore_cmux_close(cmux_obj->phy_hal, NULL, NULL); + } } - - /* Send CMUX data */ - ret = tcore_cmux_send_data(len, send_data); - - /* Flush the Channel data */ - tcore_cmux_flush_channel_data(); - - /* 5.3.4 Disconnect (DISC) command: CMUX_COMMAND_DISC command sent at DLCI 0 - * have the same meaning as the Multiplexer Close Down command - */ - if (0 == channel_id) { - g_mux_obj_ptr->state = MUX_CLOSED; - - /* Close CMUX */ - tcore_cmux_close(); + break; + case CMUX_COMMAND_SABM: + dbg("Received SABM Frame"); + if (channel->poll_final_bit == 0) { + /* + * In the case where a CMUX_COMMAND_SABM or CMUX_COMMAND_DISC + * command with the P bit set to 0 is received then the received frame + * shall be discarded. + */ + + /* Flush the Channel data */ + _cmux_flush_channel_data(cmux_obj); + } else { + /* Encoding frame */ + send_data = _cmux_encode_cmux_frame(cmux_obj, NULL, + 0, channel_id, CMUX_COMMAND_UA, + 0x01, 0x01, 0x01, &len); + if (len != 0) + /* Send CMUX data */ + ret = _cmux_send_data(cmux_obj->phy_hal, len, send_data); + else + err("Failed to encode"); + + if (channel->channel_state != CMUX_CHANNEL_ESTABLISHED) + /* Channel State set to Established */ + channel->channel_state = CMUX_CHANNEL_ESTABLISHED; } - } break; + default: + warn("invalid frame_type"); + break; } - case CMUX_COMMAND_SABM: - { - dbg("Received SABM Frame"); - if (0 == channel_info_ptr->poll_final_bit) { - /* In the case where a CMUX_COMMAND_SABM or CMUX_COMMAND_DISC command with - * the P bit set to 0 is received then the received frame shall be discarded. - */ + dbg("Exit"); +} - /* Flush the Channel data */ - tcore_cmux_flush_channel_data(); - } else { - /* Encoding frame */ - send_data = tcore_encode_cmux_frame(NULL, 0, channel_id, CMUX_COMMAND_UA, 1, 1, 1, &len); - if (0 != len) { - /* Send CMUX data */ - ret = tcore_cmux_send_data(len, send_data); - } else { - err("Failed to encode"); - } +static void _cmux_flush_channel_data(tcore_cmux_object *cmux_obj) +{ + dbg("Entry"); - if (channel_info_ptr->state != MUX_CHANNEL_ESTABLISHED) { - /* Channel State set to Established */ - channel_info_ptr->state = MUX_CHANNEL_ESTABLISHED; - } - } - break; - } - } + if (cmux_obj == NULL) + return; + + cmux_obj->internal_mux.info_field_len = 0x0; + memset(cmux_obj->internal_mux.info_field, 0x0, cmux_obj->max_cmux_buf_size); dbg("Exit"); - return; } -static void tcore_cmux_process_rcv_frame(unsigned char *data, int len) +static void _cmux_process_rcv_frame(tcore_cmux_object *cmux_obj, int length) { - unsigned char *frame_process_ptr = data; - unsigned char *buf_start_ptr = data; + unsigned char *frame_process_ptr = cmux_obj->cmux_buffer; + unsigned char *buf_start_ptr = cmux_obj->cmux_buffer; - CHANNEL *ch = NULL; + tcore_cmux_channel *ch; unsigned char channel_id; int header_length; - dbg("Entry"); - tcore_cmux_flush_channel_data(); + /* Flush channel data */ + _cmux_flush_channel_data(cmux_obj); - /* Get the Channel ID : 1st byte will be flag (F9)..Flag checking is already done.*/ + /* Get the Channel ID: 1st byte will be flag (F9). Flag checking is already done */ channel_id = (*++frame_process_ptr >> 2) & 0x3F; - if (channel_id < MAX_CMUX_CHANNELS_SUPPORTED) { // max channel is 8 - ch = g_mux_obj_ptr->channel_info[channel_id]; + if (channel_id < cmux_obj->max_cmux_channels) { + ch = cmux_obj->internal_mux.channel_info[channel_id]; ch->channel_id = channel_id; - // get the EA bit + /* get the EA bit */ ch->ext_bit = *frame_process_ptr & 0x01; - // get the CR bit + /* get the CR bit */ ch->cr_bit = (*frame_process_ptr++ >> 1) & 0x01; - // get the Frame Type + /* get the Frame Type */ ch->frame_type = *frame_process_ptr++; - // get the poll/Final bit + /* get the poll/Final bit */ ch->poll_final_bit = (ch->frame_type & 0x10) >> 4; - // get the length . TBD - if (*frame_process_ptr & 0x01) { // if, len < 127 - g_mux_obj_ptr->info_field_len = *frame_process_ptr++ >> 1; + /* get the length . TBD */ + if (*frame_process_ptr & 0x01) { /* if, len < 127 */ + cmux_obj->internal_mux.info_field_len = *frame_process_ptr++ >> 1; header_length = 3; } else { - g_mux_obj_ptr->info_field_len = *(frame_process_ptr + 1) << 7; - g_mux_obj_ptr->info_field_len = g_mux_obj_ptr->info_field_len | ((*frame_process_ptr++ & 0xFE) >> 1); + cmux_obj->internal_mux.info_field_len = *(frame_process_ptr + 1) << 7; + cmux_obj->internal_mux.info_field_len = + (cmux_obj->internal_mux.info_field_len + | ((*frame_process_ptr++ & 0xFE) >> 1)); header_length = 4; frame_process_ptr++; } - dbg("info_field_len: %d", g_mux_obj_ptr->info_field_len); + dbg("info_field_len: [%d]", cmux_obj->internal_mux.info_field_len); /* Copy received information field */ - memcpy(g_mux_obj_ptr->info_field, frame_process_ptr, g_mux_obj_ptr->info_field_len); + memcpy(cmux_obj->internal_mux.info_field, frame_process_ptr, + cmux_obj->internal_mux.info_field_len); - frame_process_ptr = frame_process_ptr + g_mux_obj_ptr->info_field_len; + frame_process_ptr = frame_process_ptr + cmux_obj->internal_mux.info_field_len; - // CRC check of the header - if (rcv_crc_check(buf_start_ptr + 1, header_length, *frame_process_ptr)) { - dbg("Calling tcore_cmux_process_channel_data"); - tcore_cmux_process_channel_data(ch); - } else { + /* CRC check of the header */ + if (_cmux_check_recv_crc((buf_start_ptr + 1), header_length, *frame_process_ptr)) { + dbg("Calling _cmux_process_channel_data"); + _cmux_process_channel_data(cmux_obj, ch); + } else err("CRC check of the header FAILED.. Drop the packet !!"); + } else + err("Incorrect channel... Drop the packet !!"); + + dbg("Exit"); +} + +static TReturn _cmux_send_data(TcoreHal *hal, int data_len, unsigned char *data) +{ + TReturn ret; + dbg("Entry"); + + /* Directly send to Physical HAL */ + ret = tcore_hal_send_data(hal, data_len, (void *) data); + if (ret != TCORE_RETURN_SUCCESS) { + err("Failed to send CMUX data"); + } else + dbg("Successfully sent CMUX data"); + + dbg("Exit"); + return ret; +} + +static gboolean _cmux_recv_cmux_data(tcore_cmux_object *cmux_obj, + tcore_cmux_channel *channel) +{ + TcoreHal *hal; + dbg("Entry"); + + /* Dereferencing HAL from Channel Pointer */ + hal = channel->hal; + if (hal == NULL) { + err("No HAL"); + return FALSE; + } + + dbg("Dispatching to logical HAL - hal: [0x%x]", (unsigned int)hal); + if (tcore_hal_dispatch_response_data(hal, 0, + cmux_obj->internal_mux.info_field_len, + cmux_obj->internal_mux.info_field) + != TCORE_RETURN_SUCCESS) { + err("Exit"); + return FALSE; + } + + dbg("Exit"); + return TRUE; +} + +static TReturn _cmux_hal_power(TcoreHal *hal, gboolean flag) +{ + dbg("Entry"); + + if (flag == TRUE) { /* Powering ON */ + dbg("Powering ON"); + return tcore_hal_set_power_state(hal, TRUE); + } else { /* Powering OFF */ + dbg("Powering OFF"); + return tcore_hal_set_power_state(hal, FALSE); + } +} + +static TReturn _cmux_hal_send(TcoreHal *hal, unsigned int data_len, void *data) +{ + tcore_cmux_object *cmux_obj; + char *hal_name; + unsigned char *send_data; + char *channel_name; + int channel_id; + int len; + + TReturn ret = TCORE_RETURN_FAILURE; + dbg("Entry"); + + /* Check if Logical HAL is Powered ON */ + if (tcore_hal_get_power_state(hal) == FALSE) { + err("HAL is not Powered UP"); + return TCORE_RETURN_FAILURE; + } + + /* + * Get CMUX Object from Modem Interface Plug-in + */ + cmux_obj = _cmux_get_cmux_object(tcore_hal_ref_plugin(hal)); + if (cmux_obj == NULL) { + err("Failed to find CMUX object"); + return TCORE_RETURN_FAILURE; + } + + channel_id = cmux_obj->max_cmux_channels + 1; + + channel_name = tcore_hal_get_name(hal); + dbg("HAL name: [%s]", channel_name); + + if (channel_name != NULL) { + int i; + + /* + * Channel 0 is dedicated to CMUX Control Channel, + * hence starting from 1. + */ + for (i = 1 ; cmux_obj->max_cmux_channels > i ; i++) { + hal_name = + tcore_hal_get_name(cmux_obj->internal_mux.channel_info[i]->hal); + if (hal_name == NULL) { + dbg("HAL name: [%s]", hal_name); + continue; + } + + /* + * Comparing all Logical HAL names with required HAL name. + */ + if (strcmp(hal_name, channel_name) == 0) { + channel_id = cmux_obj->internal_mux.channel_info[i]->channel_id; + dbg("Found Channel ID: [%d]", channel_id); + + /* Free HAL name */ + g_free(hal_name); + + break; + } + + /* Free HAL name */ + g_free(hal_name); } + + /* Free memory */ + g_free(channel_name); } else { - err("Incorrect channel... Drop the packet !!"); + err("No name defined for HAL"); + return ret; } + if (channel_id > cmux_obj->max_cmux_channels) { + err("Failed to find Channel ID"); + return ret; + } + + /* Muxing operation and Frame creation */ + /* Encoding frame */ + send_data = _cmux_encode_cmux_frame(cmux_obj, data, data_len, channel_id, + CMUX_COMMAND_UIH, 0x1, 0x1, 0x0, &len); + if (len == 0) { + err("Failed to encode"); + return TCORE_RETURN_FAILURE; + } + + /* Send CMUX data */ + ret = _cmux_send_data(cmux_obj->phy_hal, len, send_data); + dbg("Exit"); - return; + return ret; } -int tcore_cmux_rcv_from_hal(unsigned char *data, size_t length) +static TReturn _cmux_hal_setup_netif(CoreObject *co, + TcoreHalSetupNetifCallback func, void *user_data, + unsigned int cid, gboolean enable) { - #define TCORE_MUX_DECODE_FLAG_HUNT 0 - #define TCORE_MUX_DECODE_ADDR_HUNT 1 - #define TCORE_MUX_DECODE_CONTROL_HUNT 2 - #define TCORE_MUX_DECODE_LENGTH1_HUNT 3 - #define TCORE_MUX_DECODE_LENGTH2_HUNT 4 - #define TCORE_MUX_DECODE_DATA_HUNT 5 - #define TCORE_MUX_DECODE_FCS_HUNT 6 - - static int decode_state = TCORE_MUX_DECODE_FLAG_HUNT; - static unsigned char dec_fcs = 0xff; - static unsigned char mux_buffer[4096]; - static unsigned char* dec_data = mux_buffer; - static unsigned short dec_length = 0; - static size_t full_frame_len = 0; + tcore_cmux_object *cmux_obj; + TcoreHal *hal; + dbg("Entry"); - size_t pos = -1; - int cp_len = 0; + /* Get secondary HAL from Core Object */ + hal = tcore_object_get_hal(co); -DECODE_STATE_CHANGE: - if (++pos >= length) - { - return 1; + /* + * Get CMUX Object from Modem Interface Plug-in + */ + cmux_obj = _cmux_get_cmux_object(tcore_hal_ref_plugin(hal)); + if (cmux_obj == NULL) + return TCORE_RETURN_FAILURE; + + return tcore_hal_setup_netif(cmux_obj->phy_hal, + co, func, user_data, cid, enable); +} + +/* CMUX supported HAL (Logical HAL) operations */ +static struct tcore_hal_operations cmux_hops = { + .power = _cmux_hal_power, + .send = _cmux_hal_send, + .setup_netif = _cmux_hal_setup_netif, +}; + +static TcoreHal *_cmux_create_logical_hal(tcore_cmux_object *cmux_obj, + tcore_cmux_channel *channel) +{ + TcoreHal *hal; + char channel_id_name[CMUX_MAX_CHANNEL_NAME]; + dbg("Entry"); + + if ((cmux_obj == NULL) || (channel == NULL)) { + err("Invalid input parameters"); + return NULL; } - switch(decode_state) - { - case TCORE_MUX_DECODE_FLAG_HUNT: full_frame_len = 0; dec_length = 0; dec_fcs = 0xff; dec_data = mux_buffer; goto FLAG_HUNT; break; - case TCORE_MUX_DECODE_ADDR_HUNT: goto ADDR_HUNT; break; - case TCORE_MUX_DECODE_CONTROL_HUNT: goto CONTROL_HUNT; break; - case TCORE_MUX_DECODE_LENGTH1_HUNT: goto LENGTH1_HUNT; break; - case TCORE_MUX_DECODE_LENGTH2_HUNT: goto LENGTH2_HUNT; break; - case TCORE_MUX_DECODE_DATA_HUNT: goto DATA_HUNT; break; - case TCORE_MUX_DECODE_FCS_HUNT: goto FCS_HUNT; break; + /* Creating Logical HAL for Core Object - Mode - 'AT mode' */ + snprintf(channel_id_name, sizeof(channel_id_name), + "channel_%d", channel->channel_id); + + /* Creating Logical HAL */ + hal = tcore_hal_new(cmux_obj->plugin, + channel_id_name, &cmux_hops, TCORE_HAL_MODE_AT); + dbg("hal: %p", hal); + if (hal == NULL) { + err("Failed to allocate memory"); + return NULL; } -FLAG_HUNT: - while (data[pos] != 0xF9) { - if (++pos >= length) { - return 1; + /* Updating Logical HAL of CMUX Channel */ + channel->hal = hal; + + dbg("Exit"); + return hal; +} + +tcore_cmux_object *_cmux_new(int max_channels, unsigned int buffer_size) +{ + tcore_cmux_object *cmux_obj; + int i; + dbg("Entry"); + + /* Allocating memory for mux */ + cmux_obj = (tcore_cmux_object *)g_try_new0(tcore_cmux_object, 1); + if (cmux_obj == NULL) { + err("Failed to allocate memory"); + return NULL; + } + + /* Allocating memory for info_field */ + cmux_obj->internal_mux.info_field = + (unsigned char *)g_try_malloc0(buffer_size); + if (cmux_obj->internal_mux.info_field == NULL) { + err("Failed to allocate memory for info field"); + goto ERROR; + } + + /* CMUX State initialize to CMUX_NOT_INITIALIZED */ + cmux_obj->cmux_state = CMUX_NOT_INITIALIZED; + + /* + * Allocating memory for channel_info + * max_channels defines the maximum channels user requested, + * hence + 1 is required for CMUX Control Channel + */ + for (i = 0; i < (max_channels + 1) ; i++) { + /* Allocating memory for channel_info */ + cmux_obj->internal_mux.channel_info[i] = + (tcore_cmux_channel *)g_try_new0(tcore_cmux_channel, 1); + if (cmux_obj->internal_mux.channel_info[i] == NULL) { + err("Failed to allocate memory for channel_info of channel: [%d]", i); + goto ERROR; } } - decode_state = TCORE_MUX_DECODE_ADDR_HUNT; + + dbg("Exit"); + return cmux_obj; + +ERROR: + /* Free allocated memory */ + if (cmux_obj != NULL) { + /* Free info_field */ + g_free(cmux_obj->internal_mux.info_field); + + for (i = 0; i < (max_channels + 1) ; i++) + /* Free channel_info */ + g_free(cmux_obj->internal_mux.channel_info[i]); + + /* Free CMUX object memory */ + g_free(cmux_obj); + } + + err("Exit"); + return NULL; +} + +static void _cmux_channel_init(tcore_cmux_object *cmux_obj, int channel_id) +{ + tcore_cmux_channel *ch; + dbg("Entry"); + + ch = cmux_obj->internal_mux.channel_info[channel_id]; + if (ch == NULL) + return; + + ch->channel_id = channel_id; + ch->channel_state = CMUX_CHANNEL_SABM_SEND_WAITING_FOR_UA; + + ch->hal = NULL; + + /* TODO - Check if required */ + ch->frame_type = CMUX_COMMAND_SABM; + ch->ext_bit = 0x01; + ch->cr_bit = 0x01; + ch->poll_final_bit = 0x01; + + dbg("Channel ID [%d] - Initialized", channel_id); +} + +static void _cmux_close_channel(tcore_cmux_object *cmux_obj, int channel_id) +{ + tcore_cmux_channel *ch; + unsigned char *send_data; + int ret, len = 0; + dbg("Entry"); + + ch = cmux_obj->internal_mux.channel_info[channel_id]; + if (ch == NULL) + return; + + if (ch->channel_state != CMUX_CHANNEL_CLOSED) { + ch->frame_type = CMUX_COMMAND_DISC; + ch->ext_bit = 0x01; + ch->cr_bit = 0x01; + ch->channel_state = CMUX_CHANNEL_DISC_SEND_WAITING_FOR_UA; + + /* Send DSC command */ + /* Encoding frame */ + send_data = _cmux_encode_cmux_frame(cmux_obj, NULL, 0, channel_id, + CMUX_COMMAND_DISC, 0x01, 0x01, 0x01, &len); + if (len != 0) { + /* Send CMUX data */ + ret = _cmux_send_data(cmux_obj->phy_hal, len, send_data); + dbg("return %d", ret); + } + else { + err("Failed to encode"); + } + } else + /* Channel is already closed */ + err("Channel is already closed"); + + dbg("Exit"); +} + +static void _cmux_free(tcore_cmux_object *cmux_obj) +{ + int channel; + dbg("Entry"); + + /* + * This function is used internally only, hence sanity check for 'cmux_obj' + * is NOT required. + */ + /* Free Information Field */ + g_free(cmux_obj->internal_mux.info_field); + cmux_obj->internal_mux.info_field = NULL; + + for (channel = 0; channel < cmux_obj->max_cmux_channels; channel++) { + /* Free Channel Information */ + g_free(cmux_obj->internal_mux.channel_info[channel]); + cmux_obj->internal_mux.channel_info[channel] = NULL; + } + + /* Free CMUX Object */ + g_free(cmux_obj); + cmux_obj = NULL; + + dbg("Exit"); +} + +static void _cmux_on_confirmation_message_send(TcorePending *plugin, + gboolean result, void *user_data) +{ + dbg("Message out from queue"); + + if (result == FALSE) { /* Fail */ + err("SEND FAIL"); + } else + dbg("SEND OK"); +} + +void tcore_cmux_rcv_from_hal(TcoreHal *hal, unsigned char *data, size_t length) +{ +#define TCORE_CMUX_DECODE_FLAG_HUNT 0 +#define TCORE_CMUX_DECODE_ADDR_HUNT 1 +#define TCORE_CMUX_DECODE_CONTROL_HUNT 2 +#define TCORE_CMUX_DECODE_LENGTH1_HUNT 3 +#define TCORE_CMUX_DECODE_LENGTH2_HUNT 4 +#define TCORE_CMUX_DECODE_DATA_HUNT 5 +#define TCORE_CMUX_DECODE_FCS_HUNT 6 + + tcore_cmux_object *cmux_obj; + + static int decode_state = TCORE_CMUX_DECODE_FLAG_HUNT; + static unsigned char dec_fcs; + static unsigned char *dec_data; + static unsigned short dec_length; + static size_t full_frame_len; + + size_t pos = -1; + int cp_len; + dbg("Entry"); + + /* + * Get CMUX Object from Modem Interface Plug-in + */ + cmux_obj = _cmux_get_cmux_object(tcore_hal_ref_plugin(hal)); + if (cmux_obj == NULL) + return; + +DECODE_STATE_CHANGE: + if (++pos >= length) + return; + + switch(decode_state) { + case TCORE_CMUX_DECODE_FLAG_HUNT: + full_frame_len = 0; + dec_length = 0; + dec_fcs = 0xFF; + dec_data = cmux_obj->cmux_buffer; + goto FLAG_HUNT; + break; + case TCORE_CMUX_DECODE_ADDR_HUNT: + goto ADDR_HUNT; + break; + case TCORE_CMUX_DECODE_CONTROL_HUNT: + goto CONTROL_HUNT; + break; + case TCORE_CMUX_DECODE_LENGTH1_HUNT: + goto LENGTH1_HUNT; + break; + case TCORE_CMUX_DECODE_LENGTH2_HUNT: + goto LENGTH2_HUNT; + break; + case TCORE_CMUX_DECODE_DATA_HUNT: + goto DATA_HUNT; + break; + case TCORE_CMUX_DECODE_FCS_HUNT: + goto FCS_HUNT; + break; + default: + warn("invalid decode_state"); + break; + } + +FLAG_HUNT: + while (data[pos] != CMUX_FRAME_DELIMITER) + if (++pos >= length) + return; + + decode_state = TCORE_CMUX_DECODE_ADDR_HUNT; goto DECODE_STATE_CHANGE; ADDR_HUNT: - while (data[pos] == 0xF9) { - if (++pos >= length) { - return 1; - } - } + while (data[pos] == CMUX_FRAME_DELIMITER) + if (++pos >= length) + return; dec_fcs = crc_table[dec_fcs^data[pos]]; - decode_state = TCORE_MUX_DECODE_CONTROL_HUNT; - *dec_data++ = 0xF9; + decode_state = TCORE_CMUX_DECODE_CONTROL_HUNT; + *dec_data++ = CMUX_FRAME_DELIMITER; *dec_data++ = data[pos]; full_frame_len += 2; goto DECODE_STATE_CHANGE; CONTROL_HUNT: dec_fcs = crc_table[dec_fcs^data[pos]]; - decode_state = TCORE_MUX_DECODE_LENGTH1_HUNT; + decode_state = TCORE_CMUX_DECODE_LENGTH1_HUNT; *dec_data++ = data[pos]; full_frame_len++; goto DECODE_STATE_CHANGE; @@ -950,21 +1196,13 @@ CONTROL_HUNT: LENGTH1_HUNT: dec_length = data[pos] >> 1; dec_fcs = crc_table[dec_fcs^data[pos]]; - if (data[pos] & 0x1) - { // ea + if (data[pos] & 0x1) /* EA */ if (dec_length > 0) - { - decode_state = TCORE_MUX_DECODE_DATA_HUNT; - } + decode_state = TCORE_CMUX_DECODE_DATA_HUNT; else - { - decode_state = TCORE_MUX_DECODE_FCS_HUNT; - } - } + decode_state = TCORE_CMUX_DECODE_FCS_HUNT; else - { - decode_state = TCORE_MUX_DECODE_LENGTH2_HUNT; - } + decode_state = TCORE_CMUX_DECODE_LENGTH2_HUNT; *dec_data++ = data[pos]; full_frame_len++; @@ -973,21 +1211,18 @@ LENGTH1_HUNT: LENGTH2_HUNT: dec_length |= ((unsigned short)data[pos] << 7); dec_fcs = crc_table[dec_fcs^data[pos]]; - decode_state = TCORE_MUX_DECODE_DATA_HUNT; + decode_state = TCORE_CMUX_DECODE_DATA_HUNT; *dec_data++ = data[pos]; full_frame_len++; goto DECODE_STATE_CHANGE; DATA_HUNT: - if (dec_length < (length - pos)) // frame data fully available in the buffer - { + if (dec_length < (length - pos)) { /* frame data fully available in the buffer */ cp_len = dec_length; - decode_state = TCORE_MUX_DECODE_FCS_HUNT; - } - else // frame data partially available in the buffer - { + decode_state = TCORE_CMUX_DECODE_FCS_HUNT; + } else { /* frame data partially available in the buffer */ cp_len = (length - pos); - decode_state = TCORE_MUX_DECODE_DATA_HUNT; + decode_state = TCORE_CMUX_DECODE_DATA_HUNT; } memcpy(dec_data, data + pos, cp_len); @@ -999,169 +1234,190 @@ DATA_HUNT: goto DECODE_STATE_CHANGE; FCS_HUNT: - //if (crc_table[dec_fcs^data[pos]] == 0xCF) // valid FCS, store frame. - { - *dec_data++ = data[pos]; - *dec_data++ = 0xF9; - full_frame_len += 2; - tcore_cmux_process_rcv_frame(mux_buffer, full_frame_len); - } + *dec_data++ = data[pos]; + *dec_data++ = CMUX_FRAME_DELIMITER; + full_frame_len += 2; + _cmux_process_rcv_frame(cmux_obj, full_frame_len); - // enter flag hunt mode - decode_state = TCORE_MUX_DECODE_FLAG_HUNT; + /* enter flag hunt mode */ + decode_state = TCORE_CMUX_DECODE_FLAG_HUNT; goto DECODE_STATE_CHANGE; } -static void tcore_cmux_channel_init(CMUX_Channels channel_id) +/* CMUX initialization */ +TReturn tcore_cmux_init(TcoreHal *phy_hal, unsigned int frame_size, + TcorePendingResponseCallback resp_cb, void *resp_cb_data) { - CHANNEL *ch = NULL; - - ch = g_mux_obj_ptr->channel_info[channel_id]; - memset(ch, 0x0, sizeof(CHANNEL)); - - ch->channel_id = channel_id; - ch->state = MUX_CHANNEL_SABM_SEND_WAITING_FOR_UA; + TcorePending *pending = NULL; + TcoreATRequest *req = NULL; + TReturn ret = TCORE_RETURN_FAILURE; + char *cmd_str; + dbg("Entry"); - ch->co = NULL; - ch->hal = NULL; + if ((phy_hal == NULL) || (resp_cb == NULL)) + return TCORE_RETURN_EINVAL; + + if (frame_size > 32768) + return TCORE_RETURN_EINVAL; + + /* + * 3GPP 27.010 Section 5.7.2 Maximum Frame Size (N1) + * If frame size is greater than Zero then, + * the request is sent for frame size + * else, + * request is sent for 'default' frame size + * (default Value: 31 (64 if Advanced option is used)). + */ + if (frame_size > 0) + cmd_str = g_strdup_printf("AT+CMUX=0,0,%d,1509,10,3,30,,", frame_size); + else + cmd_str = g_strdup_printf("AT+CMUX=0,0,,1509,10,3,30,,"); - /* TODO - Check if required */ - ch->frame_type = CMUX_COMMAND_SABM; - ch->ext_bit = 0x01; - ch->cr_bit = 0x01; - ch->poll_final_bit = 0x01; + if (cmd_str == NULL) + return TCORE_RETURN_ENOMEM; - dbg("Channel ID %d initialized", channel_id); + /* Create Pending Request */ + pending = tcore_pending_new(NULL, 0); + if (pending == NULL) { + dbg("Pending is NULL"); - return; -} + g_free(cmd_str); + return ret; + } -static void tcore_cmux_close_channel(int channel_id) -{ - CHANNEL *ch = NULL; - unsigned char *send_data = NULL; - int ret, len = 0; + /* Create AT-Command Request */ + req = tcore_at_request_new(cmd_str, "+CMUX:", TCORE_AT_NO_RESULT); - dbg("Entry"); + /* Free command string */ + g_free(cmd_str); - ch = g_mux_obj_ptr->channel_info[channel_id]; + if (req == NULL) { + dbg("Request is NULL"); + tcore_pending_free(pending); + return ret; + } + dbg("AT Command: [%s], Prefix(if any): [%s], AT-Command length: [%d]", req->cmd, req->prefix, strlen(req->cmd)); - if (ch->state != MUX_CHANNEL_CLOSED) { - ch->frame_type = CMUX_COMMAND_DISC; - ch->ext_bit = 0x01; - ch->cr_bit = 0x01; - ch->state = MUX_CHANNEL_DISC_SEND_WAITING_FOR_UA; + tcore_pending_set_request_data(pending, 0, req); + tcore_pending_set_response_callback(pending, resp_cb, resp_cb_data); + tcore_pending_set_send_callback(pending, _cmux_on_confirmation_message_send, NULL); - /* Send DSC command */ - /* Encoding frame */ - send_data = tcore_encode_cmux_frame(NULL, 0, channel_id, CMUX_COMMAND_DISC, 0x01, 0x01, 0x01, &len); - if (0 != len) { - /* Send CMUX data */ - ret = tcore_cmux_send_data(len, send_data); - } else { - err("Failed to encode"); - } - } else { - /* Channel is already closed */ - err("Channel is already closed"); - } + ret = tcore_hal_send_request(phy_hal, pending); dbg("Exit"); - return; + return ret; } -static void tcore_cmux_free(void) +/* Setup Internal CMUX */ +TReturn tcore_cmux_setup_internal_mux(tcore_cmux_mode mode, + int max_channels, unsigned int cmux_buf_size, TcoreHal *phy_hal, + cmux_setup_cb_func channel_setup_cb, gpointer channel_setup_user_data, + cmux_setup_complete_cb_func setup_complete_cb, gpointer setup_complete_user_data) { - int channel; + tcore_cmux_object *cmux_obj; + unsigned char *data; + int data_len; + int temp_index; + TReturn ret = TCORE_RETURN_FAILURE; dbg("Entry"); - - if (g_mux_obj_ptr) { - /* Free Information Field */ - if (g_mux_obj_ptr->info_field) { - free(g_mux_obj_ptr->info_field); - g_mux_obj_ptr->info_field = NULL; - } - - for (channel = 0; channel < MAX_CMUX_CHANNELS_SUPPORTED; channel++) { - /* Free Channel Information */ - if (g_mux_obj_ptr->channel_info[channel]) { - free(g_mux_obj_ptr->channel_info[channel]); - g_mux_obj_ptr->channel_info[channel] = NULL; - } - } - - /* Free MUX Object */ - free(g_mux_obj_ptr); - g_mux_obj_ptr = NULL; - } else { - err("MUX Object doesn't exist"); + dbg("Internal CMUX setup request"); + + /* Sanity Check */ + if ((cmux_buf_size <= 0) + || (phy_hal == NULL) + || (channel_setup_cb == NULL) + || (setup_complete_cb == NULL)) { + err("CMUX Buffer size: [%d] Physical HAL: [0x%x] setup_complete_cb: [0x%x]", + cmux_buf_size, (unsigned int)phy_hal, setup_complete_cb); + return TCORE_RETURN_EINVAL; } - dbg("Exit"); - return; -} - -TReturn tcore_cmux_init(TcorePlugin *plugin, TcoreHal *hal) -{ - unsigned char *data = NULL; - int data_len = 0; + dbg("Physical HAL: [0x%x] cmux_buf_size: [%d]", + (unsigned int)phy_hal, cmux_buf_size); - int index; + /* + * Max Channels + * (+ 1) is for CMUX Control Channel + */ + if ((max_channels +1) >= CMUX_CHANNEL_MAX) { + err("Number of Channels requested is greater than supported"); + return TCORE_RETURN_EINVAL; + } - TReturn ret = TCORE_RETURN_SUCCESS; + /* Create new CMUX Object */ + cmux_obj = _cmux_new(max_channels, cmux_buf_size); + if (cmux_obj == NULL) { + err("Failed to create CMUX object"); + return TCORE_RETURN_ENOMEM; + } - dbg("Entry"); + /* Maximum Buffer size for CMUX frame processing */ + cmux_obj->max_cmux_buf_size = cmux_buf_size; - dbg("Physical HAL: %x", hal); + /* Maximum Channels requested */ + cmux_obj->max_cmux_channels = max_channels + 1; - /* Creat new CMUX Object */ - g_mux_obj_ptr = tcore_cmux_new(); - if (NULL == g_mux_obj_ptr) { - err("Failed to create MUX object"); + /* Allocating buffer for CMUX frames proposing */ + cmux_obj->cmux_buffer = (unsigned char *)g_try_malloc0(cmux_buf_size); + if (cmux_obj->cmux_buffer == NULL) { + err("Failed to allocate memory"); - ret = TCORE_RETURN_FAILURE; + ret = TCORE_RETURN_ENOMEM; goto ERROR; } - /* Save Plugin */ - g_mux_obj_ptr->plugin = plugin; + /* Update 'mode' */ + cmux_obj->cmux_mode = mode; + dbg("Mode: \'%s\'", (mode == CMUX_MODE_BASIC ? "Basic" : "Advanced")); /* Save Physical HAL */ - g_mux_obj_ptr->phy_hal = hal; + cmux_obj->phy_hal = phy_hal; + + /* Save Modem Interface Plug-in */ + cmux_obj->plugin = tcore_hal_ref_plugin(phy_hal); - /* Setting Receive callback function for data received from Physical HAL */ - g_mux_obj_ptr->cb_func = tcore_cmux_recv_mux_data; + /* CMUX setup callback function */ + cmux_obj->internal_mux.channel_setup_cb = channel_setup_cb; + cmux_obj->internal_mux.channel_setup_user_data = channel_setup_user_data; - /* After MUX setup, AT parse functionality of PHY HAL should be disabled, - * here we change the mode of PHYSICAL HAL to Transparent. - */ - tcore_hal_set_mode(g_mux_obj_ptr->phy_hal, TCORE_HAL_MODE_TRANSPARENT); + /* CMUX setup complete callback function */ + cmux_obj->internal_mux.setup_complete_cb = setup_complete_cb; + cmux_obj->internal_mux.setup_complete_user_data = setup_complete_user_data; + + /* + * After CMUX setup, AT parse functionality of PHY HAL should be disabled, + * here we change the mode of PHYSICAL HAL to Transparent from AT. + */ + tcore_hal_set_mode(phy_hal, TCORE_HAL_MODE_TRANSPARENT); dbg("Physical HAL mode changed to Transparent"); - /* Initialize all the Channels */ + /* Adding CMUX object to Global List */ + g_cmux_obj = g_slist_insert(g_cmux_obj, cmux_obj, 0); + + /* Initialize all the Channels for the CMUX object */ /* Open all Channels */ - for (index = 0; index < MAX_CMUX_CHANNELS_SUPPORTED; index++) { - dbg("Initialize the Channel %d", index); - tcore_cmux_channel_init((CMUX_Channels) index); + for (temp_index = 0; temp_index < cmux_obj->max_cmux_channels; temp_index++) { + dbg("Initializing CMUX Channel [%d]", temp_index); + _cmux_channel_init(cmux_obj, temp_index); - dbg("Opening Channel %d", index); + dbg("Opening Channel ID [%d]", temp_index); /* Encode CMUX Frame */ - data = tcore_encode_cmux_frame(NULL, 0, index, CMUX_COMMAND_SABM, 0x01, 0x01, 0x01, &data_len); - if (0 == data_len) { + data = _cmux_encode_cmux_frame(cmux_obj, NULL, 0, temp_index, + CMUX_COMMAND_SABM, 0x01, 0x01, 0x01, &data_len); + if (data_len == 0) { err("Failed to encode"); - - ret = TCORE_RETURN_FAILURE; goto ERROR; } - dbg("data_len: %d data: %s", data_len, data); + dbg("data_len: [%d] data: [%s]", data_len, data); /* Send CMUX data */ - tcore_cmux_send_data(data_len, data); - dbg("CMUX Control Request sent to CP"); - - /* Set Core object and HAL */ - tcore_cmux_link_core_object_hal((CMUX_Channels) index, plugin); + ret = _cmux_send_data(cmux_obj->phy_hal, data_len, data); + if (ret != TCORE_RETURN_SUCCESS) { + err("Failed to send CMUX Control Request for Channel ID: [%d]", temp_index); + goto ERROR; + } else + dbg("CMUX Control Request sent to CP"); } dbg("Exit"); @@ -1169,77 +1425,61 @@ TReturn tcore_cmux_init(TcorePlugin *plugin, TcoreHal *hal) ERROR: /* Free the allocated CMUX memory */ - tcore_cmux_free(); + _cmux_free(cmux_obj); err("Exit"); return ret; } -void tcore_cmux_close(void) +/* Close CMUX */ +void tcore_cmux_close(TcoreHal *phy_hal, + cmux_channel_close_cb_func channel_close_cb, gpointer channel_close_user_data) { - int channel = 0; - int index = 0; - CoreObject *co = NULL; - GSList *co_list = NULL; - + tcore_cmux_object *cmux_obj; + int channel_id; dbg("Entry"); - for (channel = 0; channel < MAX_CMUX_CHANNELS_SUPPORTED; channel++) { - dbg("Channel ID: %d", channel); - index = 0; + /* + * Get CMUX Object from Modem Interface Plug-in + */ + cmux_obj = _cmux_get_cmux_object(tcore_hal_ref_plugin(phy_hal)); + if (cmux_obj == NULL) + return; - /* Close Channel - Send DSC command */ - tcore_cmux_close_channel(channel); - - /* Revert Physical HAL as HAL of each Core Object associated to this Channel */ - while (NULL != cmux_channel_core_object[channel].core_object_name[index]) { - co = NULL; - - /* Core Objects list */ - co_list = g_mux_obj_ptr->channel_info[channel]->co; - dbg("Core Objects list : %p", co_list); - - /* Core Object list may contain multiple Core Objects. - * Revert to Physical HAL for each of the Core Objects associated - * with this Channel - */ - while (NULL != co_list) { - if (NULL != co_list->data) { - if (!strcmp((const char *) cmux_channel_core_object[channel].core_object_name[index], (const char *) tcore_object_ref_name((CoreObject *) co_list->data))) { - co = (CoreObject *) co_list->data; - dbg("Core Object found "); - break; - } - } + /* Internal CMUX */ + dbg("Closing Internal CMUX"); - /* To next Core Object in the list */ - co_list = co_list->next; - } + /* Close all Channels */ + for (channel_id = 0; + channel_id < cmux_obj->max_cmux_channels; + channel_id++) { + dbg("Closing Channel - ID: [%d]", channel_id); - /* Set the previous Physical HAL as HAL for Core Object */ - if (NULL != co) { - tcore_object_set_hal(co, g_mux_obj_ptr->phy_hal); - } else { - /* Proceed to next Channel */ - err("No more Core Objects present in this Channel"); - break; - } + /* Close Channel - Send DSC command */ + _cmux_close_channel(cmux_obj, channel_id); - /* To next Core Object */ - index++; - } + /* Invoke callback */ + if (channel_close_cb != NULL) + channel_close_cb(cmux_obj->internal_mux.channel_info[channel_id]->hal, + channel_close_user_data); /* Free Logical HAL for Channel */ - tcore_hal_free(g_mux_obj_ptr->channel_info[channel]->hal); - g_mux_obj_ptr->channel_info[channel]->hal = NULL; + tcore_hal_free(cmux_obj->internal_mux.channel_info[channel_id]->hal); + cmux_obj->internal_mux.channel_info[channel_id]->hal = NULL; } - /* Change the mode of PHYSICAL HAL to Custom */ - tcore_hal_set_mode(g_mux_obj_ptr->phy_hal, TCORE_HAL_MODE_AT); + /* Freeing CMUX frame processing buffer */ + g_free(cmux_obj->cmux_buffer); + cmux_obj->cmux_buffer = NULL; + + /* Change the mode of PHYSICAL HAL from Transparent to AT */ + tcore_hal_set_mode(cmux_obj->phy_hal, TCORE_HAL_MODE_AT); + + /* Remove from list */ + g_cmux_obj = g_slist_remove(g_cmux_obj, cmux_obj); /* Free all the allocated memory */ - tcore_cmux_free(); + _cmux_free(cmux_obj); dbg("Exit"); - return; } diff --git a/src/plugin.c b/src/plugin.c index 1e6cba8..035cc73 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -52,7 +52,7 @@ TcorePlugin *tcore_plugin_new(Server *server, { TcorePlugin *p; - p = calloc(sizeof(struct tcore_plugin_type), 1); + p = calloc(1, sizeof(struct tcore_plugin_type)); if (!p) return NULL; @@ -79,9 +79,6 @@ void tcore_plugin_free(TcorePlugin *plugin) if (plugin->list_co) { for (list = plugin->list_co; list; list = list->next) { - if (!list) - continue; - o = list->data; if (!o) continue; @@ -133,7 +130,7 @@ char *tcore_plugin_get_filename(TcorePlugin *plugin) return strdup(plugin->filename); } -char* tcore_plugin_ref_plugin_name(TcorePlugin *plugin) +const char* tcore_plugin_ref_plugin_name(TcorePlugin *plugin) { if (!plugin) return NULL; @@ -165,7 +162,7 @@ TReturn tcore_plugin_link_user_data(TcorePlugin *plugin, void *user_data) void *tcore_plugin_ref_user_data(TcorePlugin *plugin) { if (!plugin) - return FALSE; + return NULL; return plugin->user_data; } @@ -182,7 +179,19 @@ TReturn tcore_plugin_add_core_object(TcorePlugin *plugin, CoreObject *co) return TCORE_RETURN_SUCCESS; } -CoreObject *tcore_plugin_ref_core_object(TcorePlugin *plugin, const char *name) +TReturn tcore_plugin_remove_core_object(TcorePlugin *plugin, CoreObject *co) +{ + if (!plugin || !co) + return TCORE_RETURN_EINVAL; + + dbg("remove core_object! (name=%s)", tcore_object_ref_name(co)); + + plugin->list_co = g_slist_remove(plugin->list_co, co); + + return TCORE_RETURN_SUCCESS; +} + +CoreObject *tcore_plugin_ref_core_object(TcorePlugin *plugin, unsigned int type) { GSList *list; CoreObject *co; @@ -191,14 +200,11 @@ CoreObject *tcore_plugin_ref_core_object(TcorePlugin *plugin, const char *name) return NULL; for (list = plugin->list_co; list; list = list->next) { - if (!list) - continue; - co = list->data; if (!co) continue; - if (strcmp(tcore_object_ref_name(co), name) == 0) { + if (tcore_object_get_type(co) == type) { return co; } } @@ -206,8 +212,7 @@ CoreObject *tcore_plugin_ref_core_object(TcorePlugin *plugin, const char *name) return NULL; } - -GSList *tcore_plugin_get_core_objects_bytype(TcorePlugin *plugin, unsigned int type) +GSList *tcore_plugin_get_core_objects(TcorePlugin *plugin) { GSList *list, *rlist = NULL; CoreObject *co; @@ -216,16 +221,31 @@ GSList *tcore_plugin_get_core_objects_bytype(TcorePlugin *plugin, unsigned int t return NULL; for (list = plugin->list_co; list; list = list->next) { - if (!list) + co = list->data; + if (!co) continue; + rlist = g_slist_append(rlist, co); + } + + return rlist; +} + +GSList *tcore_plugin_get_core_objects_bytype(TcorePlugin *plugin, unsigned int type) +{ + GSList *list, *rlist = NULL; + CoreObject *co; + + if (!plugin) + return NULL; + + for (list = plugin->list_co; list; list = list->next) { co = list->data; if (!co) continue; - if (tcore_object_get_type(co) == type) { + if ((CORE_OBJECT_TYPE_DEFAULT |(tcore_object_get_type(co) & 0x0FF00000)) == type) rlist = g_slist_append(rlist, co); - } } return rlist; @@ -242,9 +262,6 @@ TReturn tcore_plugin_core_object_event_emit(TcorePlugin *plugin, const char *eve dbg("event(%s) emit", event); for (list = plugin->list_co; list; list = list->next) { - if (!list) - continue; - co = list->data; if (!co) continue; diff --git a/src/queue.c b/src/queue.c index 83704b4..0f115b5 100644 --- a/src/queue.c +++ b/src/queue.c @@ -91,7 +91,7 @@ static gboolean _on_pending_timeout(gpointer user_data) tcore_pending_emit_timeout_callback(p); p->on_response = NULL; - tcore_hal_dispatch_response_data(p->queue->hal, p->id, 0, NULL); + tcore_hal_free_timeout_pending_request(p->queue->hal, p, 0, NULL); return FALSE; } @@ -100,7 +100,7 @@ TcorePending *tcore_pending_new(CoreObject *co, unsigned int id) { TcorePending *p; - p = calloc(sizeof(struct tcore_pending_type), 1); + p = calloc(1, sizeof(struct tcore_pending_type)); if (!p) return NULL; @@ -131,11 +131,12 @@ void tcore_pending_free(TcorePending *pending) dbg("pending(0x%x) free, id=0x%x", (unsigned int)pending, pending->id); - if ((tcore_hal_get_mode(pending->queue->hal) != TCORE_HAL_MODE_AT) - && (tcore_hal_get_mode(pending->queue->hal) != TCORE_HAL_MODE_TRANSPARENT)) - { - if (pending->data) - free(pending->data); + if (pending->queue) { + enum tcore_hal_mode mode = tcore_hal_get_mode(pending->queue->hal); + if ((mode != TCORE_HAL_MODE_AT) + && (mode != TCORE_HAL_MODE_TRANSPARENT)) + if (pending->data) + free(pending->data); } if (pending->timer_src) { @@ -233,6 +234,16 @@ TReturn tcore_pending_get_priority(TcorePending *pending, return TCORE_RETURN_SUCCESS; } +TReturn tcore_pending_start_timer(TcorePending *pending) +{ + /* pending timer */ + if (pending->timeout > 0 && pending->on_timeout) { + dbg("start pending timer! (%d secs)", pending->timeout); + pending->timer_src = g_timeout_add_seconds(pending->timeout, _on_pending_timeout, pending); + } + return TCORE_RETURN_SUCCESS; +} + TReturn tcore_pending_set_timeout(TcorePending *pending, unsigned int timeout) { if (!pending) @@ -243,6 +254,14 @@ TReturn tcore_pending_set_timeout(TcorePending *pending, unsigned int timeout) return TCORE_RETURN_SUCCESS; } +unsigned int tcore_pending_get_timeout(TcorePending *pending) +{ + if (!pending) + return 0; + + return pending->timeout; +} + TReturn tcore_pending_get_send_status(TcorePending *pending, gboolean *result_status) { @@ -300,14 +319,6 @@ TReturn tcore_pending_emit_send_callback(TcorePending *pending, gboolean result) if (pending->on_send) pending->on_send(pending, result, pending->on_send_user_data); - if (result == TRUE) { - if (pending->flag_auto_free_after_sent == FALSE && pending->timeout > 0) { - /* timer */ - dbg("start pending timer! (%d secs)", pending->timeout); - pending->timer_src = g_timeout_add_seconds(pending->timeout, _on_pending_timeout, pending); - } - } - return TCORE_RETURN_SUCCESS; } @@ -373,7 +384,7 @@ TcoreQueue *tcore_queue_new(TcoreHal *h) { TcoreQueue *queue; - queue = calloc(sizeof(struct tcore_queue_type), 1); + queue = calloc(1, sizeof(struct tcore_queue_type)); if (!queue) return FALSE; @@ -453,8 +464,8 @@ TReturn tcore_queue_push(TcoreQueue *queue, TcorePending *pending) break; } - dbg("pending(0x%x) push to queue. queue length=%d", - (unsigned int)pending, g_queue_get_length(queue->gq)); + dbg("pending(%p) push to queue(%p). queue length=%d", + (unsigned int)pending, queue, g_queue_get_length(queue->gq)); return TCORE_RETURN_SUCCESS; } @@ -637,8 +648,6 @@ TcorePending *tcore_queue_ref_next_pending(TcoreQueue *queue) else { break; } - - i++; } while (pending != NULL); if (pending->flag_sent == TRUE) { @@ -657,6 +666,31 @@ unsigned int tcore_queue_get_length(TcoreQueue *queue) return g_queue_get_length(queue->gq); } +unsigned int tcore_queue_get_normal_length(TcoreQueue *queue) +{ + TcorePending *pending; + int i = 0; + + if (!queue) + return 0; + + do { + pending = g_queue_peek_nth(queue->gq, i); + if (!pending) { + break; + } + + if (pending->priority == TCORE_PENDING_PRIORITY_IMMEDIATELY) { + i++; + continue; + } + + break; + } while (1); + + return g_queue_get_length(queue->gq) - i; +} + TcoreHal *tcore_queue_ref_hal(TcoreQueue *queue) { if (!queue) @@ -677,12 +711,14 @@ TReturn tcore_queue_cancel_pending_by_command(TcoreQueue *queue, enum tcore_requ if (!pending) break; - dbg("pending(0x%x) cancel", pending); + dbg("pending(0x%x) cancel", (unsigned int)pending); if (queue->hal) { + dbg("hal %p", queue->hal); tcore_hal_dispatch_response_data(queue->hal, pending->id, 0, NULL); } else { + dbg("no hal"); pending = tcore_queue_pop_by_pending(queue, pending); tcore_pending_emit_response_callback(pending, 0, NULL); tcore_user_request_unref(tcore_pending_ref_user_request(pending)); diff --git a/src/server.c b/src/server.c index e8de071..c73c759 100644 --- a/src/server.c +++ b/src/server.c @@ -38,6 +38,9 @@ #include "communicator.h" #include "storage.h" #include "udev.h" +#include "util.h" + +#define MODEMS_PATH "/usr/lib/telephony/plugins/modems/" struct tcore_server_type { GMainLoop *mainloop; @@ -45,12 +48,25 @@ struct tcore_server_type { GSList *communicators; GSList *storages; GSList *hals; + GSList *modems; + + GSList *template_co; + GSList *hook_list_request; GSList *hook_list_notification; TcorePlugin *default_plugin; TcoreUdev *udev; }; +struct tcore_modem_type { + char *cp_name; + TcorePlugin *modem_iface_plugin; + + TcorePlugin *modem_plugin; + + void *mapping_tbl; +}; + struct hook_request_type { enum tcore_request_command command; TcoreServerRequestHook func; @@ -75,28 +91,74 @@ static gint _compare_priority(gconstpointer a, gconstpointer b) tcore_plugin_get_description(plugin2)->priority; } +static char *_server_enumerate_modem(TcorePlugin *plugin) +{ + static unsigned int cp_counter = 0; + const char *filename; + + if (plugin == NULL) + return NULL; + + /* + * Presently enumeration is based on Modem Interface Plug-in descriptor name + * followed by an incremental Positive integer 'cp_count'. + * + * For example, if Modem Interface Plug-in descriptor name is 'qmimodem' then, + * 'name' would be enumerated as "qmimodem_N", where N >= 0 + */ + filename = tcore_plugin_ref_plugin_name(plugin); + if (filename == NULL) + return NULL; + + dbg("%s", filename); + + return g_strdup_printf("%s%d", filename, cp_counter++); +} + +static TcoreModem *__get_modem(TcorePlugin *modem_plugin) +{ + GSList *list; + TcoreModem *modem; + Server *s; + + s = tcore_plugin_ref_server(modem_plugin); + if (s == NULL) { + err("server is NULL"); + return NULL; + } + + for (list = s->modems; list; list = list->next) { + modem = list->data; + if (modem == NULL) { + dbg("Modem is NULL"); + continue; + } + + if (modem->modem_plugin == modem_plugin) + return modem; + } + + err("Modem not found"); + + return NULL; +} + static TcorePlugin *_find_default_plugin(Server *s) { GSList *list; - TcorePlugin *p; - GSList *co_list; + TcoreModem *modem; if (s->default_plugin != NULL) { return s->default_plugin; } - for (list = s->plugins; list; list = list->next) { - p = list->data; - if (!p) - continue; - - co_list = tcore_plugin_get_core_objects_bytype(p, CORE_OBJECT_TYPE_MODEM); - if (!co_list) + for (list = s->modems; list; list = list->next) { + modem = list->data; + if (modem == NULL) continue; - g_slist_free(co_list); - s->default_plugin = p; - return p; + s->default_plugin = modem->modem_plugin; + return modem->modem_plugin; } return NULL; @@ -106,12 +168,15 @@ Server *tcore_server_new() { Server *s; - s = calloc(sizeof(struct tcore_server_type), 1); - if (!s) + s = calloc(1, sizeof(struct tcore_server_type)); + if (!s) { + err("Server allocation failed!!!"); return NULL; + } s->mainloop = g_main_loop_new (NULL, FALSE); if (!s->mainloop) { + err("mainloop creation failed!!!"); free(s); return NULL; } @@ -133,39 +198,58 @@ void tcore_server_free(Server *s) TcorePlugin *p = NULL; struct tcore_plugin_define_desc *desc = NULL; - if (!s) + if (!s) { + err("Server is NULL"); return; + } + s->plugins = g_slist_reverse(s->plugins); - if (s->mainloop) - g_main_loop_unref(s->mainloop); - - for (list = s->plugins; list; list = list->next) { - p = list->data; - if (!p) - continue; + /* Unload all plug-ins */ + for (list = s->plugins; list; list = list->next) { + p = list->data; + if (!p) + continue; - desc = (struct tcore_plugin_define_desc *)tcore_plugin_get_description(p); + desc = (struct tcore_plugin_define_desc *)tcore_plugin_get_description(p); if (!desc || !desc->unload) continue; - desc->unload(p); + desc->unload(p); + + tcore_plugin_free(p); - tcore_plugin_free(p); + list->data = NULL; + } + + /* Free plug-ins */ + if (s->plugins) { + g_slist_free(s->plugins); + s->plugins = NULL; + } - list->data = NULL; - } + /* Unref 'mainloop' */ + if (s->mainloop) { + g_main_loop_unref(s->mainloop); + } - if (s->plugins) { - g_slist_free(s->plugins); - s->plugins = NULL; - } + /* Free server */ + free(s); + dbg("Freeing Server"); } TReturn tcore_server_run(Server *s) { + char *version; + if (!s || !s->mainloop) return TCORE_RETURN_EINVAL; + version = tcore_util_get_version(); + if (version) { + dbg("libtcore version: %s", version); + free(version); + } + tcore_server_send_notification(s, NULL, TNOTI_SERVER_RUN, 0, NULL); g_main_loop_run(s->mainloop); @@ -198,23 +282,23 @@ TReturn tcore_server_add_plugin(Server *s, TcorePlugin *plugin) TcorePlugin *tcore_server_find_plugin(Server *s, const char *name) { GSList *list; - TcorePlugin *p; + TcoreModem *modem; - if (g_strcmp0(name, TCORE_PLUGIN_DEFAULT) == 0) { + dbg("Name: [%s]", name); + if (g_strcmp0(TCORE_PLUGIN_DEFAULT, name) == 0) return _find_default_plugin(s); - } - for (list = s->plugins; list; list = list->next) { - p = list->data; - if (!p) { + for (list = s->modems; list; list = list->next) { + modem = list->data; + if (modem == NULL) continue; - } - if (g_strcmp0(tcore_plugin_get_description(p)->name, name) == 0) { - return p; - } + if (g_strcmp0(modem->cp_name, name) == 0) + return modem->modem_plugin; } + err("Modem plugin not found"); + return NULL; } @@ -238,6 +322,17 @@ TReturn tcore_server_add_communicator(Server *s, Communicator *comm) return TCORE_RETURN_SUCCESS; } +TReturn tcore_server_remove_communicator(Server *s, Communicator *comm) +{ + if (!s || !comm) + return TCORE_RETURN_EINVAL; + + s->communicators = g_slist_remove( s->communicators, comm ); + + return TCORE_RETURN_SUCCESS; +} + + GSList *tcore_server_ref_communicators(Server *s) { if (!s) @@ -329,6 +424,20 @@ TReturn tcore_server_add_hal(Server *s, TcoreHal *hal) return TCORE_RETURN_SUCCESS; } +TReturn tcore_server_remove_hal(Server *s, TcoreHal *hal) +{ + if (!s || !hal) + return TCORE_RETURN_EINVAL; + + /* Remove HAL from list */ + s->hals = g_slist_remove(s->hals, hal); + + /* Send Notification */ + tcore_server_send_notification(s, NULL, TNOTI_SERVER_REMOVED_HAL, 0, NULL); + + return TCORE_RETURN_SUCCESS; +} + GSList *tcore_server_ref_hals(Server *s) { if (!s) @@ -337,6 +446,23 @@ GSList *tcore_server_ref_hals(Server *s) return s->hals; } +CoreObject *tcore_server_find_template_object(Server *s, unsigned int type) +{ + GSList *list; + CoreObject *template_co; + + for (list = s->template_co; list; list = list->next) { + template_co = list->data; + if (template_co == NULL) + continue; + + if (type == tcore_object_get_type(template_co)) + return template_co; + } + + return NULL; +} + TcoreHal *tcore_server_find_hal(Server *s, const char *name) { GSList *list; @@ -384,7 +510,7 @@ TcoreUdev *tcore_server_ref_udev(Server *s) TReturn tcore_server_dispatch_request(Server *s, UserRequest *ur) { - char *modem = NULL; + char *modem_name = NULL; TcorePlugin *p; enum tcore_request_command command = 0; GSList *list, *co_list=NULL; @@ -392,6 +518,7 @@ TReturn tcore_server_dispatch_request(Server *s, UserRequest *ur) int category; CoreObject *o; TReturn ret = TCORE_RETURN_ENOSYS; + TReturn prev_ret = TCORE_RETURN_FAILURE; if (!s || !ur) return TCORE_RETURN_EINVAL; @@ -409,16 +536,16 @@ TReturn tcore_server_dispatch_request(Server *s, UserRequest *ur) } } - modem = tcore_user_request_get_modem_name(ur); - if (!modem) + modem_name = tcore_user_request_get_modem_name(ur); + if (!modem_name) return TCORE_RETURN_EINVAL; - p = tcore_server_find_plugin(s, modem); + p = tcore_server_find_plugin(s, (const char*)modem_name); if (!p) { - free(modem); + free(modem_name); return TCORE_RETURN_SERVER_WRONG_PLUGIN; } - free(modem); + free(modem_name); command = tcore_user_request_get_command(ur); @@ -426,7 +553,7 @@ TReturn tcore_server_dispatch_request(Server *s, UserRequest *ur) co_list = tcore_plugin_get_core_objects_bytype(p, category); if (!co_list) { - warn("can't find 0x%x core_object", category); + warn("can't find 0x%x core_object. co_list is null.", category); return TCORE_RETURN_ENOSYS; } @@ -437,10 +564,21 @@ TReturn tcore_server_dispatch_request(Server *s, UserRequest *ur) continue; } - if (tcore_object_dispatch_request(o, ur) == TCORE_RETURN_SUCCESS) - ret = TCORE_RETURN_SUCCESS; - else - dbg("failed..."); + /* + * SUCCESS would be returned if even one of the Core Object + * in the list 'co_list' Successfully processes the request. + * + * The concept is to consider that the Request is being + * processed atleast by 1 entity. + */ + ret = tcore_object_dispatch_request(o, ur); + if ( ret != TCORE_RETURN_SUCCESS) { + dbg("failed... ret=[%d]", ret); + } + else { + prev_ret = ret; + } + ret = prev_ret; } g_slist_free(co_list); @@ -454,12 +592,12 @@ TReturn tcore_server_send_notification(Server *s, CoreObject *source, GSList *list; Communicator *comm; struct hook_notification_type *hook; - if (!s) return TCORE_RETURN_EINVAL; - for (list = s->hook_list_notification; list; list = list->next) { + for (list = s->hook_list_notification; list;) { hook = list->data; + list = list->next; if (!hook) { continue; } @@ -471,8 +609,9 @@ TReturn tcore_server_send_notification(Server *s, CoreObject *source, } } - for (list = s->communicators; list; list = list->next) { + for (list = s->communicators; list;) { comm = list->data; + list = list->next; if (!comm) { continue; } @@ -492,7 +631,7 @@ TReturn tcore_server_add_request_hook(Server *s, if (!s || !func) return TCORE_RETURN_EINVAL; - hook = calloc(sizeof(struct hook_request_type), 1); + hook = calloc(1, sizeof(struct hook_request_type)); if (!hook) return TCORE_RETURN_ENOMEM; @@ -538,7 +677,7 @@ TReturn tcore_server_add_notification_hook(Server *s, if (!s || !func) return TCORE_RETURN_EINVAL; - hook = calloc(sizeof(struct hook_notification_type), 1); + hook = calloc(1, sizeof(struct hook_notification_type)); if (!hook) return TCORE_RETURN_ENOMEM; @@ -575,3 +714,331 @@ TReturn tcore_server_remove_notification_hook(Server *s, return TCORE_RETURN_SUCCESS; } + +TcoreModem *tcore_server_register_modem(Server *s, TcorePlugin *modem_iface_plugin) +{ + TcoreModem *modem; + + if ((s == NULL) || (modem_iface_plugin == NULL)) { + err("Server [%p] Modem Interface Plug-in: [%p]", s, modem_iface_plugin); + return NULL; + } + + /* Allocate 'modem' */ + modem = g_try_new0(TcoreModem, 1); + if (modem == NULL) { + err("Failed to allocate memory"); + return NULL; + } + + /* Enumerate CP Name to 'modem' */ + modem->cp_name = _server_enumerate_modem(modem_iface_plugin); + + /* Update Modem Interface Plug-in to 'modem' */ + modem->modem_iface_plugin = modem_iface_plugin; + + /* Add 'modem' to 'modems' list */ + s->modems = g_slist_append(s->modems, modem); + dbg("Added to 'modems' entry - CP Name: [%s] Modem Interface Plug-in: [%s]", + modem->cp_name, tcore_plugin_ref_plugin_name(modem_iface_plugin)); + + return modem; +} + +void tcore_server_unregister_modem(Server *s, TcoreModem *modem) +{ + if ((s == NULL) || (modem == NULL)) { + err("server [%p] Modem: [%p]", s, modem); + return; + } + + /* Remove 'modem' from 'modems' list */ + s->modems = g_slist_remove(s->modems, modem); + dbg("Removed from 'modems' entry - CP Name: [%s] Modem Interface Plug-in: [%s]", + modem->cp_name, tcore_plugin_ref_plugin_name(modem->modem_iface_plugin)); + + /* Free memory */ + g_free(modem->cp_name); + g_free(modem); +} + +GSList *tcore_server_get_cp_name_list(Server *s) +{ + GSList *cp_name_list = NULL; + GSList *list; + TcoreModem *modem; + + int i = 0; + + if (s == NULL) { + err("Server is NULL"); + return NULL; + } + + for (list = s->modems; list; list = list->next) { + modem = list->data; + if (modem == NULL) { + dbg("No modem - continue"); + continue; + } + + /* Add CP name to 'cp_name_list' */ + dbg("[%d] CP Name: [%s]", i++, modem->cp_name); + cp_name_list = g_slist_append(cp_name_list, g_strdup(modem->cp_name)); + } + + /* 'cp_name_list' would be freed by the calling function */ + return cp_name_list; +} + +const char *tcore_server_get_cp_name_by_plugin(TcorePlugin *modem_plugin) +{ + TcoreModem *modem; + + if (modem_plugin == NULL) { + err("Modem Plug-in is NULL"); + return NULL; + } + + modem = __get_modem(modem_plugin); + if (modem == NULL) { + err("Failed to find 'modem' for Plug-in: [%s]", + tcore_plugin_ref_plugin_name(modem_plugin)); + return NULL; + } + + return (const char *)modem->cp_name; +} + +gboolean tcore_server_add_cp_mapping_tbl_entry(TcoreModem *modem, + unsigned int co_type, TcoreHal *hal) +{ + if (modem == NULL) { + err("Modem is NULL"); + return FALSE; + } + + /* + * Set the Mapping Table to the Modems list + */ + modem->mapping_tbl = + tcore_object_add_mapping_tbl_entry(modem->mapping_tbl, + co_type, hal); + + return TRUE; +} + +void tcore_server_remove_cp_mapping_tbl(TcoreModem *modem) +{ + if (modem == NULL) { + err("Modem is NULL"); + return; + } + + /* Removing the Mapping Table from the Modems list */ + tcore_object_remove_mapping_tbl(modem->mapping_tbl); +} + +void tcore_server_remove_cp_mapping_tbl_entry(TcoreModem *modem, + TcoreHal *hal) +{ + if (modem == NULL) { + err("Modem is NULL"); + return; + } + + /* Removing the Mapping Table Entry from the Modems list */ + modem->mapping_tbl = + tcore_object_remove_mapping_tbl_entry(modem->mapping_tbl, hal); +} + +void *tcore_server_get_cp_mapping_tbl(TcorePlugin *modem_plugin) +{ + TcoreModem *modem; + + if (modem_plugin == NULL) { + err("Modem Interface is NULL"); + return NULL; + } + + modem = __get_modem(modem_plugin); + if (modem == NULL) { + err("Failed to find 'modem' for Modem Plug-in: [%s]", + tcore_plugin_ref_plugin_name(modem_plugin)); + return NULL; + } + + return modem->mapping_tbl; +} + +void tcore_server_print_modems(Server *s) +{ + TcoreModem *modem; + GSList *list; + + if (s == NULL) { + err("Server is NULL"); + return; + } + + for (list = s->modems ; list ; list = list->next) { + modem = list->data; + if (modem == NULL) { + dbg("Modem is NULL"); + continue; + } + + msg("Modem: [0x%x] CP Name: [%s]", modem, modem->cp_name); + msg("Modem Plug-in: [%s] <---> Modem Interface Plug-in: [%s]", + tcore_plugin_ref_plugin_name(modem->modem_plugin), + tcore_plugin_ref_plugin_name(modem->modem_iface_plugin)); + } +} + +TReturn tcore_server_load_modem_plugin(Server *s, + TcoreModem *modem, + const char *name) +{ + struct tcore_plugin_define_desc *desc; + TcorePlugin *modem_plugin; + char *filename = NULL; + void *handle; + TReturn ret = TCORE_RETURN_FAILURE; + + if ((s == NULL) || (modem == NULL) || (name == NULL)) { + err("Server: [%p] modem: [%p] Plug-in Name (.so): [%s] ", + s, modem, name); + ret = TCORE_RETURN_EINVAL; + goto out; + } + + filename = g_build_filename(MODEMS_PATH, name, NULL); + + /* Open '.so' */ + handle = dlopen(filename, RTLD_LAZY); + if (handle == NULL) { + err("Failed to load '%s': %s", filename, dlerror()); + goto out; + } + + desc = dlsym(handle, "plugin_define_desc"); + if (desc == NULL) { + err("Failed to obtain the address of plugin_define_desc: %s", dlerror()); + dlclose(handle); + goto out; + } + + dbg("Plugin %s found", desc->name); + + if (desc->load != NULL) { + /* Load Modem Plug-in */ + if (desc->load() == FALSE) { + err("Failed to load %s plugin", desc->name); + dlclose(handle); + goto out; + } + } + + /* Create new Plug-in */ + modem_plugin = tcore_plugin_new(s, desc, filename, handle); + if (modem_plugin == NULL) { + err("Modem Plug-in is NULL"); + dlclose(handle); + goto out; + } + + /* Update Modem Plug-in to 'modem' */ + modem->modem_plugin = modem_plugin; + + dbg("Plugin %s loaded successfully", desc->name); + + if (desc->init == NULL) { + err("Plugin %s has no initializer", desc->name); + dlclose(handle); + goto out; + } + + /* Initialize Modem Plug-in */ + if (desc->init(modem_plugin) == FALSE) { + err("Plugin %s initialization failed", desc->name); + dlclose(handle); + goto out; + } + + dbg("Plugin %s initialization success", desc->name); + + /* Notify addition of Plug-in to Upper Layers */ + tcore_server_send_notification(s, NULL, TNOTI_SERVER_ADDED_MODEM_PLUGIN, + 0, modem_plugin); + + ret = TCORE_RETURN_SUCCESS; + +out: + g_free(filename); + + return ret; +} + +void tcore_server_unload_modem_plugin(Server *s, TcoreModem *modem) +{ + TcorePlugin *modem_plugin; + const struct tcore_plugin_define_desc *desc; + + if ((s == NULL) || (modem == NULL)) { + err("Server: [%p] modem: [%p]", s, modem); + return; + } + + /* Extract Modem Plug-in */ + modem_plugin = modem->modem_plugin; + if (modem_plugin == NULL) { + err("Modem Plug-in is NULL"); + return; + } + + msg("Modem Plug-in: [%s] <---> Modem Interface Plug-in: [%s] - CP Name: [%s]", + tcore_plugin_ref_plugin_name(modem->modem_plugin), + tcore_plugin_ref_plugin_name(modem->modem_iface_plugin), modem->cp_name); + + /* Notify removal of Plug-in to Upper Layers */ + tcore_server_send_notification(s, NULL, TNOTI_SERVER_REMOVED_MODEM_PLUGIN, + 0, modem_plugin); + + /* Extract descriptor of Modem Plug-in */ + desc = tcore_plugin_get_description(modem_plugin); + if (desc != NULL) { + /* Unload Modem Plug-in */ + if (desc->unload != NULL) { + dbg("Unloading Modem Plug-in: [%s]", + tcore_plugin_ref_plugin_name(modem_plugin)); + desc->unload(modem_plugin); + } + } + + /* Free Modem Plug-in */ + tcore_plugin_free(modem_plugin); + modem->modem_plugin = NULL; + + dbg("Unloaded Modem Plug-in"); +} + +GSList *tcore_server_get_modem_plugin_list(Server *s) +{ + GSList *list; + GSList *modem_plugin_list = NULL; + TcoreModem *modem; + + for (list = s->modems; list; list = list->next) { + modem = list->data; + if (modem == NULL) { + dbg("Modem is NULL"); + continue; + } + if (NULL != modem->modem_plugin) { + modem_plugin_list = g_slist_append(modem_plugin_list, modem->modem_plugin); + } + } + + return modem_plugin_list; +} + diff --git a/src/storage.c b/src/storage.c index e35c61d..a65aa6b 100644 --- a/src/storage.c +++ b/src/storage.c @@ -47,7 +47,7 @@ Storage *tcore_storage_new(TcorePlugin *plugin, const char *name, { Storage *strg; - strg = calloc(sizeof(struct tcore_storage_type), 1); + strg = calloc(1, sizeof(struct tcore_storage_type)); if (!strg) return NULL; @@ -139,7 +139,7 @@ gboolean tcore_storage_set_bool(Storage *strg, enum tcore_storage_key key, int tcore_storage_get_int(Storage *strg, enum tcore_storage_key key) { if (!strg || !strg->ops || !strg->ops->get_int) { - return FALSE; + return -1; } return strg->ops->get_int(strg, key); @@ -148,7 +148,7 @@ int tcore_storage_get_int(Storage *strg, enum tcore_storage_key key) char *tcore_storage_get_string(Storage *strg, enum tcore_storage_key key) { if (!strg || !strg->ops || !strg->ops->get_string) { - return FALSE; + return NULL; } return strg->ops->get_string(strg, key); @@ -166,25 +166,25 @@ gboolean tcore_storage_get_bool(Storage *strg, enum tcore_storage_key key) static void tcore_storage_vkey_callback_dispatcher(Storage *strg, enum tcore_storage_key key, void *value) { - gpointer tmp = NULL; gchar *key_gen = NULL; + GSList *cb_data = NULL; struct storage_callback_type *tmp_cb = NULL; key_gen = g_strdup_printf("%d", key); - tmp = g_hash_table_lookup(strg->callback, key_gen); - - if (tmp != NULL) { + if (!key_gen) + return; - GSList *cb_data = (GSList *) tmp; + cb_data = g_hash_table_lookup(strg->callback, key_gen); + while (cb_data) { + tmp_cb = cb_data->data; + if (tmp_cb) + if (tmp_cb->cb_fn) + tmp_cb->cb_fn(key, value, tmp_cb->user_data); - do { - tmp_cb = cb_data->data; - tmp_cb->cb_fn(key, value, tmp_cb->user_data); - } while ((cb_data = g_slist_next(cb_data))); + cb_data = g_slist_next(cb_data); } g_free(key_gen); - return; } gboolean tcore_storage_set_key_callback(Storage *strg, @@ -207,19 +207,24 @@ gboolean tcore_storage_set_key_callback(Storage *strg, key_gen = g_strdup_printf("%d", key); tmp = g_hash_table_lookup(strg->callback, key_gen); if (tmp != NULL) { - GSList *cb_data = (GSList *) tmp; + GSList *cb_data = tmp; - do { + while (cb_data) { tmp_cb = cb_data->data; - if (tmp_cb->cb_fn == cb) { - g_free(key_gen); - g_free(strg_cb_data); - return FALSE; + if (tmp_cb) { + if ((tmp_cb->cb_fn == cb) + && (tmp_cb->user_data == user_data)) { + g_free(key_gen); + g_free(strg_cb_data); + return FALSE; + } } - } while ((cb_data = g_slist_next(cb_data))); + cb_data = g_slist_next(cb_data); + } - tmp = g_slist_append( (GSList *)tmp, strg_cb_data); + tmp = g_slist_append(tmp, strg_cb_data); + g_hash_table_replace(strg->callback, g_strdup(key_gen), tmp); } else { GSList *data = NULL; @@ -235,7 +240,7 @@ gboolean tcore_storage_set_key_callback(Storage *strg, gboolean tcore_storage_remove_key_callback(Storage *strg, enum tcore_storage_key key, TcoreStorageKeyCallback cb) { - gpointer tmp = NULL; + GSList *tmp = NULL; gchar *key_gen = NULL; GSList *cb_data = NULL; int cb_cnt = 0; @@ -247,28 +252,29 @@ gboolean tcore_storage_remove_key_callback(Storage *strg, key_gen = g_strdup_printf("%d", key); tmp = g_hash_table_lookup(strg->callback, key_gen); - if (tmp == NULL){ g_free(key_gen); return FALSE; } - cb_data = (GSList *) tmp; - - do { + cb_data = tmp; + while (cb_data) { tmp_cb = cb_data->data; - if (tmp_cb->cb_fn == cb) { - tmp = g_slist_remove((GSList *) tmp, cb_data->data); - g_free(cb_data->data); - break; + if (tmp_cb) { + if (tmp_cb->cb_fn == cb) { + tmp = g_slist_remove(tmp, tmp_cb); + g_free(tmp_cb); + break; + } } - } while ((cb_data = g_slist_next(cb_data))); + cb_data = g_slist_next(cb_data); + } - cb_cnt = g_slist_length( (GSList *) tmp ); + cb_cnt = g_slist_length(tmp); dbg("glist cnt (%d)", cb_cnt); - if(cb_cnt == 0){ + if (cb_cnt == 0) { g_hash_table_remove(strg->callback, key_gen); strg->ops->remove_key_callback(strg, key); } diff --git a/src/udev.c b/src/udev.c index 3e13a5e..5c06884 100644 --- a/src/udev.c +++ b/src/udev.c @@ -60,7 +60,7 @@ static void _on_uevent(GUdevClient *client, gchar *action, GUdevDevice *device, return; dbg("action = '%s'", action); - + for (cb = udev->callbacks; cb; cb = cb->next) { node = cb->data; if (!node) @@ -85,7 +85,7 @@ TcoreUdev *tcore_udev_new(Server *s, const gchar **subsystems) { TcoreUdev *udev; - udev = calloc(sizeof(struct tcore_udev_type), 1); + udev = calloc(1, sizeof(struct tcore_udev_type)); if (!udev) return NULL; @@ -152,7 +152,7 @@ TReturn tcore_udev_add_enumerator_callback(TcoreUdev *udev, TcoreUdevEnumerCallb if (!udev || !func) return TCORE_RETURN_FAILURE; - node = calloc(sizeof(struct udev_enumer_callback_type), 1); + node = calloc(1, sizeof(struct udev_enumer_callback_type)); if (!node) return TCORE_RETURN_ENOMEM; @@ -204,7 +204,7 @@ TReturn tcore_udev_add_callback(TcoreUdev *udev, const char *subsystem, const ch if (!udev || !func) return TCORE_RETURN_FAILURE; - node = calloc(sizeof(struct udev_callback_type), 1); + node = calloc(1, sizeof(struct udev_callback_type)); if (!node) return TCORE_RETURN_ENOMEM; diff --git a/src/user_request.c b/src/user_request.c index edd10e2..5d7f27c 100644 --- a/src/user_request.c +++ b/src/user_request.c @@ -30,8 +30,9 @@ struct tcore_user_request_type { int ref; - struct tcore_user_info ui; + /* Communicator information */ + void *user_info; Communicator *comm; char *modem_name; @@ -45,15 +46,19 @@ struct tcore_user_request_type { unsigned int metainfo_len; UserRequestFreeHook free_hook; - UserRequestResponseHook response_hook; - void *response_hook_user_data; + GSList *response_hook; +}; + +struct hook_response_type { + UserRequestResponseHook func; + void *user_data; }; UserRequest *tcore_user_request_new(Communicator *comm, const char *modem_name) { UserRequest *ur; - ur = calloc(sizeof(struct tcore_user_request_type), 1); + ur = calloc(1, sizeof(struct tcore_user_request_type)); if (!ur) return NULL; @@ -77,6 +82,8 @@ void tcore_user_request_free(UserRequest *ur) return; } + g_slist_free_full(ur->response_hook, free); + if (ur->free_hook) ur->free_hook(ur); @@ -131,11 +138,19 @@ TReturn tcore_user_request_set_free_hook(UserRequest *ur, TReturn tcore_user_request_set_response_hook(UserRequest *ur, UserRequestResponseHook resp_hook, void *user_data) { + struct hook_response_type *hook; + if (!ur) return TCORE_RETURN_EINVAL; - ur->response_hook = resp_hook; - ur->response_hook_user_data = user_data; + hook = calloc(1, sizeof(struct hook_response_type)); + if (!hook) + return TCORE_RETURN_ENOMEM; + + hook->func = resp_hook; + hook->user_data = user_data; + + ur->response_hook = g_slist_append(ur->response_hook, hook); return TCORE_RETURN_SUCCESS; } @@ -159,53 +174,46 @@ char *tcore_user_request_get_modem_name(UserRequest *ur) return strdup(ur->modem_name); } -TReturn tcore_user_request_set_user_info(UserRequest *ur, - const struct tcore_user_info *ui) +TReturn tcore_user_request_set_user_info(UserRequest *ur, void *user_info) { - if (!ur || !ui) + if (!ur) return TCORE_RETURN_EINVAL; - ur->ui.uid = ui->uid; - ur->ui.gid = ui->gid; - ur->ui.pid = ui->pid; - ur->ui.channel_id = ui->channel_id; - ur->ui.client_cmd = ui->client_cmd; - ur->ui.user_data = ui->user_data; - - if (ur->ui.appname) { - dbg("free old appname (%s)", ur->ui.appname); - free(ur->ui.appname); - ur->ui.appname = NULL; - } - - if (ui->appname) { - ur->ui.appname = strdup(ui->appname); - dbg("alloc appname(%s, %s)", ur->ui.appname, ui->appname); - } + ur->user_info = user_info; return TCORE_RETURN_SUCCESS; } -const struct tcore_user_info *tcore_user_request_ref_user_info(UserRequest *ur) +void *tcore_user_request_ref_user_info(UserRequest *ur) { if (!ur) return NULL; - return &(ur->ui); + return ur->user_info; } TReturn tcore_user_request_send_response(UserRequest *ur, enum tcore_response_command command, unsigned int data_len, const void *data) { + GSList *list; + struct hook_response_type *hook; + if (!ur) { dbg("ur is NULL"); return TCORE_RETURN_EINVAL; } - if (ur->response_hook) { - ur->response_hook(ur, command, data_len, data, - ur->response_hook_user_data); + for (list = ur->response_hook; list;) { + hook = list->data; + list = list->next; + + if (!hook) { + continue; + } + + if (hook->func) + hook->func(ur, command, data_len, data, hook->user_data); } if (ur->comm) { @@ -241,14 +249,25 @@ TReturn tcore_user_request_set_data(UserRequest *ur, if (!ur) return TCORE_RETURN_EINVAL; - ur->data_len = data_len; + if (ur->data != NULL) { + free(ur->data); + ur->data = NULL; + } - if (data_len > 0 && data != NULL) { - ur->data = calloc(data_len, 1); - if (!ur->data) - return TCORE_RETURN_ENOMEM; + ur->data_len = data_len; - memcpy(ur->data, data, data_len); + if (data_len > 0) { + if (data != NULL) { + ur->data = calloc(data_len, 1); + if (!ur->data) { + ur->data_len = 0; + return TCORE_RETURN_ENOMEM; + } + + memcpy(ur->data, data, data_len); + } + else + ur->data_len = 0; } else { ur->data = NULL; @@ -263,17 +282,28 @@ TReturn tcore_user_request_set_metainfo(UserRequest *ur, if (!ur) return TCORE_RETURN_EINVAL; - if (metainfo_len > 0 && metainfo != NULL) { - ur->metainfo = calloc(metainfo_len, 1); - if (!ur->metainfo) - return TCORE_RETURN_ENOMEM; + if (ur->metainfo != NULL) { + free(ur->metainfo); + ur->metainfo = NULL; + } + + ur->metainfo_len = metainfo_len; + + if (metainfo_len > 0) { + if (metainfo != NULL) { + ur->metainfo = calloc(metainfo_len, 1); + if (!ur->metainfo) { + ur->metainfo_len = 0; + return TCORE_RETURN_ENOMEM; + } - ur->metainfo_len = metainfo_len; - memcpy(ur->metainfo, metainfo, metainfo_len); + memcpy(ur->metainfo, metainfo, metainfo_len); + } + else + ur->metainfo_len = 0; } else { ur->metainfo = NULL; - ur->metainfo_len = 0; } return TCORE_RETURN_SUCCESS; diff --git a/src/util.c b/src/util.c index 0f3c2a0..9462299 100644 --- a/src/util.c +++ b/src/util.c @@ -31,18 +31,818 @@ #include #include +#include #include "tcore.h" #include "util.h" +#define tabGsmUniMax2 9 +#define tabGsmUniMax 42 +#define TAB_SPACE " " + +gboolean tcore_debug = TRUE; + +static gboolean _find_gsm_code_exception_table(unsigned short src); +static int _get_gsm_code_size(unsigned short* src, int src_len); +static gboolean _convert_gsm_to_unicode(unsigned short *dest, int dest_len, unsigned char *src, unsigned int src_len); +static int _convert_gsm_to_ucs2(unsigned short* dest, unsigned char* src, unsigned int src_len); +static void _convert_gsm_to_utf8(unsigned char *dest, unsigned short *dest_len, unsigned char *src, unsigned int src_len); +static gboolean _convert_unicode_to_gsm(unsigned char* dest, int dest_len, unsigned short* src, int src_len); +static char* _convert_ucs_to_utf8(unsigned char *src, int src_len); +static int _convert_ucs2_to_gsm(unsigned char* dest, unsigned short* src, unsigned int src_len); +static void _convert_alpha_field_ucs2_to_utf8(unsigned char *out, unsigned short *out_len, unsigned char *in, unsigned short in_len); +static int _convert_utf8_to_unicode(unsigned short* dest, unsigned char* src, unsigned int src_len); + +typedef struct { + char gsm; + unsigned short unicode; +} GsmUniTable; + +const GsmUniTable gsm_unicode2_table[] = { + { 0x14, 0x005E }, { 0x28, 0x007B }, { 0x29, 0x007D }, { 0x2F, 0x005C }, + { 0x3C, 0x005B }, { 0x3D, 0x007E }, { 0x3E, 0x005D }, { 0x40, 0x007C }, + { 0x65, 0x20AC } }; + +const GsmUniTable gsm_unicode_table[] = { + { 0x00, 0x0040 }, { 0x01, 0x00A3 }, { 0x02, 0x0024 }, { 0x03, 0x00A5 }, + { 0x04, 0x00E8 }, { 0x05, 0x00E9 }, { 0x06, 0x00F9 }, { 0x07, 0x00EC }, { 0x08, 0x00F2 }, + { 0x09, 0x00E7 }, { 0x0B, 0x00D8 }, { 0x0C, 0x00F8 }, { 0x0E, 0x00C5 }, { 0x0F, 0x00E5 }, + { 0x10, 0x0394 }, { 0x11, 0x005F }, { 0x12, 0x03A6 }, { 0x13, 0x0393 }, { 0x14, 0x039B }, + { 0x15, 0x03A9 }, { 0x16, 0x03A0 }, { 0x17, 0x03A8 }, { 0x18, 0x03A3 }, { 0x19, 0x0398 }, + { 0x1A, 0x039E }, { 0x1C, 0x00C6 }, { 0x1D, 0x00E6 }, { 0x1E, 0x00DF }, { 0x1F, 0x00C9 }, + { 0x24, 0x00A4 }, { 0x40, 0x00A1 }, { 0x5B, 0x00C4 }, { 0x5C, 0x00D6 }, { 0x5D, 0x00D1 }, + { 0x5E, 0x00DC }, { 0x5F, 0x00A7 }, { 0x60, 0x00BF }, { 0x7B, 0x00E4 }, { 0x7C, 0x00F6 }, + { 0x7D, 0x00F1 }, { 0x7E, 0x00FC }, { 0x7F, 0x00E0 }, }; + + + + +static gboolean _find_gsm_code_exception_table(unsigned short src) +{ + if ((src >= 0x0020 && src <= 0x0023) + || (src >= 0x0025 && src <= 0x003F) + || (src >= 0x0041 && src <= 0x005A) + || (src >= 0x0061 && src <= 0x007A) + || src == 0x000A || src == 0x000D) + return TRUE; + return FALSE; +} + +static int _get_gsm_code_size(unsigned short* src, int src_len) +{ + gboolean in_table = FALSE; + gboolean in_sec_table = FALSE; + int i, gsm_len = 0; + + if (NULL == src) { + dbg( "INPUT PARAM was NULL"); + return -1; + } + + for (; src_len > 0 && src; src_len--) { + if (_find_gsm_code_exception_table(*src) == TRUE) { + src++; + gsm_len++; + continue; + } + in_table = FALSE; + for (i = 0; i < tabGsmUniMax; i++) { + if (*src == gsm_unicode_table[i].unicode) { + src++; + in_table = TRUE; + gsm_len++; + break; + } + } + if (in_table == FALSE) { + in_sec_table = FALSE; + for (i = 0; i < tabGsmUniMax2; i++) {/* second table */ + if (*src == gsm_unicode2_table[i].unicode) { + src++; + in_table = TRUE; + in_sec_table = TRUE; + gsm_len += 2; + break; + } + } + if (in_sec_table == FALSE) {/* second*/ + if (_find_gsm_code_exception_table(*src) == FALSE) { + dbg( "GSM Char[%d], gsm_len[%d]", *src, gsm_len); + return -1; + } + src++; + gsm_len++; + } + } + } + return gsm_len; +} + +static gboolean _convert_gsm_to_unicode(unsigned short *dest, int dest_len, unsigned char *src, unsigned int src_len) +{ + int count, tmp_len; + + if(!dest || !src) { + dbg( "dest(%p) or src(%p) is null",dest, src); + return FALSE; + } + + if(!src_len){ + dest[0] = '\0'; + return TRUE; + } + + dbg("source string (%s) len(%d)", src, src_len); + + for(count = 0; count < (int)src_len; count++){ + if(src[count] == 0x1B) + src_len--; + } + dbg("strlen excluding escape character (%d)", src_len); + + tmp_len = _convert_gsm_to_ucs2(dest, src, src_len); + dest[tmp_len] = '\0'; + + return TRUE; +} + +static int _convert_gsm_to_ucs2(unsigned short* dest, unsigned char* src, unsigned int src_len) +{ + int count; + unsigned short* org; + + org = dest; + + for(count=0; count < (int)src_len; count++){ + int table_index=0; + gboolean b_tabled = FALSE; + + /* + * if the first byte is 0x1B, it is the escape character. + * The byte value shoulbe be changed to unicode. + */ + if(*src == 0x1B){ + src++; count++;//move to next byte + for(table_index=0; table_index < tabGsmUniMax2; table_index++){ + if(*src == gsm_unicode2_table[table_index].gsm){ + *dest = gsm_unicode2_table[table_index].unicode; + b_tabled = TRUE; + break; + } + } + + //if matched data is not in table, it should be changed to NULL; + if(!b_tabled){ + *dest = 0x0020; + } + } + else{ + for(table_index=0; table_index < tabGsmUniMax; table_index++){ + if(*src == gsm_unicode_table[table_index].gsm){ + *dest = gsm_unicode_table[table_index].unicode; + b_tabled = TRUE; + break; + } + } + + //if matched data is not in table, it is using original value; + if(!b_tabled){ + *dest = *src; + } + } + + //move to next position + src++; dest++; + } + + dbg("cvt sr(%s), the size of data (%d) ", org, dest - org); + return (dest - org); +} + +static void _convert_gsm_to_utf8(unsigned char* dest, unsigned short* dest_len, unsigned char* src, unsigned int src_len) +{ + unsigned short tmp_len = 0; + char *target_tmp = NULL; + unsigned char *raw_unicode = NULL; + unsigned short tmp_dest[SAT_TEXT_STRING_LEN_MAX]; + + memset(tmp_dest, 0 , SAT_TEXT_STRING_LEN_MAX); + + _convert_gsm_to_unicode(tmp_dest, SAT_TEXT_STRING_LEN_MAX, src, src_len); + while(tmp_dest[tmp_len] != '\0'){ + tmp_len++; + } + tmp_len++; // add null character + + tmp_len = tmp_len*2; //for byte align + raw_unicode = (unsigned char*)malloc(tmp_len); + if(!raw_unicode) + return; + + memset(raw_unicode, 0, tmp_len); + + memcpy(raw_unicode, (unsigned char*)tmp_dest, tmp_len); + + target_tmp = _convert_ucs_to_utf8(raw_unicode, tmp_len); + if(!target_tmp){ + dbg( "str is NULL"); + g_free(raw_unicode); + return; + } + + *dest_len = strlen((const char*)target_tmp); + dbg("utf8 (%s), len(%d)", (const char*)target_tmp, strlen((const char*)target_tmp)); + memcpy(dest, target_tmp, strlen((const char*)target_tmp)); + dbg("final utf8 str (%s), length (%d)", dest, tmp_len); + + g_free(raw_unicode); + g_free(target_tmp); + return; +} + +static gboolean _convert_unicode_to_gsm(unsigned char* dest, int dest_len, unsigned short* src, int src_len) +{ + char* tmp_str; + int gc_len = 0; + + if ((NULL == dest) || (NULL == src)) { + dbg( "INPUT PARAM was NULL"); + return FALSE; + } + + if (src_len == 0) + return FALSE; + + gc_len = _get_gsm_code_size(src, src_len); + if (0 >= gc_len) { + dbg( "Warning: Error[%d] while finding the GSM Code Size", gc_len); + return FALSE; + } + + if (dest_len < gc_len) { + if (dest_len == sizeof(void*)) { + dbg( "Out buffer size seems to be small (%s)", dest); + } else { + dbg("Buffer size is too small (%s): dest_len(%d), gc_len(%d)", dest, dest_len, gc_len); + } + return FALSE; + } + + tmp_str = calloc(1, (unsigned short) gc_len); + if (tmp_str == NULL) { + dbg( "Memory Allocation Failed!"); + return FALSE; + } + + gc_len = _convert_ucs2_to_gsm((unsigned char*) tmp_str, src, src_len); + if (gc_len != -1) { + memcpy((char*) dest, (char*) tmp_str, gc_len); + free(tmp_str); + return TRUE; + } + + free(tmp_str); + return FALSE; +} + +static char* _convert_ucs_to_utf8(unsigned char* src, int src_len) +{ + char* utf_str = NULL; + iconv_t cd = NULL; + size_t ileft = 0; + size_t oleft = 0; + + char* pIn = NULL; + char* in_buf = NULL; + char* out_buf = NULL; + + if (!src) { + dbg("src is null"); + return NULL; + } + + ileft = src_len * 2;//over allocate as utf-8 may occupy 3 bytes + oleft = src_len * 3;//over allocate as utf-8 may occupy 3 bytes + pIn = in_buf = (char*) malloc(ileft + 2); + if (in_buf == NULL) { + dbg("in_buf allocation failed"); + return NULL; + } + utf_str = out_buf = (char *) malloc(oleft + 1); + if (utf_str == NULL) { + dbg("in_buf allocation failed"); + free(in_buf); + return NULL; + } + + memset(in_buf, 0x00, ileft + 2); + memset(out_buf, 0x00, oleft + 1); + memcpy(in_buf, src, ileft); + + in_buf[ileft] = '\0'; + + cd = iconv_open("UTF-8", "UCS-2"); + + if (iconv(cd, (char**) &in_buf, &ileft, &out_buf, &oleft) == (size_t)(-1)) { + dbg("failed to iconv errno:%d", errno); + } else { + utf_str[src_len * 2 - ileft] = '\0'; + } + + iconv_close(cd); + free(pIn); + + return utf_str; +} + +static int _convert_ucs2_to_gsm(unsigned char* dest, unsigned short* src, unsigned int src_len) +{ + unsigned char* rear = NULL; + unsigned short* p; + unsigned char temp; + gboolean in_table = FALSE; + gboolean in_sec_table = FALSE; + int i, gc_len = 0; + + if ((!dest) || (!src) || (0x00 == src_len)) { + dbg( "Warning: Wrong Input"); + return -1; + } + + rear = dest; + p = src; + + for (; src_len > 0 && p; src_len--) { + in_table = FALSE; + for (i = 0; i < tabGsmUniMax; i++) { /* is in table */ + if (*p == gsm_unicode_table[i].unicode) { + temp = (unsigned char) (gsm_unicode_table[i].gsm); + *rear = temp; + rear++; + p++; + in_table = TRUE; + gc_len++; + break; + } + } + if (in_table == FALSE) { + in_sec_table = FALSE; + for (i = 0; i < tabGsmUniMax2; i++) { /* second table*/ + if (*p == gsm_unicode2_table[i].unicode) { + *rear = 0x1B; + rear++; + temp = (unsigned char) (gsm_unicode2_table[i].gsm); + *rear = temp; + rear++; + p++; + in_table = TRUE; + in_sec_table = TRUE; + gc_len += 2; + break; + } + } + if (in_sec_table == FALSE) { /* second */ + if (_find_gsm_code_exception_table(*p) == FALSE) + return -1; + temp = (unsigned char) (*p); /* isn't in table. but it's just able to be converted to GSM (0x00?? -> 0x??)*/ + *rear = temp; + rear++; + p++; + gc_len++; + } + } + } + src = p; + return gc_len; +} + +int tcore_util_convert_ucs2_to_utf8(char *out, unsigned short *out_len, char *in, unsigned short in_len) +{ + //input string "char *in" should be BIG-ENDIAN format. + gsize byte_converted = 0; + gsize byte_read = 0; + gchar *str_converted = NULL; + + if (NULL == out || NULL == out_len || NULL == in) { + dbg( "Invalid Input Parameter"); + return 0; + } +try_again: + str_converted = (gchar *)g_convert((const gchar *)in, (gssize)in_len, "UTF8", "UCS-2BE", &byte_read, &byte_converted, NULL); + + dbg("read:[%d] converted:[%d] out:[%s]", byte_read, byte_converted, str_converted); + + *out_len = byte_converted; + if (str_converted) { + memcpy(out, str_converted, byte_converted); + g_free(str_converted); + } else { + warn("Cannot get converted data"); + if (byte_read > 0) { + in_len = byte_read; + goto try_again; + } + } + return 0; +} + +static void _convert_alpha_field_ucs2_to_utf8(unsigned char *out, unsigned short *out_len, unsigned char *in, unsigned short in_len) +{ + //input string "unsigned char *in" should be BIG-ENDIAN format. + int i = 0; + + switch(in[0]) { + case 0x80: { + dbg("[UCS2] prefix case:[0x80]"); + tcore_util_hex_dump(" [UCS2] ", in_len, in); + tcore_util_convert_ucs2_to_utf8((char *)out, out_len, (char*)in+1, in_len-1); + } break; + + case 0x81: { + unsigned char num = in[1]; //number of characters + unsigned short base = (unsigned short) in[2] << 7; //base pointer for UCS2 type + int data_loc = 3; //starting location of data + unsigned short* in_buf = NULL; + dbg("[UCS2] prefix case:[0x81]"); + in_buf = (unsigned short*)malloc(num * sizeof(unsigned short)); + if(in_buf == NULL) { + dbg("in_buf malloc failed."); + return; + } + + for(i=0; i 1000b), then remaining 7 bits are GSM default character. + _convert_gsm_to_ucs2(&in_buf[i], &in[data_loc], 1); + dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]); + } else { // if the MSB is 1 then the remaining 7 bits are offset value added to Base Pointer which the result defines the UCS2 character. + in_buf[i] = base + ((unsigned short)(in[data_loc]) & 0x7F); + dbg("[UCS2]in_buf[%d]=0x%04x", i, in_buf[i]); + } + } + { + unsigned char *dest = NULL; + dest = (unsigned char*)malloc(num*2); + if(dest == NULL) { + dbg("dest malloc failed."); + free(in_buf); + return; + } + + tcore_util_swap_byte_order(dest, (unsigned char*)in_buf, num*2); + tcore_util_convert_ucs2_to_utf8((char *)out, out_len, (char*) dest, num*2); + + free(in_buf); + free(dest); + } + } break; + + case 0x82: { + unsigned char num = in[1]; //number of characters + unsigned short base = ((unsigned short) in[2] << 8) | (unsigned short) in[3]; //base pointer for UCS2 type + int data_loc = 4; //starting location of data + unsigned short* in_buf = NULL; + dbg("[UCS2] prefix case:[0x82]"); + in_buf = (unsigned short*)malloc(num * sizeof(unsigned short)); + if(in_buf == NULL) { + dbg("in_buf malloc failed."); + return; + } + + for(i=0; i 0 && (*src != '\0')) { + if (*src < 0x80) { + *dest = (*src & 0x7F); + dest++; + src++; + src_len--; + } else if (((0xC0 <= *src) && (*src < 0xE0)) && (*(src + 1) >= 0x80)) { + hi = *src & 0x1F; + low = *(src+1) & 0x3F; + *dest = (hi << 6) | low; + dest++; + src += 2; + src_len -= 2; + } else if ((*src >= 0xE0) && (*(src + 1) >= 0x80) && (*(src + 2) >= 0x80)) { + hi = *src & 0x0F; + mid = *(src+1) & 0x3F; + low = *(src+2) & 0x3F; + *dest = (hi << 12) | (mid << 6) | low; + dest++; + src += 3; + src_len -= 3; + } else { + *dest = (*src & 0x7F); + dest++; + src++; + src_len--; + dbg( "utf8 incorrect range"); + } + } + *dest = 0; + return (dest - org); +} + +static char _convert_gsm7bit_extension( char c ) +{ + switch ( c ) { + case 0x0A: + case 0x1B: + return ' '; + case 0x14: + return '^'; + case 0x28: + return '{'; + case 0x29: + return '}'; + case 0x2F: + return '\\'; + case 0x3C: + return '['; + case 0x3D: + return '~'; + case 0x3E: + return ']'; + case 0x40: + return '|'; + /* + case 0x65: + This code represents the EURO currency symbol. The code value is that used for the character ‘e’. Therefore + a receiving entity which is incapable of displaying the EURO currency symbol will display the character ‘e’ + instead. GSM 03.38 + */ + case 0x65: + return 'e'; + default: + dbg("this is not extension character : (0x%x)", c); + break; + } + + return c; +} + +gboolean tcore_util_convert_utf8_to_gsm(unsigned char *dest, int *dest_len, unsigned char* src, int src_len) +{ + unsigned short *uc = NULL; + int gc_len = 0; + int uc_len = 0; + + if (src == NULL || src_len == 0) { + dbg( "WARNING: Invalid Parameter"); + return FALSE; + } + + uc = (unsigned short*) calloc(src_len + 1, sizeof(unsigned short)); + if (!uc) { + dbg( "WARNING: calloc Failed"); + return FALSE; + } + + /*Converting from UTF8 => UNICODE*/ + uc_len = _convert_utf8_to_unicode(uc, src, src_len); + dbg( "uc_len:[%d]", uc_len); + if(uc_len == -1) { + dbg( "_convert_utf8_to_unicode returns false!"); + free(uc); + return FALSE; + } + + /*Finding the GSMCode Size*/ + gc_len = _get_gsm_code_size(uc, uc_len); + dbg( "gc_len:[%d]", gc_len); + if ( gc_len == -1) { + dbg( "SM- DATA is not in GSM7BIT Character Set & Error:[%d]", gc_len); + free(uc); + return FALSE; + } + + *dest_len = gc_len; + /*Converting from UNICODE ==> GSM CODE */ + if (_convert_unicode_to_gsm((unsigned char*) dest, *dest_len, uc, uc_len) == FALSE) { + dbg( "_convert_unicode_to_gsm Failed"); + *dest_len = 0x00; + free(uc); + return FALSE; + } + + if(uc) + free(uc); + return TRUE; +} + +gboolean tcore_util_convert_utf8_to_ucs2(char **dest, int *dest_len, unsigned char *src, int src_len) +{ + gsize byte_converted = 0; + gsize byte_read = 0; + gchar *str_converted = NULL; + + if (NULL == src || NULL == dest || NULL == dest_len) { + dbg( "Invalid Input Parameter"); + return FALSE; + } +try_again: + /*Converting from UTF8 => UCS-2 BIG-ENDIAN FORMAT using the g_convert*/ + str_converted = (gchar *)g_convert((const gchar *)src, (gssize)src_len, "UCS-2BE", "UTF8", &byte_read, &byte_converted, NULL); + + dbg("byte_read: [%d] byte_converted: [%d]", byte_read, byte_converted); + if (str_converted) { + *dest = str_converted; + *dest_len = byte_converted; + } else { + warn("Cannot get converted string"); + if (byte_read > 0) { + src_len = byte_read; + goto try_again; + } + } + return TRUE; +} + +gboolean tcore_util_convert_string_to_utf8(unsigned char *dest, unsigned short *dest_len, + enum alphabet_format dcs, const unsigned char *src, unsigned short src_len) +{ + dbg("dcs=[0x%02x], src=[%s], src_len=[%d]", dcs, src, src_len ); + + if(src==NULL || src_len==0) { + err("src is NULL or src_len is 0"); + return FALSE; + } + + switch (dcs) { + case ALPHABET_FORMAT_SMS_DEFAULT: { + unsigned char* tmp_dest_str = NULL; + tmp_dest_str = (unsigned char*)tcore_util_unpack_gsm7bit((const unsigned char *)src, src_len); + + if(!tmp_dest_str) { + err("temp_dest_str is NULL"); + return FALSE; + } + _convert_gsm_to_utf8(dest, dest_len, tmp_dest_str, strlen((const char*)tmp_dest_str)); + if(tmp_dest_str) { + free(tmp_dest_str); + } + } break; + + case ALPHABET_FORMAT_8BIT_DATA: {//GSM7bit with bit 8 set to 0 + int tmp_str_len = 0; + unsigned char *src_buf = NULL; + + src_buf = (unsigned char*)malloc(src_len); + if(src_buf == NULL) { + dbg("src_buf malloc failed."); + return FALSE; + } + + memset(src_buf, 0, src_len); + memcpy(src_buf, src, src_len); + + /*get string length*/ + /* 0xFF is the end of string */ + while (src[tmp_str_len] != 0xFF && tmp_str_len < src_len) { + tmp_str_len++; + } + /* last space character must be deleted */ + while (src[tmp_str_len - 1] == 0x20 && tmp_str_len > 0) { + tmp_str_len--; + } + dbg( "tmp_str_len[%d]", tmp_str_len); + + _convert_gsm_to_utf8(dest, dest_len, src_buf, tmp_str_len); + if(src_buf != NULL) + free(src_buf); + } break; + + case ALPHABET_FORMAT_UCS2: { + unsigned char *src_buf = NULL; + + src_buf = (unsigned char*)malloc(src_len); + if(src_buf == NULL) { + dbg("src_buf malloc failed."); + return FALSE; + } + + memset(src_buf, 0, src_len); + memcpy(src_buf, src, src_len); + + _convert_alpha_field_ucs2_to_utf8(dest, dest_len, src_buf, src_len); + if(src_buf != NULL) + free(src_buf); + } break; + + default: { + dbg("not handled alpha format[0x%02x]", dcs); + return FALSE; + } break; + } + return TRUE; +} + +gboolean tcore_util_convert_ascii_to_utf8( unsigned char **dest, int *dest_len, unsigned char *src, int src_len ) +{ + int i = 0, j = 0, tmp_len = 0; + unsigned char *tmp = 0; + + if ( (!dest) || (!src) || (!dest_len) ) + return FALSE; + + if ( !src_len ) { + src_len = strlen( (char*)src ); + } + + tmp_len = (src_len * 2); + tmp = g_new0( unsigned char, tmp_len ); + + for ( i=0, j=0; i= 0x80) && (src[i] <= 0xBF) ) { + tmp[j] = 0xC2; + tmp[++j] = src[i]; + + } else { //( (src[i] >= 0xC0) && (src[i] <= 0xFF) ) + tmp[j] = 0xC3; + tmp[++j] = (src[i] - 0x40); + + } + } + + *dest_len = (j+1); + + *dest = g_new0( unsigned char, *dest_len ); + memcpy( *dest, tmp, j ); + + g_free( tmp ); + + return TRUE; +} + +void tcore_util_swap_byte_order(unsigned char* dest, const unsigned char* src, int src_len) +{ + int i = 0; + for (i = 0; i+1 < src_len; i=i+2) { + dest[i] = src[i+1]; + dest[i+1] = src[i]; + } + if(src_len%2==1) + dest[i-1] = src[i-1]; + dbg("swap completed."); +} + static gboolean _tcore_util_marshal_create_gvalue(GValue *value, const void *data, enum tcore_util_marshal_data_type type) { switch (type) { case TCORE_UTIL_MARSHAL_DATA_CHAR_TYPE: g_value_init(value, type); - g_value_set_char(value, *((gchar *) data)); + g_value_set_schar(value, *((gchar *) data)); break; case TCORE_UTIL_MARSHAL_DATA_BOOLEAN_TYPE: @@ -85,7 +885,7 @@ static gboolean _tcore_util_return_value(GValue *src, void **dest, switch (type) { case TCORE_UTIL_MARSHAL_DATA_CHAR_TYPE: *dest = g_new0(gchar, 1); - *((gchar *) *dest) = g_value_get_char(src); + *((gchar *) *dest) = g_value_get_schar(src); break; case TCORE_UTIL_MARSHAL_DATA_BOOLEAN_TYPE: @@ -132,6 +932,8 @@ static void _tcore_util_marshal_remove_value(gpointer value) } g_value_unset((GValue *) value); + g_free(value); + return; } @@ -343,6 +1145,103 @@ TReturn tcore_util_netif_set(const char *name, const char *ipaddr, return TCORE_RETURN_SUCCESS; } +TReturn tcore_util_reset_ipv4_socket(const char *name, const char* ipaddr) +{ + int ret; + int fd; + struct ifreq ifr; + struct sockaddr_in sai; + + if (!name) + return TCORE_RETURN_EINVAL; + + if (strlen(name) > IFNAMSIZ) + return TCORE_RETURN_EINVAL; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + return TCORE_RETURN_FAILURE; + } + + memset(&sai, 0, sizeof(struct sockaddr_in)); + sai.sin_family = AF_INET; + sai.sin_port = 0; + if (ipaddr) { + if (!inet_aton(ipaddr, &sai.sin_addr)) { + dbg("fail to inet_aton()"); + close(fd); + return TCORE_RETURN_FAILURE; + } + } + + memset(&ifr, 0, sizeof(struct ifreq)); + memcpy(&ifr.ifr_addr, &sai, sizeof(sai)); + strncpy(ifr.ifr_name, name, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ - 1] = '\0'; + + if(!ipaddr) { + ret = ioctl(fd, SIOCGIFADDR, &ifr); + if (ret < 0) { + dbg("fail to ioctl[SIOCGIFADDR]!!!"); + close(fd); + return TCORE_RETURN_FAILURE; + } + } + /* SIOCKILLADDR is initially introduced in Android OS. */ +#ifndef SIOCKILLADDR +#define SIOCKILLADDR 0x8939 +#endif + ret = ioctl(fd, SIOCKILLADDR, &ifr); + if (ret < 0) { + dbg("fail to ioctl[SIOCKILLADDR]!!!"); + close(fd); + return TCORE_RETURN_FAILURE; + } + + if(ipaddr) { + dbg("devname: %s, ipaddr: %s", name, ipaddr); + } else { + memset(&sai, 0, sizeof(struct sockaddr_in)); + memcpy(&sai, &ifr.ifr_addr, sizeof(struct sockaddr_in)); + dbg("devname: %s, ipaddr: %s", name, inet_ntoa(sai.sin_addr)); + } + close(fd); + return TCORE_RETURN_SUCCESS; +} + +TReturn tcore_util_netif_set_mtu(const char *name, unsigned int mtu) +{ + int ret; + int fd; + struct ifreq ifr; + + if (!name) + return TCORE_RETURN_EINVAL; + + if (strlen(name) > IFNAMSIZ) + return TCORE_RETURN_EINVAL; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + return TCORE_RETURN_FAILURE; + } + + memset(&ifr, 0, sizeof(struct ifreq)); + strncpy(ifr.ifr_name, name, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ - 1] = '\0'; + ifr.ifr_data = (void*)mtu; + + ret = ioctl(fd, SIOCSIFMTU, &ifr); + if (ret < 0) { + dbg("fail to ioctl[SIOCSIFMTU]!!!"); + close(fd); + return TCORE_RETURN_FAILURE; + } + + close(fd); + return TCORE_RETURN_SUCCESS; +} + char *tcore_util_get_string_by_ip4type(union tcore_ip4_type ip) { char buf[16]; /* 'nnn'*4 + '.'*3 + '\0' */ @@ -409,9 +1308,12 @@ enum tcore_dcs_type tcore_util_get_cbs_coding_scheme(unsigned char encode) case 0xF0: if ((encode & 0x04) == 0x00) dcs = TCORE_DCS_TYPE_7_BIT; - else if ((encode & 0x04) == 0x01) + else if ((encode & 0x04) == 0x04) dcs = TCORE_DCS_TYPE_8_BIT; break; + default: + err("invalid encoding type"); + break; } return dcs; @@ -442,7 +1344,7 @@ unsigned char *tcore_util_decode_hex(const char *src, int len) out_len = len; } - buf = calloc(out_len, 1); + buf = calloc(1, out_len); if (!buf) return NULL; @@ -456,10 +1358,44 @@ unsigned char *tcore_util_decode_hex(const char *src, int len) return buf; } +void tcore_util_hex_dump(const char *pad, int size, const void *data) +{ + char buf[255] = {0, }; + char hex[4] = {0, }; + int i = 0; + unsigned char *p = NULL; + + if (0 >= size) { + msg("%sno data", pad); + return; + } + + p = (unsigned char *)data; + + g_snprintf(buf, 255, "%s%04X: ", pad, 0); + for (i = 0; i max_len){ - err("[SAT] PARSER - number length exceeds the max"); + err("PARSER - number length exceeds the max"); return NULL; } dest = malloc((src_len*2)*sizeof(char)+1); + if (!dest) + return NULL; + memset(dest, 0, (src_len*2)*sizeof(char)+1); - for(index = 0; index < src_len; index++){ - l_bcd = src[index] & 0x0F; - h_bcd = (src[index] & 0xF0) >> 0x04; + for(count = 0; count < src_len; count++){ + l_bcd = src[count] & 0x0F; + h_bcd = (src[count] & 0xF0) >> 0x04; switch(l_bcd){ case 0x0A: @@ -617,10 +1610,34 @@ char* tcore_util_convert_bcd2ascii(const char* src, int src_len, int max_len) if(h_bcd != 0x0F) dest[len] = '\0'; - dbg("[SAT] SAT PARSER - number(%s) len(%d)", dest, len); + dbg("PARSER - number(%s) len(%d)", dest, len); return dest; } +char* tcore_util_convert_digit2ascii(const char* src, int src_len) +{ + int count = 0; + char *dest = NULL; + + if(!src) + return NULL; + + dest = malloc((src_len+1)*sizeof(char)); + if(!dest) + return NULL; + + memset(dest, 0, (src_len+1)*sizeof(char)); + + for(count = 0; count < src_len; count++){ + dest[count] = src[count] + '0'; + } + dest[count] = '\0'; + + dbg("PARSER - number(%s) len(%d)", dest, strlen(dest)); + return dest; +} + + GHashTable *tcore_util_marshal_create() { GHashTable *ht = NULL; @@ -642,9 +1659,13 @@ void tcore_util_marshal_destory(GHashTable *ht) GHashTable *tcore_util_marshal_deserialize_string(const gchar *serialized_string) { - int index = 0; + int count = 0; gchar **tuple = NULL; GHashTable *ht = NULL; + GValue src = G_VALUE_INIT; + + if (!serialized_string) + return NULL; ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, _tcore_util_marshal_remove_value); @@ -653,30 +1674,31 @@ GHashTable *tcore_util_marshal_deserialize_string(const gchar *serialized_string return ht; } - tuple = g_strsplit((gchar *) serialized_string, " ", 0); + g_value_init(&src, G_TYPE_STRING); + + tuple = g_strsplit(serialized_string, " ", 0); - while (strlen(tuple[index]) > 3) { + while (strlen(tuple[count]) > 3) { int tmp = 0; guchar *content = NULL; gchar **inner_tuple = NULL; - GValue *src = g_new0(GValue, 1); GValue *dest = g_new0(GValue, 1); unsigned int type = 0; - inner_tuple = g_strsplit(tuple[index], ":", 0); + inner_tuple = g_strsplit(tuple[count], ":", 0); type = atoi(inner_tuple[1]); content = g_base64_decode(inner_tuple[2], (gsize *)&tmp); - g_value_init(src, G_TYPE_STRING); g_value_init(dest, type); - g_value_set_string(src, (const gchar *)content); - _tcore_util_marshal_convert_str_to_type(src, dest, type); + g_value_set_string(&src, (const gchar *)content); + _tcore_util_marshal_convert_str_to_type(&src, dest, type); g_hash_table_insert(ht, g_strdup(inner_tuple[0]), dest); + g_value_reset(&src); g_free(content); g_strfreev(inner_tuple); - index++; + count++; } g_strfreev(tuple); @@ -820,3 +1842,14 @@ GHashTable *tcore_util_marshal_get_object(GHashTable *ht, const gchar *key) return rvalue; } + +char *tcore_util_get_version(void) +{ + return strdup(TCORE_VERSION); +} + +void tcore_util_set_log(gboolean enable) +{ + tcore_debug = enable; +} + diff --git a/unit-test/CMakeLists.txt b/unit-test/CMakeLists.txt new file mode 100644 index 0000000..f917c74 --- /dev/null +++ b/unit-test/CMakeLists.txt @@ -0,0 +1,38 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(libtcore-unit-test C) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") +SET(INCLUDEDIR "\${prefix}/include") +REMOVE_DEFINITIONS("-DFEATURE_TLOG_DEBUG") + +SET(TESTS + test-at + test-co + test-queue + test-dcs + test-hal + test-util + test-network +) + +FOREACH(test ${TESTS}) + ADD_EXECUTABLE(${test} ${test}.c log.c) + TARGET_LINK_LIBRARIES(${test} ${pkgs_LDFLAGS} "-L${CMAKE_BINARY_DIR} -ltcore -ldl") +# INSTALL(TARGETS ${test} RUNTIME DESTINATION bin/) + ADD_DEPENDENCIES(${test} run.sh) + SET(TEST_LIST "${TEST_LIST} ${test}") +ENDFOREACH(test) + + +ADD_CUSTOM_TARGET(run.sh) +ADD_CUSTOM_COMMAND( + TARGET run.sh + POST_BUILD + COMMAND echo "gtester ${TEST_LIST} -o report.xml" > run.sh + COMMAND chmod +x run.sh + COMMENT "Generating gtester script" + VERBATIM # for double-quoted strings.. + ) +ADD_DEPENDENCIES(run.sh tcore) diff --git a/unit-test/log.c b/unit-test/log.c new file mode 100644 index 0000000..e641019 --- /dev/null +++ b/unit-test/log.c @@ -0,0 +1,20 @@ +#define FEATURE_TLOG_DEBUG + +#include +#include + +#include +#include + +void tcore_log(enum tcore_log_type type, enum tcore_log_priority priority, const char *tag, const char *fmt, ...) +{ + va_list ap; + char buf[1024]; + + va_start(ap, fmt); + vsnprintf(buf, 1023, fmt, ap); + va_end(ap); + + printf("%s: %s", tag, buf); + fflush(stdout); +} diff --git a/unit-test/test-at.c b/unit-test/test-at.c new file mode 100644 index 0000000..b089616 --- /dev/null +++ b/unit-test/test-at.c @@ -0,0 +1,223 @@ + +#include +#include +#include + +#include + +#include +#include + +static gboolean on_cmti(TcoreAT *at, const GSList *lines, void *user_data) +{ + int *checked = user_data; + + *checked = 1; + + printf("data = [%s]\n", (char *)lines->data); + + return FALSE; +} + +static gboolean on_cmt(TcoreAT *at, const GSList *lines, void *user_data) +{ + int *checked = user_data; + + if (g_slist_length((GSList *)lines) != 2) { + printf("invalid message\n"); + return TRUE; + } + + *checked = 2; + + printf("data1 = [%s]\n", (char *)lines->data); + printf("data2 = [%s]\n", (char *)lines->next->data); + + return TRUE; +} + +static void test_noti(void) +{ + TcoreAT *at; + TReturn ret; + int checked = 0; + char *msg = NULL; + + at = tcore_at_new(NULL); + g_assert(at); + + ret = tcore_at_add_notification(at, "+CMTI:", FALSE, on_cmti, &checked); + g_assert(ret == TCORE_RETURN_SUCCESS); + + ret = tcore_at_add_notification(at, "+CMT:", TRUE, on_cmt, &checked); + g_assert(ret == TCORE_RETURN_SUCCESS); + + + /* Non type PDU message */ + msg = (char *)"+CMTI: \"SM\", 1\r\n"; + ret = tcore_at_process(at, strlen(msg), msg); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* callback check */ + g_assert(checked == 1); + + + /* Completed PDU message */ + msg = (char *)"+CMT: 19\r\n038121F3100481214301112170137192410404F17B590E\r\n"; + ret = tcore_at_process(at, strlen(msg), msg); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* callback check */ + g_assert(checked == 2); + + + /* Split PDU message */ + checked = 0; + msg = (char *)"+CMT: 19\r\n"; + ret = tcore_at_process(at, strlen(msg), msg); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* callback check */ + g_assert(checked == 0); + + msg = (char *)"038121F310"; + ret = tcore_at_process(at, strlen(msg), msg); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* callback check */ + g_assert(checked == 0); + + msg = (char *)"0481214301112170137192410404F17B590E\r\n"; + ret = tcore_at_process(at, strlen(msg), msg); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* callback check */ + g_assert(checked == 2); + +} + +static void test_buf_write(void) +{ +#define BUF_SIZE 1024 + TcoreAT *at; + TReturn ret; + char *msg_1 = (char *)"ATZ"; + char msg_2[BUF_SIZE + 1]; + + at = tcore_at_new(NULL); + g_assert(at); + + ret = tcore_at_buf_write(at, strlen(msg_1), msg_1); + g_assert(ret == TCORE_RETURN_SUCCESS); + + memset(msg_2, '1', BUF_SIZE); + msg_2[BUF_SIZE] = '\0'; + ret = tcore_at_buf_write(at, strlen(msg_2), msg_2); + g_assert(ret == TCORE_RETURN_SUCCESS); + + tcore_at_free (at); +} + +static void test_tok(void) +{ + GSList *tokens; + char *buf; + + /* test unsolicited message */ + tokens = tcore_at_tok_new("CSQ: 31, 99"); + g_assert(tokens); + + g_assert_cmpstr((char *)g_slist_nth_data(tokens, 0), ==, "31"); + g_assert_cmpstr(tcore_at_tok_nth(tokens, 1), ==, "99"); + g_assert(g_slist_nth_data(tokens, 2) == NULL); + + tcore_at_tok_free(tokens); + + /* test sub token (list type) */ + tokens = tcore_at_tok_new("(2, \"T-Meego\", \"TTAU\", \"23401\", 2)"); + g_assert(tokens); + + g_assert_cmpstr((char *)g_slist_nth_data(tokens, 0), ==, "2"); + g_assert_cmpstr(tcore_at_tok_nth(tokens, 1), ==, "\"T-Meego\""); + g_assert_cmpstr(tcore_at_tok_nth(tokens, 2), ==, "\"TTAU\""); + g_assert_cmpstr(tcore_at_tok_nth(tokens, 3), ==, "\"23401\""); + g_assert_cmpstr(tcore_at_tok_nth(tokens, 4), ==, "2"); + + /* test extract */ + buf = tcore_at_tok_extract(tcore_at_tok_nth(tokens, 2)); + g_assert(buf); + g_assert_cmpstr(buf, ==, "TTAU"); + free(buf); + + tcore_at_tok_free(tokens); + + /* test extract */ + buf = tcore_at_tok_extract("(haha)"); + g_assert(buf); + g_assert_cmpstr(buf, ==, "haha"); + free(buf); + + /* test extract */ + buf = tcore_at_tok_extract("(a)"); + g_assert(buf); + g_assert_cmpstr(buf, ==, "a"); + free(buf); + + /* test extract */ + buf = tcore_at_tok_extract("()"); + g_assert(buf); + g_assert_cmpstr(buf, ==, ""); + free(buf); + + /* test extract */ + buf = tcore_at_tok_extract("("); + g_assert(buf); + g_assert_cmpstr(buf, ==, "("); + free(buf); + + /* test extract */ + buf = tcore_at_tok_extract(")"); + g_assert(buf); + g_assert_cmpstr(buf, ==, ")"); + free(buf); + + /* test extract */ + buf = tcore_at_tok_extract(""); + g_assert(buf); + g_assert_cmpstr(buf, ==, ""); + free(buf); +} + +static void test_pdu_resp(void) +{ + TcoreAT *at; + TcoreATRequest *req; + TReturn ret; + char *msg; + + at = tcore_at_new(NULL); + g_assert(at); + + req = tcore_at_request_new("AT+CMGR=1", "+CMGR", TCORE_AT_PDU); + g_assert(req); + + ret = tcore_at_set_request(at, req, TRUE); + + msg = (char *)"+CMGR: 1,,105\r\n12345678901234567890\r\nOK\r\n"; + ret = tcore_at_process(at, strlen(msg), msg); + g_assert(ret == TRUE); + + tcore_at_free (at); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/at/buf_write", test_buf_write); + g_test_add_func("/at/tok", test_tok); + g_test_add_func("/at/noti", test_noti); + g_test_add_func("/at/pdu_resp", test_pdu_resp); + + return g_test_run(); +} diff --git a/unit-test/test-co.c b/unit-test/test-co.c new file mode 100644 index 0000000..325a98d --- /dev/null +++ b/unit-test/test-co.c @@ -0,0 +1,313 @@ + +#include +#include +#include + +#include + +#include +#include + +static int _count = 0; + +static gboolean on_event1(CoreObject *o, const void *event_info, void *user_data) +{ + _count++; + + g_assert(o); + g_assert(event_info); + g_assert_cmpstr(event_info, ==, "ok"); + + return TRUE; +} + +static gboolean on_event2(CoreObject *o, const void *event_info, void *user_data) +{ + _count++; + + g_assert(o); + g_assert(event_info); + g_assert_cmpstr(event_info, ==, "ok"); + + return FALSE; +} + + +static void test_co_new(void) +{ + CoreObject *co; + + co = tcore_object_new(NULL, "test", NULL); + g_assert(co); + + tcore_object_free (co); +} + +static void test_callback_renew(void) +{ + CoreObject *co; + TReturn ret; + + co = tcore_object_new(NULL, "test", NULL); + g_assert(co); + + // lifetime: unlimit + _count = 0; + ret = tcore_object_add_callback(co, "event1", on_event1, NULL); + g_assert(ret == TCORE_RETURN_SUCCESS); + + ret = tcore_object_emit_callback(co, "event1", "ok"); + g_assert(ret == TCORE_RETURN_SUCCESS); + + ret = tcore_object_emit_callback(co, "event1", "ok"); + g_assert(ret == TCORE_RETURN_SUCCESS); + + g_assert(_count == 2); +} + +static void test_callback_once(void) +{ + CoreObject *co; + TReturn ret; + + co = tcore_object_new(NULL, "test", NULL); + g_assert(co); + + // lifetime: one time callback + unlimit callback + _count = 0; + ret = tcore_object_add_callback(co, "event2", on_event2, NULL); + g_assert(ret == TCORE_RETURN_SUCCESS); + ret = tcore_object_add_callback(co, "event1", on_event1, NULL); + g_assert(ret == TCORE_RETURN_SUCCESS); + + ret = tcore_object_emit_callback(co, "event2", "ok"); + g_assert(ret == TCORE_RETURN_SUCCESS); + + ret = tcore_object_emit_callback(co, "event2", "ok"); + g_assert(ret == TCORE_RETURN_SUCCESS); + + g_assert(_count == 1); + + ret = tcore_object_emit_callback(co, "event1", "ok"); + g_assert(ret == TCORE_RETURN_SUCCESS); + + g_assert(_count == 2); + + tcore_object_free (co); +} + +static gboolean on_prop_changed (CoreObject *co, const void *event_info, + void *user_data) +{ + int *mode = user_data; + GSList *key = (GSList *)event_info; + const char *data; + + switch (*mode) { + case 1: + g_assert (g_slist_length(key) == 1); + g_assert_cmpstr (key->data, ==, "qqq"); + data = tcore_object_ref_property (co, "qqq"); + g_assert_cmpstr (data, ==, "1234"); + break; + + case 2: + g_assert (g_slist_length (key) == 1); + g_assert_cmpstr (key->data, ==, "qqq"); + data = tcore_object_ref_property (co, "qqq"); + g_assert (data == NULL); + break; + + case 3: + g_assert (g_slist_length (key) == 1); + g_assert_cmpstr (key->data, ==, "www"); + data = tcore_object_ref_property (co, "www"); + g_assert_cmpstr (data, ==, "heap"); + break; + + case 4: + g_assert (g_slist_length (key) == 1); + g_assert_cmpstr (key->data, ==, "www"); + data = tcore_object_ref_property (co, "www"); + g_assert (data == NULL); + break; + + case 5: + g_assert (g_slist_length (key) == 1); + g_assert_cmpstr (key->data, ==, "key"); + data = tcore_object_ref_property (co, "key"); + g_assert_cmpstr (data, ==, "1"); + break; + + case 6: + g_assert (g_slist_length (key) == 1); + g_assert_cmpstr (key->data, ==, "key"); + data = tcore_object_ref_property (co, "key"); + g_assert_cmpstr (data, ==, "2"); + break; + + case 7: + g_assert (FALSE); + break; + + case 8: + g_assert (g_slist_length (key) == 1); + g_assert_cmpstr (key->data, ==, "key"); + data = tcore_object_ref_property (co, "key"); + g_assert_cmpstr (data, ==, "2"); + break; + + case 9: + g_assert (g_slist_length (key) == 2); + g_assert_cmpstr (key->data, ==, "foo"); + g_assert_cmpstr (key->next->data, ==, "bar"); + data = tcore_object_ref_property (co, "foo"); + g_assert_cmpstr (data, ==, "1"); + data = tcore_object_ref_property (co, "bar"); + g_assert_cmpstr (data, ==, "2"); + break; + + case 10: + g_assert (g_slist_length (key) == 1); + g_assert_cmpstr (key->data, ==, "foo"); + data = tcore_object_ref_property (co, "foo"); + g_assert (data == NULL); + break; + + case 11: + g_assert (g_slist_length (key) == 2); + g_assert (g_slist_find_custom (key, "foo", + (GCompareFunc)g_strcmp0) != NULL); + g_assert (CORE_OBJECT_KEY_FIND(key, "bar") != NULL); + data = tcore_object_ref_property (co, "foo"); + g_assert_cmpstr (data, ==, "1"); + data = tcore_object_ref_property (co, "bar"); + g_assert (data == NULL); + break; + + default: + g_assert (FALSE); + break; + } + + /* Set flag to callback invocation success */ + *mode = 0; + + return TRUE; +} + +static void test_property (void) +{ + CoreObject *co; + const char *data; + char *test; + GHashTable *raw; + int mode = 0; + GSList *tmp_list; + + co = tcore_object_new (NULL, "test", NULL); + g_assert (co); + + tcore_object_add_callback (co, CORE_OBJECT_EVENT_PROPERTY_CHANGED, + on_prop_changed, &mode); + + raw = tcore_object_ref_property_hash (co); + g_assert (raw); + + /* Case: Basic property set */ + mode = 1; + tcore_object_set_property (co, "qqq", "1234"); + g_assert (g_hash_table_size (raw) == 1); + g_assert (mode == 0); + + data = tcore_object_ref_property (co, "qqq"); + g_assert_cmpstr(data, ==, "1234"); + + /* Case: Basic property remove */ + mode = 2; + tcore_object_set_property (co, "qqq", NULL); + g_assert (g_hash_table_size (raw) == 0); + g_assert (mode == 0); + + data = tcore_object_ref_property (co, "qqq"); + g_assert (data == NULL); + + /* Case: Malloc property set */ + mode = 3; + test = strdup("heap"); + tcore_object_set_property (co, "www", test); + g_assert (g_hash_table_size (raw) == 1); + g_assert (mode == 0); + free(test); + + data = tcore_object_ref_property (co, "www"); + g_assert_cmpstr(data, ==, "heap"); + + /* Case: Malloc property remove */ + mode = 4; + tcore_object_set_property (co, "www", NULL); + g_assert (g_hash_table_size (raw) == 0); + g_assert (mode == 0); + + data = tcore_object_ref_property (co, "www"); + g_assert (data == NULL); + + /* Case: Same key & Different value set */ + mode = 5; + tcore_object_set_property (co, "key", "1"); + g_assert (g_hash_table_size (raw) == 1); + g_assert (mode == 0); + + mode = 6; + tcore_object_set_property (co, "key", "2"); + g_assert (g_hash_table_size (raw) == 1); + g_assert (mode == 0); + + /* Case: Same key & Same value set => No callback invocation */ + mode = 7; + tcore_object_set_property (co, "key", "2"); + g_assert (g_hash_table_size (raw) == 1); + g_assert (mode == 7); + + /* Case: Same key & Same value set & force event invocation */ + mode = 8; + tcore_object_set_property (co, "key", "2"); + g_assert (g_hash_table_size (raw) == 1); + + tmp_list = g_slist_append (NULL, (char*)"key"); + tcore_object_emit_callback(co, CORE_OBJECT_EVENT_PROPERTY_CHANGED, tmp_list); + g_assert (mode == 0); + g_slist_free(tmp_list); + + /* Case: Multiple property set */ + mode = 9; + tcore_object_set_property (co, "foo", "1", "bar", "2"); + g_assert (g_hash_table_size (raw) == 3); + g_assert (mode == 0); + + /* Case: Set key without value => same as key with NULL: remove key */ + mode = 10; + tcore_object_set_property (co, "foo"); + g_assert (g_hash_table_size (raw) == 2); + g_assert (mode == 0); + + /* Case: Multiple property set with unset (foo set, bar unset) */ + mode = 11; + tcore_object_set_property (co, "foo", "1", "bar"); + g_assert (g_hash_table_size (raw) == 2); + g_assert (mode == 0); + + tcore_object_free (co); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/co/new", test_co_new); + g_test_add_func("/co/callback_renew", test_callback_renew); + g_test_add_func("/co/callback_once", test_callback_once); + g_test_add_func("/co/property", test_property); + + return g_test_run(); +} diff --git a/unit-test/test-dcs.c b/unit-test/test-dcs.c new file mode 100644 index 0000000..5d6a3b0 --- /dev/null +++ b/unit-test/test-dcs.c @@ -0,0 +1,69 @@ + +#include +#include +#include + +#include + +#include +#include + +#if 0 +static void dump_hex(const char *msg, unsigned char *data, int data_len) +{ + int i; + + printf("%s", msg); + + for (i = 0; i < data_len; i++) { + printf("%02X ", data[i]); + }; + + printf("\n"); +} +#endif + +static void test_7bit(void) +{ + unsigned char *dest; + unsigned char packed[] = { 0xE8, 0x32, 0x9B, 0xFD, 0x06, 0x00 }; + + /* unpack packed-data('hello') */ + dest = tcore_util_unpack_gsm7bit(packed, 0x05); + g_assert_cmpstr((char *)dest, ==, "hello"); + free(dest); + + /* pack 'hello' */ + dest = tcore_util_pack_gsm7bit((unsigned char *)"hello", strlen("hello")); + + if(!dest){ + g_assert(memcmp(packed, dest, strlen((char *)dest)) == 0); + free(dest); + } +} + +static void test_hex(void) +{ + char *hex = (char *)"1A2B3C4D5E6F"; + unsigned char expected[] = { 0x1A, 0x2B, 0x3C, 0x4D, 0x5E, 0x6F }; + unsigned char *dest; + + dest = tcore_util_decode_hex(hex, strlen(hex)); + g_assert(memcmp(dest, expected, strlen((char *)dest)) == 0); + free(dest); +} + +static void test_ucs(void) +{ +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/dcs/hex", test_hex); + g_test_add_func("/dcs/7bit", test_7bit); + g_test_add_func("/dcs/ucs", test_ucs); + + return g_test_run(); +} diff --git a/unit-test/test-hal.c b/unit-test/test-hal.c new file mode 100644 index 0000000..43691ca --- /dev/null +++ b/unit-test/test-hal.c @@ -0,0 +1,96 @@ + +#include +#include +#include + +#include + +#include +#include + +int g_flag; + + +static void on_recv_callback(TcoreHal *h, unsigned int data_len, const void *data, void *user_data) +{ + g_assert(data_len == 3); + g_assert_cmpstr((char *)data, ==, "123"); + + g_flag++; +} + +static void on_recv_callback2(TcoreHal *h, unsigned int data_len, const void *data, void *user_data) +{ + g_assert(data_len == 3); + g_assert_cmpstr((char *)data, ==, "123"); + + g_flag++; +} + +static void test_callback(void) +{ + TcoreHal *h; + + h = tcore_hal_new(NULL, "test_hal", NULL, TCORE_HAL_MODE_CUSTOM); + g_assert(h); + + tcore_hal_add_recv_callback(h, on_recv_callback, NULL); + + g_flag = 0; + tcore_hal_emit_recv_callback(h, 3, "123"); + g_assert(g_flag == 1); + + tcore_hal_remove_recv_callback(h, on_recv_callback); + + g_flag = 0; + tcore_hal_emit_recv_callback(h, 3, "123"); + g_assert(g_flag == 0); + + tcore_hal_free(h); +} + +static void test_callback2(void) +{ + TcoreHal *h; + + h = tcore_hal_new(NULL, "test_hal", NULL, TCORE_HAL_MODE_CUSTOM); + g_assert(h); + + tcore_hal_add_recv_callback(h, on_recv_callback, NULL); + tcore_hal_add_recv_callback(h, on_recv_callback2, NULL); + + g_flag = 0; + tcore_hal_emit_recv_callback(h, 3, "123"); + g_assert(g_flag == 2); + + tcore_hal_remove_recv_callback(h, on_recv_callback); + + g_flag = 0; + tcore_hal_emit_recv_callback(h, 3, "123"); + g_assert(g_flag == 1); + + /* remove already removed callback */ + tcore_hal_remove_recv_callback(h, on_recv_callback); + + g_flag = 0; + tcore_hal_emit_recv_callback(h, 3, "123"); + g_assert(g_flag == 1); + + tcore_hal_remove_recv_callback(h, on_recv_callback2); + + g_flag = 0; + tcore_hal_emit_recv_callback(h, 3, "123"); + g_assert(g_flag == 0); + + tcore_hal_free(h); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/hal/callback", test_callback); + g_test_add_func("/hal/callback2", test_callback2); + + return g_test_run(); +} diff --git a/unit-test/test-network.c b/unit-test/test-network.c new file mode 100644 index 0000000..28f3af8 --- /dev/null +++ b/unit-test/test-network.c @@ -0,0 +1,76 @@ + +#include +#include +#include + +#include + +#include +#include +#include + + +static void test_operator(void) +{ + TcorePlugin *p; + CoreObject *o; + struct tcore_network_operator_info noi; + struct tcore_network_operator_info *tmp_noi; + TReturn ret; + + p = tcore_plugin_new (NULL, NULL, NULL, NULL); + g_assert (p); + + o = tcore_network_new (p, "test_network", NULL, NULL); + g_assert (o); + + /* Add 2 items */ + snprintf (noi.mcc, 4, "123"); + snprintf (noi.mnc, 4, "01"); + snprintf (noi.name, 41, "Hello"); + ret = tcore_network_operator_info_add (o, &noi); + g_assert (ret == TCORE_RETURN_SUCCESS); + + snprintf (noi.mcc, 4, "123"); + snprintf (noi.mnc, 4, "02"); + snprintf (noi.name, 41, "World"); + ret = tcore_network_operator_info_add (o, &noi); + g_assert (ret == TCORE_RETURN_SUCCESS); + + /* Check items */ + tmp_noi = tcore_network_operator_info_find (o, "123", "01"); + g_assert (tmp_noi); + g_assert_cmpstr (tmp_noi->name, ==, "Hello"); + + tmp_noi = tcore_network_operator_info_find (o, "123", "02"); + g_assert (tmp_noi); + g_assert_cmpstr (tmp_noi->name, ==, "World"); + + /* Replace item */ + snprintf (noi.mcc, 4, "123"); + snprintf (noi.mnc, 4, "02"); + snprintf (noi.name, 41, "Update"); + ret = tcore_network_operator_info_add (o, &noi); + g_assert (ret == TCORE_RETURN_SUCCESS); + + /* Check items */ + tmp_noi = tcore_network_operator_info_find (o, "123", "01"); + g_assert (tmp_noi); + g_assert_cmpstr (tmp_noi->name, ==, "Hello"); + + tmp_noi = tcore_network_operator_info_find (o, "123", "02"); + g_assert (tmp_noi); + g_assert_cmpstr (tmp_noi->name, ==, "Update"); + + tcore_network_free (o); + tcore_plugin_free (p); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/network/operator", test_operator); + + return g_test_run(); +} diff --git a/unit-test/test-queue.c b/unit-test/test-queue.c new file mode 100644 index 0000000..23ab692 --- /dev/null +++ b/unit-test/test-queue.c @@ -0,0 +1,289 @@ + +#include +#include + +#include + +#include +#include +#include +#include + +static int g_flag; + +static TReturn always_send_ok(TcoreHal *hal, unsigned int data_len, void *data) +{ + return TCORE_RETURN_SUCCESS; +} + +static struct tcore_hal_operations hops = { + .send = always_send_ok, +}; + +static void test_queue_hal(void) +{ + TcoreHal *h; + TcorePending *pending1; + TcorePending *pending2; + TcorePending *pending3; + TcorePending *pending = NULL; + TReturn ret; + + h = tcore_hal_new(NULL, "test_hal", &hops, TCORE_HAL_MODE_CUSTOM); + g_assert(h); + + ret = tcore_hal_set_power_state(h, TRUE); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* first item */ + pending1 = tcore_pending_new(NULL, 1); + g_assert(pending1); + tcore_pending_set_priority(pending1, TCORE_PENDING_PRIORITY_IMMEDIATELY); + + /* second item */ + pending2 = tcore_pending_new(NULL, 1); + g_assert(pending2); + tcore_pending_set_auto_free_status_after_sent(pending2, TRUE); + + /* third item */ + pending3 = tcore_pending_new(NULL, 1); + g_assert(pending3); + tcore_pending_set_priority(pending3, TCORE_PENDING_PRIORITY_IMMEDIATELY); + + /* send pending1 */ + ret = tcore_hal_send_request(h, pending1); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* send pending2 -> queue */ + ret = tcore_hal_send_request(h, pending2); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* remove pending1 */ + ret = tcore_hal_dispatch_response_data(h, 1, 0, NULL); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* check next pending */ + pending = tcore_queue_ref_pending_by_id(tcore_hal_ref_queue(h), 1); + g_assert(pending == pending2); + + /* force send (because g_main_loop not work in unit test) */ + tcore_hal_send_force(h); + + /* check next pending (pending2 is auto free) */ + pending = tcore_queue_ref_pending_by_id(tcore_hal_ref_queue(h), 1); + g_assert(pending == NULL); + + /* send pending3 */ + ret = tcore_hal_send_request(h, pending3); + g_assert(ret == TCORE_RETURN_SUCCESS); + + pending = tcore_queue_ref_pending_by_id(tcore_hal_ref_queue(h), 1); + g_assert(pending == pending3); + + /* remove pending3 */ + ret = tcore_hal_dispatch_response_data(h, 1, 0, NULL); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* check next pending (no more pending) */ + pending = tcore_queue_ref_pending_by_id(tcore_hal_ref_queue(h), 1); + g_assert(pending == NULL); + + tcore_hal_free(h); +} + +static void test_queue_push_priority(void) +{ + TcoreQueue *q; + TcorePending *pending1; + TcorePending *pending2; + TcorePending *pending3; + TcorePending *pending = NULL; + TReturn ret; + + q = tcore_queue_new(NULL); + g_assert(q); + + /* first item */ + pending1 = tcore_pending_new(NULL, 1); + g_assert(pending1); + tcore_pending_set_priority(pending1, TCORE_PENDING_PRIORITY_IMMEDIATELY); + + ret = tcore_queue_push(q, pending1); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* second item */ + pending2 = tcore_pending_new(NULL, 1); + g_assert(pending2); + + ret = tcore_queue_push(q, pending2); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* third item, but push to second item position */ + pending3 = tcore_pending_new(NULL, 1); + g_assert(pending3); + tcore_pending_set_priority(pending3, TCORE_PENDING_PRIORITY_IMMEDIATELY); + + ret = tcore_queue_push(q, pending3); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* pop test (order by priority) */ + pending = tcore_queue_pop_by_id(q, 1); + g_assert(pending == pending1); + + pending = tcore_queue_pop_by_id(q, 1); + g_assert(pending == pending3); + + pending = tcore_queue_pop_by_id(q, 1); + g_assert(pending == pending2); + + tcore_queue_free(q); +} + +static void test_queue_push(void) +{ + TcoreQueue *q; + TcorePending *pending1; + TcorePending *pending2; + TcorePending *pending3; + TcorePending *pending = NULL; + TReturn ret; + + q = tcore_queue_new(NULL); + g_assert(q); + + /* first item */ + pending1 = tcore_pending_new(NULL, 1); + g_assert(pending1); + + ret = tcore_queue_push(q, pending1); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* second item */ + pending2 = tcore_pending_new(NULL, 1); + g_assert(pending2); + + ret = tcore_queue_push(q, pending2); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* third item */ + pending3 = tcore_pending_new(NULL, 1); + g_assert(pending3); + + ret = tcore_queue_push(q, pending3); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* pop test (order by push sequence (same priority)) */ + pending = tcore_queue_pop_by_id(q, 1); + g_assert(pending == pending1); + + pending = tcore_queue_pop_by_id(q, 1); + g_assert(pending == pending2); + + pending = tcore_queue_pop_by_id(q, 1); + g_assert(pending == pending3); + + tcore_queue_free(q); +} + +static void on_resp(TcorePending *pending, int data_len, const void *data, void *user_data) +{ + printf("on_resp !!\n"); + g_flag++; +} + +static void test_queue_push_cancel(void) +{ + TcoreHal *h; + TcorePending *pending1; + TcorePending *pending2; + TcorePending *pending3; + TcorePending *p; + TReturn ret; + UserRequest *ur1; + UserRequest *ur2; + + h = tcore_hal_new(NULL, "test_hal", &hops, TCORE_HAL_MODE_CUSTOM); + g_assert(h); + + ret = tcore_hal_set_power_state(h, TRUE); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* first item */ + ur1 = tcore_user_request_new(NULL, NULL); + g_assert(ur1); + + tcore_user_request_set_command(ur1, TREQ_NETWORK_SEARCH); + + pending1 = tcore_pending_new(NULL, 1); + g_assert(pending1); + + tcore_pending_set_response_callback(pending1, on_resp, NULL); + tcore_pending_link_user_request(pending1, ur1); + + ret = tcore_hal_send_request(h, pending1); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* force update send state */ + tcore_pending_emit_send_callback(pending1, TRUE); + + /* second item */ + ur2 = tcore_user_request_new(NULL, NULL); + g_assert(ur2); + + tcore_user_request_set_command(ur2, TREQ_NETWORK_SEARCH); + + pending2 = tcore_pending_new(NULL, 1); + g_assert(pending2); + + tcore_pending_set_response_callback(pending2, on_resp, NULL); + tcore_pending_link_user_request(pending2, ur2); + + ret = tcore_hal_send_request(h, pending2); + g_assert(ret == TCORE_RETURN_SUCCESS); + + /* third item */ + pending3 = tcore_pending_new(NULL, 1); + g_assert(pending3); + + ret = tcore_hal_send_request(h, pending3); + g_assert(ret == TCORE_RETURN_SUCCESS); + + + /* search */ + p = tcore_queue_search_by_command(tcore_hal_ref_queue(h), TREQ_NETWORK_SEARCH, TRUE); + g_assert(p == pending1); + + p = tcore_queue_search_by_command(tcore_hal_ref_queue(h), TREQ_NETWORK_SEARCH, FALSE); + g_assert(p == pending2); + + /* cancel */ + g_flag = 0; + ret = tcore_queue_cancel_pending_by_command(tcore_hal_ref_queue(h), TREQ_NETWORK_SEARCH); + g_assert(ret == TCORE_RETURN_SUCCESS); + + g_assert(g_flag == 2); + +} + +static void test_queue_new(void) +{ + TcoreQueue *q; + + q = tcore_queue_new(NULL); + g_assert(q); + + tcore_queue_free(q); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/queue/new", test_queue_new); + g_test_add_func("/queue/push", test_queue_push); + g_test_add_func("/queue/push_priority", test_queue_push_priority); + g_test_add_func("/queue/push_cancel", test_queue_push_cancel); + g_test_add_func("/queue/hal", test_queue_hal); + + return g_test_run(); +} diff --git a/unit-test/test-util.c b/unit-test/test-util.c new file mode 100644 index 0000000..50cc9ee --- /dev/null +++ b/unit-test/test-util.c @@ -0,0 +1,92 @@ + +#include +#include +#include + +#include + +#include +#include + +static void test_marshal(void) +{ + GHashTable *list; + int value_int; + + list = tcore_util_marshal_create (); + g_assert(list); + + value_int = 1; + tcore_util_marshal_add_data (list, "key1", &value_int, TCORE_UTIL_MARSHAL_DATA_INT_TYPE); + g_assert(tcore_util_marshal_get_int (list, "key1") == value_int); + + value_int = 2; + tcore_util_marshal_add_data (list, "key2", &value_int, TCORE_UTIL_MARSHAL_DATA_INT_TYPE); + g_assert(tcore_util_marshal_get_int (list, "key2") == value_int); + + tcore_util_marshal_destory (list); +} + +static void test_marshal_serialize(void) +{ + GHashTable *list; + GHashTable *item; + GHashTable *tmp; + gchar *serialized; + int i; + char buf[255]; + int value_int; + + list = tcore_util_marshal_create (); + g_assert(list); + + value_int = 1; + tcore_util_marshal_add_data (list, "key1", &value_int, TCORE_UTIL_MARSHAL_DATA_INT_TYPE); + g_assert(tcore_util_marshal_get_int (list, "key1") == value_int); + + value_int = 2; + tcore_util_marshal_add_data (list, "key2", &value_int, TCORE_UTIL_MARSHAL_DATA_INT_TYPE); + g_assert(tcore_util_marshal_get_int (list, "key2") == value_int); + + item = tcore_util_marshal_create (); + g_assert (item); + tcore_util_marshal_add_data (list, "key_object", item, TCORE_UTIL_MARSHAL_DATA_OBJECT_TYPE); + + for (i = 0; i < 3; i++) { + item = tcore_util_marshal_create (); + g_assert (item); + + value_int = i * 10; + snprintf (buf, 255, "sub-%d", i); + tcore_util_marshal_add_data (item, buf, &value_int, TCORE_UTIL_MARSHAL_DATA_INT_TYPE); + g_assert(tcore_util_marshal_get_int (item, buf) == value_int); + + tcore_util_marshal_add_data (list, buf, item, TCORE_UTIL_MARSHAL_DATA_OBJECT_TYPE); + } + + serialized = tcore_util_marshal_serialize (list); + g_assert (serialized); + tcore_util_marshal_destory (list); + + tmp = tcore_util_marshal_deserialize_string (serialized); + g_assert (tmp); + + free (serialized); + + g_assert(tcore_util_marshal_get_int (tmp, "key1") == 1); + g_assert(tcore_util_marshal_get_int (tmp, "key2") == 2); + + tcore_util_marshal_destory (tmp); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + g_type_init(); + + g_test_add_func("/util/marshal", test_marshal); + g_test_add_func("/util/marshal_serialize", test_marshal_serialize); + + return g_test_run(); +}