--- a/AndroidManifest.xml Thu May 10 16:11:18 2012 +0200
+++ b/AndroidManifest.xml Tue Jun 05 16:44:38 2012 +0200
@@ -28,6 +28,12 @@
<activity android:name=".ui.ContactList" android:label="@string/contact_list_name"
android:launchMode="singleTask" />
+ <activity android:name=".ui.Call" android:label="Call String en dur">
+ <intent-filter android:label="Beem Connection">
+ <action
+ android:name="com.beem.project.beem.service.XmppConnectionAdapter.CONNECTION_CLOSED" />
+ </intent-filter>
+ </activity>
<activity android:name=".ui.GroupList" android:label="GroupList" />
<activity android:name=".ui.PrivacyList" android:label="@string/privacy_list_name" />
@@ -61,7 +67,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.beem.project.beem.BEEM_SERVICE"/>
<uses-feature name="android.hardware.touchscreen" required="false" />
- <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="7" />
+ <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="10" />
<supports-screens android:largeScreens="true"
android:normalScreens="true" android:smallScreens="true" android:anyDensity="true" />
</manifest>
Binary file assets/alerting has changed
--- a/build.xml Thu May 10 16:11:18 2012 +0200
+++ b/build.xml Tue Jun 05 16:44:38 2012 +0200
@@ -89,7 +89,6 @@
<import file="${sdk.dir}/tools/ant/build.xml" />
<property name="external.libs.dir" value="libs" />
-
<target name="javadoc" depends="-setup, -build-setup, -code-gen">
<javadoc author="true" destdir="${javadoc.output}" doctitle="Beem javadoc" source="1.6" use="true" version="false" bootclasspathref="android.target.classpath">
<sourcepath>
--- a/doc/asmack-beem/README.txt Thu May 10 16:11:18 2012 +0200
+++ b/doc/asmack-beem/README.txt Tue Jun 05 16:44:38 2012 +0200
@@ -14,26 +14,13 @@
-------
First check out the last version of asmack
-> git clone git://github.com/rtreffer/asmack.git
-
-Then apply the beem-build-process.patch on the source.
-> cd asmack
-> patch -p1 < beem-build-process.patch
->
+> git://github.com/klnikita/asmack.git
-Add the beem flavour to the patch repository
-> cp -R beem_patches patch/beem
->
-
-The 50-fix_chatmanager.patch is only necessary to fix a little bug in smack. The
-patch has been proposed to the Smack developers. See
-http://www.igniterealtime.org/issues/browse/SMACK-269 for progress.
-
-Edit your local.properties file to contains the path of the android SDK. See
-local.properties.example
+In the asmack folder, edit your local.properties file to contains the path of the android SDK.
+See local.properties.example
Build asmack
-> ./build.batch
+> ./build.batch -j -c
>
The build directory will contains the files :
--- a/doc/asmack-beem/beem-build-process.patch Thu May 10 16:11:18 2012 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-diff --git a/build.bash b/build.bash
-index ce793f9..8a7f6bf 100755
---- a/build.bash
-+++ b/build.bash
-@@ -15,11 +15,11 @@ fetch() {
- if ! [ -f "${2}/.svn/entries" ]; then
- mkdir "${2}"
- cd "${2}"
-- svn co --non-interactive --trust-server-cert "${1}" "."
-+ svn co --non-interactive --trust-server-cert "${1}" -r "${3}" "."
- else
- cd "${2}"
- svn cleanup
-- svn up
-+ svn up -r "${3}"
- fi
- )
- }
-@@ -37,11 +37,11 @@ gitfetch() {
- }
-
- fetchall() {
-- gitfetch "git://github.com/rtreffer/smack.git" "smack"
-- fetch "http://svn.apache.org/repos/asf/qpid/trunk/qpid/java/management/common/src/main/" "qpid"
-- fetch "http://svn.apache.org/repos/asf/harmony/enhanced/java/trunk/classlib/modules/auth/src/main/java/common/" "harmony"
-- fetch "https://dnsjava.svn.sourceforge.net/svnroot/dnsjava/trunk" "dnsjava"
-- fetch "https://kenai.com/svn/jbosh~main/trunk/jbosh/src/main/java" "jbosh"
-+ fetch "http://svn.igniterealtime.org/svn/repos/smack/trunk" "smack" "11644"
-+ fetch "http://svn.apache.org/repos/asf/qpid/trunk/qpid/java/management/common/src/main/" "qpid" "HEAD"
-+ fetch "http://svn.apache.org/repos/asf/harmony/enhanced/java/trunk/classlib/modules/auth/src/main/java/common/" "harmony" "HEAD"
-+ fetch "https://dnsjava.svn.sourceforge.net/svnroot/dnsjava/trunk" "dnsjava" "HEAD"
-+ gitfetch "git://kenai.com/jbosh~origin" "jbosh"
- }
-
- copyfolder() {
-@@ -67,7 +67,7 @@ buildsrc() {
- copyfolder "src/dnsjava" "build/src/trunk" "org"
- copyfolder "src/harmony" "build/src/trunk" "."
- copyfolder "src/custom" "build/src/trunk" "."
-- copyfolder "src/jbosh" "build/src/trunk" "."
-+ copyfolder "src/jbosh/src/main/java" "build/src/trunk" "."
- }
-
- patchsrc() {
--- a/doc/asmack-beem/beem_patches/10-PubSubManager-non-final.patch Thu May 10 16:11:18 2012 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-Index: org/jivesoftware/smackx/pubsub/PubSubManager.java
-===================================================================
---- org/jivesoftware/smackx/pubsub/PubSubManager.java (revision 11464)
-+++ org/jivesoftware/smackx/pubsub/PubSubManager.java (working copy)
-@@ -41,7 +41,7 @@
- *
- * @author Robin Collier
- */
--final public class PubSubManager
-+public class PubSubManager
- {
- private XMPPConnection con;
- private String to;
--- a/doc/asmack-beem/beem_patches/10-custom-sslcontext.patch Thu May 10 16:11:18 2012 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-Index: org/jivesoftware/smack/XMPPConnection.java
-===================================================================
---- org/jivesoftware/smack/XMPPConnection.java (révision 11644)
-+++ org/jivesoftware/smack/XMPPConnection.java (copie de travail)
-@@ -758,14 +758,14 @@
- * @throws Exception if an exception occurs.
- */
- void proceedTLSReceived() throws Exception {
-- SSLContext context = SSLContext.getInstance("TLS");
-+ SSLContext context = this.config.getCustomSSLContext();
- KeyStore ks = null;
- KeyManager[] kms = null;
- PasswordCallback pcb = null;
-
- if(config.getCallbackHandler() == null) {
- ks = null;
-- } else {
-+ } else if (context == null) {
- //System.out.println("Keystore type: "+configuration.getKeystoreType());
- if(config.getKeystoreType().equals("NONE")) {
- ks = null;
-@@ -821,10 +821,12 @@
- }
-
- // Verify certificate presented by the server
-- context.init(kms,
-- new javax.net.ssl.TrustManager[]{new ServerTrustManager(getServiceName(), config)},
-- //new javax.net.ssl.TrustManager[]{new OpenTrustManager()},
-- new java.security.SecureRandom());
-+ if (context == null) {
-+ context = SSLContext.getInstance("TLS");
-+ context.init(kms,
-+ new javax.net.ssl.TrustManager[]{new ServerTrustManager(getServiceName(), config)},
-+ new java.security.SecureRandom());
-+ }
- Socket plain = socket;
- // Secure the plain connection
- socket = context.getSocketFactory().createSocket(plain,
-Index: org/jivesoftware/smack/ConnectionConfiguration.java
-===================================================================
---- org/jivesoftware/smack/ConnectionConfiguration.java (révision 11644)
-+++ org/jivesoftware/smack/ConnectionConfiguration.java (copie de travail)
-@@ -20,6 +20,7 @@
-
- package org.jivesoftware.smack;
-
-+import javax.net.ssl.SSLContext;
- import org.jivesoftware.smack.proxy.ProxyInfo;
- import org.jivesoftware.smack.util.DNSUtil;
-
-@@ -59,6 +60,7 @@
- private boolean selfSignedCertificateEnabled = false;
- private boolean expiredCertificatesCheckEnabled = false;
- private boolean notMatchingDomainCheckEnabled = false;
-+ private SSLContext customSSLContext;
-
- private boolean compressionEnabled = false;
-
-@@ -487,6 +489,25 @@
- }
-
- /**
-+ * Gets the custom SSLContext for SSL sockets. This is null by default.
-+ *
-+ * @return the SSLContext previously set with setCustomSSLContext() or null.
-+ */
-+ public SSLContext getCustomSSLContext() {
-+ return this.customSSLContext;
-+ }
-+
-+ /**
-+ * Sets a custom SSLContext for creating SSL sockets. A custom Context causes all other
-+ * SSL/TLS realted settings to be ignored.
-+ *
-+ * @param context the custom SSLContext for new sockets; null to reset default behaviour.
-+ */
-+ public void setCustomSSLContext(SSLContext context) {
-+ this.customSSLContext = context;
-+ }
-+
-+ /**
- * Returns true if the connection is going to use stream compression. Stream compression
- * will be requested after TLS was established (if TLS was enabled) and only if the server
- * offered stream compression. With stream compression network traffic can be reduced
--- a/doc/asmack-beem/beem_patches/50-fix-chatmanager.patch Thu May 10 16:11:18 2012 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
- Copyright (C) 2010 by Frederic-Charles Barthelery,
- Jean-Manuel Da Silva,
- Nikita Kozlov,
- Philippe Lago,
- Jean Baptiste Vergely,
- Vincent Veronis.
-
- 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.
-
---- ../../../src/smack/org/jivesoftware/smack/ChatManager.java 2010-02-23 19:27:26.000000000 +0100
-+++ org/jivesoftware/smack/ChatManager.java 2010-02-23 19:37:47.000000000 +0100
-@@ -111,7 +111,9 @@
- chat = getUserChat(message.getFrom());
- }
- }
--
-+ if (chat == null) {
-+ chat = getUserChat(StringUtils.parseBareAddress(message.getFrom()));
-+ }
- if(chat == null) {
- chat = createChat(message);
- }
--- a/doc/asmack-beem/beem_patches/50-fix-sasl-incorrect-encoding.patch Thu May 10 16:11:18 2012 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
- Copyright (C) 2010 by Frederic-Charles Barthelery,
- Jean-Manuel Da Silva,
- Nikita Kozlov,
- Philippe Lago,
- Jean Baptiste Vergely,
- Vincent Veronis.
-
- 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.
-
---- org/jivesoftware/smack/sasl/SASLMechanism.java~ 2010-07-20 15:13:25.000000000 +0200
-+++ org/jivesoftware/smack/sasl/SASLMechanism.java 2010-07-20 15:15:41.000000000 +0200
-@@ -263,9 +263,6 @@
- if (authenticationText != null) {
- stanza.append(authenticationText);
- }
-- else {
-- stanza.append("=");
-- }
- stanza.append("</response>");
- return stanza.toString();
- }
--- a/doc/asmack-beem/beem_patches/50-improved-pubsub.patch Thu May 10 16:11:18 2012 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
---- ../../../src/smack/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java (révision 11644)
-+++ org/jivesoftware/smackx/pubsub/provider/ItemProvider.java (copie de travail)
-@@ -45,6 +45,8 @@
- }
- else
- {
-+ while (tag != XmlPullParser.START_TAG)
-+ tag = parser.next();
- String payloadElemName = parser.getName();
- String payloadNS = parser.getNamespace();
-
---- ../../../src/org/jivesoftware/smackx/pubsub/Node.java (révision 11644)
-+++ org/jivesoftware/smackx/pubsub/Node.java (copie de travail)
-@@ -60,7 +60,7 @@
- *
- * For example, OpenFire requires the server to be prefixed by <b>pubsub</b>
- */
-- void setTo(String toAddress)
-+ public void setTo(String toAddress)
- {
- to = toAddress;
- }
---- ../../../src/org/jivesoftware/smackx/pubsub/LeafNode.java (révision 11644)
-+++ org/jivesoftware/smackx/pubsub/LeafNode.java (copie de travail)
-@@ -34,7 +34,7 @@
- */
- public class LeafNode extends Node
- {
-- LeafNode(Connection connection, String nodeName)
-+ public LeafNode(Connection connection, String nodeName)
- {
- super(connection, nodeName);
- }
---- ../../../src/org/jivesoftware/smackx/pubsub/PubSubManager.java (révision 11644)
-+++ org/jivesoftware/smackx/pubsub/PubSubManager.java (copie de travail)
-@@ -43,8 +43,8 @@
- */
- final public class PubSubManager
- {
-- private Connection con;
-- private String to;
-+ protected Connection con;
-+ protected String to;
- private Map<String, Node> nodeMap = new ConcurrentHashMap<String, Node>();
-
- /**
--- a/doc/asmack-beem/beem_patches/50-public-info-features.patch Thu May 10 16:11:18 2012 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
- Copyright (C) 2010 by Frederic-Charles Barthelery,
- Jean-Manuel Da Silva,
- Nikita Kozlov,
- Philippe Lago,
- Jean Baptiste Vergely,
- Vincent Veronis.
-
- 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.
-
---- org/jivesoftware/smackx/packet/DiscoverInfo.java 2010-07-22 22:16:27.000000000 +0200
-+++ org/jivesoftware/smackx/packet/DiscoverInfo.java 2010-07-22 22:58:43.000000000 +0200
-@@ -62,7 +62,7 @@
- *
- * @return an Iterator on the discovered features of an XMPP entity
- */
-- Iterator<Feature> getFeatures() {
-+ public Iterator<Feature> getFeatures() {
- synchronized (features) {
- return Collections.unmodifiableList(features).iterator();
- }
-@@ -266,4 +266,4 @@
- return buf.toString();
- }
- }
--}
-\ Pas de fin de ligne à la fin du fichier.
-+}
--- a/doc/asmack-beem/beem_patches/COPYING Thu May 10 16:11:18 2012 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,202 +0,0 @@
-
- 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.
--- a/doc/asmack-beem/beem_patches/README.txt Thu May 10 16:11:18 2012 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-This directory contains different patch to apply on asmack sources. These
-patches will allow us to build a custom flavour of asmack for Beem. This
-directory must be copied in the patch directory of asmack in order to be used.
-Then build asmack the usual way.
-
-All the patches are released under the Apache License, Version 2.0
-You may obtain a copy of the License at
-http://www.apache.org.licenses/LICENCE-2.0
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/Android.mk Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,50 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := gsm
+
+SRC_FILES := gsm/add.c\
+ gsm/code.c\
+ gsm/debug.c\
+ gsm/decode.c\
+ gsm/gsm_create.c\
+ gsm/gsm_decode.c\
+ gsm/gsm_destroy.c\
+ gsm/gsm_encode.c\
+ gsm/gsm_explode.c\
+ gsm/gsm_implode.c\
+ gsm/gsm_option.c\
+ gsm/gsm_print.c\
+ gsm/long_term.c\
+ gsm/lpc.c\
+ gsm/preprocess.c\
+ gsm/rpe.c\
+ gsm/short_term.c\
+ gsm/table.c\
+ gsm/gsm_jni.c
+LOCAL_SRC_FILES := $(SRC_FILES)
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := g722
+
+SRC_FILES := g722/g722_encode.c\
+ g722/g722_decode.c\
+ g722/g722_jni.c
+LOCAL_SRC_FILES := $(SRC_FILES)
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := OSNetworkSystem
+
+SRC_FILES := OSNetworkSystem.cpp
+
+#LOCAL_LDLIBS := -llog
+LOCAL_SRC_FILES := $(SRC_FILES)
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/Application.mk Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,3 @@
+APP_PROJECT_PATH := /home/nikita/devel/beem/beem-audio/
+APP_BUILD_SCRIPT := ${APP_PROJECT_PATH}/jni/Android.mk
+APP_MODULES := gsm g722 OSNetworkSystem
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/OSNetworkSystem.cpp Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,3688 @@
+/*
+ * Copyright (C) 2009 The Sipdroid Open Source Project
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * This file is part of Sipdroid (http://www.sipdroid.org)
+ *
+ * Sipdroid is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this source code; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define LOG_TAG "OSNetworkSystem"
+
+#include <android/log.h>
+#include "jni.h"
+#include "errno.h"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/un.h>
+
+//#include <cutils/properties.h>
+//#include <cutils/adb_networking.h>
+//#include <utils/LogSocket.h>
+//#include "AndroidSystemNatives.h"
+
+/**
+ * @name Socket Errors
+ * Error codes for socket operations
+ *
+ * @internal SOCKERR* range from -200 to -299 avoid overlap
+ */
+#define SOCKERR_BADSOCKET -200 /* generic error */
+#define SOCKERR_NOTINITIALIZED -201 /* socket library uninitialized */
+#define SOCKERR_BADAF -202 /* bad address family */
+#define SOCKERR_BADPROTO -203 /* bad protocol */
+#define SOCKERR_BADTYPE -204 /* bad type */
+#define SOCKERR_SYSTEMBUSY -205 /* system busy handling requests */
+#define SOCKERR_SYSTEMFULL -206 /* too many sockets */
+#define SOCKERR_NOTCONNECTED -207 /* socket is not connected */
+#define SOCKERR_INTERRUPTED -208 /* the call was cancelled */
+#define SOCKERR_TIMEOUT -209 /* the operation timed out */
+#define SOCKERR_CONNRESET -210 /* the connection was reset */
+#define SOCKERR_WOULDBLOCK -211 /* the socket is marked as nonblocking operation would block */
+#define SOCKERR_ADDRNOTAVAIL -212 /* address not available */
+#define SOCKERR_ADDRINUSE -213 /* address already in use */
+#define SOCKERR_NOTBOUND -214 /* the socket is not bound */
+#define SOCKERR_UNKNOWNSOCKET -215 /* resolution of fileDescriptor to socket failed */
+#define SOCKERR_INVALIDTIMEOUT -216 /* the specified timeout is invalid */
+#define SOCKERR_FDSETFULL -217 /* Unable to create an FDSET */
+#define SOCKERR_TIMEVALFULL -218 /* Unable to create a TIMEVAL */
+#define SOCKERR_REMSOCKSHUTDOWN -219 /* The remote socket has shutdown gracefully */
+#define SOCKERR_NOTLISTENING -220 /* listen() was not invoked prior to accept() */
+#define SOCKERR_NOTSTREAMSOCK -221 /* The socket does not support connection-oriented service */
+#define SOCKERR_ALREADYBOUND -222 /* The socket is already bound to an address */
+#define SOCKERR_NBWITHLINGER -223 /* The socket is marked non-blocking & SO_LINGER is non-zero */
+#define SOCKERR_ISCONNECTED -224 /* The socket is already connected */
+#define SOCKERR_NOBUFFERS -225 /* No buffer space is available */
+#define SOCKERR_HOSTNOTFOUND -226 /* Authoritative Answer Host not found */
+#define SOCKERR_NODATA -227 /* Valid name, no data record of requested type */
+#define SOCKERR_BOUNDORCONN -228 /* The socket has not been bound or is already connected */
+#define SOCKERR_OPNOTSUPP -229 /* The socket does not support the operation */
+#define SOCKERR_OPTUNSUPP -230 /* The socket option is not supported */
+#define SOCKERR_OPTARGSINVALID -231 /* The socket option arguments are invalid */
+#define SOCKERR_SOCKLEVELINVALID -232 /* The socket level is invalid */
+#define SOCKERR_TIMEOUTFAILURE -233
+#define SOCKERR_SOCKADDRALLOCFAIL -234 /* Unable to allocate the sockaddr structure */
+#define SOCKERR_FDSET_SIZEBAD -235 /* The calculated maximum size of the file descriptor set is bad */
+#define SOCKERR_UNKNOWNFLAG -236 /* The flag is unknown */
+#define SOCKERR_MSGSIZE -237 /* The datagram was too big to fit the specified buffer & was truncated. */
+#define SOCKERR_NORECOVERY -238 /* The operation failed with no recovery possible */
+#define SOCKERR_ARGSINVALID -239 /* The arguments are invalid */
+#define SOCKERR_BADDESC -240 /* The socket argument is not a valid file descriptor */
+#define SOCKERR_NOTSOCK -241 /* The socket argument is not a socket */
+#define SOCKERR_HOSTENTALLOCFAIL -242 /* Unable to allocate the hostent structure */
+#define SOCKERR_TIMEVALALLOCFAIL -243 /* Unable to allocate the timeval structure */
+#define SOCKERR_LINGERALLOCFAIL -244 /* Unable to allocate the linger structure */
+#define SOCKERR_IPMREQALLOCFAIL -245 /* Unable to allocate the ipmreq structure */
+#define SOCKERR_FDSETALLOCFAIL -246 /* Unable to allocate the fdset structure */
+#define SOCKERR_OPFAILED -247 /* Operation failed */
+#define SOCKERR_VALUE_NULL -248 /* The value indexed was NULL */
+#define SOCKERR_CONNECTION_REFUSED -249 /* connection was refused */
+#define SOCKERR_ENETUNREACH -250 /* network is not reachable */
+#define SOCKERR_EACCES -251 /* permissions do not allow action on socket */
+#define SOCKERR_EHOSTUNREACH -252 /* no route to host */
+#define SOCKERR_EPIPE -253 /* broken pipe */
+
+#define JAVASOCKOPT_TCP_NODELAY 1
+#define JAVASOCKOPT_IP_TOS 3
+#define JAVASOCKOPT_SO_REUSEADDR 4
+#define JAVASOCKOPT_SO_KEEPALIVE 8
+#define JAVASOCKOPT_MCAST_TIME_TO_LIVE 10 /* Currently unused */
+#define JAVASOCKOPT_SO_BINDADDR 15
+#define JAVASOCKOPT_MCAST_INTERFACE 16
+#define JAVASOCKOPT_MCAST_TTL 17
+#define JAVASOCKOPT_IP_MULTICAST_LOOP 18
+#define JAVASOCKOPT_MCAST_ADD_MEMBERSHIP 19
+#define JAVASOCKOPT_MCAST_DROP_MEMBERSHIP 20
+#define JAVASOCKOPT_IP_MULTICAST_IF2 31
+#define JAVASOCKOPT_SO_BROADCAST 32
+#define JAVASOCKOPT_SO_LINGER 128
+#define JAVASOCKOPT_REUSEADDR_AND_REUSEPORT 10001
+#define JAVASOCKOPT_SO_SNDBUF 4097
+#define JAVASOCKOPT_SO_RCVBUF 4098
+#define JAVASOCKOPT_SO_RCVTIMEOUT 4102
+#define JAVASOCKOPT_SO_OOBINLINE 4099
+
+/* constants for calling multi-call functions */
+#define SOCKET_STEP_START 10
+#define SOCKET_STEP_CHECK 20
+#define SOCKET_STEP_DONE 30
+
+#define BROKEN_MULTICAST_IF 1
+#define BROKEN_MULTICAST_TTL 2
+#define BROKEN_TCP_NODELAY 4
+
+#define SOCKET_CONNECT_STEP_START 0
+#define SOCKET_CONNECT_STEP_CHECK 1
+
+#define SOCKET_OP_NONE 0
+#define SOCKET_OP_READ 1
+#define SOCKET_OP_WRITE 2
+#define SOCKET_READ_WRITE 3
+
+#define SOCKET_MSG_PEEK 1
+#define SOCKET_MSG_OOB 2
+
+#define SOCKET_NOFLAGS 0
+
+#undef BUFFERSIZE
+#define BUFFERSIZE 2048
+
+// wait for 500000 usec = 0.5 second
+#define SEND_RETRY_TIME 500000
+
+
+struct CachedFields {
+ jfieldID fd_descriptor;
+ jclass iaddr_class;
+ jmethodID iaddr_class_init;
+ jmethodID iaddr_getbyaddress;
+ jfieldID iaddr_ipaddress;
+ jclass genericipmreq_class;
+ jclass integer_class;
+ jmethodID integer_class_init;
+ jfieldID integer_class_value;
+ jclass boolean_class;
+ jmethodID boolean_class_init;
+ jfieldID boolean_class_value;
+ jclass byte_class;
+ jmethodID byte_class_init;
+ jfieldID byte_class_value;
+ jclass string_class;
+ jmethodID string_class_init;
+ jfieldID socketimpl_address;
+ jfieldID socketimpl_port;
+ jclass dpack_class;
+ jfieldID dpack_address;
+ jfieldID dpack_port;
+ jfieldID dpack_length;
+ jclass fd_class;
+ jfieldID descriptor;
+} gCachedFields;
+
+static int useAdbNetworking = 0;
+
+/* needed for connecting with timeout */
+typedef struct selectFDSet {
+ int nfds;
+ int sock;
+ fd_set writeSet;
+ fd_set readSet;
+ fd_set exceptionSet;
+} selectFDSet;
+
+static const char * netLookupErrorString(int anErrorNum);
+
+#define log_socket_close(a,b)
+#define log_socket_connect(a,b,c)
+#define add_send_stats(a,b)
+#define add_recv_stats(a,b)
+#define adb_networking_connect_fd(a,b) 0
+#define adb_networking_gethostbyname(a,b) 0
+#define PROPERTY_VALUE_MAX 1
+#define property_get(a,b,c)
+#define assert(a)
+/*
+ * Throw an exception with the specified class and an optional message.
+ */
+int jniThrowException(JNIEnv* env, const char* className, const char* msg)
+{
+ jclass exceptionClass;
+
+ exceptionClass = env->FindClass(className);
+ if (exceptionClass == NULL) {
+// LOGE("Unable to find exception class %s\n", className);
+ assert(0); /* fatal during dev; should always be fatal? */
+ return -1;
+ }
+
+ if (env->ThrowNew(exceptionClass, msg) != JNI_OK) {
+// LOGE("Failed throwing '%s' '%s'\n", className, msg);
+ assert(!"failed to throw");
+ }
+ return 0;
+}
+
+/*
+ * Internal helper function.
+ *
+ * Get the file descriptor.
+ */
+static inline int getFd(JNIEnv* env, jobject obj)
+{
+ return env->GetIntField(obj, gCachedFields.descriptor);
+}
+
+/*
+ * Internal helper function.
+ *
+ * Set the file descriptor.
+ */
+static inline void setFd(JNIEnv* env, jobject obj, jint value)
+{
+ env->SetIntField(obj, gCachedFields.descriptor, value);
+}
+
+/*
+ * For JNIHelp.c
+ * Get an int file descriptor from a java.io.FileDescriptor
+ */
+
+static int jniGetFDFromFileDescriptor (JNIEnv* env, jobject fileDescriptor) {
+
+ return getFd(env, fileDescriptor);
+}
+
+/*
+ * For JNIHelp.c
+ * Set the descriptor of a java.io.FileDescriptor
+ */
+
+static void jniSetFileDescriptorOfFD (JNIEnv* env, jobject fileDescriptor, int value) {
+
+ setFd(env, fileDescriptor, value);
+}
+
+/**
+ * Throws an SocketException with the message affiliated with the errorCode.
+ */
+static void throwSocketException(JNIEnv *env, int errorCode) {
+ jniThrowException(env, "java/net/SocketException",
+ netLookupErrorString(errorCode));
+}
+
+/**
+ * Throws an IOException with the given message.
+ */
+static void throwIOExceptionStr(JNIEnv *env, const char *message) {
+ jniThrowException(env, "java/io/IOException", message);
+}
+
+/**
+ * Throws a NullPointerException.
+ */
+static void throwNullPointerException(JNIEnv *env) {
+ jniThrowException(env, "java/lang/NullPointerException", NULL);
+}
+
+/**
+ * Converts a 4-byte array to a native address structure. Throws a
+ * NullPointerException or an IOException in case of error. This is
+ * signaled by a return value of -1. The normal return value is 0.
+ */
+static int javaAddressToStructIn(
+ JNIEnv *env, jbyteArray java_address, struct in_addr *address) {
+
+ memset(address, 0, sizeof(address));
+
+ if (java_address == NULL) {
+ return -1;
+ }
+
+ if (env->GetArrayLength(java_address) != sizeof(address->s_addr)) {
+ return -1;
+ }
+
+ jbyte * java_address_bytes
+ = env->GetByteArrayElements(java_address, NULL);
+
+ memcpy(&(address->s_addr),
+ java_address_bytes,
+ sizeof(address->s_addr));
+
+ env->ReleaseByteArrayElements(java_address, java_address_bytes, JNI_ABORT);
+
+ return 0;
+}
+
+/**
+ * Converts a native address structure to a 4-byte array. Throws a
+ * NullPointerException or an IOException in case of error. This is
+ * signaled by a return value of -1. The normal return value is 0.
+ */
+static int structInToJavaAddress(
+ JNIEnv *env, struct in_addr *address, jbyteArray java_address) {
+
+ if (java_address == NULL) {
+ return -1;
+ }
+
+ if (env->GetArrayLength(java_address) != sizeof(address->s_addr)) {
+ return -1;
+ }
+
+ jbyte *java_address_bytes;
+
+ java_address_bytes = env->GetByteArrayElements(java_address, NULL);
+
+ memcpy(java_address_bytes, &(address->s_addr), sizeof(address->s_addr));
+
+ env->ReleaseByteArrayElements(java_address, java_address_bytes, 0);
+
+ return 0;
+}
+
+/**
+ * Converts a native address structure to an InetAddress object.
+ * Throws a NullPointerException or an IOException in case of
+ * error. This is signaled by a return value of -1. The normal
+ * return value is 0.
+ */
+static int socketAddressToInetAddress(JNIEnv *env,
+ struct sockaddr_in *sockaddress, jobject inetaddress, int *port) {
+
+ jbyteArray ipaddress;
+ int result;
+
+ ipaddress = (jbyteArray)env->GetObjectField(inetaddress,
+ gCachedFields.iaddr_ipaddress);
+
+ if (structInToJavaAddress(env, &sockaddress->sin_addr, ipaddress) < 0) {
+ return -1;
+ }
+
+ *port = ntohs(sockaddress->sin_port);
+
+ return 0;
+}
+
+/**
+ * Converts an InetAddress object to a native address structure.
+ * Throws a NullPointerException or an IOException in case of
+ * error. This is signaled by a return value of -1. The normal
+ * return value is 0.
+ */
+static int inetAddressToSocketAddress(JNIEnv *env,
+ jobject inetaddress, int port, struct sockaddr_in *sockaddress) {
+
+ jbyteArray ipaddress;
+ int result;
+
+ ipaddress = (jbyteArray)env->GetObjectField(inetaddress,
+ gCachedFields.iaddr_ipaddress);
+
+ memset(sockaddress, 0, sizeof(sockaddress));
+
+ sockaddress->sin_family = AF_INET;
+ sockaddress->sin_port = htons(port);
+
+ if (javaAddressToStructIn(env, ipaddress, &(sockaddress->sin_addr)) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static jobject structInToInetAddress(JNIEnv *env, struct in_addr *address) {
+ jbyteArray bytes;
+ int success;
+
+ bytes = env->NewByteArray(4);
+
+ if (bytes == NULL) {
+ return NULL;
+ }
+
+ if (structInToJavaAddress(env, address, bytes) < 0) {
+ return NULL;
+ }
+
+ return env->CallStaticObjectMethod(gCachedFields.iaddr_class,
+ gCachedFields.iaddr_getbyaddress, bytes);
+}
+
+/**
+ * Answer a new java.lang.Boolean object.
+ *
+ * @param env pointer to the JNI library
+ * @param anInt the Boolean constructor argument
+ *
+ * @return the new Boolean
+ */
+
+static jobject newJavaLangBoolean(JNIEnv * env, jint anInt) {
+ jclass tempClass;
+ jmethodID tempMethod;
+
+ tempClass = gCachedFields.boolean_class;
+ tempMethod = gCachedFields.boolean_class_init;
+ return env->NewObject(tempClass, tempMethod, (jboolean) (anInt != 0));
+}
+
+/**
+ * Answer a new java.lang.Byte object.
+ *
+ * @param env pointer to the JNI library
+ * @param anInt the Byte constructor argument
+ *
+ * @return the new Byte
+ */
+
+static jobject newJavaLangByte(JNIEnv * env, jbyte val) {
+ jclass tempClass;
+ jmethodID tempMethod;
+
+ tempClass = gCachedFields.byte_class;
+ tempMethod = gCachedFields.byte_class_init;
+ return env->NewObject(tempClass, tempMethod, val);
+}
+
+/**
+ * Answer a new java.lang.Integer object.
+ *
+ * @param env pointer to the JNI library
+ * @param anInt the Integer constructor argument
+ *
+ * @return the new Integer
+ */
+
+static jobject newJavaLangInteger(JNIEnv * env, jint anInt) {
+ jclass tempClass;
+ jmethodID tempMethod;
+
+ tempClass = gCachedFields.integer_class;
+ tempMethod = gCachedFields.integer_class_init;
+ return env->NewObject(tempClass, tempMethod, anInt);
+}
+
+/**
+ * Answer a new java.lang.String object.
+ *
+ * @param env pointer to the JNI library
+ * @param anInt the byte[] constructor argument
+ *
+ * @return the new String
+ */
+
+static jobject newJavaLangString(JNIEnv * env, jbyteArray bytes) {
+ jclass tempClass;
+ jmethodID tempMethod;
+
+ tempClass = gCachedFields.string_class;
+ tempMethod = gCachedFields.string_class_init;
+ return env->NewObject(tempClass, tempMethod, (jbyteArray) bytes);
+}
+
+/**
+ * Query OS for timestamp.
+ * Retrieve the current value of system clock and convert to milliseconds.
+ *
+ * @param[in] portLibrary The port library.
+ *
+ * @return 0 on failure, time value in milliseconds on success.
+ * @deprecated Use @ref time_hires_clock and @ref time_hires_delta
+ *
+ * technically, this should return I_64 since both timeval.tv_sec and
+ * timeval.tv_usec are long
+ */
+
+static int time_msec_clock() {
+ struct timeval tp;
+ struct timezone tzp;
+
+ gettimeofday(&tp, &tzp);
+ return (tp.tv_sec * 1000) + (tp.tv_usec / 1000);
+}
+
+/**
+ * check if the passed sockaddr_in struct contains a localhost address
+ *
+ * @param[in] address pointer to the address to check
+ *
+ * @return 0 if the passed address isn't a localhost address
+ */
+static int isLocalhost(struct sockaddr_in *address) {
+ // return address == 127.0.0.1
+ return (unsigned int) address->sin_addr.s_addr == 16777343;
+}
+
+/**
+ * Answer the errorString corresponding to the errorNumber, if available.
+ * This function will answer a default error string, if the errorNumber is not
+ * recognized.
+ *
+ * This function will have to be reworked to handle internationalization
+ * properly, removing the explicit strings.
+ *
+ * @param anErrorNum the error code to resolve to a human readable string
+ *
+ * @return a human readable error string
+ */
+
+static const char * netLookupErrorString(int anErrorNum) {
+ switch (anErrorNum) {
+ case SOCKERR_BADSOCKET:
+ return "Bad socket";
+ case SOCKERR_NOTINITIALIZED:
+ return "Socket library uninitialized";
+ case SOCKERR_BADAF:
+ return "Bad address family";
+ case SOCKERR_BADPROTO:
+ return "Bad protocol";
+ case SOCKERR_BADTYPE:
+ return "Bad type";
+ case SOCKERR_SYSTEMBUSY:
+ return "System busy handling requests";
+ case SOCKERR_SYSTEMFULL:
+ return "Too many sockets allocated";
+ case SOCKERR_NOTCONNECTED:
+ return "Socket is not connected";
+ case SOCKERR_INTERRUPTED:
+ return "The system call was cancelled";
+ case SOCKERR_TIMEOUT:
+ return "The operation timed out";
+ case SOCKERR_CONNRESET:
+ return "The connection was reset";
+ case SOCKERR_WOULDBLOCK:
+ return "The nonblocking operation would block";
+ case SOCKERR_ADDRNOTAVAIL:
+ return "The address is not available";
+ case SOCKERR_ADDRINUSE:
+ return "The address is already in use";
+ case SOCKERR_NOTBOUND:
+ return "The socket is not bound";
+ case SOCKERR_UNKNOWNSOCKET:
+ return "Resolution of the FileDescriptor to socket failed";
+ case SOCKERR_INVALIDTIMEOUT:
+ return "The specified timeout is invalid";
+ case SOCKERR_FDSETFULL:
+ return "Unable to create an FDSET";
+ case SOCKERR_TIMEVALFULL:
+ return "Unable to create a TIMEVAL";
+ case SOCKERR_REMSOCKSHUTDOWN:
+ return "The remote socket has shutdown gracefully";
+ case SOCKERR_NOTLISTENING:
+ return "Listen() was not invoked prior to accept()";
+ case SOCKERR_NOTSTREAMSOCK:
+ return "The socket does not support connection-oriented service";
+ case SOCKERR_ALREADYBOUND:
+ return "The socket is already bound to an address";
+ case SOCKERR_NBWITHLINGER:
+ return "The socket is marked non-blocking & SO_LINGER is non-zero";
+ case SOCKERR_ISCONNECTED:
+ return "The socket is already connected";
+ case SOCKERR_NOBUFFERS:
+ return "No buffer space is available";
+ case SOCKERR_HOSTNOTFOUND:
+ return "Authoritative Answer Host not found";
+ case SOCKERR_NODATA:
+ return "Valid name, no data record of requested type";
+ case SOCKERR_BOUNDORCONN:
+ return "The socket has not been bound or is already connected";
+ case SOCKERR_OPNOTSUPP:
+ return "The socket does not support the operation";
+ case SOCKERR_OPTUNSUPP:
+ return "The socket option is not supported";
+ case SOCKERR_OPTARGSINVALID:
+ return "The socket option arguments are invalid";
+ case SOCKERR_SOCKLEVELINVALID:
+ return "The socket level is invalid";
+ case SOCKERR_TIMEOUTFAILURE:
+ return "The timeout operation failed";
+ case SOCKERR_SOCKADDRALLOCFAIL:
+ return "Failed to allocate address structure";
+ case SOCKERR_FDSET_SIZEBAD:
+ return "The calculated maximum size of the file descriptor set is bad";
+ case SOCKERR_UNKNOWNFLAG:
+ return "The flag is unknown";
+ case SOCKERR_MSGSIZE:
+ return "The datagram was too big to fit the specified buffer, so truncated";
+ case SOCKERR_NORECOVERY:
+ return "The operation failed with no recovery possible";
+ case SOCKERR_ARGSINVALID:
+ return "The arguments are invalid";
+ case SOCKERR_BADDESC:
+ return "The socket argument is not a valid file descriptor";
+ case SOCKERR_NOTSOCK:
+ return "The socket argument is not a socket";
+ case SOCKERR_HOSTENTALLOCFAIL:
+ return "Unable to allocate the hostent structure";
+ case SOCKERR_TIMEVALALLOCFAIL:
+ return "Unable to allocate the timeval structure";
+ case SOCKERR_LINGERALLOCFAIL:
+ return "Unable to allocate the linger structure";
+ case SOCKERR_IPMREQALLOCFAIL:
+ return "Unable to allocate the ipmreq structure";
+ case SOCKERR_FDSETALLOCFAIL:
+ return "Unable to allocate the fdset structure";
+ case SOCKERR_OPFAILED:
+ return "Operation failed";
+ case SOCKERR_CONNECTION_REFUSED:
+ return "Connection refused";
+ case SOCKERR_ENETUNREACH:
+ return "Network unreachable";
+ case SOCKERR_EHOSTUNREACH:
+ return "No route to host";
+ case SOCKERR_EPIPE:
+ return "Broken pipe";
+ case SOCKERR_EACCES:
+ return "Permission denied (maybe missing INTERNET permission)";
+
+ default:
+// LOGE("unknown socket error %d", anErrorNum);
+ return "unknown error";
+ }
+}
+
+static int convertError(int errorCode) {
+ switch (errorCode) {
+ case EBADF:
+ return SOCKERR_BADDESC;
+ case ENOBUFS:
+ return SOCKERR_NOBUFFERS;
+ case EOPNOTSUPP:
+ return SOCKERR_OPNOTSUPP;
+ case ENOPROTOOPT:
+ return SOCKERR_OPTUNSUPP;
+ case EINVAL:
+ return SOCKERR_SOCKLEVELINVALID;
+ case ENOTSOCK:
+ return SOCKERR_NOTSOCK;
+ case EINTR:
+ return SOCKERR_INTERRUPTED;
+ case ENOTCONN:
+ return SOCKERR_NOTCONNECTED;
+ case EAFNOSUPPORT:
+ return SOCKERR_BADAF;
+ /* note: CONNRESET not included because it has the same
+ * value as ECONNRESET and they both map to SOCKERR_CONNRESET */
+ case ECONNRESET:
+ return SOCKERR_CONNRESET;
+ case EAGAIN:
+ return SOCKERR_WOULDBLOCK;
+ case EPROTONOSUPPORT:
+ return SOCKERR_BADPROTO;
+ case EFAULT:
+ return SOCKERR_ARGSINVALID;
+ case ETIMEDOUT:
+ return SOCKERR_TIMEOUT;
+ case ECONNREFUSED:
+ return SOCKERR_CONNECTION_REFUSED;
+ case ENETUNREACH:
+ return SOCKERR_ENETUNREACH;
+ case EACCES:
+ return SOCKERR_EACCES;
+ case EPIPE:
+ return SOCKERR_EPIPE;
+ case EHOSTUNREACH:
+ return SOCKERR_EHOSTUNREACH;
+ case EADDRINUSE:
+ return SOCKERR_ADDRINUSE;
+ case EADDRNOTAVAIL:
+ return SOCKERR_ADDRNOTAVAIL;
+ case EMSGSIZE:
+ return SOCKERR_MSGSIZE;
+ default:
+// LOGE("unclassified errno %d (%s)", errorCode, strerror(errorCode));
+ return SOCKERR_OPFAILED;
+ }
+}
+
+static int sockSelect(int nfds, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, struct timeval *timeout) {
+
+ int result = select(nfds, readfds, writefds, exceptfds, timeout);
+
+ if (result < 0) {
+ if (errno == EINTR) {
+ result = SOCKERR_INTERRUPTED;
+ } else {
+ result = SOCKERR_OPFAILED;
+ }
+ } else if (result == 0) {
+ result = SOCKERR_TIMEOUT;
+ }
+ return result;
+}
+
+#define SELECT_READ_TYPE 0
+#define SELECT_WRITE_TYPE 1
+
+static int selectWait(int handle, int uSecTime, int type) {
+ fd_set fdset;
+ struct timeval time, *timePtr;
+ int result = 0;
+ int size = handle + 1;
+
+ FD_ZERO(&fdset);
+ FD_SET(handle, &fdset);
+
+ if (0 <= uSecTime) {
+ /* Use a timeout if uSecTime >= 0 */
+ memset(&time, 0, sizeof(time));
+ time.tv_usec = uSecTime;
+ timePtr = &time;
+ } else {
+ /* Infinite timeout if uSecTime < 0 */
+ timePtr = NULL;
+ }
+
+ if (type == SELECT_READ_TYPE) {
+ result = sockSelect(size, &fdset, NULL, NULL, timePtr);
+ } else {
+ result = sockSelect(size, NULL, &fdset, NULL, timePtr);
+ }
+ return result;
+}
+
+static int pollSelectWait(JNIEnv *env, jobject fileDescriptor, int timeout, int type) {
+ /* now try reading the socket for the timespan timeout.
+ * if timeout is 0 try forever until the soclets gets ready or until an
+ * exception occurs.
+ */
+ int pollTimeoutUSec = 100000, pollMsec = 100;
+ int finishTime = 0;
+ int timeLeft = timeout;
+ int hasTimeout = timeout > 0 ? 1 : 0;
+ int result = 0;
+ int handle;
+
+ if (hasTimeout) {
+ finishTime = time_msec_clock() + timeout;
+ }
+
+ int poll = 1;
+
+ while (poll) { /* begin polling loop */
+
+ /*
+ * Fetch the handle every time in case the socket is closed.
+ */
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_INTERRUPTED);
+ return -1;
+ }
+
+ if (hasTimeout) {
+
+ if (timeLeft - 10 < pollMsec) {
+ pollTimeoutUSec = timeLeft <= 0 ? 0 : (timeLeft * 1000);
+ }
+
+ result = selectWait(handle, pollTimeoutUSec, type);
+
+ /*
+ * because we are polling at a time smaller than timeout
+ * (presumably) lets treat an interrupt and timeout the same - go
+ * see if we're done timewise, and then just try again if not.
+ */
+ if (SOCKERR_TIMEOUT == result ||
+ SOCKERR_INTERRUPTED == result) {
+
+ timeLeft = finishTime - time_msec_clock();
+
+ if (timeLeft <= 0) {
+ /*
+ * Always throw the "timeout" message because that is
+ * effectively what has happened, even if we happen to
+ * have been interrupted.
+ */
+ jniThrowException(env, "java/net/SocketTimeoutException",
+ netLookupErrorString(SOCKERR_TIMEOUT));
+ } else {
+ continue; // try again
+ }
+
+ } else if (0 > result) {
+ log_socket_close(handle, result);
+ throwSocketException(env, result);
+ }
+ poll = 0;
+
+ } else { /* polling with no timeout (why would you do this?)*/
+
+ result = selectWait(handle, pollTimeoutUSec, type);
+
+ /*
+ * if interrupted (or a timeout) just retry
+ */
+ if (SOCKERR_TIMEOUT == result ||
+ SOCKERR_INTERRUPTED == result) {
+
+ continue; // try again
+ } else if (0 > result) {
+ log_socket_close(handle, result);
+ throwSocketException(env, result);
+ }
+ poll = 0;
+ }
+ } /* end polling loop */
+
+ return result;
+}
+
+/**
+ * A helper method, to set the connect context to a Long object.
+ *
+ * @param env pointer to the JNI library
+ * @param longclass Java Long Object
+ */
+void setConnectContext(JNIEnv *env,jobject longclass,jbyte * context) {
+ jclass descriptorCLS;
+ jfieldID descriptorFID;
+ descriptorCLS = env->FindClass("java/lang/Long");
+ descriptorFID = env->GetFieldID(descriptorCLS, "value", "J");
+ env->SetLongField(longclass, descriptorFID, (jlong)((jint)context));
+};
+
+/**
+ * A helper method, to get the connect context.
+ *
+ * @param env pointer to the JNI library
+ * @param longclass Java Long Object
+ */
+jbyte *getConnectContext(JNIEnv *env, jobject longclass) {
+ jclass descriptorCLS;
+ jfieldID descriptorFID;
+ descriptorCLS = env->FindClass("java/lang/Long");
+ descriptorFID = env->GetFieldID(descriptorCLS, "value", "J");
+ return (jbyte*) ((jint)env->GetLongField(longclass, descriptorFID));
+};
+
+// typical ip checksum
+unsigned short ip_checksum(unsigned short* buffer, int size) {
+ register unsigned short * buf = buffer;
+ register int bufleft = size;
+ register unsigned long sum = 0;
+
+ while (bufleft > 1) {
+ sum = sum + (*buf++);
+ bufleft = bufleft - sizeof(unsigned short );
+ }
+ if (bufleft) {
+ sum = sum + (*(unsigned char*)buf);
+ }
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum += (sum >> 16);
+
+ return (unsigned short )(~sum);
+}
+
+/**
+ * Establish a connection to a peer with a timeout. This function is called
+ * repeatedly in order to carry out the connect and to allow other tasks to
+ * proceed on certain platforms. The caller must first call with
+ * step = SOCKET_STEP_START, if the result is SOCKERR_NOTCONNECTED it will then
+ * call it with step = CHECK until either another error or 0 is returned to
+ * indicate the connect is complete. Each time the function should sleep for no
+ * more than timeout milliseconds. If the connect succeeds or an error occurs,
+ * the caller must always end the process by calling the function with
+ * step = SOCKET_STEP_DONE
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] sock pointer to the unconnected local socket.
+ * @param[in] addr pointer to the sockaddr, specifying remote host/port.
+ * @param[in] timeout the timeout in milliseconds. If timeout is negative,
+ * perform a block operation.
+ * @param[in,out] pointer to context pointer. Filled in on first call and then
+ * to be passed into each subsequent call.
+ *
+ * @return 0, if no errors occurred, otherwise the (negative) error code.
+ */
+static int sockConnectWithTimeout(int handle, struct sockaddr_in addr,
+ unsigned int timeout, unsigned int step, jbyte *ctxt) {
+ int rc = 0;
+ struct timeval passedTimeout;
+ int errorVal;
+ socklen_t errorValLen = sizeof(int);
+ struct selectFDSet *context = NULL;
+
+ if (SOCKET_STEP_START == step) {
+
+ context = (struct selectFDSet *) ctxt;
+
+ context->sock = handle;
+ context->nfds = handle + 1;
+
+ if (useAdbNetworking && !isLocalhost(&addr)) {
+
+ // LOGD("+connect to address 0x%08x (via adb)",
+ // addr.sin_addr.s_addr);
+ rc = adb_networking_connect_fd(handle, &addr);
+ // LOGD("-connect ret %d errno %d (via adb)", rc, errno);
+
+ } else {
+ log_socket_connect(handle, ntohl(addr.sin_addr.s_addr),
+ ntohs(addr.sin_port));
+ /* set the socket to non-blocking */
+ int block = JNI_TRUE;
+ rc = ioctl(handle, FIONBIO, &block);
+ if (0 != rc) {
+ return convertError(rc);
+ }
+
+ // LOGD("+connect to address 0x%08x (via normal) on handle %d",
+ // addr.sin_addr.s_addr, handle);
+ do {
+ rc = connect(handle, (struct sockaddr *) &addr,
+ sizeof(struct sockaddr));
+ } while (rc < 0 && errno == EINTR);
+ // LOGD("-connect to address 0x%08x (via normal) returned %d",
+ // addr.sin_addr.s_addr, (int) rc);
+
+ }
+
+ if (rc == -1) {
+ rc = errno;
+ switch (rc) {
+ case EINTR:
+ return SOCKERR_ALREADYBOUND;
+ case EAGAIN:
+ case EINPROGRESS:
+ return SOCKERR_NOTCONNECTED;
+ default:
+ return convertError(rc);
+ }
+ }
+
+ /* we connected right off the bat so just return */
+ return rc;
+
+ } else if (SOCKET_STEP_CHECK == step) {
+ /* now check if we have connected yet */
+
+ context = (struct selectFDSet *) ctxt;
+
+ /*
+ * set the timeout value to be used. Because on some unix platforms we
+ * don't get notified when a socket is closed we only sleep for 100ms
+ * at a time
+ */
+ passedTimeout.tv_sec = 0;
+ if (timeout > 100) {
+ passedTimeout.tv_usec = 100 * 1000;
+ } else if ((int)timeout >= 0) {
+ passedTimeout.tv_usec = timeout * 1000;
+ }
+
+ /* initialize the FD sets for the select */
+ FD_ZERO(&(context->exceptionSet));
+ FD_ZERO(&(context->writeSet));
+ FD_ZERO(&(context->readSet));
+ FD_SET(context->sock, &(context->writeSet));
+ FD_SET(context->sock, &(context->readSet));
+ FD_SET(context->sock, &(context->exceptionSet));
+
+ rc = select(context->nfds,
+ &(context->readSet),
+ &(context->writeSet),
+ &(context->exceptionSet),
+ (int)timeout >= 0 ? &passedTimeout : NULL);
+
+ /* if there is at least one descriptor ready to be checked */
+ if (0 < rc) {
+ /* if the descriptor is in the write set we connected or failed */
+ if (FD_ISSET(context->sock, &(context->writeSet))) {
+
+ if (!FD_ISSET(context->sock, &(context->readSet))) {
+ /* ok we have connected ok */
+ return 0;
+ } else {
+ /* ok we have more work to do to figure it out */
+ if (getsockopt(context->sock, SOL_SOCKET, SO_ERROR,
+ &errorVal, &errorValLen) >= 0) {
+ return errorVal ? convertError(errorVal) : 0;
+ } else {
+ return convertError(errno);
+ }
+ }
+ }
+
+ /* if the descriptor is in the exception set the connect failed */
+ if (FD_ISSET(context->sock, &(context->exceptionSet))) {
+ if (getsockopt(context->sock, SOL_SOCKET, SO_ERROR, &errorVal,
+ &errorValLen) >= 0) {
+ return errorVal ? convertError(errorVal) : 0;
+ }
+ rc = errno;
+ return convertError(rc);
+ }
+
+ } else if (rc < 0) {
+ /* something went wrong with the select call */
+ rc = errno;
+
+ /* if it was EINTR we can just try again. Return not connected */
+ if (EINTR == rc) {
+ return SOCKERR_NOTCONNECTED;
+ }
+
+ /* some other error occured so look it up and return */
+ return convertError(rc);
+ }
+
+ /*
+ * if we get here the timeout expired or the connect had not yet
+ * completed just indicate that the connect is not yet complete
+ */
+ return SOCKERR_NOTCONNECTED;
+ } else if (SOCKET_STEP_DONE == step) {
+ /* we are done the connect or an error occured so clean up */
+ if (handle != -1) {
+ int block = JNI_FALSE;
+ ioctl(handle, FIONBIO, &block);
+ }
+ return 0;
+ }
+ return SOCKERR_ARGSINVALID;
+}
+
+/**
+ * Join/Leave the nominated multicast group on the specified socket.
+ * Implemented by setting the multicast 'add membership'/'drop membership'
+ * option at the HY_IPPROTO_IP level on the socket.
+ *
+ * Implementation note for multicast sockets in general:
+ *
+ * - This code is untested, because at the time of this writing multicast can't
+ * be properly tested on Android due to GSM routing restrictions. So it might
+ * or might not work.
+ *
+ * - The REUSEPORT socket option that Harmony employs is not supported on Linux
+ * and thus also not supported on Android. It's is not needed for multicast
+ * to work anyway (REUSEADDR should suffice).
+ *
+ * @param env pointer to the JNI library.
+ * @param socketP pointer to the hysocket to join/leave on.
+ * @param optVal pointer to the InetAddress, the multicast group to join/drop.
+ *
+ * @exception SocketException if an error occurs during the call
+ */
+static void mcastAddDropMembership (JNIEnv * env, int handle, jobject optVal,
+ int ignoreIF, int setSockOptVal) {
+ int result;
+ struct ip_mreq ipmreqP;
+ struct sockaddr_in sockaddrP;
+ int length = sizeof(struct ip_mreq);
+ socklen_t lengthIF = sizeof(struct sockaddr_in);
+
+ /*
+ * JNI objects needed to access the information in the optVal oject
+ * passed in. The object passed in is a GenericIPMreq object
+ */
+ jclass cls;
+ jfieldID multiaddrID;
+ jfieldID interfaceAddrID;
+ jobject multiaddr;
+ jobject interfaceAddr;
+
+ /*
+ * check whether we are getting an InetAddress or an Generic IPMreq, for now
+ * we support both so that we will not break the tests
+ */
+ if (env->IsInstanceOf (optVal, gCachedFields.iaddr_class)) {
+
+ ipmreqP.imr_interface.s_addr = htonl(INADDR_ANY);
+ if (!ignoreIF) {
+
+ result = getsockopt(handle, IPPROTO_IP, IP_MULTICAST_IF, &sockaddrP,
+ &lengthIF);
+
+ if (0 != result) {
+ throwSocketException (env, convertError(errno));
+ return;
+ }
+
+ memcpy(&(ipmreqP.imr_interface.s_addr), &(sockaddrP.sin_addr), 4);
+ }
+
+ result = inetAddressToSocketAddress(env, optVal, 0, &sockaddrP);
+
+ if (result < 0) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ }
+
+ memcpy(&(ipmreqP.imr_multiaddr.s_addr), &(sockaddrP.sin_addr), 4);
+
+ result = setsockopt(handle, IPPROTO_IP, setSockOptVal, &ipmreqP, length);
+ if (0 != result) {
+ throwSocketException (env, convertError(errno));
+ return;
+ }
+
+ } else {
+
+ /* we need the multicast address regardless of the type of address */
+ cls = env->GetObjectClass(optVal);
+ multiaddrID = env->GetFieldID(cls, "multiaddr", "Ljava/net/InetAddress;");
+ multiaddr = env->GetObjectField(optVal, multiaddrID);
+
+ result = inetAddressToSocketAddress(env, multiaddr, 0, &sockaddrP);
+
+ if (result < 0) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ }
+
+ memcpy(&(ipmreqP.imr_multiaddr.s_addr), &(sockaddrP.sin_addr), 4);
+
+ /* we need to use an IP_MREQ as it is an IPV4 address */
+ interfaceAddrID = env->GetFieldID(cls, "interfaceAddr",
+ "Ljava/net/InetAddress;");
+ interfaceAddr = env->GetObjectField(optVal, interfaceAddrID);
+
+ ipmreqP.imr_interface.s_addr = htonl(INADDR_ANY);
+
+ /*
+ * if an interfaceAddr was passed then use that value, otherwise set the
+ * interface to all 0 to indicate the system should select the interface
+ * used
+ */
+ if (!ignoreIF) {
+ if (NULL != interfaceAddr) {
+
+ result = inetAddressToSocketAddress(env, interfaceAddr, 0,
+ &sockaddrP);
+
+ if (result < 0) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ }
+
+ memcpy(&(ipmreqP.imr_interface.s_addr), &(sockaddrP.sin_addr), 4);
+
+ }
+ }
+
+ /* join/drop the multicast address */
+ result = setsockopt(handle, IPPROTO_IP, setSockOptVal, &ipmreqP, length);
+ if (0 != result) {
+ throwSocketException (env, convertError(errno));
+ return;
+ }
+ }
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_oneTimeInitializationImpl(JNIEnv* env, jobject obj,
+ jboolean jcl_supports_ipv6) {
+ // LOGD("ENTER oneTimeInitializationImpl of OSNetworkSystem");
+
+ char useAdbNetworkingProperty[PROPERTY_VALUE_MAX];
+ char adbConnectedProperty[PROPERTY_VALUE_MAX];
+
+ property_get("android.net.use-adb-networking", useAdbNetworkingProperty, "");
+ property_get("adb.connected", adbConnectedProperty, "");
+
+ if (strlen((char *)useAdbNetworkingProperty) > 0
+ && strlen((char *)adbConnectedProperty) > 0) {
+ useAdbNetworking = 1;
+ }
+
+ memset(&gCachedFields, 0, sizeof(gCachedFields));
+
+ // initializing InetAddress
+
+ jclass iaddrclass = env->FindClass("java/net/InetAddress");
+
+ if (iaddrclass == NULL) {
+ jniThrowException(env, "java/lang/ClassNotFoundException",
+ "java.net.InetAddress");
+ return;
+ }
+
+ gCachedFields.iaddr_class = (jclass) env->NewGlobalRef(iaddrclass);
+
+ jmethodID iaddrclassinit = env->GetMethodID(iaddrclass, "<init>", "()V");
+
+ if (iaddrclassinit == NULL) {
+ jniThrowException(env, "java/lang/NoSuchMethodError", "InetAddress.<init>()");
+ return;
+ }
+
+ gCachedFields.iaddr_class_init = iaddrclassinit;
+
+ jmethodID iaddrgetbyaddress = env->GetStaticMethodID(iaddrclass,
+ "getByAddress", "([B)Ljava/net/InetAddress;");
+
+ if (iaddrgetbyaddress == NULL) {
+ jniThrowException(env, "java/lang/NoSuchMethodError",
+ "InetAddress.getByAddress(byte[] val)");
+ return;
+ }
+
+ gCachedFields.iaddr_getbyaddress = iaddrgetbyaddress;
+
+ jmethodID iaddrgetaddress = env->GetStaticMethodID(iaddrclass,
+ "getByAddress", "([B)Ljava/net/InetAddress;");
+
+
+
+
+ jfieldID iaddripaddress = env->GetFieldID(iaddrclass, "ipaddress", "[B");
+
+ if (iaddripaddress == NULL) {
+ jniThrowException(env, "java/lang/NoSuchFieldError",
+ "Can't find field InetAddress.ipaddress");
+ return;
+ }
+
+ gCachedFields.iaddr_ipaddress = iaddripaddress;
+
+ // get the GenericIPMreq class
+
+ jclass genericipmreqclass = env->FindClass("org/apache/harmony/luni/net/GenericIPMreq");
+
+ if (genericipmreqclass == NULL) {
+ jniThrowException(env, "java/lang/ClassNotFoundException",
+ "org.apache.harmony.luni.net.GenericIPMreq");
+ return;
+ }
+
+ gCachedFields.genericipmreq_class = (jclass) env->NewGlobalRef(genericipmreqclass);
+
+ // initializing Integer
+
+ jclass integerclass = env->FindClass("java/lang/Integer");
+
+ if (integerclass == NULL) {
+ jniThrowException(env, "java/lang/ClassNotFoundException",
+ "java.lang.Integer");
+ return;
+ }
+
+ jmethodID integerclassinit = env->GetMethodID(integerclass, "<init>", "(I)V");
+
+ if (integerclassinit == NULL) {
+ jniThrowException(env, "java/lang/NoSuchMethodError",
+ "Integer.<init>(int val)");
+ return;
+ }
+
+ jfieldID integerclassvalue = env->GetFieldID(integerclass, "value", "I");
+
+ if (integerclassvalue == NULL) {
+ jniThrowException(env, "java/lang/NoSuchMethodError", "Integer.value");
+ return;
+ }
+
+ gCachedFields.integer_class = (jclass) env->NewGlobalRef(integerclass);
+ gCachedFields.integer_class_init = integerclassinit;
+ gCachedFields.integer_class_value = integerclassvalue;
+
+ // initializing Boolean
+
+ jclass booleanclass = env->FindClass("java/lang/Boolean");
+
+ if (booleanclass == NULL) {
+ jniThrowException(env, "java/lang/ClassNotFoundException",
+ "java.lang.Boolean");
+ return;
+ }
+
+ jmethodID booleanclassinit = env->GetMethodID(booleanclass, "<init>", "(Z)V");
+
+ if (booleanclassinit == NULL) {
+ jniThrowException(env, "java/lang/NoSuchMethodError",
+ "Boolean.<init>(boolean val)");
+ return;
+ }
+
+ jfieldID booleanclassvalue = env->GetFieldID(booleanclass, "value", "Z");
+
+ if (booleanclassvalue == NULL) {
+ jniThrowException(env, "java/lang/NoSuchMethodError", "Boolean.value");
+ return;
+ }
+
+ gCachedFields.boolean_class = (jclass) env->NewGlobalRef(booleanclass);
+ gCachedFields.boolean_class_init = booleanclassinit;
+ gCachedFields.boolean_class_value = booleanclassvalue;
+
+ // initializing Byte
+
+ jclass byteclass = env->FindClass("java/lang/Byte");
+
+ if (byteclass == NULL) {
+ jniThrowException(env, "java/lang/ClassNotFoundException",
+ "java.lang.Byte");
+ return;
+ }
+
+ jmethodID byteclassinit = env->GetMethodID(byteclass, "<init>", "(B)V");
+
+ if (byteclassinit == NULL) {
+ jniThrowException(env, "java/lang/NoSuchMethodError",
+ "Byte.<init>(byte val)");
+ return;
+ }
+
+ jfieldID byteclassvalue = env->GetFieldID(byteclass, "value", "B");
+
+ if (byteclassvalue == NULL) {
+ jniThrowException(env, "java/lang/NoSuchMethodError", "Byte.value");
+ return;
+ }
+
+ gCachedFields.byte_class = (jclass) env->NewGlobalRef(byteclass);
+ gCachedFields.byte_class_init = byteclassinit;
+ gCachedFields.byte_class_value = byteclassvalue;
+
+ // initializing String
+
+ jclass stringclass = env->FindClass("java/lang/String");
+
+ if (stringclass == NULL) {
+ jniThrowException(env, "java/lang/ClassNotFoundException",
+ "java.lang.String");
+ return;
+ }
+
+ jmethodID stringclassinit = env->GetMethodID(stringclass, "<init>", "([B)V");
+
+ if (stringclassinit == NULL) {
+ jniThrowException(env, "java/lang/NoSuchMethodError",
+ "String.<init>(byte[] val)");
+ return;
+ }
+
+ gCachedFields.string_class = (jclass) env->NewGlobalRef(stringclass);
+ gCachedFields.string_class_init = stringclassinit;
+
+ // initializing ScoketImpl
+
+ jclass socketimplclass = env->FindClass("java/net/SocketImpl");
+
+ if (socketimplclass == NULL) {
+ jniThrowException(env, "java/lang/ClassNotFoundException",
+ "java.net.SocketImpl");
+ return;
+ }
+
+ jfieldID socketimplport = env->GetFieldID(socketimplclass, "port", "I");
+
+ if (socketimplport == NULL) {
+ jniThrowException(env, "java/lang/NoSuchFieldError", "SocketImpl.port");
+ return;
+ }
+
+ jfieldID socketimpladdress = env->GetFieldID(socketimplclass, "address",
+ "Ljava/net/InetAddress;");
+
+ if (socketimpladdress == NULL) {
+ jniThrowException(env, "java/lang/NoSuchFieldError",
+ "SocketImpl.address");
+ return;
+ }
+
+ gCachedFields.socketimpl_address = socketimpladdress;
+ gCachedFields.socketimpl_port = socketimplport;
+
+ gCachedFields.dpack_class = env->FindClass("java/net/DatagramPacket");
+ if (gCachedFields.dpack_class == NULL) {
+ jniThrowException(env, "java/lang/ClassNotFoundException",
+ "java.net.DatagramPacket");
+ return;
+ }
+
+ gCachedFields.dpack_address = env->GetFieldID(gCachedFields.dpack_class,
+ "address", "Ljava/net/InetAddress;");
+ if (gCachedFields.dpack_address == NULL) {
+ jniThrowException(env, "java/lang/NoSuchFieldError",
+ "DatagramPacket.address");
+ return;
+ }
+
+ gCachedFields.dpack_port = env->GetFieldID(gCachedFields.dpack_class,
+ "port", "I");
+ if (gCachedFields.dpack_port == NULL) {
+ jniThrowException(env, "java/lang/NoSuchFieldError",
+ "DatagramPacket.port");
+ return;
+ }
+
+ gCachedFields.dpack_length = env->GetFieldID(gCachedFields.dpack_class,
+ "length", "I");
+ if (gCachedFields.dpack_length == NULL) {
+ jniThrowException(env, "java/lang/NoSuchFieldError",
+ "DatagramPacket.length");
+ return;
+ }
+
+ gCachedFields.fd_class = env->FindClass("java/io/FileDescriptor");
+ if (gCachedFields.fd_class == NULL) {
+ jniThrowException(env, "java/lang/ClassNotFoundException",
+ "java.io.FileDescriptor");
+ return;
+ }
+ gCachedFields.descriptor = env->GetFieldID(gCachedFields.fd_class, "descriptor", "I");
+ if (gCachedFields.descriptor == NULL) {
+ jniThrowException(env, "java/lang/NoSuchFieldError",
+ "FileDescriptor.descriptor");
+ return;
+ }
+
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_createSocketImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jboolean preferIPv4Stack) {
+ // LOGD("ENTER createSocketImpl");
+
+ int ret = socket(PF_INET, SOCK_STREAM, 0);
+
+ if (ret < 0) {
+ int err = convertError(errno);
+ throwSocketException(env, err);
+ return;
+ }
+
+ jniSetFileDescriptorOfFD(env, fileDescriptor, ret);
+
+ return;
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_createDatagramSocketImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jboolean preferIPv4Stack) {
+ // LOGD("ENTER createDatagramSocketImpl");
+
+ int ret = socket(PF_INET, SOCK_DGRAM, 0);
+
+ if (ret < 0) {
+ int err = convertError(errno);
+ throwSocketException(env, err);
+ return;
+ }
+
+ jniSetFileDescriptorOfFD(env, fileDescriptor, ret);
+
+ return;
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_readSocketDirectImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jint address, jint offset, jint count,
+ jint timeout) {
+ // LOGD("ENTER readSocketDirectImpl");
+
+ int handle;
+ jbyte *message = (jbyte *)address;
+ int result, ret, localCount;
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return 0;
+ }
+
+ result = selectWait(handle, timeout, SELECT_READ_TYPE);
+
+ if (0 > result) {
+ return 0;
+ }
+
+ localCount = (count < 65536) ? count : 65536;
+
+ do {
+ ret = recv(handle, (jbyte *) message, localCount, SOCKET_NOFLAGS);
+ } while (ret < 0 && errno == EINTR);
+
+ if (0 == ret) {
+ return -1;
+ } else if (ret == -1) {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ return 0;
+ }
+ add_recv_stats(handle, ret);
+ return ret;
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_readSocketImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jbyteArray data, jint offset, jint count,
+ jint timeout) {
+ // LOGD("ENTER readSocketImpl");
+
+ jbyte *message;
+ int result, localCount;
+
+ jbyte internalBuffer[BUFFERSIZE];
+
+ localCount = (count < 65536) ? count : 65536;
+
+ if (localCount > BUFFERSIZE) {
+ message = (jbyte*)malloc(localCount * sizeof(jbyte));
+ if (message == NULL) {
+ jniThrowException(env, "java/lang/OutOfMemoryError",
+ "couldn't allocate enough memory for readSocket");
+ return 0;
+ }
+ } else {
+ message = (jbyte *)internalBuffer;
+ }
+
+ result = Java_org_sipdroid_net_impl_OSNetworkSystem_readSocketDirectImpl(env, clazz, fileDescriptor,
+ (jint) message, offset, count, timeout);
+
+ if (result > 0) {
+ env->SetByteArrayRegion(data, offset, result, (jbyte *)message);
+ }
+
+ if (((jbyte *)message) != internalBuffer) {
+ free(( jbyte *)message);
+ }
+
+ return result;
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_writeSocketDirectImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jint address, jint offset, jint count) {
+ // LOGD("ENTER writeSocketDirectImpl");
+
+ int handle;
+ jbyte *message = (jbyte *)address;
+ int result = 0, sent = 0;
+
+ if (count <= 0) {
+ return 0;
+ }
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return 0;
+ }
+
+ result = send(handle, (jbyte *) message, (int) count, SOCKET_NOFLAGS);
+ if (result < 0) {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+
+ if (SOCKERR_WOULDBLOCK == err){
+ jclass socketExClass,errorCodeExClass;
+ jmethodID errorCodeExConstructor, socketExConstructor,socketExCauseMethod;
+ jobject errorCodeEx, socketEx;
+ const char* errorMessage = netLookupErrorString(err);
+ jstring errorMessageString = env->NewStringUTF(errorMessage);
+
+ errorCodeExClass = env->FindClass("org/apache/harmony/luni/util/ErrorCodeException");
+ if (!errorCodeExClass){
+ return 0;
+ }
+ errorCodeExConstructor = env->GetMethodID(errorCodeExClass,"<init>","(I)V");
+ if (!errorCodeExConstructor){
+ return 0;
+ }
+ errorCodeEx = env->NewObject(errorCodeExClass,errorCodeExConstructor,err);
+
+ socketExClass = env->FindClass("java/net/SocketException");
+ if (!socketExClass) {
+ return 0;
+ }
+ socketExConstructor = env->GetMethodID(socketExClass,"<init>","(Ljava/lang/String;)V");
+ if (!socketExConstructor) {
+ return 0;
+ }
+ socketEx = env->NewObject(socketExClass, socketExConstructor, errorMessageString);
+ socketExCauseMethod = env->GetMethodID(socketExClass,"initCause","(Ljava/lang/Throwable;)Ljava/lang/Throwable;");
+ env->CallObjectMethod(socketEx,socketExCauseMethod,errorCodeEx);
+ env->Throw((jthrowable)socketEx);
+ return 0;
+ }
+ throwSocketException(env, err);
+ return 0;
+ }
+
+ add_send_stats(handle, result);
+ return result;
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_writeSocketImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jbyteArray data, jint offset, jint count) {
+ // LOGD("ENTER writeSocketImpl");
+
+ jbyte *message;
+ int sent = 0;
+ jint result = 0;
+
+/* TODO: ARRAY PINNING */
+#define INTERNAL_SEND_BUFFER_MAX 512
+ jbyte internalBuffer[INTERNAL_SEND_BUFFER_MAX];
+
+ if (count > INTERNAL_SEND_BUFFER_MAX) {
+ message = (jbyte*)malloc(count * sizeof( jbyte));
+ if (message == NULL) {
+ jniThrowException(env, "java/lang/OutOfMemoryError",
+ "couldn't allocate enough memory for writeSocket");
+ return 0;
+ }
+ } else {
+ message = (jbyte *)internalBuffer;
+ }
+
+ env->GetByteArrayRegion(data, offset, count, message);
+
+ result = Java_org_sipdroid_net_impl_OSNetworkSystem_writeSocketDirectImpl(env, clazz, fileDescriptor,
+ (jint) message, offset, count);
+
+ if (( jbyte *)message != internalBuffer) {
+ free(( jbyte *)message);
+ }
+#undef INTERNAL_SEND_BUFFER_MAX
+ return result;
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_setNonBlockingImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jboolean nonblocking) {
+ // LOGD("ENTER setNonBlockingImpl");
+
+ int handle;
+ int result;
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ }
+
+ int block = nonblocking;
+
+ result = ioctl(handle, FIONBIO, &block);
+
+ if (result == -1) {
+ throwSocketException(env, convertError(errno));
+ }
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_connectSocketImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jint trafficClass, jobject inetAddr, jint port);
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_connectWithTimeoutSocketImpl(JNIEnv* env,
+ jclass clazz, jobject fileDescriptor, jint timeout, jint trafficClass,
+ jobject inetAddr, jint port, jint step, jbyteArray passContext) {
+ // LOGD("ENTER connectWithTimeoutSocketImpl");
+
+ int handle;
+ int result = 0;
+ struct sockaddr_in address;
+ jbyte *context = NULL;
+
+ memset(&address, 0, sizeof(address));
+
+ address.sin_family = AF_INET;
+
+ result = inetAddressToSocketAddress(env, inetAddr, port,
+ (struct sockaddr_in *) &address);
+
+ if (result < 0) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return result;
+ }
+
+ // Check if we're using adb networking and redirect in case it is used.
+ if (useAdbNetworking && !isLocalhost(&address)) {
+ return Java_org_sipdroid_net_impl_OSNetworkSystem_connectSocketImpl(env, clazz, fileDescriptor,
+ trafficClass, inetAddr, port);
+ }
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return -1;
+ }
+
+ address.sin_port = htons(port);
+
+ context = (jbyte *)env->GetPrimitiveArrayCritical(passContext, NULL);
+
+ switch (step) {
+ case SOCKET_CONNECT_STEP_START:
+ result = sockConnectWithTimeout(handle, address, 0,
+ SOCKET_STEP_START, context);
+ break;
+ case SOCKET_CONNECT_STEP_CHECK:
+ result = sockConnectWithTimeout(handle, address, timeout,
+ SOCKET_STEP_CHECK, context);
+ break;
+ }
+
+ env->ReleasePrimitiveArrayCritical(passContext, context, JNI_ABORT);
+
+ if (0 == result) {
+ /* connected , so stop here */
+ sockConnectWithTimeout(handle, address, 0, SOCKET_STEP_DONE, NULL);
+ } else if (result != SOCKERR_NOTCONNECTED) {
+ /* can not connect... */
+ sockConnectWithTimeout(handle, address, 0, SOCKET_STEP_DONE, NULL);
+ if (result == SOCKERR_EACCES) {
+ jniThrowException(env, "java/lang/SecurityException",
+ netLookupErrorString(result));
+ } else {
+ jniThrowException(env, "java/net/ConnectException",
+ netLookupErrorString(result));
+ }
+ }
+
+ return result;
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_connectStreamWithTimeoutSocketImpl(JNIEnv* env,
+ jclass clazz, jobject fileDescriptor, jint remotePort, jint timeout,
+ jint trafficClass, jobject inetAddr) {
+ // LOGD("ENTER connectStreamWithTimeoutSocketImpl");
+
+ int result = 0;
+ int handle;
+ struct sockaddr_in address;
+ jbyte *context = NULL;
+ int remainingTimeout = timeout;
+ int passedTimeout = 0;
+ int finishTime = 0;
+ int blocking = 0;
+ char hasTimeout = timeout > 0;
+
+ /* if a timeout was specified calculate the finish time value */
+ if (hasTimeout) {
+ finishTime = time_msec_clock() + (int) timeout;
+ }
+
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ } else {
+ result = inetAddressToSocketAddress(env, inetAddr, remotePort,
+ (struct sockaddr_in *) &address);
+
+ if (result < 0) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ }
+
+ // Check if we're using adb networking and redirect in case it is used.
+ if (useAdbNetworking && !isLocalhost(&address)) {
+ int retVal = Java_org_sipdroid_net_impl_OSNetworkSystem_connectSocketImpl(env, clazz,
+ fileDescriptor, trafficClass, inetAddr, remotePort);
+ if (retVal != 0) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ }
+ return;
+ }
+
+ /*
+ * we will be looping checking for when we are connected so allocate
+ * the descriptor sets that we will use
+ */
+ context =(jbyte *) malloc(sizeof(struct selectFDSet));
+
+ if (NULL == context) {
+ throwSocketException(env, SOCKERR_NOBUFFERS);
+ return;
+ }
+
+ result = sockConnectWithTimeout(handle, address, 0, SOCKET_STEP_START, context);
+ if (0 == result) {
+ /* ok we connected right away so we are done */
+ sockConnectWithTimeout(handle, address, 0, SOCKET_STEP_DONE, context);
+ goto bail;
+ } else if (result != SOCKERR_NOTCONNECTED) {
+ log_socket_close(handle, result);
+ sockConnectWithTimeout(handle, address, 0, SOCKET_STEP_DONE,
+ context);
+ /* we got an error other than NOTCONNECTED so we cannot continue */
+ if (SOCKERR_EACCES == result) {
+ jniThrowException(env, "java/lang/SecurityException",
+ netLookupErrorString(result));
+ } else {
+ throwSocketException(env, result);
+ }
+ goto bail;
+ }
+
+ while (SOCKERR_NOTCONNECTED == result) {
+ passedTimeout = remainingTimeout;
+
+ /*
+ * ok now try and connect. Depending on the platform this may sleep
+ * for up to passedTimeout milliseconds
+ */
+ result = sockConnectWithTimeout(handle, address, passedTimeout,
+ SOCKET_STEP_CHECK, context);
+
+ /*
+ * now check if the socket is still connected.
+ * Do it here as some platforms seem to think they
+ * are connected if the socket is closed on them.
+ */
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (handle == 0 || handle == -1) {
+ sockConnectWithTimeout(handle, address, 0,
+ SOCKET_STEP_DONE, context);
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ goto bail;
+ }
+
+ /*
+ * check if we are now connected,
+ * if so we can finish the process and return
+ */
+ if (0 == result) {
+ sockConnectWithTimeout(handle, address, 0,
+ SOCKET_STEP_DONE, context);
+ goto bail;
+ }
+
+ /*
+ * if the error is SOCKERR_NOTCONNECTED then we have not yet
+ * connected and we may not be done yet
+ */
+ if (SOCKERR_NOTCONNECTED == result) {
+ /* check if the timeout has expired */
+ if (hasTimeout) {
+ remainingTimeout = finishTime - time_msec_clock();
+ if (remainingTimeout <= 0) {
+ log_socket_close(handle, result);
+ sockConnectWithTimeout(handle, address, 0,
+ SOCKET_STEP_DONE, context);
+ jniThrowException(env,
+ "java/net/SocketTimeoutException",
+ netLookupErrorString(result));
+ goto bail;
+ }
+ } else {
+ remainingTimeout = 100;
+ }
+ } else {
+ log_socket_close(handle, result);
+ sockConnectWithTimeout(handle, address, remainingTimeout,
+ SOCKET_STEP_DONE, context);
+ if ((SOCKERR_CONNRESET == result) ||
+ (SOCKERR_CONNECTION_REFUSED == result) ||
+ (SOCKERR_ADDRNOTAVAIL == result) ||
+ (SOCKERR_ADDRINUSE == result) ||
+ (SOCKERR_ENETUNREACH == result)) {
+ jniThrowException(env, "java/net/ConnectException",
+ netLookupErrorString(result));
+ } else if (SOCKERR_EACCES == result) {
+ jniThrowException(env, "java/lang/SecurityException",
+ netLookupErrorString(result));
+ } else {
+ throwSocketException(env, result);
+ }
+ goto bail;
+ }
+ }
+ }
+
+bail:
+
+ /* free the memory for the FD set */
+ if (context != NULL) {
+ free(context);
+ }
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_connectSocketImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jint trafficClass, jobject inetAddr, jint port) {
+ //LOGD("ENTER direct-call connectSocketImpl\n");
+
+ struct sockaddr_in address;
+ int ret;
+ int handle;
+ jbyteArray java_in_addr;
+
+ memset(&address, 0, sizeof(address));
+
+ address.sin_family = AF_INET;
+
+ ret = inetAddressToSocketAddress(env, inetAddr, port,
+ (struct sockaddr_in *) &address);
+
+ if (ret < 0) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return ret;
+ }
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return -1;
+ }
+
+ address.sin_port = htons(port);
+
+ if (useAdbNetworking && !isLocalhost(&address)) {
+
+ // LOGD("+connect to address 0x%08x port %d (via adb)",
+ // address.sin_addr.s_addr, (int) port);
+ ret = adb_networking_connect_fd(handle, &address);
+ // LOGD("-connect ret %d errno %d (via adb)", ret, errno);
+
+ } else {
+
+ // call this method with a timeout of zero
+ Java_org_sipdroid_net_impl_OSNetworkSystem_connectStreamWithTimeoutSocketImpl(env, clazz,
+ fileDescriptor, port, 0, trafficClass, inetAddr);
+ if (env->ExceptionOccurred() != 0) {
+ return -1;
+ } else {
+ return 0;
+ }
+
+ }
+
+ if (ret < 0) {
+ jniThrowException(env, "java/net/ConnectException",
+ netLookupErrorString(convertError(errno)));
+ return ret;
+ }
+
+ return ret;
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_socketBindImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jint port, jobject inetAddress) {
+ // LOGD("ENTER socketBindImpl");
+
+ struct sockaddr_in sockaddress;
+ int ret;
+ int handle;
+
+ ret = inetAddressToSocketAddress(env, inetAddress, port,
+ (struct sockaddr_in *) &sockaddress);
+
+ if (ret < 0) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ }
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ }
+
+ ret = bind(handle, (const sockaddr*)&sockaddress, sizeof(sockaddress));
+
+ if (ret < 0) {
+ jniThrowException(env, "java/net/BindException",
+ netLookupErrorString(convertError(errno)));
+ return;
+ }
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_listenStreamSocketImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jint backlog) {
+ // LOGD("ENTER listenStreamSocketImpl");
+
+ int ret;
+ int handle;
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ }
+
+ ret = listen(handle, backlog);
+
+ if (ret < 0) {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ return;
+ }
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_availableStreamImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor) {
+ // LOGD("ENTER availableStreamImpl");
+
+ int handle;
+ char message[BUFFERSIZE];
+
+ int result;
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return 0;
+ }
+
+ do {
+ result = selectWait(handle, 1, SELECT_READ_TYPE);
+
+ if (SOCKERR_TIMEOUT == result) {
+ // The read operation timed out, so answer 0 bytes available
+ return 0;
+ } else if (SOCKERR_INTERRUPTED == result) {
+ continue;
+ } else if (0 > result) {
+ log_socket_close(handle, result);
+ throwSocketException(env, result);
+ return 0;
+ }
+ } while (SOCKERR_INTERRUPTED == result);
+
+ result = recv(handle, (jbyte *) message, BUFFERSIZE, MSG_PEEK);
+
+ if (0 > result) {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ return 0;
+ }
+ add_recv_stats(handle, result);
+ return result;
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_acceptSocketImpl(JNIEnv* env, jclass clazz,
+ jobject fdServer, jobject newSocket, jobject fdnewSocket, jint timeout) {
+ // LOGD("ENTER acceptSocketImpl");
+
+ union {
+ struct sockaddr address;
+ struct sockaddr_in in_address;
+ } sa;
+
+ int ret;
+ int retFD;
+ int result;
+ int handle;
+ socklen_t addrlen;
+
+ if (newSocket == NULL) {
+ throwNullPointerException(env);
+ return;
+ }
+
+ result = pollSelectWait(env, fdServer, timeout, SELECT_READ_TYPE);
+
+ if (0 > result) {
+ return;
+ }
+
+ handle = jniGetFDFromFileDescriptor(env, fdServer);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ }
+
+ do {
+ addrlen = sizeof(sa);
+ ret = accept(handle, &(sa.address), &addrlen);
+ } while (ret < 0 && errno == EINTR);
+
+ if (ret < 0) {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ return;
+ }
+
+ retFD = ret;
+
+ /* For AF_INET / inetOrLocal == true only: put
+ * peer address and port in instance variables
+ * We don't bother for UNIX domain sockets, since most peers are
+ * anonymous anyway
+ */
+ if (sa.address.sa_family == AF_INET) {
+ // inetOrLocal should also be true
+
+ jobject inetAddress;
+
+ inetAddress = structInToInetAddress(env, &(sa.in_address.sin_addr));
+
+ if (inetAddress == NULL) {
+ close(retFD);
+ newSocket = NULL;
+ return;
+ }
+
+ env->SetObjectField(newSocket,
+ gCachedFields.socketimpl_address, inetAddress);
+
+ env->SetIntField(newSocket, gCachedFields.socketimpl_port,
+ ntohs(sa.in_address.sin_port));
+ }
+
+ jniSetFileDescriptorOfFD(env, fdnewSocket, retFD);
+}
+
+extern "C" jboolean Java_org_sipdroid_net_impl_OSNetworkSystem_supportsUrgentDataImpl(JNIEnv* env,
+ jclass clazz, jobject fileDescriptor) {
+ // LOGD("ENTER supportsUrgentDataImpl");
+
+ int handle;
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+ if (handle == 0 || handle == -1) {
+ return JNI_FALSE;
+ }
+
+ return JNI_TRUE;
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_sendUrgentDataImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jbyte value) {
+ // LOGD("ENTER sendUrgentDataImpl");
+
+ int handle;
+ int result;
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ }
+
+ result = send(handle, (jbyte *) &value, 1, MSG_OOB);
+ if (result < 0) {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ }
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_connectDatagramImpl2(JNIEnv* env, jclass clazz,
+ jobject fd, jint port, jint trafficClass, jobject inetAddress) {
+ // LOGD("ENTER connectDatagramImpl2");
+
+ int handle = jniGetFDFromFileDescriptor(env, fd);
+
+ struct sockaddr_in sockAddr;
+ int ret;
+
+ ret = inetAddressToSocketAddress(env, inetAddress, port, &sockAddr);
+
+ if (ret < 0) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ }
+ log_socket_connect(handle, ntohl(sockAddr.sin_addr.s_addr), port);
+ int result = connect(handle, (struct sockaddr *)&sockAddr, sizeof(sockAddr));
+ if (result < 0) {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ }
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_disconnectDatagramImpl(JNIEnv* env, jclass clazz,
+ jobject fd) {
+ // LOGD("ENTER disconnectDatagramImpl");
+
+ int handle = jniGetFDFromFileDescriptor(env, fd);
+
+ struct sockaddr_in *sockAddr;
+ socklen_t sockAddrLen = sizeof(struct sockaddr_in);
+ sockAddr = (struct sockaddr_in *) malloc(sockAddrLen);
+ memset(sockAddr, 0, sockAddrLen);
+
+ sockAddr->sin_family = AF_UNSPEC;
+ int result = connect(handle, (struct sockaddr *)sockAddr, sockAddrLen);
+ free(sockAddr);
+
+ if (result < 0) {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ }
+}
+
+extern "C" jboolean Java_org_sipdroid_net_impl_OSNetworkSystem_socketBindImpl2(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jint port, jboolean bindToDevice,
+ jobject inetAddress) {
+ // LOGD("ENTER socketBindImpl2");
+
+ struct sockaddr_in sockaddress;
+ int ret;
+ int handle;
+
+ ret = inetAddressToSocketAddress(env, inetAddress, port,
+ (struct sockaddr_in *) &sockaddress);
+
+ if (ret < 0) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return 0;
+ }
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return 0;
+ }
+
+ ret = bind(handle, (const sockaddr*)&sockaddress, sizeof(sockaddress));
+
+ if (ret < 0) {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+ jniThrowException(env, "java/net/BindException", netLookupErrorString(err));
+ return 0;
+ }
+
+ return 0;
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_peekDatagramImpl(JNIEnv* env, jclass clazz,
+ jobject fd, jobject sender, jint receiveTimeout) {
+ // LOGD("ENTER peekDatagramImpl");
+
+ int port = -1;
+
+ int result = pollSelectWait (env, fd, receiveTimeout, SELECT_READ_TYPE);
+ if (0> result) {
+ return (jint) 0;
+ }
+
+ int handle = jniGetFDFromFileDescriptor(env, fd);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return 0;
+ }
+
+ struct sockaddr_in sockAddr;
+ socklen_t sockAddrLen = sizeof(sockAddr);
+
+ int length = recvfrom(handle, NULL, 0, MSG_PEEK,
+ (struct sockaddr *)&sockAddr, &sockAddrLen);
+
+ if (length < 0) {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ return 0;
+ }
+
+ if (socketAddressToInetAddress(env, &sockAddr, sender, &port) < 0) {
+ throwIOExceptionStr(env, "Address conversion failed");
+ return -1;
+ }
+ add_recv_stats(handle, length);
+ return port;
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_receiveDatagramDirectImpl(JNIEnv* env, jclass clazz,
+ jobject fd, jobject packet, jint address, jint offset, jint length,
+ jint receiveTimeout, jboolean peek) {
+ // LOGD("ENTER receiveDatagramDirectImpl");
+
+ int result = pollSelectWait (env, fd, receiveTimeout, SELECT_READ_TYPE);
+ if (0 > result) {
+ return (jint) 0;
+ }
+
+ int handle = jniGetFDFromFileDescriptor(env, fd);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return 0;
+ }
+
+ struct sockaddr_in sockAddr;
+ socklen_t sockAddrLen = sizeof(sockAddr);
+
+ int mode = peek ? MSG_PEEK : 0;
+
+ int actualLength = recvfrom(handle, (char*)(address + offset), length, mode,
+ (struct sockaddr *)&sockAddr, &sockAddrLen);
+
+ if (actualLength < 0) {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ return 0;
+ }
+
+ if (packet != NULL) {
+ int port = ntohs(sockAddr.sin_port);
+ jobject sender = env->GetObjectField(packet, gCachedFields.dpack_address);
+ //__android_log_print(ANDROID_LOG_INFO,"OSNetwork","Sender address %x ", sender);
+ if (sender != 0) {
+ jbyteArray addr = (jbyteArray)env->GetObjectField(sender, gCachedFields.iaddr_ipaddress);
+ //__android_log_print(ANDROID_LOG_INFO,"OSNetwork","Sender Recup");
+ if ((structInToJavaAddress(env, &sockAddr.sin_addr, addr)) < 0) {
+ jniThrowException(env, "java/net/SocketException",
+ "Could not set address of packet.");
+ return 0;
+ }
+ }
+ else {
+ jbyteArray addr = env->NewByteArray(sizeof(struct in_addr));
+ if ((structInToJavaAddress(env, &sockAddr.sin_addr, addr)) < 0) {
+ jniThrowException(env, "java/net/SocketException",
+ "Could not set address of packet.");
+ return 0;
+ }
+ sender = env->CallStaticObjectMethod(
+ gCachedFields.iaddr_class, gCachedFields.iaddr_getbyaddress,
+ addr);
+
+ }
+ env->SetObjectField(packet, gCachedFields.dpack_address, sender);
+ env->SetIntField(packet, gCachedFields.dpack_port, port);
+ env->SetIntField(packet, gCachedFields.dpack_length, actualLength);
+ }
+ add_recv_stats(handle, actualLength);
+ return actualLength;
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_receiveDatagramImpl(JNIEnv* env, jclass clazz,
+ jobject fd, jobject packet, jbyteArray data, jint offset, jint length,
+ jint receiveTimeout, jboolean peek) {
+ // LOGD("ENTER receiveDatagramImpl");
+
+ int localLength = (length < 65536) ? length : 65536;
+ jbyte *bytes = (jbyte*) malloc(localLength);
+ if (bytes == NULL) {
+ jniThrowException(env, "java/lang/OutOfMemoryError",
+ "couldn't allocate enough memory for receiveDatagram");
+ return 0;
+ }
+
+ int actualLength = Java_org_sipdroid_net_impl_OSNetworkSystem_receiveDatagramDirectImpl(env, clazz, fd,
+ packet, (jint)bytes, offset, localLength, receiveTimeout, peek);
+
+ if (actualLength > 0) {
+ env->SetByteArrayRegion(data, offset, actualLength, bytes);
+ }
+ free(bytes);
+
+ return actualLength;
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_recvConnectedDatagramDirectImpl(JNIEnv* env,
+ jclass clazz, jobject fd, jobject packet, jint address, jint offset,
+ jint length, jint receiveTimeout, jboolean peek) {
+ // LOGD("ENTER receiveConnectedDatagramDirectImpl");
+
+ int result = pollSelectWait (env, fd, receiveTimeout, SELECT_READ_TYPE);
+
+ if (0 > result) {
+ return 0;
+ }
+
+ int handle = jniGetFDFromFileDescriptor(env, fd);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return 0;
+ }
+
+ int mode = peek ? MSG_PEEK : 0;
+
+ int actualLength = recvfrom(handle,
+ (char*)(address + offset), length, mode, NULL, NULL);
+
+ if (actualLength < 0) {
+ jniThrowException(env, "java/net/PortUnreachableException", "");
+ return 0;
+ }
+
+ if ( packet != NULL) {
+ env->SetIntField(packet, gCachedFields.dpack_length, actualLength);
+ }
+ add_recv_stats(handle, actualLength);
+ return actualLength;
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_recvConnectedDatagramImpl(JNIEnv* env, jclass clazz,
+ jobject fd, jobject packet, jbyteArray data, jint offset, jint length,
+ jint receiveTimeout, jboolean peek) {
+ // LOGD("ENTER receiveConnectedDatagramImpl");
+
+ int localLength = (length < 65536) ? length : 65536;
+ jbyte *bytes = (jbyte*) malloc(localLength);
+ if (bytes == NULL) {
+ jniThrowException(env, "java/lang/OutOfMemoryError",
+ "couldn't allocate enough memory for recvConnectedDatagram");
+ return 0;
+ }
+
+ int actualLength = Java_org_sipdroid_net_impl_OSNetworkSystem_recvConnectedDatagramDirectImpl(env,
+ clazz, fd, packet, (jint)bytes, offset, localLength,
+ receiveTimeout, peek);
+
+ if (actualLength > 0) {
+ env->SetByteArrayRegion(data, offset, actualLength, bytes);
+ }
+ free(bytes);
+
+ return actualLength;
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_sendDatagramDirectImpl(JNIEnv* env, jclass clazz,
+ jobject fd, jint address, jint offset, jint length, jint port,
+ jboolean bindToDevice, jint trafficClass, jobject inetAddress) {
+ // LOGD("ENTER sendDatagramDirectImpl");
+
+ int result = 0;
+
+ int handle = jniGetFDFromFileDescriptor(env, fd);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return 0;
+ }
+
+ struct sockaddr_in receiver;
+
+ if (inetAddressToSocketAddress(env, inetAddress, port, &receiver) < 0) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return 0;
+ }
+
+ result = sendto(handle, (char*)(address + offset), length, SOCKET_NOFLAGS,
+ (struct sockaddr*)&receiver, sizeof(receiver));
+
+ if (result < 0) {
+ int err = convertError(errno);
+ if ((SOCKERR_CONNRESET == err)
+ || (SOCKERR_CONNECTION_REFUSED == err)) {
+ return 0;
+ } else {
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ return 0;
+ }
+ }
+ add_send_stats(handle, result);
+ return result;
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_sendDatagramImpl(JNIEnv* env, jclass clazz,
+ jobject fd, jbyteArray data, jint offset, jint length, jint port,
+ jboolean bindToDevice, jint trafficClass, jobject inetAddress) {
+ // LOGD("ENTER sendDatagramImpl");
+
+ jbyte *bytes = env->GetByteArrayElements(data, NULL);
+ int actualLength = Java_org_sipdroid_net_impl_OSNetworkSystem_sendDatagramDirectImpl(env, clazz, fd,
+ (jint)bytes, offset, length, port, bindToDevice, trafficClass,
+ inetAddress);
+ env->ReleaseByteArrayElements(data, bytes, JNI_ABORT);
+
+ return actualLength;
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_sendConnectedDatagramDirectImpl(JNIEnv* env,
+ jclass clazz, jobject fd, jint address, jint offset, jint length,
+ jboolean bindToDevice) {
+ // LOGD("ENTER sendConnectedDatagramDirectImpl");
+
+ int handle = jniGetFDFromFileDescriptor(env, fd);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return 0;
+ }
+
+ int result = send(handle, (char*)(address + offset), length, 0);
+
+ if (result < 0) {
+ int err = convertError(errno);
+ if ((SOCKERR_CONNRESET == err) || (SOCKERR_CONNECTION_REFUSED == err)) {
+ return 0;
+ } else {
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ return 0;
+ }
+ }
+ add_send_stats(handle, length);
+ return result;
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_sendConnectedDatagramImpl(JNIEnv* env, jclass clazz,
+ jobject fd, jbyteArray data, jint offset, jint length,
+ jboolean bindToDevice) {
+ // LOGD("ENTER sendConnectedDatagramImpl");
+
+ jbyte *bytes = env->GetByteArrayElements(data, NULL);
+ int actualLength = Java_org_sipdroid_net_impl_OSNetworkSystem_sendConnectedDatagramDirectImpl(env,
+ clazz, fd, (jint)bytes, offset, length, bindToDevice);
+ env->ReleaseByteArrayElements(data, bytes, JNI_ABORT);
+
+ return actualLength;
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_createServerStreamSocketImpl(JNIEnv* env,
+ jclass clazz, jobject fileDescriptor, jboolean preferIPv4Stack) {
+ // LOGD("ENTER createServerStreamSocketImpl");
+
+ if (fileDescriptor == NULL) {
+ throwNullPointerException(env);
+ return;
+ }
+
+ int handle = socket(PF_INET, SOCK_STREAM, 0);
+
+ if (handle < 0) {
+ int err = convertError(errno);
+ throwSocketException(env, err);
+ return;
+ }
+
+ jniSetFileDescriptorOfFD(env, fileDescriptor, handle);
+
+ int value = 1;
+
+ setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(int));
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_createMulticastSocketImpl(JNIEnv* env,
+ jclass clazz, jobject fileDescriptor, jboolean preferIPv4Stack) {
+ // LOGD("ENTER createMulticastSocketImpl");
+
+ int handle = socket(PF_INET, SOCK_DGRAM, 0);
+
+ if (handle < 0) {
+ int err = convertError(errno);
+ throwSocketException(env, err);
+ return;
+ }
+
+ jniSetFileDescriptorOfFD(env, fileDescriptor, handle);
+
+ int value = 1;
+
+ // setsockopt(handle, SOL_SOCKET, SO_REUSEPORT, &value, sizeof(jbyte));
+ setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(int));
+}
+
+/*
+ * @param timeout in milliseconds. If zero, block until data received
+ */
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_receiveStreamImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jbyteArray data, jint offset, jint count,
+ jint timeout) {
+ // LOGD("ENTER receiveStreamImpl");
+
+ int result;
+ int handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return 0;
+ }
+
+ // Cap read length to available buf size
+ int spaceAvailable = env->GetArrayLength(data) - offset;
+ int localCount = count < spaceAvailable? count : spaceAvailable;
+
+ jboolean isCopy;
+ jbyte *body = env->GetByteArrayElements(data, &isCopy);
+
+ // set timeout
+ struct timeval tv;
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+ setsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)&tv,
+ sizeof(struct timeval));
+
+ do {
+ result = recv(handle, body + offset, localCount, SOCKET_NOFLAGS);
+ } while (result < 0 && errno == EINTR);
+
+ env->ReleaseByteArrayElements(data, body, 0);
+
+ /*
+ * If no bytes are read, return -1 to signal 'endOfFile'
+ * to the Java input stream
+ */
+ if (0 < result) {
+ add_recv_stats(handle, result);
+ return result;
+ } else if (0 == result) {
+ return -1;
+ } else {
+ // If EAGAIN or EWOULDBLOCK, read timed out
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ jniThrowException(env, "java/net/SocketTimeoutException",
+ netLookupErrorString(SOCKERR_TIMEOUT));
+ } else {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ }
+ return 0;
+ }
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_sendStreamImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jbyteArray data, jint offset, jint count) {
+ // LOGD("ENTER sendStreamImpl");
+
+ int handle = 0;
+ int result = 0, sent = 0;
+
+ jboolean isCopy;
+ jbyte *message = env->GetByteArrayElements(data, &isCopy);
+
+ // Cap write length to available buf size
+ int spaceAvailable = env->GetArrayLength(data) - offset;
+ if (count > spaceAvailable) count = spaceAvailable;
+
+ while (sent < count) {
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env,
+ sent == 0 ? SOCKERR_BADSOCKET : SOCKERR_INTERRUPTED);
+ env->ReleaseByteArrayElements(data, message, 0);
+ return 0;
+ }
+
+ // LOGD("before select %d", count);
+ selectWait(handle, SEND_RETRY_TIME, SELECT_WRITE_TYPE);
+ result = send(handle, (jbyte *)message + offset + sent,
+ (int) count - sent, SOCKET_NOFLAGS);
+
+ if (result < 0) {
+ result = errno;
+ if (result == EAGAIN ||result == EWOULDBLOCK) {
+ // LOGD("write blocked %d", sent);
+ continue;
+ }
+ env->ReleaseByteArrayElements(data, message, 0);
+ int err = convertError(result);
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ return 0;
+ }
+ sent += result;
+ }
+
+ env->ReleaseByteArrayElements(data, message, 0);
+ add_send_stats(handle, sent);
+ return sent;
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_shutdownInputImpl(JNIEnv* env, jobject obj,
+ jobject fileDescriptor) {
+ // LOGD("ENTER shutdownInputImpl");
+
+ int ret;
+ int handle;
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ }
+
+ ret = shutdown(handle, SHUT_RD);
+
+ if (ret < 0) {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ return;
+ }
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_shutdownOutputImpl(JNIEnv* env, jobject obj,
+ jobject fileDescriptor) {
+ // LOGD("ENTER shutdownOutputImpl");
+
+ int ret;
+ int handle;
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (handle == 0 || handle == -1) {
+ return;
+ }
+
+ ret = shutdown(handle, SHUT_WR);
+
+ if (ret < 0) {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ return;
+ }
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_sendDatagramImpl2(JNIEnv* env, jclass clazz,
+ jobject fd, jbyteArray data, jint offset, jint length, jint port,
+ jobject inetAddress) {
+ // LOGD("ENTER sendDatagramImpl2");
+
+ jbyte *message;
+ jbyte nhostAddrBytes[4];
+ unsigned short nPort;
+ int result = 0, sent = 0;
+ int handle = 0;
+ struct sockaddr_in sockaddrP;
+
+ if (inetAddress != NULL) {
+
+ result = inetAddressToSocketAddress(env, inetAddress, port,
+ (struct sockaddr_in *) &sockaddrP);
+
+ if (result < 0) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return 0;
+ }
+
+ handle = jniGetFDFromFileDescriptor(env, fd);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return 0;
+ }
+ }
+
+ message = (jbyte*) malloc(length * sizeof(jbyte));
+ if (message == NULL) {
+ jniThrowException(env, "java/lang/OutOfMemoryError",
+ "couldn't allocate enough memory for readSocket");
+ return 0;
+ }
+
+ env->GetByteArrayRegion(data, offset, length, message);
+
+ while (sent < length) {
+ handle = jniGetFDFromFileDescriptor(env, fd);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env,
+ sent == 0 ? SOCKERR_BADSOCKET : SOCKERR_INTERRUPTED);
+ free(message);
+ return 0;
+ }
+
+ result = sendto(handle, (char *) (message + sent),
+ (int) (length - sent), SOCKET_NOFLAGS,
+ (struct sockaddr *) &sockaddrP, sizeof(sockaddrP));
+
+ if (result < 0) {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+ throwSocketException(env, err);
+ free(message);
+ return 0;
+ }
+
+ sent += result;
+ }
+
+ free(message);
+ add_send_stats(handle, sent);
+ return sent;
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_selectImpl(JNIEnv* env, jclass clazz,
+ jobjectArray readFDArray, jobjectArray writeFDArray, jint countReadC,
+ jint countWriteC, jintArray outFlags, jlong timeout) {
+ // LOGD("ENTER selectImpl");
+
+ struct timeval timeP;
+ int result = 0;
+ int size = 0;
+ jobject gotFD;
+ fd_set *fdset_read,*fdset_write;
+ int handle;
+ jboolean isCopy ;
+ jint *flagArray;
+ int val;
+ unsigned int time_sec = (unsigned int)timeout/1000;
+ unsigned int time_msec = (unsigned int)(timeout%1000);
+
+ fdset_read = (fd_set *)malloc(sizeof(fd_set));
+ fdset_write = (fd_set *)malloc(sizeof(fd_set));
+
+ FD_ZERO(fdset_read);
+ FD_ZERO(fdset_write);
+
+ for (val = 0; val<countReadC; val++) {
+
+ gotFD = env->GetObjectArrayElement(readFDArray,val);
+
+ handle = jniGetFDFromFileDescriptor(env, gotFD);
+
+ FD_SET(handle, fdset_read);
+
+ if (0 > (size - handle)) {
+ size = handle;
+ }
+ }
+
+ for (val = 0; val<countWriteC; val++) {
+
+ gotFD = env->GetObjectArrayElement(writeFDArray,val);
+
+ handle = jniGetFDFromFileDescriptor(env, gotFD);
+
+ FD_SET(handle, fdset_write);
+
+ if (0 > (size - handle)) {
+ size = handle;
+ }
+ }
+
+ /* the size is the max_fd + 1 */
+ size =size + 1;
+
+ if (0 > size) {
+ result = SOCKERR_FDSET_SIZEBAD;
+ } else {
+ /* only set when timeout >= 0 (non-block)*/
+ if (0 <= timeout) {
+
+ timeP.tv_sec = time_sec;
+ timeP.tv_usec = time_msec*1000;
+
+ result = sockSelect(size, fdset_read, fdset_write, NULL, &timeP);
+
+ } else {
+ result = sockSelect(size, fdset_read, fdset_write, NULL, NULL);
+ }
+ }
+
+ if (0 < result) {
+ /*output the result to a int array*/
+ flagArray = env->GetIntArrayElements(outFlags, &isCopy);
+
+ for (val=0; val<countReadC; val++) {
+ gotFD = env->GetObjectArrayElement(readFDArray,val);
+
+ handle = jniGetFDFromFileDescriptor(env, gotFD);
+
+ if (FD_ISSET(handle,fdset_read)) {
+ flagArray[val] = SOCKET_OP_READ;
+ } else {
+ flagArray[val] = SOCKET_OP_NONE;
+ }
+ }
+
+ for (val=0; val<countWriteC; val++) {
+
+ gotFD = env->GetObjectArrayElement(writeFDArray,val);
+
+ handle = jniGetFDFromFileDescriptor(env, gotFD);
+
+ if (FD_ISSET(handle,fdset_write)) {
+ flagArray[val+countReadC] = SOCKET_OP_WRITE;
+ } else {
+ flagArray[val+countReadC] = SOCKET_OP_NONE;
+ }
+ }
+
+ env->ReleaseIntArrayElements(outFlags, flagArray, 0);
+ }
+
+ free(fdset_write);
+ free(fdset_read);
+
+ /* return both correct and error result, let java handle the exception*/
+ return result;
+}
+
+extern "C" jobject Java_org_sipdroid_net_impl_OSNetworkSystem_getSocketLocalAddressImpl(JNIEnv* env,
+ jclass clazz, jobject fileDescriptor, jboolean preferIPv6Addresses) {
+ // LOGD("ENTER getSocketLocalAddressImpl");
+
+ struct sockaddr_in addr;
+ socklen_t addrLen = sizeof(addr);
+
+ memset(&addr, 0, addrLen);
+
+ int handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ int result;
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_UNKNOWNSOCKET);
+ return NULL;
+ }
+
+ result = getsockname(handle, (struct sockaddr *)&addr, &addrLen);
+
+ // Spec says ignore all errors
+
+ return structInToInetAddress(env, &(addr.sin_addr));
+
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_getSocketLocalPortImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jboolean preferIPv6Addresses) {
+ // LOGD("ENTER getSocketLocalPortImpl");
+
+ struct sockaddr_in addr;
+ socklen_t addrLen = sizeof(addr);
+
+ int handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+ int result;
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_UNKNOWNSOCKET);
+ return 0;
+ }
+
+ result = getsockname(handle, (struct sockaddr *)&addr, &addrLen);
+
+ if (0 != result) {
+ // The java spec does not indicate any exceptions on this call
+ return 0;
+ } else {
+ return ntohs(addr.sin_port);
+ }
+}
+
+extern "C" jobject Java_org_sipdroid_net_impl_OSNetworkSystem_getSocketOptionImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jint anOption) {
+ // LOGD("ENTER getSocketOptionImpl");
+
+ int handle;
+ int intValue = 0;
+ socklen_t intSize = sizeof(int);
+ unsigned char byteValue = 0;
+ socklen_t byteSize = sizeof(unsigned char);
+ int result;
+ struct sockaddr_in sockVal;
+ socklen_t sockSize = sizeof(sockVal);
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return NULL;
+ }
+
+ switch ((int) anOption & 0xffff) {
+ case JAVASOCKOPT_SO_LINGER: {
+ struct linger lingr;
+ socklen_t size = sizeof(struct linger);
+ result = getsockopt(handle, SOL_SOCKET, SO_LINGER, &lingr, &size);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return NULL;
+ }
+ if (!lingr.l_onoff) {
+ intValue = -1;
+ } else {
+ intValue = lingr.l_linger;
+ }
+ return newJavaLangInteger(env, intValue);
+ }
+ case JAVASOCKOPT_TCP_NODELAY: {
+ if ((anOption >> 16) & BROKEN_TCP_NODELAY) {
+ return NULL;
+ }
+ result = getsockopt(handle, IPPROTO_TCP, TCP_NODELAY, &intValue, &intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return NULL;
+ }
+ return newJavaLangBoolean(env, intValue);
+ }
+ case JAVASOCKOPT_MCAST_TTL: {
+ if ((anOption >> 16) & BROKEN_MULTICAST_TTL) {
+ return newJavaLangByte(env, 0);
+ }
+ result = getsockopt(handle, IPPROTO_IP, IP_MULTICAST_TTL, &byteValue, &byteSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return NULL;
+ }
+ return newJavaLangByte(env, (jbyte)(byteValue & 0xFF));
+ }
+ case JAVASOCKOPT_MCAST_INTERFACE: {
+ if ((anOption >> 16) & BROKEN_MULTICAST_IF) {
+ return NULL;
+ }
+ result = getsockopt(handle, IPPROTO_IP, IP_MULTICAST_IF, &sockVal, &sockSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return NULL;
+ }
+ return structInToInetAddress(env, &(sockVal.sin_addr));
+ }
+ case JAVASOCKOPT_SO_SNDBUF: {
+ result = getsockopt(handle, SOL_SOCKET, SO_SNDBUF, &intValue, &intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return NULL;
+ }
+ return newJavaLangInteger(env, intValue);
+ }
+ case JAVASOCKOPT_SO_RCVBUF: {
+ result = getsockopt(handle, SOL_SOCKET, SO_RCVBUF, &intValue, &intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return NULL;
+ }
+ return newJavaLangInteger(env, intValue);
+ }
+ case JAVASOCKOPT_SO_BROADCAST: {
+ result = getsockopt(handle, SOL_SOCKET, SO_BROADCAST, &intValue, &intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return NULL;
+ }
+ return newJavaLangBoolean(env, intValue);
+ }
+ case JAVASOCKOPT_SO_REUSEADDR: {
+ result = getsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &intValue, &intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return NULL;
+ }
+ return newJavaLangBoolean(env, intValue);
+ }
+ case JAVASOCKOPT_SO_KEEPALIVE: {
+ result = getsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &intValue, &intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return NULL;
+ }
+ return newJavaLangBoolean(env, intValue);
+ }
+ case JAVASOCKOPT_SO_OOBINLINE: {
+ result = getsockopt(handle, SOL_SOCKET, SO_OOBINLINE, &intValue, &intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return NULL;
+ }
+ return newJavaLangBoolean(env, intValue);
+ }
+ case JAVASOCKOPT_IP_MULTICAST_LOOP: {
+ result = getsockopt(handle, IPPROTO_IP, IP_MULTICAST_LOOP, &intValue, &intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return NULL;
+ }
+ return newJavaLangBoolean(env, intValue);
+ }
+ case JAVASOCKOPT_IP_TOS: {
+ result = getsockopt(handle, IPPROTO_IP, IP_TOS, &intValue, &intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return NULL;
+ }
+ return newJavaLangInteger(env, intValue);
+ }
+ case JAVASOCKOPT_SO_RCVTIMEOUT: {
+ struct timeval timeout;
+ socklen_t size = sizeof(timeout);
+ result = getsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, &timeout, &size);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return NULL;
+ }
+ return newJavaLangInteger(env, timeout.tv_sec * 1000 + timeout.tv_usec/1000);
+ }
+ default: {
+ throwSocketException(env, SOCKERR_OPTUNSUPP);
+ return NULL;
+ }
+ }
+
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_setSocketOptionImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor, jint anOption, jobject optVal) {
+ // LOGD("ENTER setSocketOptionImpl");
+
+ int handle, result;
+ int intVal, intSize = sizeof(int);
+ unsigned char byteVal, byteSize = sizeof(unsigned char);
+ struct sockaddr_in sockVal;
+ int sockSize = sizeof(sockVal);
+
+ if (env->IsInstanceOf(optVal, gCachedFields.integer_class)) {
+ intVal = (int) env->GetIntField(optVal, gCachedFields.integer_class_value);
+ } else if (env->IsInstanceOf(optVal, gCachedFields.boolean_class)) {
+ intVal = (int) env->GetBooleanField(optVal, gCachedFields.boolean_class_value);
+ } else if (env->IsInstanceOf(optVal, gCachedFields.byte_class)) {
+ byteVal = (int) env->GetByteField(optVal, gCachedFields.byte_class_value);
+ } else if (env->IsInstanceOf(optVal, gCachedFields.iaddr_class)) {
+ if (inetAddressToSocketAddress(env, optVal, 0, &sockVal) < 0) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ }
+ } else if (env->IsInstanceOf(optVal, gCachedFields.genericipmreq_class)) {
+ // we'll use optVal directly
+ } else {
+ throwSocketException(env, SOCKERR_OPTUNSUPP);
+ return;
+ }
+
+ handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ }
+
+ switch ((int) anOption & 0xffff) {
+ case JAVASOCKOPT_SO_LINGER: {
+ struct linger lingr;
+ lingr.l_onoff = intVal > 0 ? 1 : 0;
+ lingr.l_linger = intVal;
+ result = setsockopt(handle, SOL_SOCKET, SO_LINGER, &lingr,
+ sizeof(struct linger));
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_TCP_NODELAY: {
+ if ((anOption >> 16) & BROKEN_TCP_NODELAY) {
+ return;
+ }
+ result = setsockopt(handle, IPPROTO_TCP, TCP_NODELAY, &intVal, intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_MCAST_TTL: {
+ if ((anOption >> 16) & BROKEN_MULTICAST_TTL) {
+ return;
+ }
+ result = setsockopt(handle, IPPROTO_IP, IP_MULTICAST_TTL, &byteVal, byteSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_MCAST_ADD_MEMBERSHIP: {
+ mcastAddDropMembership(env, handle, optVal,
+ (anOption >> 16) & BROKEN_MULTICAST_IF, IP_ADD_MEMBERSHIP);
+ return;
+ }
+
+ case JAVASOCKOPT_MCAST_DROP_MEMBERSHIP: {
+ mcastAddDropMembership(env, handle, optVal,
+ (anOption >> 16) & BROKEN_MULTICAST_IF, IP_DROP_MEMBERSHIP);
+ return;
+ }
+
+ case JAVASOCKOPT_MCAST_INTERFACE: {
+ if ((anOption >> 16) & BROKEN_MULTICAST_IF) {
+ return;
+ }
+ result = setsockopt(handle, IPPROTO_IP, IP_MULTICAST_IF, &sockVal, sockSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_SO_SNDBUF: {
+ result = setsockopt(handle, SOL_SOCKET, SO_SNDBUF, &intVal, intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_SO_RCVBUF: {
+ result = setsockopt(handle, SOL_SOCKET, SO_RCVBUF, &intVal, intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_SO_BROADCAST: {
+ result = setsockopt(handle, SOL_SOCKET, SO_BROADCAST, &intVal, intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_SO_REUSEADDR: {
+ result = setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &intVal, intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return;
+ }
+ break;
+ }
+ case JAVASOCKOPT_SO_KEEPALIVE: {
+ result = setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &intVal, intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_SO_OOBINLINE: {
+ result = setsockopt(handle, SOL_SOCKET, SO_OOBINLINE, &intVal, intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_IP_MULTICAST_LOOP: {
+ result = setsockopt(handle, IPPROTO_IP, IP_MULTICAST_LOOP, &intVal, intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_IP_TOS: {
+ result = setsockopt(handle, IPPROTO_IP, IP_TOS, &intVal, intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_REUSEADDR_AND_REUSEPORT: {
+ // SO_REUSEPORT doesn't need to get set on this System
+ result = setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &intVal, intSize);
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_SO_RCVTIMEOUT: {
+ struct timeval timeout;
+ timeout.tv_sec = intVal / 1000;
+ timeout.tv_usec = (intVal % 1000) * 1000;
+ result = setsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, &timeout,
+ sizeof(struct timeval));
+ if (0 != result) {
+ throwSocketException(env, convertError(errno));
+ return;
+ }
+ break;
+ }
+
+ default: {
+ throwSocketException(env, SOCKERR_OPTUNSUPP);
+ }
+ }
+}
+
+extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_getSocketFlagsImpl(JNIEnv* env, jclass clazz) {
+ // LOGD("ENTER getSocketFlagsImpl");
+
+ // Not implemented by harmony
+ return 0;
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_socketCloseImpl(JNIEnv* env, jclass clazz,
+ jobject fileDescriptor) {
+ // LOGD("ENTER socketCloseImpl");
+
+ int handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (handle == 0 || handle == -1) {
+ throwSocketException(env, SOCKERR_BADSOCKET);
+ return;
+ }
+
+ log_socket_close(handle, SOCKET_CLOSE_LOCAL);
+
+ jniSetFileDescriptorOfFD(env, fileDescriptor, -1);
+
+ close(handle);
+}
+
+extern "C" jobject Java_org_sipdroid_net_impl_OSNetworkSystem_getHostByAddrImpl(JNIEnv* env, jclass clazz,
+ jbyteArray addrStr) {
+ // LOGD("ENTER getHostByAddrImpl");
+
+ if (addrStr == NULL) {
+ throwNullPointerException(env);
+ return JNI_FALSE;
+ }
+
+ jstring address = (jstring)newJavaLangString(env, addrStr);
+ jstring result;
+ const char* addr = env->GetStringUTFChars(address, NULL);
+
+ struct hostent* ent = gethostbyaddr(addr, strlen(addr), AF_INET);
+
+ if (ent != NULL && ent->h_name != NULL) {
+ result = env->NewStringUTF(ent->h_name);
+ } else {
+ result = NULL;
+ }
+
+ env->ReleaseStringUTFChars(address, addr);
+
+ return result;
+}
+
+extern "C" jobject Java_org_sipdroid_net_impl_OSNetworkSystem_getHostByNameImpl(JNIEnv* env, jclass clazz,
+ jstring nameStr, jboolean preferIPv6Addresses) {
+ // LOGD("ENTER getHostByNameImpl");
+
+ if (nameStr == NULL) {
+ throwNullPointerException(env);
+ return NULL;
+ }
+
+ const char* name = env->GetStringUTFChars(nameStr, NULL);
+
+ if (useAdbNetworking) {
+
+ union {
+ struct in_addr a;
+ jbyte j[4];
+ } outaddr;
+
+ // LOGD("ADB networking: +gethostbyname '%s'", name);
+ int err;
+ err = adb_networking_gethostbyname(name, &(outaddr.a));
+
+ env->ReleaseStringUTFChars(nameStr, name);
+#if 0
+ LOGD("ADB networking: -gethostbyname err %d addr 0x%08x %u.%u.%u.%u",
+ err, (unsigned int)outaddr.a.s_addr,
+ outaddr.j[0],outaddr.j[1],
+ outaddr.j[2],outaddr.j[3]);
+#endif
+
+ if (err < 0) {
+ return NULL;
+ } else {
+ jbyteArray addr = env->NewByteArray(4);
+ env->SetByteArrayRegion(addr, 0, 4, outaddr.j);
+ return addr;
+ }
+ } else {
+
+ // normal case...no adb networking
+ struct hostent* ent = gethostbyname(name);
+
+ env->ReleaseStringUTFChars(nameStr, name);
+
+ if (ent != NULL && ent->h_length > 0) {
+ jbyteArray addr = env->NewByteArray(4);
+ jbyte v[4];
+ memcpy(v, ent->h_addr, 4);
+ env->SetByteArrayRegion(addr, 0, 4, v);
+ return addr;
+ } else {
+ return NULL;
+ }
+ }
+}
+
+extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_setInetAddressImpl(JNIEnv* env, jobject obj,
+ jobject sender, jbyteArray address) {
+ // LOGD("ENTER setInetAddressImpl");
+
+ env->SetObjectField(sender, gCachedFields.iaddr_ipaddress, address);
+}
+
+/*
+extern "C" jobject Java_org_sipdroid_net_impl_OSNetworkSystem_inheritedChannelImpl(JNIEnv* env, jobject obj) {
+ // LOGD("ENTER inheritedChannelImpl");
+
+ int socket = 0;
+ int opt;
+ socklen_t length = sizeof(opt);
+ int socket_type;
+ struct sockaddr_in local_addr;
+ struct sockaddr_in remote_addr;
+ jclass channel_class, socketaddr_class, serverSocket_class, socketImpl_class;
+ jobject channel_object = NULL, socketaddr_object, serverSocket_object;
+ jobject fd_object, addr_object, localAddr_object, socketImpl_object;
+ jfieldID port_field, socketaddr_field, bound_field, fd_field;
+ jfieldID serverSocket_field, socketImpl_field, addr_field, localAddr_field;
+ jmethodID channel_new;
+ jbyteArray addr_array;
+ struct sockaddr_in *sock;
+ jbyte * address;
+ jbyte * localAddr;
+ jboolean jtrue = JNI_TRUE;
+
+ if (0 != getsockopt(socket, SOL_SOCKET, SO_TYPE, &opt, &length)) {
+ return NULL;
+ }
+ if (SOCK_STREAM !=opt && SOCK_DGRAM !=opt) {
+ return NULL;
+ }
+ socket_type = opt;
+
+ length = sizeof(struct sockaddr);
+ if (0 != getsockname(socket, (struct sockaddr *)&local_addr, &length)) {
+ return NULL;
+ } else {
+ if (AF_INET != local_addr.sin_family || length != sizeof(struct sockaddr)) {
+ return NULL;
+ }
+ localAddr = (jbyte*) malloc(sizeof(jbyte)*4);
+ if (NULL == localAddr) {
+ return NULL;
+ }
+ memcpy (localAddr, &(local_addr.sin_addr.s_addr), 4);
+ }
+ if (0 != getpeername(socket, (struct sockaddr *)&remote_addr, &length)) {
+ remote_addr.sin_port = 0;
+ remote_addr.sin_addr.s_addr = 0;
+ address = (jbyte*) malloc(sizeof(jbyte)*4);
+ bzero(address, sizeof(jbyte)*4);
+ } else {
+ if (AF_INET != remote_addr.sin_family
+ || length != sizeof(struct sockaddr)) {
+ return NULL;
+ }
+ address = (jbyte*) malloc(sizeof(jbyte)*4);
+ memcpy (address, &(remote_addr.sin_addr.s_addr), 4);
+ }
+
+ // analysis end, begin pack to java
+ if (SOCK_STREAM == opt) {
+ if (remote_addr.sin_port!=0) {
+ //socket
+ channel_class = env->FindClass(
+ "org/apache/harmony/nio/internal/SocketChannelImpl");
+ if (NULL == channel_class) {
+ goto clean;
+ }
+
+ channel_new = env->GetMethodID(channel_class, "<init>", "()V");
+ if (NULL == channel_new) {
+ goto clean;
+ }
+ channel_object = env->NewObject(channel_class, channel_new);
+ if (NULL == channel_object) {
+ goto clean;
+ }
+ // new and set FileDescript
+
+ fd_field = env->GetFieldID(channel_class, "fd",
+ "java/io/FielDescriptor");
+ fd_object = env->GetObjectField(channel_object, fd_field);
+ if (NULL == fd_object) {
+ goto clean;
+ }
+
+ jniSetFileDescriptorOfFD(env, fd_object, socket);
+
+ // local port
+ port_field = env->GetFieldID(channel_class, "localPort", "I");
+ env->SetIntField(channel_object, port_field,
+ ntohs(local_addr.sin_port));
+
+ // new and set remote addr
+ addr_object = env->NewObject(gCachedFields.iaddr_class,
+ gCachedFields.iaddr_class_init);
+ if (NULL == addr_object) {
+ goto clean;
+ }
+ socketaddr_class = env->FindClass("java/net/InetSocketAddress");
+ socketaddr_field = env->GetFieldID(channel_class, "connectAddress",
+ "Ljava/net/InetSocketAddress;");
+ socketaddr_object = env->GetObjectField(channel_object,
+ socketaddr_field);
+ if (NULL == socketaddr_object) {
+ goto clean;
+ }
+ addr_field = env->GetFieldID(socketaddr_class, "addr",
+ "Ljava/net/InetAddress;");
+ env->SetObjectField(socketaddr_object, addr_field, addr_object);
+ addr_array = env->NewByteArray((jsize)4);
+ env->SetByteArrayRegion(addr_array, (jsize)0, (jsize)4, address);
+ env->SetObjectField(addr_object, gCachedFields.iaddr_ipaddress,
+ addr_array);
+
+ // localAddr
+ socketaddr_class = env->FindClass("java/net/InetSocketAddress");
+ socketaddr_field = env->GetFieldID(channel_class, "connectAddress",
+ "Ljava/net/InetSocketAddress;");
+ socketaddr_object = env->GetObjectField(channel_object,
+ socketaddr_field);
+
+ localAddr_field = env->GetFieldID(channel_class, "localAddress",
+ "Ljava/net/InetAddress;");
+ localAddr_object = env->NewObject(gCachedFields.iaddr_class,
+ gCachedFields.iaddr_class_init);
+ jfieldID socketaddr_field = env->GetFieldID(channel_class,
+ "connectAddress", "Ljava/net/InetSocketAddress;");
+ jobject socketaddr_object = env->GetObjectField(channel_object,
+ socketaddr_field);
+ env->SetObjectField(socketaddr_object, localAddr_field,
+ localAddr_object);
+ if (NULL == localAddr_object) {
+ goto clean;
+ }
+ addr_array = env->NewByteArray((jsize)4);
+ env->SetByteArrayRegion(addr_array, (jsize)0, (jsize)4, localAddr);
+ env->SetObjectField(localAddr_object, gCachedFields.iaddr_ipaddress,
+ addr_array);
+
+
+ // set port
+ port_field = env->GetFieldID(socketaddr_class, "port", "I");
+ env->SetIntField(socketaddr_object, port_field,
+ ntohs(remote_addr.sin_port));
+
+ // set bound
+ if (0 != local_addr.sin_port) {
+ bound_field = env->GetFieldID(channel_class, "isBound", "Z");
+ env->SetBooleanField(channel_object, bound_field, jtrue);
+ }
+
+ } else {
+ //serverSocket
+ channel_class = env->FindClass(
+ "org/apache/harmony/nio/internal/ServerSocketChannelImpl");
+ if (NULL == channel_class) {
+ goto clean;
+ }
+
+ channel_new = env->GetMethodID(channel_class, "<init>", "()V");
+ if (NULL == channel_new) {
+ goto clean;
+ }
+ channel_object = env->NewObject(channel_class, channel_new);
+ if (NULL == channel_object) {
+ goto clean;
+ }
+
+ serverSocket_field = env->GetFieldID(channel_class, "socket",
+ "Ljava/net/ServerSocket;");
+ serverSocket_class = env->FindClass("Ljava/net/ServerSocket;");
+ serverSocket_object = env->GetObjectField(channel_object,
+ serverSocket_field);
+ // set bound
+ if (0 != local_addr.sin_port) {
+ bound_field = env->GetFieldID(channel_class, "isBound", "Z");
+ env->SetBooleanField(channel_object, bound_field, jtrue);
+ bound_field = env->GetFieldID(serverSocket_class, "isBound", "Z");
+ env->SetBooleanField(serverSocket_object, bound_field, jtrue);
+ }
+ // localAddr
+ socketImpl_class = env->FindClass("java/net/SocketImpl");
+ socketImpl_field = env->GetFieldID(channel_class, "impl",
+ "Ljava/net/SocketImpl;");
+ socketImpl_object = env->GetObjectField(channel_object,
+ socketImpl_field);
+ if (NULL == socketImpl_object) {
+ goto clean;
+ }
+
+ localAddr_field = env->GetFieldID(channel_class, "localAddress",
+ "Ljava/net/InetAddress;");
+ localAddr_object = env->NewObject(gCachedFields.iaddr_class,
+ gCachedFields.iaddr_class_init);
+ if (NULL == localAddr_object) {
+ goto clean;
+ }
+ env->SetObjectField(socketImpl_object, localAddr_field,
+ localAddr_object);
+ addr_array = env->NewByteArray((jsize)4);
+ env->SetByteArrayRegion(addr_array, (jsize)0, (jsize)4, localAddr);
+ env->SetObjectField(localAddr_object,
+ gCachedFields.iaddr_ipaddress, addr_array);
+
+ // set port
+ port_field = env->GetFieldID(socketImpl_class, "localport", "I");
+ env->SetIntField(socketImpl_object, port_field,
+ ntohs(local_addr.sin_port));
+ }
+ } else {
+ //Datagram Socket
+ // new DatagramChannel
+ channel_class = env->FindClass(
+ "org/apache/harmony/nio/internal/DatagramChannelImpl");
+ if (NULL == channel_class) {
+ goto clean;
+ }
+
+ channel_new = env->GetMethodID(channel_class, "<init>", "()V");
+ if (NULL == channel_new) {
+ goto clean;
+ }
+ channel_object = env->NewObject(channel_class, channel_new);
+ if (NULL == channel_object) {
+ goto clean;
+ }
+
+ // new and set FileDescript
+ fd_field = env->GetFieldID(channel_class, "fd", "java/io/FileDescriptor");
+ fd_object = env->GetObjectField(channel_object, fd_field);
+ if (NULL == fd_object) {
+ goto clean;
+ }
+
+ jniSetFileDescriptorOfFD(env, fd_object, socket);
+
+ port_field = env->GetFieldID(channel_class, "localPort", "I");
+ env->SetIntField(channel_object, port_field, ntohs(local_addr.sin_port));
+
+ // new and set remote addr
+ addr_object = env->NewObject(gCachedFields.iaddr_class,
+ gCachedFields.iaddr_class_init);
+ if (NULL == addr_object) {
+ goto clean;
+ }
+ socketaddr_class = env->FindClass("java/net/InetSocketAddress");
+ socketaddr_field = env->GetFieldID(channel_class, "connectAddress",
+ "Ljava/net/InetSocketAddress;");
+ socketaddr_object = env->GetObjectField(channel_object, socketaddr_field);
+ if (NULL == socketaddr_object) {
+ goto clean;
+ }
+ addr_field = env->GetFieldID(socketaddr_class, "addr",
+ "Ljava/net/InetAddress;");
+ env->SetObjectField(socketaddr_object, addr_field, addr_object);
+ addr_array = env->NewByteArray((jsize)4);
+ env->SetByteArrayRegion(addr_array, (jsize)0, (jsize)4, address);
+ env->SetObjectField(addr_object, gCachedFields.iaddr_ipaddress, addr_array);
+
+ // set bound
+ if (0 != local_addr.sin_port) {
+ bound_field = env->GetFieldID(channel_class, "isBound", "Z");
+ env->SetBooleanField(channel_object, bound_field, jtrue);
+ }
+ }
+clean:
+ free(address);
+ free(localAddr);
+ return channel_object;
+}
+*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/g722/g722.h Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,159 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * g722.h - The ITU G.722 codec.
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2005 Steve Underwood
+ *
+ * Despite my general liking of the GPL, I place my own contributions
+ * to this code in the public domain for the benefit of all mankind -
+ * even the slimy ones who might try to proprietize my work and use it
+ * to my detriment.
+ *
+ * Based on a single channel G.722 codec which is:
+ *
+ ***** Copyright (c) CMU 1993 *****
+ * Computer Science, Speech Group
+ * Chengxiang Lu and Alex Hauptmann
+ *
+ * $Id: g722.h 48959 2006-12-25 06:42:15Z rizzo $
+ */
+
+
+/*! \file */
+
+#if !defined(_G722_H_)
+#define _G722_H_
+
+/*! \page g722_page G.722 encoding and decoding
+\section g722_page_sec_1 What does it do?
+The G.722 module is a bit exact implementation of the ITU G.722 specification for all three
+specified bit rates - 64000bps, 56000bps and 48000bps. It passes the ITU tests.
+
+To allow fast and flexible interworking with narrow band telephony, the encoder and decoder
+support an option for the linear audio to be an 8k samples/second stream. In this mode the
+codec is considerably faster, and still fully compatible with wideband terminals using G.722.
+
+\section g722_page_sec_2 How does it work?
+???.
+*/
+
+#if !defined(__STDINT_MACROS)
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned uint32_t;
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+#endif
+
+enum
+{
+ G722_SAMPLE_RATE_8000 = 0x0001,
+ G722_PACKED = 0x0002
+};
+
+#ifndef INT16_MAX
+#define INT16_MAX 32767
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32768)
+#endif
+
+typedef struct
+{
+ /*! TRUE if the operating in the special ITU test mode, with the band split filters
+ disabled. */
+ int itu_test_mode;
+ /*! TRUE if the G.722 data is packed */
+ int packed;
+ /*! TRUE if encode from 8k samples/second */
+ int eight_k;
+ /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */
+ int bits_per_sample;
+
+ /*! Signal history for the QMF */
+ int x[24];
+
+ struct
+ {
+ int s;
+ int sp;
+ int sz;
+ int r[3];
+ int a[3];
+ int ap[3];
+ int p[3];
+ int d[7];
+ int b[7];
+ int bp[7];
+ int sg[7];
+ int nb;
+ int det;
+ } band[2];
+
+ unsigned int in_buffer;
+ int in_bits;
+ unsigned int out_buffer;
+ int out_bits;
+} g722_encode_state_t;
+
+typedef struct
+{
+ /*! TRUE if the operating in the special ITU test mode, with the band split filters
+ disabled. */
+ int itu_test_mode;
+ /*! TRUE if the G.722 data is packed */
+ int packed;
+ /*! TRUE if decode to 8k samples/second */
+ int eight_k;
+ /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */
+ int bits_per_sample;
+
+ /*! Signal history for the QMF */
+ int x[24];
+
+ struct
+ {
+ int s;
+ int sp;
+ int sz;
+ int r[3];
+ int a[3];
+ int ap[3];
+ int p[3];
+ int d[7];
+ int b[7];
+ int bp[7];
+ int sg[7];
+ int nb;
+ int det;
+ } band[2];
+
+ unsigned int in_buffer;
+ int in_bits;
+ unsigned int out_buffer;
+ int out_bits;
+} g722_decode_state_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options);
+int g722_encode_release(g722_encode_state_t *s);
+int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len);
+
+g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options);
+int g722_decode_release(g722_decode_state_t *s);
+int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/g722/g722_decode.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,398 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * g722_decode.c - The ITU G.722 codec, decode part.
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2005 Steve Underwood
+ *
+ * Despite my general liking of the GPL, I place my own contributions
+ * to this code in the public domain for the benefit of all mankind -
+ * even the slimy ones who might try to proprietize my work and use it
+ * to my detriment.
+ *
+ * Based in part on a single channel G.722 codec which is:
+ *
+ * Copyright (c) CMU 1993
+ * Computer Science, Speech Group
+ * Chengxiang Lu and Alex Hauptmann
+ *
+ * $Id: g722_decode.c 48661 2006-12-21 00:08:21Z mattf $
+ */
+
+/*! \file */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+//#include <inttypes.h>
+#include <memory.h>
+#include <stdlib.h>
+#if 0
+#include <tgmath.h>
+#endif
+
+#include "g722.h"
+
+#if !defined(FALSE)
+#define FALSE 0
+#endif
+#if !defined(TRUE)
+#define TRUE (!FALSE)
+#endif
+
+static int16_t saturate(int32_t amp)
+{
+ int16_t amp16;
+
+ /* Hopefully this is optimised for the common case - not clipping */
+ amp16 = (int16_t) amp;
+ if (amp == amp16)
+ return amp16;
+ if (amp > INT16_MAX)
+ return INT16_MAX;
+ return INT16_MIN;
+}
+/*- End of function --------------------------------------------------------*/
+
+static void block4(g722_decode_state_t *s, int band, int d);
+
+static void block4(g722_decode_state_t *s, int band, int d)
+{
+ int wd1;
+ int wd2;
+ int wd3;
+ int i;
+
+ /* Block 4, RECONS */
+ s->band[band].d[0] = d;
+ s->band[band].r[0] = saturate(s->band[band].s + d);
+
+ /* Block 4, PARREC */
+ s->band[band].p[0] = saturate(s->band[band].sz + d);
+
+ /* Block 4, UPPOL2 */
+ for (i = 0; i < 3; i++)
+ s->band[band].sg[i] = s->band[band].p[i] >> 15;
+ wd1 = saturate(s->band[band].a[1] << 2);
+
+ wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1;
+ if (wd2 > 32767)
+ wd2 = 32767;
+ wd3 = (s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128;
+ wd3 += (wd2 >> 7);
+ wd3 += (s->band[band].a[2]*32512) >> 15;
+ if (wd3 > 12288)
+ wd3 = 12288;
+ else if (wd3 < -12288)
+ wd3 = -12288;
+ s->band[band].ap[2] = wd3;
+
+ /* Block 4, UPPOL1 */
+ s->band[band].sg[0] = s->band[band].p[0] >> 15;
+ s->band[band].sg[1] = s->band[band].p[1] >> 15;
+ wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192;
+ wd2 = (s->band[band].a[1]*32640) >> 15;
+
+ s->band[band].ap[1] = saturate(wd1 + wd2);
+ wd3 = saturate(15360 - s->band[band].ap[2]);
+ if (s->band[band].ap[1] > wd3)
+ s->band[band].ap[1] = wd3;
+ else if (s->band[band].ap[1] < -wd3)
+ s->band[band].ap[1] = -wd3;
+
+ /* Block 4, UPZERO */
+ wd1 = (d == 0) ? 0 : 128;
+ s->band[band].sg[0] = d >> 15;
+ for (i = 1; i < 7; i++)
+ {
+ s->band[band].sg[i] = s->band[band].d[i] >> 15;
+ wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1;
+ wd3 = (s->band[band].b[i]*32640) >> 15;
+ s->band[band].bp[i] = saturate(wd2 + wd3);
+ }
+
+ /* Block 4, DELAYA */
+ for (i = 6; i > 0; i--)
+ {
+ s->band[band].d[i] = s->band[band].d[i - 1];
+ s->band[band].b[i] = s->band[band].bp[i];
+ }
+
+ for (i = 2; i > 0; i--)
+ {
+ s->band[band].r[i] = s->band[band].r[i - 1];
+ s->band[band].p[i] = s->band[band].p[i - 1];
+ s->band[band].a[i] = s->band[band].ap[i];
+ }
+
+ /* Block 4, FILTEP */
+ wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
+ wd1 = (s->band[band].a[1]*wd1) >> 15;
+ wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
+ wd2 = (s->band[band].a[2]*wd2) >> 15;
+ s->band[band].sp = saturate(wd1 + wd2);
+
+ /* Block 4, FILTEZ */
+ s->band[band].sz = 0;
+ for (i = 6; i > 0; i--)
+ {
+ wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
+ s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
+ }
+ s->band[band].sz = saturate(s->band[band].sz);
+
+ /* Block 4, PREDIC */
+ s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
+}
+/*- End of function --------------------------------------------------------*/
+
+g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options)
+{
+ if (s == NULL)
+ {
+ if ((s = (g722_decode_state_t *) malloc(sizeof(*s))) == NULL)
+ return NULL;
+ }
+ memset(s, 0, sizeof(*s));
+ if (rate == 48000)
+ s->bits_per_sample = 6;
+ else if (rate == 56000)
+ s->bits_per_sample = 7;
+ else
+ s->bits_per_sample = 8;
+ if ((options & G722_SAMPLE_RATE_8000))
+ s->eight_k = TRUE;
+ if ((options & G722_PACKED) && s->bits_per_sample != 8)
+ s->packed = TRUE;
+ else
+ s->packed = FALSE;
+ s->band[0].det = 32;
+ s->band[1].det = 8;
+ return s;
+}
+/*- End of function --------------------------------------------------------*/
+
+int g722_decode_release(g722_decode_state_t *s)
+{
+ free(s);
+ return 0;
+}
+/*- End of function --------------------------------------------------------*/
+
+int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len)
+{
+ static const int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042 };
+ static const int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0 };
+ static const int ilb[32] =
+ {
+ 2048, 2093, 2139, 2186, 2233, 2282, 2332,
+ 2383, 2435, 2489, 2543, 2599, 2656, 2714,
+ 2774, 2834, 2896, 2960, 3025, 3091, 3158,
+ 3228, 3298, 3371, 3444, 3520, 3597, 3676,
+ 3756, 3838, 3922, 4008
+ };
+ static const int wh[3] = {0, -214, 798};
+ static const int rh2[4] = {2, 1, 2, 1};
+ static const int qm2[4] = {-7408, -1616, 7408, 1616};
+ static const int qm4[16] =
+ {
+ 0, -20456, -12896, -8968,
+ -6288, -4240, -2584, -1200,
+ 20456, 12896, 8968, 6288,
+ 4240, 2584, 1200, 0
+ };
+ static const int qm5[32] =
+ {
+ -280, -280, -23352, -17560,
+ -14120, -11664, -9752, -8184,
+ -6864, -5712, -4696, -3784,
+ -2960, -2208, -1520, -880,
+ 23352, 17560, 14120, 11664,
+ 9752, 8184, 6864, 5712,
+ 4696, 3784, 2960, 2208,
+ 1520, 880, 280, -280
+ };
+ static const int qm6[64] =
+ {
+ -136, -136, -136, -136,
+ -24808, -21904, -19008, -16704,
+ -14984, -13512, -12280, -11192,
+ -10232, -9360, -8576, -7856,
+ -7192, -6576, -6000, -5456,
+ -4944, -4464, -4008, -3576,
+ -3168, -2776, -2400, -2032,
+ -1688, -1360, -1040, -728,
+ 24808, 21904, 19008, 16704,
+ 14984, 13512, 12280, 11192,
+ 10232, 9360, 8576, 7856,
+ 7192, 6576, 6000, 5456,
+ 4944, 4464, 4008, 3576,
+ 3168, 2776, 2400, 2032,
+ 1688, 1360, 1040, 728,
+ 432, 136, -432, -136
+ };
+ static const int qmf_coeffs[12] =
+ {
+ 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
+ };
+
+ int dlowt;
+ int rlow;
+ int ihigh;
+ int dhigh;
+ int rhigh;
+ int xout1;
+ int xout2;
+ int wd1;
+ int wd2;
+ int wd3;
+ int code;
+ int outlen;
+ int i;
+ int j;
+
+ outlen = 0;
+ rhigh = 0;
+ for (j = 0; j < len; )
+ {
+ if (s->packed)
+ {
+ /* Unpack the code bits */
+ if (s->in_bits < s->bits_per_sample)
+ {
+ s->in_buffer |= (g722_data[j++] << s->in_bits);
+ s->in_bits += 8;
+ }
+ code = s->in_buffer & ((1 << s->bits_per_sample) - 1);
+ s->in_buffer >>= s->bits_per_sample;
+ s->in_bits -= s->bits_per_sample;
+ }
+ else
+ {
+ code = g722_data[j++];
+ }
+
+ switch (s->bits_per_sample)
+ {
+ default:
+ case 8:
+ wd1 = code & 0x3F;
+ ihigh = (code >> 6) & 0x03;
+ wd2 = qm6[wd1];
+ wd1 >>= 2;
+ break;
+ case 7:
+ wd1 = code & 0x1F;
+ ihigh = (code >> 5) & 0x03;
+ wd2 = qm5[wd1];
+ wd1 >>= 1;
+ break;
+ case 6:
+ wd1 = code & 0x0F;
+ ihigh = (code >> 4) & 0x03;
+ wd2 = qm4[wd1];
+ break;
+ }
+ /* Block 5L, LOW BAND INVQBL */
+ wd2 = (s->band[0].det*wd2) >> 15;
+ /* Block 5L, RECONS */
+ rlow = s->band[0].s + wd2;
+ /* Block 6L, LIMIT */
+ if (rlow > 16383)
+ rlow = 16383;
+ else if (rlow < -16384)
+ rlow = -16384;
+
+ /* Block 2L, INVQAL */
+ wd2 = qm4[wd1];
+ dlowt = (s->band[0].det*wd2) >> 15;
+
+ /* Block 3L, LOGSCL */
+ wd2 = rl42[wd1];
+ wd1 = (s->band[0].nb*127) >> 7;
+ wd1 += wl[wd2];
+ if (wd1 < 0)
+ wd1 = 0;
+ else if (wd1 > 18432)
+ wd1 = 18432;
+ s->band[0].nb = wd1;
+
+ /* Block 3L, SCALEL */
+ wd1 = (s->band[0].nb >> 6) & 31;
+ wd2 = 8 - (s->band[0].nb >> 11);
+ wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
+ s->band[0].det = wd3 << 2;
+
+ block4(s, 0, dlowt);
+
+ if (!s->eight_k)
+ {
+ /* Block 2H, INVQAH */
+ wd2 = qm2[ihigh];
+ dhigh = (s->band[1].det*wd2) >> 15;
+ /* Block 5H, RECONS */
+ rhigh = dhigh + s->band[1].s;
+ /* Block 6H, LIMIT */
+ if (rhigh > 16383)
+ rhigh = 16383;
+ else if (rhigh < -16384)
+ rhigh = -16384;
+
+ /* Block 2H, INVQAH */
+ wd2 = rh2[ihigh];
+ wd1 = (s->band[1].nb*127) >> 7;
+ wd1 += wh[wd2];
+ if (wd1 < 0)
+ wd1 = 0;
+ else if (wd1 > 22528)
+ wd1 = 22528;
+ s->band[1].nb = wd1;
+
+ /* Block 3H, SCALEH */
+ wd1 = (s->band[1].nb >> 6) & 31;
+ wd2 = 10 - (s->band[1].nb >> 11);
+ wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
+ s->band[1].det = wd3 << 2;
+
+ block4(s, 1, dhigh);
+ }
+
+ if (s->itu_test_mode)
+ {
+ amp[outlen++] = (int16_t) (rlow << 1);
+ amp[outlen++] = (int16_t) (rhigh << 1);
+ }
+ else
+ {
+ if (s->eight_k)
+ {
+ amp[outlen++] = (int16_t) rlow;
+ }
+ else
+ {
+ /* Apply the receive QMF */
+ for (i = 0; i < 22; i++)
+ s->x[i] = s->x[i + 2];
+ s->x[22] = rlow + rhigh;
+ s->x[23] = rlow - rhigh;
+
+ xout1 = 0;
+ xout2 = 0;
+ for (i = 0; i < 12; i++)
+ {
+ xout2 += s->x[2*i]*qmf_coeffs[i];
+ xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i];
+ }
+ amp[outlen++] = (int16_t) (xout1 >> 12);
+ amp[outlen++] = (int16_t) (xout2 >> 12);
+ }
+ }
+ }
+ return outlen;
+}
+/*- End of function --------------------------------------------------------*/
+/*- End of file ------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/g722/g722_encode.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,400 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * g722_encode.c - The ITU G.722 codec, encode part.
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2005 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * Despite my general liking of the GPL, I place my own contributions
+ * to this code in the public domain for the benefit of all mankind -
+ * even the slimy ones who might try to proprietize my work and use it
+ * to my detriment.
+ *
+ * Based on a single channel 64kbps only G.722 codec which is:
+ *
+ ***** Copyright (c) CMU 1993 *****
+ * Computer Science, Speech Group
+ * Chengxiang Lu and Alex Hauptmann
+ *
+ * $Id: g722_encode.c 48661 2006-12-21 00:08:21Z mattf $
+ */
+
+/*! \file */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+//#include <inttypes.h>
+#include <memory.h>
+#include <stdlib.h>
+#if 0
+#include <tgmath.h>
+#endif
+
+#include "g722.h"
+
+#if !defined(FALSE)
+#define FALSE 0
+#endif
+#if !defined(TRUE)
+#define TRUE (!FALSE)
+#endif
+
+static int16_t saturate(int32_t amp)
+{
+ int16_t amp16;
+
+ /* Hopefully this is optimised for the common case - not clipping */
+ amp16 = (int16_t) amp;
+ if (amp == amp16)
+ return amp16;
+ if (amp > INT16_MAX)
+ return INT16_MAX;
+ return INT16_MIN;
+}
+/*- End of function --------------------------------------------------------*/
+
+static void block4(g722_encode_state_t *s, int band, int d)
+{
+ int wd1;
+ int wd2;
+ int wd3;
+ int i;
+
+ /* Block 4, RECONS */
+ s->band[band].d[0] = d;
+ s->band[band].r[0] = saturate(s->band[band].s + d);
+
+ /* Block 4, PARREC */
+ s->band[band].p[0] = saturate(s->band[band].sz + d);
+
+ /* Block 4, UPPOL2 */
+ for (i = 0; i < 3; i++)
+ s->band[band].sg[i] = s->band[band].p[i] >> 15;
+ wd1 = saturate(s->band[band].a[1] << 2);
+
+ wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1;
+ if (wd2 > 32767)
+ wd2 = 32767;
+ wd3 = (wd2 >> 7) + ((s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128);
+ wd3 += (s->band[band].a[2]*32512) >> 15;
+ if (wd3 > 12288)
+ wd3 = 12288;
+ else if (wd3 < -12288)
+ wd3 = -12288;
+ s->band[band].ap[2] = wd3;
+
+ /* Block 4, UPPOL1 */
+ s->band[band].sg[0] = s->band[band].p[0] >> 15;
+ s->band[band].sg[1] = s->band[band].p[1] >> 15;
+ wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192;
+ wd2 = (s->band[band].a[1]*32640) >> 15;
+
+ s->band[band].ap[1] = saturate(wd1 + wd2);
+ wd3 = saturate(15360 - s->band[band].ap[2]);
+ if (s->band[band].ap[1] > wd3)
+ s->band[band].ap[1] = wd3;
+ else if (s->band[band].ap[1] < -wd3)
+ s->band[band].ap[1] = -wd3;
+
+ /* Block 4, UPZERO */
+ wd1 = (d == 0) ? 0 : 128;
+ s->band[band].sg[0] = d >> 15;
+ for (i = 1; i < 7; i++)
+ {
+ s->band[band].sg[i] = s->band[band].d[i] >> 15;
+ wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1;
+ wd3 = (s->band[band].b[i]*32640) >> 15;
+ s->band[band].bp[i] = saturate(wd2 + wd3);
+ }
+
+ /* Block 4, DELAYA */
+ for (i = 6; i > 0; i--)
+ {
+ s->band[band].d[i] = s->band[band].d[i - 1];
+ s->band[band].b[i] = s->band[band].bp[i];
+ }
+
+ for (i = 2; i > 0; i--)
+ {
+ s->band[band].r[i] = s->band[band].r[i - 1];
+ s->band[band].p[i] = s->band[band].p[i - 1];
+ s->band[band].a[i] = s->band[band].ap[i];
+ }
+
+ /* Block 4, FILTEP */
+ wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
+ wd1 = (s->band[band].a[1]*wd1) >> 15;
+ wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
+ wd2 = (s->band[band].a[2]*wd2) >> 15;
+ s->band[band].sp = saturate(wd1 + wd2);
+
+ /* Block 4, FILTEZ */
+ s->band[band].sz = 0;
+ for (i = 6; i > 0; i--)
+ {
+ wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
+ s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
+ }
+ s->band[band].sz = saturate(s->band[band].sz);
+
+ /* Block 4, PREDIC */
+ s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
+}
+/*- End of function --------------------------------------------------------*/
+
+g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options)
+{
+ if (s == NULL)
+ {
+ if ((s = (g722_encode_state_t *) malloc(sizeof(*s))) == NULL)
+ return NULL;
+ }
+ memset(s, 0, sizeof(*s));
+ if (rate == 48000)
+ s->bits_per_sample = 6;
+ else if (rate == 56000)
+ s->bits_per_sample = 7;
+ else
+ s->bits_per_sample = 8;
+ if ((options & G722_SAMPLE_RATE_8000))
+ s->eight_k = TRUE;
+ if ((options & G722_PACKED) && s->bits_per_sample != 8)
+ s->packed = TRUE;
+ else
+ s->packed = FALSE;
+ s->band[0].det = 32;
+ s->band[1].det = 8;
+ return s;
+}
+/*- End of function --------------------------------------------------------*/
+
+int g722_encode_release(g722_encode_state_t *s)
+{
+ free(s);
+ return 0;
+}
+/*- End of function --------------------------------------------------------*/
+
+int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len)
+{
+ static const int q6[32] =
+ {
+ 0, 35, 72, 110, 150, 190, 233, 276,
+ 323, 370, 422, 473, 530, 587, 650, 714,
+ 786, 858, 940, 1023, 1121, 1219, 1339, 1458,
+ 1612, 1765, 1980, 2195, 2557, 2919, 0, 0
+ };
+ static const int iln[32] =
+ {
+ 0, 63, 62, 31, 30, 29, 28, 27,
+ 26, 25, 24, 23, 22, 21, 20, 19,
+ 18, 17, 16, 15, 14, 13, 12, 11,
+ 10, 9, 8, 7, 6, 5, 4, 0
+ };
+ static const int ilp[32] =
+ {
+ 0, 61, 60, 59, 58, 57, 56, 55,
+ 54, 53, 52, 51, 50, 49, 48, 47,
+ 46, 45, 44, 43, 42, 41, 40, 39,
+ 38, 37, 36, 35, 34, 33, 32, 0
+ };
+ static const int wl[8] =
+ {
+ -60, -30, 58, 172, 334, 538, 1198, 3042
+ };
+ static const int rl42[16] =
+ {
+ 0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0
+ };
+ static const int ilb[32] =
+ {
+ 2048, 2093, 2139, 2186, 2233, 2282, 2332,
+ 2383, 2435, 2489, 2543, 2599, 2656, 2714,
+ 2774, 2834, 2896, 2960, 3025, 3091, 3158,
+ 3228, 3298, 3371, 3444, 3520, 3597, 3676,
+ 3756, 3838, 3922, 4008
+ };
+ static const int qm4[16] =
+ {
+ 0, -20456, -12896, -8968,
+ -6288, -4240, -2584, -1200,
+ 20456, 12896, 8968, 6288,
+ 4240, 2584, 1200, 0
+ };
+ static const int qm2[4] =
+ {
+ -7408, -1616, 7408, 1616
+ };
+ static const int qmf_coeffs[12] =
+ {
+ 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
+ };
+ static const int ihn[3] = {0, 1, 0};
+ static const int ihp[3] = {0, 3, 2};
+ static const int wh[3] = {0, -214, 798};
+ static const int rh2[4] = {2, 1, 2, 1};
+
+ int dlow;
+ int dhigh;
+ int el;
+ int wd;
+ int wd1;
+ int ril;
+ int wd2;
+ int il4;
+ int ih2;
+ int wd3;
+ int eh;
+ int mih;
+ int i;
+ int j;
+ /* Low and high band PCM from the QMF */
+ int xlow;
+ int xhigh;
+ int g722_bytes;
+ /* Even and odd tap accumulators */
+ int sumeven;
+ int sumodd;
+ int ihigh;
+ int ilow;
+ int code;
+
+ g722_bytes = 0;
+ xhigh = 0;
+ for (j = 0; j < len; )
+ {
+ if (s->itu_test_mode)
+ {
+ xlow =
+ xhigh = amp[j++] >> 1;
+ }
+ else
+ {
+ if (s->eight_k)
+ {
+ xlow = amp[j++];
+ }
+ else
+ {
+ /* Apply the transmit QMF */
+ /* Shuffle the buffer down */
+ for (i = 0; i < 22; i++)
+ s->x[i] = s->x[i + 2];
+ s->x[22] = amp[j++];
+ s->x[23] = amp[j++];
+
+ /* Discard every other QMF output */
+ sumeven = 0;
+ sumodd = 0;
+ for (i = 0; i < 12; i++)
+ {
+ sumodd += s->x[2*i]*qmf_coeffs[i];
+ sumeven += s->x[2*i + 1]*qmf_coeffs[11 - i];
+ }
+ xlow = (sumeven + sumodd) >> 13;
+ xhigh = (sumeven - sumodd) >> 13;
+ }
+ }
+ /* Block 1L, SUBTRA */
+ el = saturate(xlow - s->band[0].s);
+
+ /* Block 1L, QUANTL */
+ wd = (el >= 0) ? el : -(el + 1);
+
+ for (i = 1; i < 30; i++)
+ {
+ wd1 = (q6[i]*s->band[0].det) >> 12;
+ if (wd < wd1)
+ break;
+ }
+ ilow = (el < 0) ? iln[i] : ilp[i];
+
+ /* Block 2L, INVQAL */
+ ril = ilow >> 2;
+ wd2 = qm4[ril];
+ dlow = (s->band[0].det*wd2) >> 15;
+
+ /* Block 3L, LOGSCL */
+ il4 = rl42[ril];
+ wd = (s->band[0].nb*127) >> 7;
+ s->band[0].nb = wd + wl[il4];
+ if (s->band[0].nb < 0)
+ s->band[0].nb = 0;
+ else if (s->band[0].nb > 18432)
+ s->band[0].nb = 18432;
+
+ /* Block 3L, SCALEL */
+ wd1 = (s->band[0].nb >> 6) & 31;
+ wd2 = 8 - (s->band[0].nb >> 11);
+ wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
+ s->band[0].det = wd3 << 2;
+
+ block4(s, 0, dlow);
+
+ if (s->eight_k)
+ {
+ /* Just leave the high bits as zero */
+ code = (0xC0 | ilow) >> (8 - s->bits_per_sample);
+ }
+ else
+ {
+ /* Block 1H, SUBTRA */
+ eh = saturate(xhigh - s->band[1].s);
+
+ /* Block 1H, QUANTH */
+ wd = (eh >= 0) ? eh : -(eh + 1);
+ wd1 = (564*s->band[1].det) >> 12;
+ mih = (wd >= wd1) ? 2 : 1;
+ ihigh = (eh < 0) ? ihn[mih] : ihp[mih];
+
+ /* Block 2H, INVQAH */
+ wd2 = qm2[ihigh];
+ dhigh = (s->band[1].det*wd2) >> 15;
+
+ /* Block 3H, LOGSCH */
+ ih2 = rh2[ihigh];
+ wd = (s->band[1].nb*127) >> 7;
+ s->band[1].nb = wd + wh[ih2];
+ if (s->band[1].nb < 0)
+ s->band[1].nb = 0;
+ else if (s->band[1].nb > 22528)
+ s->band[1].nb = 22528;
+
+ /* Block 3H, SCALEH */
+ wd1 = (s->band[1].nb >> 6) & 31;
+ wd2 = 10 - (s->band[1].nb >> 11);
+ wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
+ s->band[1].det = wd3 << 2;
+
+ block4(s, 1, dhigh);
+ code = ((ihigh << 6) | ilow) >> (8 - s->bits_per_sample);
+ }
+
+ if (s->packed)
+ {
+ /* Pack the code bits */
+ s->out_buffer |= (code << s->out_bits);
+ s->out_bits += s->bits_per_sample;
+ if (s->out_bits >= 8)
+ {
+ g722_data[g722_bytes++] = (uint8_t) (s->out_buffer & 0xFF);
+ s->out_bits -= 8;
+ s->out_buffer >>= 8;
+ }
+ }
+ else
+ {
+ g722_data[g722_bytes++] = (uint8_t) code;
+ }
+ }
+ return g722_bytes;
+}
+/*- End of function --------------------------------------------------------*/
+/*- End of file ------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/g722/g722_jni.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,80 @@
+/**
+
+g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options);
+int g722_encode_release(g722_encode_state_t *s);
+int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len);
+
+g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options);
+int g722_decode_release(g722_decode_state_t *s);
+int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len);
+
+*/
+
+#include <jni.h>
+#include "g722.h"
+
+jlong
+Java_org_sipdroid_media_codecs_G722JNI_encodeInit(JNIEnv *env, jlong jg722State, jint rate, jint options)
+{
+ return g722_encode_init((void *) jg722State, rate, options);
+}
+
+jint
+Java_org_sipdroid_media_codecs_G722JNI_encodeRelease(JNIEnv *env, jlong jg722State)
+{
+ return g722_encode_release((void *) jg722State);
+}
+
+jint
+Java_org_sipdroid_media_codecs_G722JNI_encode(JNIEnv *env, jlong jg722State, jshortArray jsignal, jlong jsrcPos, jbyteArray jg722Byte, jlong jdestPos, jint len)
+{
+ jshort *signal;
+ jbyte *g722Byte;
+ jboolean isCopyByte;
+ jboolean isCopySignal;
+ void *ctx = (void *) jg722State;
+ jint res;
+
+ g722Byte = (*env)->GetByteArrayElements(env, jg722Byte, &isCopyByte);
+ signal = (*env)->GetShortArrayElements(env, jsignal, &isCopySignal);
+
+ res = g722_encode(ctx, g722Byte + jdestPos, signal + jsrcPos, len);
+ if (isCopyByte == JNI_TRUE)
+ (*env)->ReleaseByteArrayElements(env, jg722Byte, g722Byte, 0);
+ if (isCopySignal == JNI_TRUE)
+ (*env)->ReleaseShortArrayElements(env, jsignal, signal, 0);
+ return res;
+}
+
+jlong
+Java_org_sipdroid_media_codecs_G722JNI_decodeInit(JNIEnv *env, jlong jg722State, jint rate, jint options)
+{
+ return g722_decode_init((void *) jg722State, rate, options);
+}
+
+jint
+Java_org_sipdroid_media_codecs_G722JNI_decodeRelease(JNIEnv *env, jlong jg722State)
+{
+ return g722_decode_release((void *) jg722State);
+}
+
+jint
+Java_org_sipdroid_media_codecs_G722JNI_decode(JNIEnv *env, jlong jg722State, jbyteArray jg722Byte, jlong jsrcPos, jshortArray jsignal, jlong jdestPos, jint len)
+{
+ jshort *signal;
+ jbyte *g722Byte;
+ jboolean isCopyByte;
+ jboolean isCopySignal;
+ void *ctx = (void *) jg722State;
+ jint res;
+
+ g722Byte = (*env)->GetByteArrayElements(env, jg722Byte, &isCopyByte);
+ signal = (*env)->GetShortArrayElements(env, jsignal, &isCopySignal);
+
+ res = g722_decode(ctx, signal + jdestPos, g722Byte + jsrcPos, len);
+ if (isCopyByte == JNI_TRUE)
+ (*env)->ReleaseByteArrayElements(env, jg722Byte, g722Byte, 0);
+ if (isCopySignal == JNI_TRUE)
+ (*env)->ReleaseShortArrayElements(env, jsignal, signal, 0);
+ return res;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/Android.mk Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,19 @@
+SRC_FILES := add.c\
+ code.c\
+ debug.c\
+ decode.c\
+ gsm_create.c\
+ gsm_decode.c\
+ gsm_destroy.c\
+ gsm_encode.c\
+ gsm_explode.c\
+ gsm_implode.c\
+ gsm_option.c\
+ gsm_print.c\
+ long_term.c\
+ lpc.c\
+ preprocess.c\
+ rpe.c\
+ short_term.c\
+ table.c\
+ gsm_jni.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/add.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,235 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/add.c,v 1.6 1996/07/02 09:57:33 jutta Exp $ */
+
+/*
+ * See private.h for the more commonly used macro versions.
+ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+#include "gsm.h"
+#include "proto.h"
+
+#define saturate(x) \
+ ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x))
+
+word gsm_add P2((a,b), word a, word b)
+{
+ longword sum = (longword)a + (longword)b;
+ return saturate(sum);
+}
+
+word gsm_sub P2((a,b), word a, word b)
+{
+ longword diff = (longword)a - (longword)b;
+ return saturate(diff);
+}
+
+word gsm_mult P2((a,b), word a, word b)
+{
+ if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD;
+ else return SASR( (longword)a * (longword)b, 15 );
+}
+
+word gsm_mult_r P2((a,b), word a, word b)
+{
+ if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD;
+ else {
+ longword prod = (longword)a * (longword)b + 16384;
+ prod >>= 15;
+ return prod & 0xFFFF;
+ }
+}
+
+word gsm_abs P1((a), word a)
+{
+ return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;
+}
+
+longword gsm_L_mult P2((a,b),word a, word b)
+{
+ assert( a != MIN_WORD || b != MIN_WORD );
+ return ((longword)a * (longword)b) << 1;
+}
+
+longword gsm_L_add P2((a,b), longword a, longword b)
+{
+ if (a < 0) {
+ if (b >= 0) return a + b;
+ else {
+ ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1);
+ return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2;
+ }
+ }
+ else if (b <= 0) return a + b;
+ else {
+ ulongword A = (ulongword)a + (ulongword)b;
+ return A > MAX_LONGWORD ? MAX_LONGWORD : A;
+ }
+}
+
+longword gsm_L_sub P2((a,b), longword a, longword b)
+{
+ if (a >= 0) {
+ if (b >= 0) return a - b;
+ else {
+ /* a>=0, b<0 */
+
+ ulongword A = (ulongword)a + -(b + 1);
+ return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1);
+ }
+ }
+ else if (b <= 0) return a - b;
+ else {
+ /* a<0, b>0 */
+
+ ulongword A = (ulongword)-(a + 1) + b;
+ return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1;
+ }
+}
+
+static unsigned char const bitoff[ 256 ] = {
+ 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+word gsm_norm P1((a), longword a )
+/*
+ * the number of left shifts needed to normalize the 32 bit
+ * variable L_var1 for positive values on the interval
+ *
+ * with minimum of
+ * minimum of 1073741824 (01000000000000000000000000000000) and
+ * maximum of 2147483647 (01111111111111111111111111111111)
+ *
+ *
+ * and for negative values on the interval with
+ * minimum of -2147483648 (-10000000000000000000000000000000) and
+ * maximum of -1073741824 ( -1000000000000000000000000000000).
+ *
+ * in order to normalize the result, the following
+ * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 );
+ *
+ * (That's 'ffs', only from the left, not the right..)
+ */
+{
+ assert(a != 0);
+
+ if (a < 0) {
+ if (a <= -1073741824) return 0;
+ a = ~a;
+ }
+
+ return a & 0xffff0000
+ ? ( a & 0xff000000
+ ? -1 + bitoff[ 0xFF & (a >> 24) ]
+ : 7 + bitoff[ 0xFF & (a >> 16) ] )
+ : ( a & 0xff00
+ ? 15 + bitoff[ 0xFF & (a >> 8) ]
+ : 23 + bitoff[ 0xFF & a ] );
+}
+
+longword gsm_L_asl P2((a,n), longword a, int n)
+{
+ if (n >= 32) return 0;
+ if (n <= -32) return -(a < 0);
+ if (n < 0) return gsm_L_asr(a, -n);
+ return a << n;
+}
+
+word gsm_asl P2((a,n), word a, int n)
+{
+ if (n >= 16) return 0;
+ if (n <= -16) return -(a < 0);
+ if (n < 0) return gsm_asr(a, -n);
+ return a << n;
+}
+
+longword gsm_L_asr P2((a,n), longword a, int n)
+{
+ if (n >= 32) return -(a < 0);
+ if (n <= -32) return 0;
+ if (n < 0) return a << -n;
+
+# ifdef SASR
+ return a >> n;
+# else
+ if (a >= 0) return a >> n;
+ else return -(longword)( -(ulongword)a >> n );
+# endif
+}
+
+word gsm_asr P2((a,n), word a, int n)
+{
+ if (n >= 16) return -(a < 0);
+ if (n <= -16) return 0;
+ if (n < 0) return a << -n;
+
+# ifdef SASR
+ return a >> n;
+# else
+ if (a >= 0) return a >> n;
+ else return -(word)( -(uword)a >> n );
+# endif
+}
+
+/*
+ * (From p. 46, end of section 4.2.5)
+ *
+ * NOTE: The following lines gives [sic] one correct implementation
+ * of the div(num, denum) arithmetic operation. Compute div
+ * which is the integer division of num by denum: with denum
+ * >= num > 0
+ */
+
+word gsm_div P2((num,denum), word num, word denum)
+{
+ longword L_num = num;
+ longword L_denum = denum;
+ word div = 0;
+ int k = 15;
+
+ /* The parameter num sometimes becomes zero.
+ * Although this is explicitly guarded against in 4.2.5,
+ * we assume that the result should then be zero as well.
+ */
+
+ /* assert(num != 0); */
+
+ assert(num >= 0 && denum >= num);
+ if (num == 0)
+ return 0;
+
+ while (k--) {
+ div <<= 1;
+ L_num <<= 1;
+
+ if (L_num >= L_denum) {
+ L_num -= L_denum;
+ div++;
+ }
+ }
+
+ return div;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/code.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,104 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/code.c,v 1.3 1996/07/02 09:59:05 jutta Exp $ */
+
+#include "config.h"
+
+#include <string.h>
+
+#ifdef HAS_STDLIB_H
+#include <stdlib.h>
+#else
+# include "proto.h"
+ extern char * memcpy P((char *, char *, int));
+#endif
+
+#include "private.h"
+#include "gsm.h"
+#include "proto.h"
+
+
+/*
+ * 4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER
+ */
+
+void Gsm_Coder P8((S,s,LARc,Nc,bc,Mc,xmaxc,xMc),
+
+ struct gsm_state * S,
+
+ word * s, /* [0..159] samples IN */
+
+/*
+ * The RPE-LTD coder works on a frame by frame basis. The length of
+ * the frame is equal to 160 samples. Some computations are done
+ * once per frame to produce at the output of the coder the
+ * LARc[1..8] parameters which are the coded LAR coefficients and
+ * also to realize the inverse filtering operation for the entire
+ * frame (160 samples of signal d[0..159]). These parts produce at
+ * the output of the coder:
+ */
+
+ word * LARc, /* [0..7] LAR coefficients OUT */
+
+/*
+ * Procedure 4.2.11 to 4.2.18 are to be executed four times per
+ * frame. That means once for each sub-segment RPE-LTP analysis of
+ * 40 samples. These parts produce at the output of the coder:
+ */
+
+ word * Nc, /* [0..3] LTP lag OUT */
+ word * bc, /* [0..3] coded LTP gain OUT */
+ word * Mc, /* [0..3] RPE grid selection OUT */
+ word * xmaxc,/* [0..3] Coded maximum amplitude OUT */
+ word * xMc /* [13*4] normalized RPE samples OUT */
+)
+{
+ int k;
+ word * dp = S->dp0 + 120; /* [ -120...-1 ] */
+ word * dpp = dp; /* [ 0...39 ] */
+
+ static word e[50];
+
+ word so[160];
+
+ Gsm_Preprocess (S, s, so);
+ Gsm_LPC_Analysis (S, so, LARc);
+ Gsm_Short_Term_Analysis_Filter (S, LARc, so);
+
+ for (k = 0; k <= 3; k++, xMc += 13) {
+
+ Gsm_Long_Term_Predictor ( S,
+ so+k*40, /* d [0..39] IN */
+ dp, /* dp [-120..-1] IN */
+ e + 5, /* e [0..39] OUT */
+ dpp, /* dpp [0..39] OUT */
+ Nc++,
+ bc++);
+
+ Gsm_RPE_Encoding ( S,
+ e + 5, /* e ][0..39][ IN/OUT */
+ xmaxc++, Mc++, xMc );
+ /*
+ * Gsm_Update_of_reconstructed_short_time_residual_signal
+ * ( dpp, e + 5, dp );
+ */
+
+ { register int i;
+ register longword ltmp;
+ for (i = 0; i <= 39; i++)
+ dp[ i ] = GSM_ADD( e[5 + i], dpp[i] );
+ }
+ dp += 40;
+ dpp += 40;
+
+ }
+
+ (void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160),
+ 120 * sizeof(*S->dp0) );
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/config.h Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/config.h,v 1.5 1996/07/02 11:26:20 jutta Exp $*/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+//efine SIGHANDLER_T int /* signal handlers are void */
+//efine HAS_SYSV_SIGNAL 1 /* sigs not blocked/reset? */
+
+#define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */
+//efine HAS_LIMITS_H 1 /* /usr/include/limits.h */
+#define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */
+//efine HAS_ERRNO_DECL 1 /* errno.h declares errno */
+
+#define HAS_FSTAT 1 /* fstat syscall */
+#define HAS_FCHMOD 1 /* fchmod syscall */
+#define HAS_CHMOD 1 /* chmod syscall */
+#define HAS_FCHOWN 1 /* fchown syscall */
+#define HAS_CHOWN 1 /* chown syscall */
+//efine HAS__FSETMODE 1 /* _fsetmode -- set file mode */
+
+#define HAS_STRING_H 1 /* /usr/include/string.h */
+//efine HAS_STRINGS_H 1 /* /usr/include/strings.h */
+
+#define HAS_UNISTD_H 1 /* /usr/include/unistd.h */
+#define HAS_UTIME 1 /* POSIX utime(path, times) */
+//efine HAS_UTIMES 1 /* use utimes() syscall instead */
+#define HAS_UTIME_H 1 /* UTIME header file */
+//efine HAS_UTIMBUF 1 /* struct utimbuf */
+//efine HAS_UTIMEUSEC 1 /* microseconds in utimbuf? */
+
+#endif /* CONFIG_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/debug.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/debug.c,v 1.2 1993/01/29 18:22:20 jutta Exp $ */
+
+#include "private.h"
+
+#ifndef NDEBUG
+
+/* If NDEBUG _is_ defined and no debugging should be performed,
+ * calls to functions in this module are #defined to nothing
+ * in private.h.
+ */
+
+#include <stdio.h>
+#include "proto.h"
+
+void gsm_debug_words P4( (name, from, to, ptr),
+ char * name,
+ int from,
+ int to,
+ word * ptr)
+{
+ int nprinted = 0;
+
+ fprintf( stderr, "%s [%d .. %d]: ", name, from, to );
+ while (from <= to) {
+ fprintf(stderr, "%d ", ptr[ from ] );
+ from++;
+ if (nprinted++ >= 7) {
+ nprinted = 0;
+ if (from < to) putc('\n', stderr);
+ }
+ }
+ putc('\n', stderr);
+}
+
+void gsm_debug_longwords P4( (name, from, to, ptr),
+ char * name,
+ int from,
+ int to,
+ longword * ptr)
+{
+ int nprinted = 0;
+
+ fprintf( stderr, "%s [%d .. %d]: ", name, from, to );
+ while (from <= to) {
+
+ fprintf(stderr, "%ld ", ptr[ from ] );
+ from++;
+ if (nprinted++ >= 7) {
+ nprinted = 0;
+ if (from < to) putc('\n', stderr);
+ }
+ }
+ putc('\n', stderr);
+}
+
+void gsm_debug_longword P2( (name, value),
+ char * name,
+ longword value )
+{
+ fprintf(stderr, "%s: %ld\n", name, (long)value );
+}
+
+void gsm_debug_word P2( (name, value),
+ char * name,
+ word value )
+{
+ fprintf(stderr, "%s: %ld\n", name, (long)value);
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/decode.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/decode.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */
+
+#include <stdio.h>
+
+#include "private.h"
+#include "gsm.h"
+#include "proto.h"
+
+/*
+ * 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER
+ */
+
+static void Postprocessing P2((S,s),
+ struct gsm_state * S,
+ register word * s)
+{
+ register int k;
+ register word msr = S->msr;
+ register longword ltmp; /* for GSM_ADD */
+ register word tmp;
+
+ for (k = 160; k--; s++) {
+ tmp = GSM_MULT_R( msr, 28180 );
+ msr = GSM_ADD(*s, tmp); /* Deemphasis */
+ *s = GSM_ADD(msr, msr) & 0xFFF8; /* Truncation & Upscaling */
+ }
+ S->msr = msr;
+}
+
+void Gsm_Decoder P8((S,LARcr, Ncr,bcr,Mcr,xmaxcr,xMcr,s),
+ struct gsm_state * S,
+
+ word * LARcr, /* [0..7] IN */
+
+ word * Ncr, /* [0..3] IN */
+ word * bcr, /* [0..3] IN */
+ word * Mcr, /* [0..3] IN */
+ word * xmaxcr, /* [0..3] IN */
+ word * xMcr, /* [0..13*4] IN */
+
+ word * s) /* [0..159] OUT */
+{
+ int j, k;
+ word erp[40], wt[160];
+ word * drp = S->dp0 + 120;
+
+ for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) {
+
+ Gsm_RPE_Decoding( S, *xmaxcr, *Mcr, xMcr, erp );
+ Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp );
+
+ for (k = 0; k <= 39; k++) wt[ j * 40 + k ] = drp[ k ];
+ }
+
+ Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s );
+ Postprocessing(S, s);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/gsm.h Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/*$Header: /home/kbs/jutta/src/gsm/gsm-1.0/inc/RCS/gsm.h,v 1.11 1996/07/05 18:02:56 jutta Exp $*/
+
+#ifndef GSM_H
+#define GSM_H
+
+#ifdef __cplusplus
+# define NeedFunctionPrototypes 1
+#endif
+
+#if __STDC__
+# define NeedFunctionPrototypes 1
+#endif
+
+#ifdef _NO_PROTO
+# undef NeedFunctionPrototypes
+#endif
+
+#ifdef NeedFunctionPrototypes
+# include <stdio.h> /* for FILE * */
+#endif
+
+#undef GSM_P
+#if NeedFunctionPrototypes
+# define GSM_P( protos ) protos
+#else
+# define GSM_P( protos ) ( /* protos */ )
+#endif
+
+/*
+ * Interface
+ */
+
+typedef struct gsm_state * gsm;
+typedef short gsm_signal; /* signed 16 bit */
+typedef unsigned char gsm_byte;
+typedef gsm_byte gsm_frame[33]; /* 33 * 8 bits */
+
+#define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */
+
+#define GSM_PATCHLEVEL 10
+#define GSM_MINOR 0
+#define GSM_MAJOR 1
+
+#define GSM_OPT_VERBOSE 1
+#define GSM_OPT_FAST 2
+#define GSM_OPT_LTP_CUT 3
+#define GSM_OPT_WAV49 4
+#define GSM_OPT_FRAME_INDEX 5
+#define GSM_OPT_FRAME_CHAIN 6
+
+extern gsm gsm_create GSM_P((void));
+extern void gsm_destroy GSM_P((gsm));
+
+extern int gsm_print GSM_P((FILE *, gsm, gsm_byte *));
+extern int gsm_option GSM_P((gsm, int, int *));
+
+extern void gsm_encode GSM_P((gsm, gsm_signal *, gsm_byte *));
+extern int gsm_decode GSM_P((gsm, gsm_byte *, gsm_signal *));
+
+extern int gsm_explode GSM_P((gsm, gsm_byte *, gsm_signal *));
+extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte *));
+
+#undef GSM_P
+
+#endif /* GSM_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/gsm_create.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+static char const ident[] = "$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_create.c,v 1.4 1996/07/02 09:59:05 jutta Exp $";
+
+#include "config.h"
+
+#ifdef HAS_STRING_H
+#include <string.h>
+#else
+# include "proto.h"
+ extern char * memset P((char *, int, int));
+#endif
+
+#ifdef HAS_STDLIB_H
+# include <stdlib.h>
+#else
+# ifdef HAS_MALLOC_H
+# include <malloc.h>
+# else
+ extern char * malloc();
+# endif
+#endif
+
+#include <stdio.h>
+
+#include "gsm.h"
+#include "private.h"
+#include "proto.h"
+
+gsm gsm_create P0()
+{
+ gsm r;
+
+ r = (gsm)malloc(sizeof(struct gsm_state));
+ if (!r) return r;
+
+ memset((char *)r, 0, sizeof(*r));
+ r->nrp = 40;
+
+ return r;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/gsm_decode.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,361 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_decode.c,v 1.2 1996/07/02 09:59:05 jutta Exp $ */
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_decode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target)
+{
+ word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
+
+#ifdef WAV49
+ if (s->wav_fmt) {
+
+ uword sr = 0;
+
+ s->frame_index = !s->frame_index;
+ if (s->frame_index) {
+
+ sr = *c++;
+ LARc[0] = sr & 0x3f; sr >>= 6;
+ sr |= (uword)*c++ << 2;
+ LARc[1] = sr & 0x3f; sr >>= 6;
+ sr |= (uword)*c++ << 4;
+ LARc[2] = sr & 0x1f; sr >>= 5;
+ LARc[3] = sr & 0x1f; sr >>= 5;
+ sr |= (uword)*c++ << 2;
+ LARc[4] = sr & 0xf; sr >>= 4;
+ LARc[5] = sr & 0xf; sr >>= 4;
+ sr |= (uword)*c++ << 2; /* 5 */
+ LARc[6] = sr & 0x7; sr >>= 3;
+ LARc[7] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 4;
+ Nc[0] = sr & 0x7f; sr >>= 7;
+ bc[0] = sr & 0x3; sr >>= 2;
+ Mc[0] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 1;
+ xmaxc[0] = sr & 0x3f; sr >>= 6;
+ xmc[0] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[1] = sr & 0x7; sr >>= 3;
+ xmc[2] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[3] = sr & 0x7; sr >>= 3;
+ xmc[4] = sr & 0x7; sr >>= 3;
+ xmc[5] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1; /* 10 */
+ xmc[6] = sr & 0x7; sr >>= 3;
+ xmc[7] = sr & 0x7; sr >>= 3;
+ xmc[8] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[9] = sr & 0x7; sr >>= 3;
+ xmc[10] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[11] = sr & 0x7; sr >>= 3;
+ xmc[12] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 4;
+ Nc[1] = sr & 0x7f; sr >>= 7;
+ bc[1] = sr & 0x3; sr >>= 2;
+ Mc[1] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 1;
+ xmaxc[1] = sr & 0x3f; sr >>= 6;
+ xmc[13] = sr & 0x7; sr >>= 3;
+ sr = *c++; /* 15 */
+ xmc[14] = sr & 0x7; sr >>= 3;
+ xmc[15] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[16] = sr & 0x7; sr >>= 3;
+ xmc[17] = sr & 0x7; sr >>= 3;
+ xmc[18] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[19] = sr & 0x7; sr >>= 3;
+ xmc[20] = sr & 0x7; sr >>= 3;
+ xmc[21] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[22] = sr & 0x7; sr >>= 3;
+ xmc[23] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[24] = sr & 0x7; sr >>= 3;
+ xmc[25] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 4; /* 20 */
+ Nc[2] = sr & 0x7f; sr >>= 7;
+ bc[2] = sr & 0x3; sr >>= 2;
+ Mc[2] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 1;
+ xmaxc[2] = sr & 0x3f; sr >>= 6;
+ xmc[26] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[27] = sr & 0x7; sr >>= 3;
+ xmc[28] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[29] = sr & 0x7; sr >>= 3;
+ xmc[30] = sr & 0x7; sr >>= 3;
+ xmc[31] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[32] = sr & 0x7; sr >>= 3;
+ xmc[33] = sr & 0x7; sr >>= 3;
+ xmc[34] = sr & 0x7; sr >>= 3;
+ sr = *c++; /* 25 */
+ xmc[35] = sr & 0x7; sr >>= 3;
+ xmc[36] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[37] = sr & 0x7; sr >>= 3;
+ xmc[38] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 4;
+ Nc[3] = sr & 0x7f; sr >>= 7;
+ bc[3] = sr & 0x3; sr >>= 2;
+ Mc[3] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 1;
+ xmaxc[3] = sr & 0x3f; sr >>= 6;
+ xmc[39] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[40] = sr & 0x7; sr >>= 3;
+ xmc[41] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2; /* 30 */
+ xmc[42] = sr & 0x7; sr >>= 3;
+ xmc[43] = sr & 0x7; sr >>= 3;
+ xmc[44] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[45] = sr & 0x7; sr >>= 3;
+ xmc[46] = sr & 0x7; sr >>= 3;
+ xmc[47] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[48] = sr & 0x7; sr >>= 3;
+ xmc[49] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[50] = sr & 0x7; sr >>= 3;
+ xmc[51] = sr & 0x7; sr >>= 3;
+
+ s->frame_chain = sr & 0xf;
+ }
+ else {
+ sr = s->frame_chain;
+ sr |= (uword)*c++ << 4; /* 1 */
+ LARc[0] = sr & 0x3f; sr >>= 6;
+ LARc[1] = sr & 0x3f; sr >>= 6;
+ sr = *c++;
+ LARc[2] = sr & 0x1f; sr >>= 5;
+ sr |= (uword)*c++ << 3;
+ LARc[3] = sr & 0x1f; sr >>= 5;
+ LARc[4] = sr & 0xf; sr >>= 4;
+ sr |= (uword)*c++ << 2;
+ LARc[5] = sr & 0xf; sr >>= 4;
+ LARc[6] = sr & 0x7; sr >>= 3;
+ LARc[7] = sr & 0x7; sr >>= 3;
+ sr = *c++; /* 5 */
+ Nc[0] = sr & 0x7f; sr >>= 7;
+ sr |= (uword)*c++ << 1;
+ bc[0] = sr & 0x3; sr >>= 2;
+ Mc[0] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 5;
+ xmaxc[0] = sr & 0x3f; sr >>= 6;
+ xmc[0] = sr & 0x7; sr >>= 3;
+ xmc[1] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[2] = sr & 0x7; sr >>= 3;
+ xmc[3] = sr & 0x7; sr >>= 3;
+ xmc[4] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[5] = sr & 0x7; sr >>= 3;
+ xmc[6] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2; /* 10 */
+ xmc[7] = sr & 0x7; sr >>= 3;
+ xmc[8] = sr & 0x7; sr >>= 3;
+ xmc[9] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[10] = sr & 0x7; sr >>= 3;
+ xmc[11] = sr & 0x7; sr >>= 3;
+ xmc[12] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ Nc[1] = sr & 0x7f; sr >>= 7;
+ sr |= (uword)*c++ << 1;
+ bc[1] = sr & 0x3; sr >>= 2;
+ Mc[1] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 5;
+ xmaxc[1] = sr & 0x3f; sr >>= 6;
+ xmc[13] = sr & 0x7; sr >>= 3;
+ xmc[14] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1; /* 15 */
+ xmc[15] = sr & 0x7; sr >>= 3;
+ xmc[16] = sr & 0x7; sr >>= 3;
+ xmc[17] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[18] = sr & 0x7; sr >>= 3;
+ xmc[19] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[20] = sr & 0x7; sr >>= 3;
+ xmc[21] = sr & 0x7; sr >>= 3;
+ xmc[22] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[23] = sr & 0x7; sr >>= 3;
+ xmc[24] = sr & 0x7; sr >>= 3;
+ xmc[25] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ Nc[2] = sr & 0x7f; sr >>= 7;
+ sr |= (uword)*c++ << 1; /* 20 */
+ bc[2] = sr & 0x3; sr >>= 2;
+ Mc[2] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 5;
+ xmaxc[2] = sr & 0x3f; sr >>= 6;
+ xmc[26] = sr & 0x7; sr >>= 3;
+ xmc[27] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[28] = sr & 0x7; sr >>= 3;
+ xmc[29] = sr & 0x7; sr >>= 3;
+ xmc[30] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[31] = sr & 0x7; sr >>= 3;
+ xmc[32] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[33] = sr & 0x7; sr >>= 3;
+ xmc[34] = sr & 0x7; sr >>= 3;
+ xmc[35] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1; /* 25 */
+ xmc[36] = sr & 0x7; sr >>= 3;
+ xmc[37] = sr & 0x7; sr >>= 3;
+ xmc[38] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ Nc[3] = sr & 0x7f; sr >>= 7;
+ sr |= (uword)*c++ << 1;
+ bc[3] = sr & 0x3; sr >>= 2;
+ Mc[3] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 5;
+ xmaxc[3] = sr & 0x3f; sr >>= 6;
+ xmc[39] = sr & 0x7; sr >>= 3;
+ xmc[40] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[41] = sr & 0x7; sr >>= 3;
+ xmc[42] = sr & 0x7; sr >>= 3;
+ xmc[43] = sr & 0x7; sr >>= 3;
+ sr = *c++; /* 30 */
+ xmc[44] = sr & 0x7; sr >>= 3;
+ xmc[45] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[46] = sr & 0x7; sr >>= 3;
+ xmc[47] = sr & 0x7; sr >>= 3;
+ xmc[48] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[49] = sr & 0x7; sr >>= 3;
+ xmc[50] = sr & 0x7; sr >>= 3;
+ xmc[51] = sr & 0x7; sr >>= 3;
+ }
+ }
+ else
+#endif
+ {
+ /* GSM_MAGIC = (*c >> 4) & 0xF; */
+
+ if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
+
+ LARc[0] = (*c++ & 0xF) << 2; /* 1 */
+ LARc[0] |= (*c >> 6) & 0x3;
+ LARc[1] = *c++ & 0x3F;
+ LARc[2] = (*c >> 3) & 0x1F;
+ LARc[3] = (*c++ & 0x7) << 2;
+ LARc[3] |= (*c >> 6) & 0x3;
+ LARc[4] = (*c >> 2) & 0xF;
+ LARc[5] = (*c++ & 0x3) << 2;
+ LARc[5] |= (*c >> 6) & 0x3;
+ LARc[6] = (*c >> 3) & 0x7;
+ LARc[7] = *c++ & 0x7;
+ Nc[0] = (*c >> 1) & 0x7F;
+ bc[0] = (*c++ & 0x1) << 1;
+ bc[0] |= (*c >> 7) & 0x1;
+ Mc[0] = (*c >> 5) & 0x3;
+ xmaxc[0] = (*c++ & 0x1F) << 1;
+ xmaxc[0] |= (*c >> 7) & 0x1;
+ xmc[0] = (*c >> 4) & 0x7;
+ xmc[1] = (*c >> 1) & 0x7;
+ xmc[2] = (*c++ & 0x1) << 2;
+ xmc[2] |= (*c >> 6) & 0x3;
+ xmc[3] = (*c >> 3) & 0x7;
+ xmc[4] = *c++ & 0x7;
+ xmc[5] = (*c >> 5) & 0x7;
+ xmc[6] = (*c >> 2) & 0x7;
+ xmc[7] = (*c++ & 0x3) << 1; /* 10 */
+ xmc[7] |= (*c >> 7) & 0x1;
+ xmc[8] = (*c >> 4) & 0x7;
+ xmc[9] = (*c >> 1) & 0x7;
+ xmc[10] = (*c++ & 0x1) << 2;
+ xmc[10] |= (*c >> 6) & 0x3;
+ xmc[11] = (*c >> 3) & 0x7;
+ xmc[12] = *c++ & 0x7;
+ Nc[1] = (*c >> 1) & 0x7F;
+ bc[1] = (*c++ & 0x1) << 1;
+ bc[1] |= (*c >> 7) & 0x1;
+ Mc[1] = (*c >> 5) & 0x3;
+ xmaxc[1] = (*c++ & 0x1F) << 1;
+ xmaxc[1] |= (*c >> 7) & 0x1;
+ xmc[13] = (*c >> 4) & 0x7;
+ xmc[14] = (*c >> 1) & 0x7;
+ xmc[15] = (*c++ & 0x1) << 2;
+ xmc[15] |= (*c >> 6) & 0x3;
+ xmc[16] = (*c >> 3) & 0x7;
+ xmc[17] = *c++ & 0x7;
+ xmc[18] = (*c >> 5) & 0x7;
+ xmc[19] = (*c >> 2) & 0x7;
+ xmc[20] = (*c++ & 0x3) << 1;
+ xmc[20] |= (*c >> 7) & 0x1;
+ xmc[21] = (*c >> 4) & 0x7;
+ xmc[22] = (*c >> 1) & 0x7;
+ xmc[23] = (*c++ & 0x1) << 2;
+ xmc[23] |= (*c >> 6) & 0x3;
+ xmc[24] = (*c >> 3) & 0x7;
+ xmc[25] = *c++ & 0x7;
+ Nc[2] = (*c >> 1) & 0x7F;
+ bc[2] = (*c++ & 0x1) << 1; /* 20 */
+ bc[2] |= (*c >> 7) & 0x1;
+ Mc[2] = (*c >> 5) & 0x3;
+ xmaxc[2] = (*c++ & 0x1F) << 1;
+ xmaxc[2] |= (*c >> 7) & 0x1;
+ xmc[26] = (*c >> 4) & 0x7;
+ xmc[27] = (*c >> 1) & 0x7;
+ xmc[28] = (*c++ & 0x1) << 2;
+ xmc[28] |= (*c >> 6) & 0x3;
+ xmc[29] = (*c >> 3) & 0x7;
+ xmc[30] = *c++ & 0x7;
+ xmc[31] = (*c >> 5) & 0x7;
+ xmc[32] = (*c >> 2) & 0x7;
+ xmc[33] = (*c++ & 0x3) << 1;
+ xmc[33] |= (*c >> 7) & 0x1;
+ xmc[34] = (*c >> 4) & 0x7;
+ xmc[35] = (*c >> 1) & 0x7;
+ xmc[36] = (*c++ & 0x1) << 2;
+ xmc[36] |= (*c >> 6) & 0x3;
+ xmc[37] = (*c >> 3) & 0x7;
+ xmc[38] = *c++ & 0x7;
+ Nc[3] = (*c >> 1) & 0x7F;
+ bc[3] = (*c++ & 0x1) << 1;
+ bc[3] |= (*c >> 7) & 0x1;
+ Mc[3] = (*c >> 5) & 0x3;
+ xmaxc[3] = (*c++ & 0x1F) << 1;
+ xmaxc[3] |= (*c >> 7) & 0x1;
+ xmc[39] = (*c >> 4) & 0x7;
+ xmc[40] = (*c >> 1) & 0x7;
+ xmc[41] = (*c++ & 0x1) << 2;
+ xmc[41] |= (*c >> 6) & 0x3;
+ xmc[42] = (*c >> 3) & 0x7;
+ xmc[43] = *c++ & 0x7; /* 30 */
+ xmc[44] = (*c >> 5) & 0x7;
+ xmc[45] = (*c >> 2) & 0x7;
+ xmc[46] = (*c++ & 0x3) << 1;
+ xmc[46] |= (*c >> 7) & 0x1;
+ xmc[47] = (*c >> 4) & 0x7;
+ xmc[48] = (*c >> 1) & 0x7;
+ xmc[49] = (*c++ & 0x1) << 2;
+ xmc[49] |= (*c >> 6) & 0x3;
+ xmc[50] = (*c >> 3) & 0x7;
+ xmc[51] = *c & 0x7; /* 33 */
+ }
+
+ Gsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target);
+
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/gsm_destroy.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_destroy.c,v 1.3 1994/11/28 19:52:25 jutta Exp $ */
+
+#include "gsm.h"
+#include "config.h"
+#include "proto.h"
+
+#ifdef HAS_STDLIB_H
+# include <stdlib.h>
+#else
+# ifdef HAS_MALLOC_H
+# include <malloc.h>
+# else
+ extern void free();
+# endif
+#endif
+
+void gsm_destroy P1((S), gsm S)
+{
+ if (S) free((char *)S);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/gsm_encode.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,451 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_encode.c,v 1.2 1996/07/02 09:59:05 jutta Exp $ */
+
+#include "private.h"
+#include "gsm.h"
+#include "proto.h"
+
+void gsm_encode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c)
+{
+ word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
+
+ Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc);
+
+
+ /* variable size
+
+ GSM_MAGIC 4
+
+ LARc[0] 6
+ LARc[1] 6
+ LARc[2] 5
+ LARc[3] 5
+ LARc[4] 4
+ LARc[5] 4
+ LARc[6] 3
+ LARc[7] 3
+
+ Nc[0] 7
+ bc[0] 2
+ Mc[0] 2
+ xmaxc[0] 6
+ xmc[0] 3
+ xmc[1] 3
+ xmc[2] 3
+ xmc[3] 3
+ xmc[4] 3
+ xmc[5] 3
+ xmc[6] 3
+ xmc[7] 3
+ xmc[8] 3
+ xmc[9] 3
+ xmc[10] 3
+ xmc[11] 3
+ xmc[12] 3
+
+ Nc[1] 7
+ bc[1] 2
+ Mc[1] 2
+ xmaxc[1] 6
+ xmc[13] 3
+ xmc[14] 3
+ xmc[15] 3
+ xmc[16] 3
+ xmc[17] 3
+ xmc[18] 3
+ xmc[19] 3
+ xmc[20] 3
+ xmc[21] 3
+ xmc[22] 3
+ xmc[23] 3
+ xmc[24] 3
+ xmc[25] 3
+
+ Nc[2] 7
+ bc[2] 2
+ Mc[2] 2
+ xmaxc[2] 6
+ xmc[26] 3
+ xmc[27] 3
+ xmc[28] 3
+ xmc[29] 3
+ xmc[30] 3
+ xmc[31] 3
+ xmc[32] 3
+ xmc[33] 3
+ xmc[34] 3
+ xmc[35] 3
+ xmc[36] 3
+ xmc[37] 3
+ xmc[38] 3
+
+ Nc[3] 7
+ bc[3] 2
+ Mc[3] 2
+ xmaxc[3] 6
+ xmc[39] 3
+ xmc[40] 3
+ xmc[41] 3
+ xmc[42] 3
+ xmc[43] 3
+ xmc[44] 3
+ xmc[45] 3
+ xmc[46] 3
+ xmc[47] 3
+ xmc[48] 3
+ xmc[49] 3
+ xmc[50] 3
+ xmc[51] 3
+ */
+
+#ifdef WAV49
+
+ if (s->wav_fmt) {
+ s->frame_index = !s->frame_index;
+ if (s->frame_index) {
+
+ uword sr;
+
+ sr = 0;
+ sr = sr >> 6 | LARc[0] << 10;
+ sr = sr >> 6 | LARc[1] << 10;
+ *c++ = sr >> 4;
+ sr = sr >> 5 | LARc[2] << 11;
+ *c++ = sr >> 7;
+ sr = sr >> 5 | LARc[3] << 11;
+ sr = sr >> 4 | LARc[4] << 12;
+ *c++ = sr >> 6;
+ sr = sr >> 4 | LARc[5] << 12;
+ sr = sr >> 3 | LARc[6] << 13;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | LARc[7] << 13;
+ sr = sr >> 7 | Nc[0] << 9;
+ *c++ = sr >> 5;
+ sr = sr >> 2 | bc[0] << 14;
+ sr = sr >> 2 | Mc[0] << 14;
+ sr = sr >> 6 | xmaxc[0] << 10;
+ *c++ = sr >> 3;
+ sr = sr >> 3 | xmc[0] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 3 | xmc[1] << 13;
+ sr = sr >> 3 | xmc[2] << 13;
+ sr = sr >> 3 | xmc[3] << 13;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[4] << 13;
+ sr = sr >> 3 | xmc[5] << 13;
+ sr = sr >> 3 | xmc[6] << 13;
+ *c++ = sr >> 6;
+ sr = sr >> 3 | xmc[7] << 13;
+ sr = sr >> 3 | xmc[8] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 3 | xmc[9] << 13;
+ sr = sr >> 3 | xmc[10] << 13;
+ sr = sr >> 3 | xmc[11] << 13;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[12] << 13;
+ sr = sr >> 7 | Nc[1] << 9;
+ *c++ = sr >> 5;
+ sr = sr >> 2 | bc[1] << 14;
+ sr = sr >> 2 | Mc[1] << 14;
+ sr = sr >> 6 | xmaxc[1] << 10;
+ *c++ = sr >> 3;
+ sr = sr >> 3 | xmc[13] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 3 | xmc[14] << 13;
+ sr = sr >> 3 | xmc[15] << 13;
+ sr = sr >> 3 | xmc[16] << 13;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[17] << 13;
+ sr = sr >> 3 | xmc[18] << 13;
+ sr = sr >> 3 | xmc[19] << 13;
+ *c++ = sr >> 6;
+ sr = sr >> 3 | xmc[20] << 13;
+ sr = sr >> 3 | xmc[21] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 3 | xmc[22] << 13;
+ sr = sr >> 3 | xmc[23] << 13;
+ sr = sr >> 3 | xmc[24] << 13;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[25] << 13;
+ sr = sr >> 7 | Nc[2] << 9;
+ *c++ = sr >> 5;
+ sr = sr >> 2 | bc[2] << 14;
+ sr = sr >> 2 | Mc[2] << 14;
+ sr = sr >> 6 | xmaxc[2] << 10;
+ *c++ = sr >> 3;
+ sr = sr >> 3 | xmc[26] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 3 | xmc[27] << 13;
+ sr = sr >> 3 | xmc[28] << 13;
+ sr = sr >> 3 | xmc[29] << 13;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[30] << 13;
+ sr = sr >> 3 | xmc[31] << 13;
+ sr = sr >> 3 | xmc[32] << 13;
+ *c++ = sr >> 6;
+ sr = sr >> 3 | xmc[33] << 13;
+ sr = sr >> 3 | xmc[34] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 3 | xmc[35] << 13;
+ sr = sr >> 3 | xmc[36] << 13;
+ sr = sr >> 3 | xmc[37] << 13;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[38] << 13;
+ sr = sr >> 7 | Nc[3] << 9;
+ *c++ = sr >> 5;
+ sr = sr >> 2 | bc[3] << 14;
+ sr = sr >> 2 | Mc[3] << 14;
+ sr = sr >> 6 | xmaxc[3] << 10;
+ *c++ = sr >> 3;
+ sr = sr >> 3 | xmc[39] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 3 | xmc[40] << 13;
+ sr = sr >> 3 | xmc[41] << 13;
+ sr = sr >> 3 | xmc[42] << 13;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[43] << 13;
+ sr = sr >> 3 | xmc[44] << 13;
+ sr = sr >> 3 | xmc[45] << 13;
+ *c++ = sr >> 6;
+ sr = sr >> 3 | xmc[46] << 13;
+ sr = sr >> 3 | xmc[47] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 3 | xmc[48] << 13;
+ sr = sr >> 3 | xmc[49] << 13;
+ sr = sr >> 3 | xmc[50] << 13;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[51] << 13;
+ sr = sr >> 4;
+ *c = sr >> 8;
+ s->frame_chain = *c;
+ }
+ else {
+ uword sr;
+
+ sr = 0;
+ sr = sr >> 4 | s->frame_chain << 12;
+ sr = sr >> 6 | LARc[0] << 10;
+ *c++ = sr >> 6;
+ sr = sr >> 6 | LARc[1] << 10;
+ *c++ = sr >> 8;
+ sr = sr >> 5 | LARc[2] << 11;
+ sr = sr >> 5 | LARc[3] << 11;
+ *c++ = sr >> 6;
+ sr = sr >> 4 | LARc[4] << 12;
+ sr = sr >> 4 | LARc[5] << 12;
+ *c++ = sr >> 6;
+ sr = sr >> 3 | LARc[6] << 13;
+ sr = sr >> 3 | LARc[7] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 7 | Nc[0] << 9;
+ sr = sr >> 2 | bc[0] << 14;
+ *c++ = sr >> 7;
+ sr = sr >> 2 | Mc[0] << 14;
+ sr = sr >> 6 | xmaxc[0] << 10;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[0] << 13;
+ sr = sr >> 3 | xmc[1] << 13;
+ sr = sr >> 3 | xmc[2] << 13;
+ *c++ = sr >> 6;
+ sr = sr >> 3 | xmc[3] << 13;
+ sr = sr >> 3 | xmc[4] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 3 | xmc[5] << 13;
+ sr = sr >> 3 | xmc[6] << 13;
+ sr = sr >> 3 | xmc[7] << 13;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[8] << 13;
+ sr = sr >> 3 | xmc[9] << 13;
+ sr = sr >> 3 | xmc[10] << 13;
+ *c++ = sr >> 6;
+ sr = sr >> 3 | xmc[11] << 13;
+ sr = sr >> 3 | xmc[12] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 7 | Nc[1] << 9;
+ sr = sr >> 2 | bc[1] << 14;
+ *c++ = sr >> 7;
+ sr = sr >> 2 | Mc[1] << 14;
+ sr = sr >> 6 | xmaxc[1] << 10;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[13] << 13;
+ sr = sr >> 3 | xmc[14] << 13;
+ sr = sr >> 3 | xmc[15] << 13;
+ *c++ = sr >> 6;
+ sr = sr >> 3 | xmc[16] << 13;
+ sr = sr >> 3 | xmc[17] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 3 | xmc[18] << 13;
+ sr = sr >> 3 | xmc[19] << 13;
+ sr = sr >> 3 | xmc[20] << 13;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[21] << 13;
+ sr = sr >> 3 | xmc[22] << 13;
+ sr = sr >> 3 | xmc[23] << 13;
+ *c++ = sr >> 6;
+ sr = sr >> 3 | xmc[24] << 13;
+ sr = sr >> 3 | xmc[25] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 7 | Nc[2] << 9;
+ sr = sr >> 2 | bc[2] << 14;
+ *c++ = sr >> 7;
+ sr = sr >> 2 | Mc[2] << 14;
+ sr = sr >> 6 | xmaxc[2] << 10;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[26] << 13;
+ sr = sr >> 3 | xmc[27] << 13;
+ sr = sr >> 3 | xmc[28] << 13;
+ *c++ = sr >> 6;
+ sr = sr >> 3 | xmc[29] << 13;
+ sr = sr >> 3 | xmc[30] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 3 | xmc[31] << 13;
+ sr = sr >> 3 | xmc[32] << 13;
+ sr = sr >> 3 | xmc[33] << 13;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[34] << 13;
+ sr = sr >> 3 | xmc[35] << 13;
+ sr = sr >> 3 | xmc[36] << 13;
+ *c++ = sr >> 6;
+ sr = sr >> 3 | xmc[37] << 13;
+ sr = sr >> 3 | xmc[38] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 7 | Nc[3] << 9;
+ sr = sr >> 2 | bc[3] << 14;
+ *c++ = sr >> 7;
+ sr = sr >> 2 | Mc[3] << 14;
+ sr = sr >> 6 | xmaxc[3] << 10;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[39] << 13;
+ sr = sr >> 3 | xmc[40] << 13;
+ sr = sr >> 3 | xmc[41] << 13;
+ *c++ = sr >> 6;
+ sr = sr >> 3 | xmc[42] << 13;
+ sr = sr >> 3 | xmc[43] << 13;
+ *c++ = sr >> 8;
+ sr = sr >> 3 | xmc[44] << 13;
+ sr = sr >> 3 | xmc[45] << 13;
+ sr = sr >> 3 | xmc[46] << 13;
+ *c++ = sr >> 7;
+ sr = sr >> 3 | xmc[47] << 13;
+ sr = sr >> 3 | xmc[48] << 13;
+ sr = sr >> 3 | xmc[49] << 13;
+ *c++ = sr >> 6;
+ sr = sr >> 3 | xmc[50] << 13;
+ sr = sr >> 3 | xmc[51] << 13;
+ *c++ = sr >> 8;
+ }
+ }
+
+ else
+
+#endif /* WAV49 */
+ {
+
+ *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */
+ | ((LARc[0] >> 2) & 0xF);
+ *c++ = ((LARc[0] & 0x3) << 6)
+ | (LARc[1] & 0x3F);
+ *c++ = ((LARc[2] & 0x1F) << 3)
+ | ((LARc[3] >> 2) & 0x7);
+ *c++ = ((LARc[3] & 0x3) << 6)
+ | ((LARc[4] & 0xF) << 2)
+ | ((LARc[5] >> 2) & 0x3);
+ *c++ = ((LARc[5] & 0x3) << 6)
+ | ((LARc[6] & 0x7) << 3)
+ | (LARc[7] & 0x7);
+ *c++ = ((Nc[0] & 0x7F) << 1)
+ | ((bc[0] >> 1) & 0x1);
+ *c++ = ((bc[0] & 0x1) << 7)
+ | ((Mc[0] & 0x3) << 5)
+ | ((xmaxc[0] >> 1) & 0x1F);
+ *c++ = ((xmaxc[0] & 0x1) << 7)
+ | ((xmc[0] & 0x7) << 4)
+ | ((xmc[1] & 0x7) << 1)
+ | ((xmc[2] >> 2) & 0x1);
+ *c++ = ((xmc[2] & 0x3) << 6)
+ | ((xmc[3] & 0x7) << 3)
+ | (xmc[4] & 0x7);
+ *c++ = ((xmc[5] & 0x7) << 5) /* 10 */
+ | ((xmc[6] & 0x7) << 2)
+ | ((xmc[7] >> 1) & 0x3);
+ *c++ = ((xmc[7] & 0x1) << 7)
+ | ((xmc[8] & 0x7) << 4)
+ | ((xmc[9] & 0x7) << 1)
+ | ((xmc[10] >> 2) & 0x1);
+ *c++ = ((xmc[10] & 0x3) << 6)
+ | ((xmc[11] & 0x7) << 3)
+ | (xmc[12] & 0x7);
+ *c++ = ((Nc[1] & 0x7F) << 1)
+ | ((bc[1] >> 1) & 0x1);
+ *c++ = ((bc[1] & 0x1) << 7)
+ | ((Mc[1] & 0x3) << 5)
+ | ((xmaxc[1] >> 1) & 0x1F);
+ *c++ = ((xmaxc[1] & 0x1) << 7)
+ | ((xmc[13] & 0x7) << 4)
+ | ((xmc[14] & 0x7) << 1)
+ | ((xmc[15] >> 2) & 0x1);
+ *c++ = ((xmc[15] & 0x3) << 6)
+ | ((xmc[16] & 0x7) << 3)
+ | (xmc[17] & 0x7);
+ *c++ = ((xmc[18] & 0x7) << 5)
+ | ((xmc[19] & 0x7) << 2)
+ | ((xmc[20] >> 1) & 0x3);
+ *c++ = ((xmc[20] & 0x1) << 7)
+ | ((xmc[21] & 0x7) << 4)
+ | ((xmc[22] & 0x7) << 1)
+ | ((xmc[23] >> 2) & 0x1);
+ *c++ = ((xmc[23] & 0x3) << 6)
+ | ((xmc[24] & 0x7) << 3)
+ | (xmc[25] & 0x7);
+ *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */
+ | ((bc[2] >> 1) & 0x1);
+ *c++ = ((bc[2] & 0x1) << 7)
+ | ((Mc[2] & 0x3) << 5)
+ | ((xmaxc[2] >> 1) & 0x1F);
+ *c++ = ((xmaxc[2] & 0x1) << 7)
+ | ((xmc[26] & 0x7) << 4)
+ | ((xmc[27] & 0x7) << 1)
+ | ((xmc[28] >> 2) & 0x1);
+ *c++ = ((xmc[28] & 0x3) << 6)
+ | ((xmc[29] & 0x7) << 3)
+ | (xmc[30] & 0x7);
+ *c++ = ((xmc[31] & 0x7) << 5)
+ | ((xmc[32] & 0x7) << 2)
+ | ((xmc[33] >> 1) & 0x3);
+ *c++ = ((xmc[33] & 0x1) << 7)
+ | ((xmc[34] & 0x7) << 4)
+ | ((xmc[35] & 0x7) << 1)
+ | ((xmc[36] >> 2) & 0x1);
+ *c++ = ((xmc[36] & 0x3) << 6)
+ | ((xmc[37] & 0x7) << 3)
+ | (xmc[38] & 0x7);
+ *c++ = ((Nc[3] & 0x7F) << 1)
+ | ((bc[3] >> 1) & 0x1);
+ *c++ = ((bc[3] & 0x1) << 7)
+ | ((Mc[3] & 0x3) << 5)
+ | ((xmaxc[3] >> 1) & 0x1F);
+ *c++ = ((xmaxc[3] & 0x1) << 7)
+ | ((xmc[39] & 0x7) << 4)
+ | ((xmc[40] & 0x7) << 1)
+ | ((xmc[41] >> 2) & 0x1);
+ *c++ = ((xmc[41] & 0x3) << 6) /* 30 */
+ | ((xmc[42] & 0x7) << 3)
+ | (xmc[43] & 0x7);
+ *c++ = ((xmc[44] & 0x7) << 5)
+ | ((xmc[45] & 0x7) << 2)
+ | ((xmc[46] >> 1) & 0x3);
+ *c++ = ((xmc[46] & 0x1) << 7)
+ | ((xmc[47] & 0x7) << 4)
+ | ((xmc[48] & 0x7) << 1)
+ | ((xmc[49] >> 2) & 0x1);
+ *c++ = ((xmc[49] & 0x3) << 6)
+ | ((xmc[50] & 0x7) << 3)
+ | (xmc[51] & 0x7);
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/gsm_explode.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,419 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_explode.c,v 1.2 1996/07/02 14:32:42 jutta Exp jutta $ */
+
+#include "private.h"
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_explode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target)
+{
+# define LARc target
+# define Nc *((gsm_signal (*) [17])(target + 8))
+# define bc *((gsm_signal (*) [17])(target + 9))
+# define Mc *((gsm_signal (*) [17])(target + 10))
+# define xmaxc *((gsm_signal (*) [17])(target + 11))
+
+// Wirlab
+ (void)s;
+
+#ifdef WAV49
+ if (s->wav_fmt) {
+
+ uword sr = 0;
+
+ if (s->frame_index == 1) {
+
+ sr = *c++;
+ LARc[0] = sr & 0x3f; sr >>= 6;
+ sr |= (uword)*c++ << 2;
+ LARc[1] = sr & 0x3f; sr >>= 6;
+ sr |= (uword)*c++ << 4;
+ LARc[2] = sr & 0x1f; sr >>= 5;
+ LARc[3] = sr & 0x1f; sr >>= 5;
+ sr |= (uword)*c++ << 2;
+ LARc[4] = sr & 0xf; sr >>= 4;
+ LARc[5] = sr & 0xf; sr >>= 4;
+ sr |= (uword)*c++ << 2; /* 5 */
+ LARc[6] = sr & 0x7; sr >>= 3;
+ LARc[7] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 4;
+ Nc[0] = sr & 0x7f; sr >>= 7;
+ bc[0] = sr & 0x3; sr >>= 2;
+ Mc[0] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 1;
+ xmaxc[0] = sr & 0x3f; sr >>= 6;
+#undef xmc
+#define xmc (target + 12)
+ xmc[0] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[1] = sr & 0x7; sr >>= 3;
+ xmc[2] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[3] = sr & 0x7; sr >>= 3;
+ xmc[4] = sr & 0x7; sr >>= 3;
+ xmc[5] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1; /* 10 */
+ xmc[6] = sr & 0x7; sr >>= 3;
+ xmc[7] = sr & 0x7; sr >>= 3;
+ xmc[8] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[9] = sr & 0x7; sr >>= 3;
+ xmc[10] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[11] = sr & 0x7; sr >>= 3;
+ xmc[12] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 4;
+ Nc[1] = sr & 0x7f; sr >>= 7;
+ bc[1] = sr & 0x3; sr >>= 2;
+ Mc[1] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 1;
+ xmaxc[1] = sr & 0x3f; sr >>= 6;
+#undef xmc
+#define xmc (target + 29 - 13)
+
+ xmc[13] = sr & 0x7; sr >>= 3;
+ sr = *c++; /* 15 */
+ xmc[14] = sr & 0x7; sr >>= 3;
+ xmc[15] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[16] = sr & 0x7; sr >>= 3;
+ xmc[17] = sr & 0x7; sr >>= 3;
+ xmc[18] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[19] = sr & 0x7; sr >>= 3;
+ xmc[20] = sr & 0x7; sr >>= 3;
+ xmc[21] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[22] = sr & 0x7; sr >>= 3;
+ xmc[23] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[24] = sr & 0x7; sr >>= 3;
+ xmc[25] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 4; /* 20 */
+ Nc[2] = sr & 0x7f; sr >>= 7;
+ bc[2] = sr & 0x3; sr >>= 2;
+ Mc[2] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 1;
+ xmaxc[2] = sr & 0x3f; sr >>= 6;
+
+#undef xmc
+#define xmc (target + 46 - 26)
+
+ xmc[26] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[27] = sr & 0x7; sr >>= 3;
+ xmc[28] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[29] = sr & 0x7; sr >>= 3;
+ xmc[30] = sr & 0x7; sr >>= 3;
+ xmc[31] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[32] = sr & 0x7; sr >>= 3;
+ xmc[33] = sr & 0x7; sr >>= 3;
+ xmc[34] = sr & 0x7; sr >>= 3;
+ sr = *c++; /* 25 */
+ xmc[35] = sr & 0x7; sr >>= 3;
+ xmc[36] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[37] = sr & 0x7; sr >>= 3;
+ xmc[38] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 4;
+ Nc[3] = sr & 0x7f; sr >>= 7;
+ bc[3] = sr & 0x3; sr >>= 2;
+ Mc[3] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 1;
+ xmaxc[3] = sr & 0x3f; sr >>= 6;
+#undef xmc
+#define xmc (target + 63 - 39)
+
+ xmc[39] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[40] = sr & 0x7; sr >>= 3;
+ xmc[41] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2; /* 30 */
+ xmc[42] = sr & 0x7; sr >>= 3;
+ xmc[43] = sr & 0x7; sr >>= 3;
+ xmc[44] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[45] = sr & 0x7; sr >>= 3;
+ xmc[46] = sr & 0x7; sr >>= 3;
+ xmc[47] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[48] = sr & 0x7; sr >>= 3;
+ xmc[49] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[50] = sr & 0x7; sr >>= 3;
+ xmc[51] = sr & 0x7; sr >>= 3;
+
+ s->frame_chain = sr & 0xf;
+ }
+ else {
+ sr = s->frame_chain;
+ sr |= (uword)*c++ << 4; /* 1 */
+ LARc[0] = sr & 0x3f; sr >>= 6;
+ LARc[1] = sr & 0x3f; sr >>= 6;
+ sr = *c++;
+ LARc[2] = sr & 0x1f; sr >>= 5;
+ sr |= (uword)*c++ << 3;
+ LARc[3] = sr & 0x1f; sr >>= 5;
+ LARc[4] = sr & 0xf; sr >>= 4;
+ sr |= (uword)*c++ << 2;
+ LARc[5] = sr & 0xf; sr >>= 4;
+ LARc[6] = sr & 0x7; sr >>= 3;
+ LARc[7] = sr & 0x7; sr >>= 3;
+ sr = *c++; /* 5 */
+ Nc[0] = sr & 0x7f; sr >>= 7;
+ sr |= (uword)*c++ << 1;
+ bc[0] = sr & 0x3; sr >>= 2;
+ Mc[0] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 5;
+ xmaxc[0] = sr & 0x3f; sr >>= 6;
+#undef xmc
+#define xmc (target + 12)
+ xmc[0] = sr & 0x7; sr >>= 3;
+ xmc[1] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[2] = sr & 0x7; sr >>= 3;
+ xmc[3] = sr & 0x7; sr >>= 3;
+ xmc[4] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[5] = sr & 0x7; sr >>= 3;
+ xmc[6] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2; /* 10 */
+ xmc[7] = sr & 0x7; sr >>= 3;
+ xmc[8] = sr & 0x7; sr >>= 3;
+ xmc[9] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[10] = sr & 0x7; sr >>= 3;
+ xmc[11] = sr & 0x7; sr >>= 3;
+ xmc[12] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ Nc[1] = sr & 0x7f; sr >>= 7;
+ sr |= (uword)*c++ << 1;
+ bc[1] = sr & 0x3; sr >>= 2;
+ Mc[1] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 5;
+ xmaxc[1] = sr & 0x3f; sr >>= 6;
+#undef xmc
+#define xmc (target + 29 - 13)
+
+ xmc[13] = sr & 0x7; sr >>= 3;
+ xmc[14] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1; /* 15 */
+ xmc[15] = sr & 0x7; sr >>= 3;
+ xmc[16] = sr & 0x7; sr >>= 3;
+ xmc[17] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[18] = sr & 0x7; sr >>= 3;
+ xmc[19] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[20] = sr & 0x7; sr >>= 3;
+ xmc[21] = sr & 0x7; sr >>= 3;
+ xmc[22] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[23] = sr & 0x7; sr >>= 3;
+ xmc[24] = sr & 0x7; sr >>= 3;
+ xmc[25] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ Nc[2] = sr & 0x7f; sr >>= 7;
+ sr |= (uword)*c++ << 1; /* 20 */
+ bc[2] = sr & 0x3; sr >>= 2;
+ Mc[2] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 5;
+ xmaxc[2] = sr & 0x3f; sr >>= 6;
+#undef xmc
+#define xmc (target + 46 - 26)
+ xmc[26] = sr & 0x7; sr >>= 3;
+ xmc[27] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[28] = sr & 0x7; sr >>= 3;
+ xmc[29] = sr & 0x7; sr >>= 3;
+ xmc[30] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[31] = sr & 0x7; sr >>= 3;
+ xmc[32] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[33] = sr & 0x7; sr >>= 3;
+ xmc[34] = sr & 0x7; sr >>= 3;
+ xmc[35] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1; /* 25 */
+ xmc[36] = sr & 0x7; sr >>= 3;
+ xmc[37] = sr & 0x7; sr >>= 3;
+ xmc[38] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ Nc[3] = sr & 0x7f; sr >>= 7;
+ sr |= (uword)*c++ << 1;
+ bc[3] = sr & 0x3; sr >>= 2;
+ Mc[3] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 5;
+ xmaxc[3] = sr & 0x3f; sr >>= 6;
+
+#undef xmc
+#define xmc (target + 63 - 39)
+
+ xmc[39] = sr & 0x7; sr >>= 3;
+ xmc[40] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[41] = sr & 0x7; sr >>= 3;
+ xmc[42] = sr & 0x7; sr >>= 3;
+ xmc[43] = sr & 0x7; sr >>= 3;
+ sr = *c++; /* 30 */
+ xmc[44] = sr & 0x7; sr >>= 3;
+ xmc[45] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[46] = sr & 0x7; sr >>= 3;
+ xmc[47] = sr & 0x7; sr >>= 3;
+ xmc[48] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[49] = sr & 0x7; sr >>= 3;
+ xmc[50] = sr & 0x7; sr >>= 3;
+ xmc[51] = sr & 0x7; sr >>= 3;
+ }
+ }
+ else
+#endif
+ {
+ /* GSM_MAGIC = (*c >> 4) & 0xF; */
+
+ if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
+
+ LARc[0] = (*c++ & 0xF) << 2; /* 1 */
+ LARc[0] |= (*c >> 6) & 0x3;
+ LARc[1] = *c++ & 0x3F;
+ LARc[2] = (*c >> 3) & 0x1F;
+ LARc[3] = (*c++ & 0x7) << 2;
+ LARc[3] |= (*c >> 6) & 0x3;
+ LARc[4] = (*c >> 2) & 0xF;
+ LARc[5] = (*c++ & 0x3) << 2;
+ LARc[5] |= (*c >> 6) & 0x3;
+ LARc[6] = (*c >> 3) & 0x7;
+ LARc[7] = *c++ & 0x7;
+
+ Nc[0] = (*c >> 1) & 0x7F;
+
+ bc[0] = (*c++ & 0x1) << 1;
+ bc[0] |= (*c >> 7) & 0x1;
+
+ Mc[0] = (*c >> 5) & 0x3;
+
+ xmaxc[0] = (*c++ & 0x1F) << 1;
+ xmaxc[0] |= (*c >> 7) & 0x1;
+
+#undef xmc
+#define xmc (target + 12)
+
+ xmc[0] = (*c >> 4) & 0x7;
+ xmc[1] = (*c >> 1) & 0x7;
+ xmc[2] = (*c++ & 0x1) << 2;
+ xmc[2] |= (*c >> 6) & 0x3;
+ xmc[3] = (*c >> 3) & 0x7;
+ xmc[4] = *c++ & 0x7;
+ xmc[5] = (*c >> 5) & 0x7;
+ xmc[6] = (*c >> 2) & 0x7;
+ xmc[7] = (*c++ & 0x3) << 1; /* 10 */
+ xmc[7] |= (*c >> 7) & 0x1;
+ xmc[8] = (*c >> 4) & 0x7;
+ xmc[9] = (*c >> 1) & 0x7;
+ xmc[10] = (*c++ & 0x1) << 2;
+ xmc[10] |= (*c >> 6) & 0x3;
+ xmc[11] = (*c >> 3) & 0x7;
+ xmc[12] = *c++ & 0x7;
+
+ Nc[1] = (*c >> 1) & 0x7F;
+
+ bc[1] = (*c++ & 0x1) << 1;
+ bc[1] |= (*c >> 7) & 0x1;
+
+ Mc[1] = (*c >> 5) & 0x3;
+
+ xmaxc[1] = (*c++ & 0x1F) << 1;
+ xmaxc[1] |= (*c >> 7) & 0x1;
+
+#undef xmc
+#define xmc (target + 29 - 13)
+
+ xmc[13] = (*c >> 4) & 0x7;
+ xmc[14] = (*c >> 1) & 0x7;
+ xmc[15] = (*c++ & 0x1) << 2;
+ xmc[15] |= (*c >> 6) & 0x3;
+ xmc[16] = (*c >> 3) & 0x7;
+ xmc[17] = *c++ & 0x7;
+ xmc[18] = (*c >> 5) & 0x7;
+ xmc[19] = (*c >> 2) & 0x7;
+ xmc[20] = (*c++ & 0x3) << 1;
+ xmc[20] |= (*c >> 7) & 0x1;
+ xmc[21] = (*c >> 4) & 0x7;
+ xmc[22] = (*c >> 1) & 0x7;
+ xmc[23] = (*c++ & 0x1) << 2;
+ xmc[23] |= (*c >> 6) & 0x3;
+ xmc[24] = (*c >> 3) & 0x7;
+ xmc[25] = *c++ & 0x7;
+
+ Nc[2] = (*c >> 1) & 0x7F;
+
+ bc[2] = (*c++ & 0x1) << 1; /* 20 */
+ bc[2] |= (*c >> 7) & 0x1;
+
+ Mc[2] = (*c >> 5) & 0x3;
+
+ xmaxc[2] = (*c++ & 0x1F) << 1;
+ xmaxc[2] |= (*c >> 7) & 0x1;
+
+#undef xmc
+#define xmc (target + 46 - 26)
+
+ xmc[26] = (*c >> 4) & 0x7;
+ xmc[27] = (*c >> 1) & 0x7;
+ xmc[28] = (*c++ & 0x1) << 2;
+ xmc[28] |= (*c >> 6) & 0x3;
+ xmc[29] = (*c >> 3) & 0x7;
+ xmc[30] = *c++ & 0x7;
+ xmc[31] = (*c >> 5) & 0x7;
+ xmc[32] = (*c >> 2) & 0x7;
+ xmc[33] = (*c++ & 0x3) << 1;
+ xmc[33] |= (*c >> 7) & 0x1;
+ xmc[34] = (*c >> 4) & 0x7;
+ xmc[35] = (*c >> 1) & 0x7;
+ xmc[36] = (*c++ & 0x1) << 2;
+ xmc[36] |= (*c >> 6) & 0x3;
+ xmc[37] = (*c >> 3) & 0x7;
+ xmc[38] = *c++ & 0x7;
+
+ Nc[3] = (*c >> 1) & 0x7F;
+
+ bc[3] = (*c++ & 0x1) << 1;
+ bc[3] |= (*c >> 7) & 0x1;
+
+ Mc[3] = (*c >> 5) & 0x3;
+
+ xmaxc[3] = (*c++ & 0x1F) << 1;
+ xmaxc[3] |= (*c >> 7) & 0x1;
+
+#undef xmc
+#define xmc (target + 63 - 39)
+
+ xmc[39] = (*c >> 4) & 0x7;
+ xmc[40] = (*c >> 1) & 0x7;
+ xmc[41] = (*c++ & 0x1) << 2;
+ xmc[41] |= (*c >> 6) & 0x3;
+ xmc[42] = (*c >> 3) & 0x7;
+ xmc[43] = *c++ & 0x7; /* 30 */
+ xmc[44] = (*c >> 5) & 0x7;
+ xmc[45] = (*c >> 2) & 0x7;
+ xmc[46] = (*c++ & 0x3) << 1;
+ xmc[46] |= (*c >> 7) & 0x1;
+ xmc[47] = (*c >> 4) & 0x7;
+ xmc[48] = (*c >> 1) & 0x7;
+ xmc[49] = (*c++ & 0x1) << 2;
+ xmc[49] |= (*c >> 6) & 0x3;
+ xmc[50] = (*c >> 3) & 0x7;
+ xmc[51] = *c & 0x7; /* 33 */
+ }
+
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/gsm_implode.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,518 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_implode.c,v 1.2 1996/07/02 14:32:43 jutta Exp jutta $ */
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+void gsm_implode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c)
+{
+ /* variable size index
+
+ GSM_MAGIC 4 -
+
+ LARc[0] 6 0
+ LARc[1] 6 1
+ LARc[2] 5 2
+ LARc[3] 5 3
+ LARc[4] 4 4
+ LARc[5] 4 5
+ LARc[6] 3 6
+ LARc[7] 3 7
+
+ Nc[0] 7 8
+ bc[0] 2 9
+ Mc[0] 2 10
+ xmaxc[0] 6 11
+ xmc[0] 3 12
+ xmc[1] 3 13
+ xmc[2] 3 14
+ xmc[3] 3 15
+ xmc[4] 3 16
+ xmc[5] 3 17
+ xmc[6] 3 18
+ xmc[7] 3 19
+ xmc[8] 3 20
+ xmc[9] 3 21
+ xmc[10] 3 22
+ xmc[11] 3 23
+ xmc[12] 3 24
+
+ Nc[1] 7 25
+ bc[1] 2 26
+ Mc[1] 2 27
+ xmaxc[1] 6 28
+ xmc[13] 3 29
+ xmc[14] 3 30
+ xmc[15] 3 31
+ xmc[16] 3 32
+ xmc[17] 3 33
+ xmc[18] 3 34
+ xmc[19] 3 35
+ xmc[20] 3 36
+ xmc[21] 3 37
+ xmc[22] 3 38
+ xmc[23] 3 39
+ xmc[24] 3 40
+ xmc[25] 3 41
+
+ Nc[2] 7 42
+ bc[2] 2 43
+ Mc[2] 2 44
+ xmaxc[2] 6 45
+ xmc[26] 3 46
+ xmc[27] 3 47
+ xmc[28] 3 48
+ xmc[29] 3 49
+ xmc[30] 3 50
+ xmc[31] 3 51
+ xmc[32] 3 52
+ xmc[33] 3 53
+ xmc[34] 3 54
+ xmc[35] 3 55
+ xmc[36] 3 56
+ xmc[37] 3 57
+ xmc[38] 3 58
+
+ Nc[3] 7 59
+ bc[3] 2 60
+ Mc[3] 2 61
+ xmaxc[3] 6 62
+ xmc[39] 3 63
+ xmc[40] 3 64
+ xmc[41] 3 65
+ xmc[42] 3 66
+ xmc[43] 3 67
+ xmc[44] 3 68
+ xmc[45] 3 69
+ xmc[46] 3 70
+ xmc[47] 3 71
+ xmc[48] 3 72
+ xmc[49] 3 73
+ xmc[50] 3 74
+ xmc[51] 3 75
+ */
+
+ /* There are 76 parameters per frame. The first eight are
+ * unique. The remaining 68 are four identical subframes of
+ * 17 parameters each. gsm_implode converts from a representation
+ * of these parameters as values in one array of signed words
+ * to the "packed" version of a GSM frame.
+ */
+
+# define LARc source
+# define Nc *((gsm_signal (*) [17])(source + 8))
+# define bc *((gsm_signal (*) [17])(source + 9))
+# define Mc *((gsm_signal (*) [17])(source + 10))
+# define xmaxc *((gsm_signal (*) [17])(source + 11))
+
+// Wirlab
+ (void)s;
+
+#ifdef WAV49
+ if (s->wav_fmt) {
+
+ uword sr = 0;
+ if (s->frame_index == 0) {
+
+ sr = *c++;
+ LARc[0] = sr & 0x3f; sr >>= 6;
+ sr |= (uword)*c++ << 2;
+ LARc[1] = sr & 0x3f; sr >>= 6;
+ sr |= (uword)*c++ << 4;
+ LARc[2] = sr & 0x1f; sr >>= 5;
+ LARc[3] = sr & 0x1f; sr >>= 5;
+ sr |= (uword)*c++ << 2;
+ LARc[4] = sr & 0xf; sr >>= 4;
+ LARc[5] = sr & 0xf; sr >>= 4;
+ sr |= (uword)*c++ << 2; /* 5 */
+ LARc[6] = sr & 0x7; sr >>= 3;
+ LARc[7] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 4;
+ Nc[0] = sr & 0x7f; sr >>= 7;
+ bc[0] = sr & 0x3; sr >>= 2;
+ Mc[0] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 1;
+ xmaxc[0] = sr & 0x3f; sr >>= 6;
+#undef xmc
+#define xmc (source + 12)
+ xmc[0] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[1] = sr & 0x7; sr >>= 3;
+ xmc[2] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[3] = sr & 0x7; sr >>= 3;
+ xmc[4] = sr & 0x7; sr >>= 3;
+ xmc[5] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1; /* 10 */
+ xmc[6] = sr & 0x7; sr >>= 3;
+ xmc[7] = sr & 0x7; sr >>= 3;
+ xmc[8] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[9] = sr & 0x7; sr >>= 3;
+ xmc[10] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[11] = sr & 0x7; sr >>= 3;
+ xmc[12] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 4;
+ Nc[1] = sr & 0x7f; sr >>= 7;
+ bc[1] = sr & 0x3; sr >>= 2;
+ Mc[1] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 1;
+ xmaxc[1] = sr & 0x3f; sr >>= 6;
+#undef xmc
+#define xmc (source + 29 - 13)
+ xmc[13] = sr & 0x7; sr >>= 3;
+ sr = *c++; /* 15 */
+ xmc[14] = sr & 0x7; sr >>= 3;
+ xmc[15] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[16] = sr & 0x7; sr >>= 3;
+ xmc[17] = sr & 0x7; sr >>= 3;
+ xmc[18] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[19] = sr & 0x7; sr >>= 3;
+ xmc[20] = sr & 0x7; sr >>= 3;
+ xmc[21] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[22] = sr & 0x7; sr >>= 3;
+ xmc[23] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[24] = sr & 0x7; sr >>= 3;
+ xmc[25] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 4; /* 20 */
+ Nc[2] = sr & 0x7f; sr >>= 7;
+ bc[2] = sr & 0x3; sr >>= 2;
+ Mc[2] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 1;
+ xmaxc[2] = sr & 0x3f; sr >>= 6;
+#undef xmc
+#define xmc (source + 46 - 26)
+ xmc[26] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[27] = sr & 0x7; sr >>= 3;
+ xmc[28] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[29] = sr & 0x7; sr >>= 3;
+ xmc[30] = sr & 0x7; sr >>= 3;
+ xmc[31] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[32] = sr & 0x7; sr >>= 3;
+ xmc[33] = sr & 0x7; sr >>= 3;
+ xmc[34] = sr & 0x7; sr >>= 3;
+ sr = *c++; /* 25 */
+ xmc[35] = sr & 0x7; sr >>= 3;
+ xmc[36] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[37] = sr & 0x7; sr >>= 3;
+ xmc[38] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 4;
+ Nc[3] = sr & 0x7f; sr >>= 7;
+ bc[3] = sr & 0x3; sr >>= 2;
+ Mc[3] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 1;
+ xmaxc[3] = sr & 0x3f; sr >>= 6;
+#undef xmc
+#define xmc (source + 63 - 39)
+
+ xmc[39] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[40] = sr & 0x7; sr >>= 3;
+ xmc[41] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2; /* 30 */
+ xmc[42] = sr & 0x7; sr >>= 3;
+ xmc[43] = sr & 0x7; sr >>= 3;
+ xmc[44] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[45] = sr & 0x7; sr >>= 3;
+ xmc[46] = sr & 0x7; sr >>= 3;
+ xmc[47] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[48] = sr & 0x7; sr >>= 3;
+ xmc[49] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[50] = sr & 0x7; sr >>= 3;
+ xmc[51] = sr & 0x7; sr >>= 3;
+
+ s->frame_chain = sr & 0xf;
+ }
+ else {
+ sr = s->frame_chain;
+ sr |= (uword)*c++ << 4; /* 1 */
+ LARc[0] = sr & 0x3f; sr >>= 6;
+ LARc[1] = sr & 0x3f; sr >>= 6;
+ sr = *c++;
+ LARc[2] = sr & 0x1f; sr >>= 5;
+ sr |= (uword)*c++ << 3;
+ LARc[3] = sr & 0x1f; sr >>= 5;
+ LARc[4] = sr & 0xf; sr >>= 4;
+ sr |= (uword)*c++ << 2;
+ LARc[5] = sr & 0xf; sr >>= 4;
+ LARc[6] = sr & 0x7; sr >>= 3;
+ LARc[7] = sr & 0x7; sr >>= 3;
+ sr = *c++; /* 5 */
+ Nc[0] = sr & 0x7f; sr >>= 7;
+ sr |= (uword)*c++ << 1;
+ bc[0] = sr & 0x3; sr >>= 2;
+ Mc[0] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 5;
+ xmaxc[0] = sr & 0x3f; sr >>= 6;
+#undef xmc
+#define xmc (source + 12)
+ xmc[0] = sr & 0x7; sr >>= 3;
+ xmc[1] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[2] = sr & 0x7; sr >>= 3;
+ xmc[3] = sr & 0x7; sr >>= 3;
+ xmc[4] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[5] = sr & 0x7; sr >>= 3;
+ xmc[6] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2; /* 10 */
+ xmc[7] = sr & 0x7; sr >>= 3;
+ xmc[8] = sr & 0x7; sr >>= 3;
+ xmc[9] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[10] = sr & 0x7; sr >>= 3;
+ xmc[11] = sr & 0x7; sr >>= 3;
+ xmc[12] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ Nc[1] = sr & 0x7f; sr >>= 7;
+ sr |= (uword)*c++ << 1;
+ bc[1] = sr & 0x3; sr >>= 2;
+ Mc[1] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 5;
+ xmaxc[1] = sr & 0x3f; sr >>= 6;
+#undef xmc
+#define xmc (source + 29 - 13)
+ xmc[13] = sr & 0x7; sr >>= 3;
+ xmc[14] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1; /* 15 */
+ xmc[15] = sr & 0x7; sr >>= 3;
+ xmc[16] = sr & 0x7; sr >>= 3;
+ xmc[17] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[18] = sr & 0x7; sr >>= 3;
+ xmc[19] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[20] = sr & 0x7; sr >>= 3;
+ xmc[21] = sr & 0x7; sr >>= 3;
+ xmc[22] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[23] = sr & 0x7; sr >>= 3;
+ xmc[24] = sr & 0x7; sr >>= 3;
+ xmc[25] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ Nc[2] = sr & 0x7f; sr >>= 7;
+ sr |= (uword)*c++ << 1; /* 20 */
+ bc[2] = sr & 0x3; sr >>= 2;
+ Mc[2] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 5;
+ xmaxc[2] = sr & 0x3f; sr >>= 6;
+#undef xmc
+#define xmc (source + 46 - 26)
+ xmc[26] = sr & 0x7; sr >>= 3;
+ xmc[27] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[28] = sr & 0x7; sr >>= 3;
+ xmc[29] = sr & 0x7; sr >>= 3;
+ xmc[30] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ xmc[31] = sr & 0x7; sr >>= 3;
+ xmc[32] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[33] = sr & 0x7; sr >>= 3;
+ xmc[34] = sr & 0x7; sr >>= 3;
+ xmc[35] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1; /* 25 */
+ xmc[36] = sr & 0x7; sr >>= 3;
+ xmc[37] = sr & 0x7; sr >>= 3;
+ xmc[38] = sr & 0x7; sr >>= 3;
+ sr = *c++;
+ Nc[3] = sr & 0x7f; sr >>= 7;
+ sr |= (uword)*c++ << 1;
+ bc[3] = sr & 0x3; sr >>= 2;
+ Mc[3] = sr & 0x3; sr >>= 2;
+ sr |= (uword)*c++ << 5;
+ xmaxc[3] = sr & 0x3f; sr >>= 6;
+#undef xmc
+#define xmc (source + 63 - 39)
+
+ xmc[39] = sr & 0x7; sr >>= 3;
+ xmc[40] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[41] = sr & 0x7; sr >>= 3;
+ xmc[42] = sr & 0x7; sr >>= 3;
+ xmc[43] = sr & 0x7; sr >>= 3;
+ sr = *c++; /* 30 */
+ xmc[44] = sr & 0x7; sr >>= 3;
+ xmc[45] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 2;
+ xmc[46] = sr & 0x7; sr >>= 3;
+ xmc[47] = sr & 0x7; sr >>= 3;
+ xmc[48] = sr & 0x7; sr >>= 3;
+ sr |= (uword)*c++ << 1;
+ xmc[49] = sr & 0x7; sr >>= 3;
+ xmc[50] = sr & 0x7; sr >>= 3;
+ xmc[51] = sr & 0x7; sr >>= 3;
+ }
+ }
+ else
+#endif
+ {
+
+ *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */
+ | ((LARc[0] >> 2) & 0xF);
+ *c++ = ((LARc[0] & 0x3) << 6)
+ | (LARc[1] & 0x3F);
+ *c++ = ((LARc[2] & 0x1F) << 3)
+ | ((LARc[3] >> 2) & 0x7);
+ *c++ = ((LARc[3] & 0x3) << 6)
+ | ((LARc[4] & 0xF) << 2)
+ | ((LARc[5] >> 2) & 0x3);
+ *c++ = ((LARc[5] & 0x3) << 6)
+ | ((LARc[6] & 0x7) << 3)
+ | (LARc[7] & 0x7);
+
+
+ *c++ = ((Nc[0] & 0x7F) << 1)
+
+
+ | ((bc[0] >> 1) & 0x1);
+ *c++ = ((bc[0] & 0x1) << 7)
+
+
+ | ((Mc[0] & 0x3) << 5)
+
+ | ((xmaxc[0] >> 1) & 0x1F);
+ *c++ = ((xmaxc[0] & 0x1) << 7)
+
+#undef xmc
+#define xmc (source + 12)
+
+ | ((xmc[0] & 0x7) << 4)
+ | ((xmc[1] & 0x7) << 1)
+ | ((xmc[2] >> 2) & 0x1);
+ *c++ = ((xmc[2] & 0x3) << 6)
+ | ((xmc[3] & 0x7) << 3)
+ | (xmc[4] & 0x7);
+ *c++ = ((xmc[5] & 0x7) << 5) /* 10 */
+ | ((xmc[6] & 0x7) << 2)
+ | ((xmc[7] >> 1) & 0x3);
+ *c++ = ((xmc[7] & 0x1) << 7)
+ | ((xmc[8] & 0x7) << 4)
+ | ((xmc[9] & 0x7) << 1)
+ | ((xmc[10] >> 2) & 0x1);
+ *c++ = ((xmc[10] & 0x3) << 6)
+ | ((xmc[11] & 0x7) << 3)
+ | (xmc[12] & 0x7);
+
+
+ *c++ = ((Nc[1] & 0x7F) << 1)
+
+
+ | ((bc[1] >> 1) & 0x1);
+ *c++ = ((bc[1] & 0x1) << 7)
+
+
+ | ((Mc[1] & 0x3) << 5)
+
+
+ | ((xmaxc[1] >> 1) & 0x1F);
+ *c++ = ((xmaxc[1] & 0x1) << 7)
+
+#undef xmc
+#define xmc (source + 29 - 13)
+
+ | ((xmc[13] & 0x7) << 4)
+ | ((xmc[14] & 0x7) << 1)
+ | ((xmc[15] >> 2) & 0x1);
+ *c++ = ((xmc[15] & 0x3) << 6)
+ | ((xmc[16] & 0x7) << 3)
+ | (xmc[17] & 0x7);
+ *c++ = ((xmc[18] & 0x7) << 5)
+ | ((xmc[19] & 0x7) << 2)
+ | ((xmc[20] >> 1) & 0x3);
+ *c++ = ((xmc[20] & 0x1) << 7)
+ | ((xmc[21] & 0x7) << 4)
+ | ((xmc[22] & 0x7) << 1)
+ | ((xmc[23] >> 2) & 0x1);
+ *c++ = ((xmc[23] & 0x3) << 6)
+ | ((xmc[24] & 0x7) << 3)
+ | (xmc[25] & 0x7);
+
+
+ *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */
+
+
+ | ((bc[2] >> 1) & 0x1);
+ *c++ = ((bc[2] & 0x1) << 7)
+
+
+ | ((Mc[2] & 0x3) << 5)
+
+
+ | ((xmaxc[2] >> 1) & 0x1F);
+ *c++ = ((xmaxc[2] & 0x1) << 7)
+
+#undef xmc
+#define xmc (source + 46 - 26)
+
+ | ((xmc[26] & 0x7) << 4)
+ | ((xmc[27] & 0x7) << 1)
+ | ((xmc[28] >> 2) & 0x1);
+ *c++ = ((xmc[28] & 0x3) << 6)
+ | ((xmc[29] & 0x7) << 3)
+ | (xmc[30] & 0x7);
+ *c++ = ((xmc[31] & 0x7) << 5)
+ | ((xmc[32] & 0x7) << 2)
+ | ((xmc[33] >> 1) & 0x3);
+ *c++ = ((xmc[33] & 0x1) << 7)
+ | ((xmc[34] & 0x7) << 4)
+ | ((xmc[35] & 0x7) << 1)
+ | ((xmc[36] >> 2) & 0x1);
+ *c++ = ((xmc[36] & 0x3) << 6)
+ | ((xmc[37] & 0x7) << 3)
+ | (xmc[38] & 0x7);
+
+
+ *c++ = ((Nc[3] & 0x7F) << 1)
+
+
+ | ((bc[3] >> 1) & 0x1);
+ *c++ = ((bc[3] & 0x1) << 7)
+
+
+ | ((Mc[3] & 0x3) << 5)
+
+
+ | ((xmaxc[3] >> 1) & 0x1F);
+ *c++ = ((xmaxc[3] & 0x1) << 7)
+
+#undef xmc
+#define xmc (source + 63 - 39)
+
+ | ((xmc[39] & 0x7) << 4)
+ | ((xmc[40] & 0x7) << 1)
+ | ((xmc[41] >> 2) & 0x1);
+ *c++ = ((xmc[41] & 0x3) << 6) /* 30 */
+ | ((xmc[42] & 0x7) << 3)
+ | (xmc[43] & 0x7);
+ *c++ = ((xmc[44] & 0x7) << 5)
+ | ((xmc[45] & 0x7) << 2)
+ | ((xmc[46] >> 1) & 0x3);
+ *c++ = ((xmc[46] & 0x1) << 7)
+ | ((xmc[47] & 0x7) << 4)
+ | ((xmc[48] & 0x7) << 1)
+ | ((xmc[49] >> 2) & 0x1);
+ *c++ = ((xmc[49] & 0x3) << 6)
+ | ((xmc[50] & 0x7) << 3)
+ | (xmc[51] & 0x7);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/gsm_jni.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,87 @@
+
+
+/**
+extern gsm gsm_create GSMJNI_P((void));
+extern void gsm_destroy GSMJNI_P((gsm));
+
+extern int gsm_print GSMJNI_P((FILE *, gsm, gsm_byte *));
+extern int gsm_option GSMJNI_P((gsm, int, int *));
+
+extern void gsm_encode GSMJNI_P((gsm, gsm_signal *, gsm_byte *));
+extern int gsm_decode GSMJNI_P((gsm, gsm_byte *, gsm_signal *));
+
+extern int gsm_explode GSMJNI_P((gsm, gsm_byte *, gsm_signal *));
+extern void gsm_implode GSMJNI_P((gsm, gsm_signal *, gsm_byte *));
+*/
+
+
+#include <jni.h>
+
+
+#include "gsm.h"
+#include "private.h"
+#include "proto.h"
+
+jlong
+Java_org_sipdroid_media_codecs_GSMJNI_create(JNIEnv *env)
+{
+ return gsm_create();
+}
+
+void
+Java_org_sipdroid_media_codecs_GSMJNI_destroy(JNIEnv *env, jlong jgsm)
+{
+ gsm_destroy((void *)jgsm);
+}
+
+void
+Java_org_sipdroid_media_codecs_GSMJNI_encode(JNIEnv *env, jlong jgsm, jshortArray jgsmSignal, jlong jsrcPos, jbyteArray jgsmByte, jlong jdestPos)
+{
+ jshort *gsmSignal;
+ jbyte *gsmByte;
+ jboolean isCopyByte;
+ jboolean isCopySignal;
+ void *ctx = (void *) jgsm;
+
+ gsmByte = (*env)->GetByteArrayElements( env, jgsmByte, &isCopyByte);
+ gsmSignal = (*env)->GetShortArrayElements( env, jgsmSignal, &isCopySignal);
+
+ gsm_encode(ctx, gsmSignal + jsrcPos, gsmByte + jdestPos);
+ if (isCopyByte == JNI_TRUE)
+ (*env)->ReleaseByteArrayElements(env, jgsmByte, gsmByte,0);
+ if (isCopySignal == JNI_TRUE)
+ (*env)->ReleaseShortArrayElements(env, jgsmSignal, gsmSignal,0);
+}
+
+jint
+Java_org_sipdroid_media_codecs_GSMJNI_decode(JNIEnv *env, jlong jgsm, jbyteArray jgsmByte, jlong jdestPos, jshortArray jgsmSignal, jlong jsrcPos)
+{
+ jshort *gsmSignal;
+ jbyte *gsmByte;
+ jboolean isCopyByte;
+ jboolean isCopySignal;
+ jint res;
+
+ gsmSignal = (*env)->GetShortArrayElements( env, jgsmSignal, &isCopySignal);
+ gsmByte = (*env)->GetByteArrayElements( env, jgsmByte, &isCopyByte);
+ res = gsm_decode((void *)jgsm, gsmByte + jdestPos, gsmSignal + jsrcPos);
+ if (isCopyByte == JNI_TRUE)
+ (*env)->ReleaseByteArrayElements(env, jgsmByte, gsmByte,0);
+ if (isCopySignal == JNI_TRUE)
+ (*env)->ReleaseShortArrayElements(env, jgsmSignal, gsmSignal,0);
+ return res;
+}
+
+jint
+Java_org_sipdroid_media_codecs_GSMJNI_option(JNIEnv *env, jlong jgsm, jint jopt, jintArray jval)
+{
+ jint *val;
+ jboolean isCopyVal;
+ jint res;
+
+ val = (*env)->GetIntArrayElements( env, jval, &isCopyVal);
+ res = gsm_option((void *)jgsm, jopt, val);
+ if (isCopyVal == JNI_TRUE)
+ (*env)->ReleaseIntArrayElements(env, jval, val,0);
+ return res;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/gsm_option.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_option.c,v 1.3 1996/07/02 09:59:05 jutta Exp $ */
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_option P3((r, opt, val), gsm r, int opt, int * val)
+{
+ int result = -1;
+
+ switch (opt) {
+ case GSM_OPT_LTP_CUT:
+#ifdef LTP_CUT
+ result = r->ltp_cut;
+ if (val) r->ltp_cut = *val;
+#endif
+ break;
+
+ case GSM_OPT_VERBOSE:
+#ifndef NDEBUG
+ result = r->verbose;
+ if (val) r->verbose = *val;
+#endif
+ break;
+
+ case GSM_OPT_FAST:
+
+#if defined(FAST) && defined(USE_FLOAT_MUL)
+ result = r->fast;
+ if (val) r->fast = !!*val;
+#endif
+ break;
+
+ case GSM_OPT_FRAME_CHAIN:
+
+#ifdef WAV49
+ result = r->frame_chain;
+ if (val) r->frame_chain = *val;
+#endif
+ break;
+
+ case GSM_OPT_FRAME_INDEX:
+
+#ifdef WAV49
+ result = r->frame_index;
+ if (val) r->frame_index = *val;
+#endif
+ break;
+
+ case GSM_OPT_WAV49:
+
+#ifdef WAV49
+ result = r->wav_fmt;
+ if (val) r->wav_fmt = !!*val;
+#endif
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/gsm_print.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,170 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_print.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */
+
+#include <stdio.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_print P3((f, s, c), FILE * f, gsm s, gsm_byte * c)
+{
+ word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
+// Wirlab
+ (void)s;
+
+
+ /* GSM_MAGIC = (*c >> 4) & 0xF; */
+
+ if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
+
+ LARc[0] = (*c++ & 0xF) << 2; /* 1 */
+ LARc[0] |= (*c >> 6) & 0x3;
+ LARc[1] = *c++ & 0x3F;
+ LARc[2] = (*c >> 3) & 0x1F;
+ LARc[3] = (*c++ & 0x7) << 2;
+ LARc[3] |= (*c >> 6) & 0x3;
+ LARc[4] = (*c >> 2) & 0xF;
+ LARc[5] = (*c++ & 0x3) << 2;
+ LARc[5] |= (*c >> 6) & 0x3;
+ LARc[6] = (*c >> 3) & 0x7;
+ LARc[7] = *c++ & 0x7;
+
+
+ Nc[0] = (*c >> 1) & 0x7F;
+ bc[0] = (*c++ & 0x1) << 1;
+ bc[0] |= (*c >> 7) & 0x1;
+ Mc[0] = (*c >> 5) & 0x3;
+ xmaxc[0] = (*c++ & 0x1F) << 1;
+ xmaxc[0] |= (*c >> 7) & 0x1;
+ xmc[0] = (*c >> 4) & 0x7;
+ xmc[1] = (*c >> 1) & 0x7;
+ xmc[2] = (*c++ & 0x1) << 2;
+ xmc[2] |= (*c >> 6) & 0x3;
+ xmc[3] = (*c >> 3) & 0x7;
+ xmc[4] = *c++ & 0x7;
+ xmc[5] = (*c >> 5) & 0x7;
+ xmc[6] = (*c >> 2) & 0x7;
+ xmc[7] = (*c++ & 0x3) << 1; /* 10 */
+ xmc[7] |= (*c >> 7) & 0x1;
+ xmc[8] = (*c >> 4) & 0x7;
+ xmc[9] = (*c >> 1) & 0x7;
+ xmc[10] = (*c++ & 0x1) << 2;
+ xmc[10] |= (*c >> 6) & 0x3;
+ xmc[11] = (*c >> 3) & 0x7;
+ xmc[12] = *c++ & 0x7;
+
+ Nc[1] = (*c >> 1) & 0x7F;
+ bc[1] = (*c++ & 0x1) << 1;
+ bc[1] |= (*c >> 7) & 0x1;
+ Mc[1] = (*c >> 5) & 0x3;
+ xmaxc[1] = (*c++ & 0x1F) << 1;
+ xmaxc[1] |= (*c >> 7) & 0x1;
+ xmc[13] = (*c >> 4) & 0x7;
+ xmc[14] = (*c >> 1) & 0x7;
+ xmc[15] = (*c++ & 0x1) << 2;
+ xmc[15] |= (*c >> 6) & 0x3;
+ xmc[16] = (*c >> 3) & 0x7;
+ xmc[17] = *c++ & 0x7;
+ xmc[18] = (*c >> 5) & 0x7;
+ xmc[19] = (*c >> 2) & 0x7;
+ xmc[20] = (*c++ & 0x3) << 1;
+ xmc[20] |= (*c >> 7) & 0x1;
+ xmc[21] = (*c >> 4) & 0x7;
+ xmc[22] = (*c >> 1) & 0x7;
+ xmc[23] = (*c++ & 0x1) << 2;
+ xmc[23] |= (*c >> 6) & 0x3;
+ xmc[24] = (*c >> 3) & 0x7;
+ xmc[25] = *c++ & 0x7;
+
+
+ Nc[2] = (*c >> 1) & 0x7F;
+ bc[2] = (*c++ & 0x1) << 1; /* 20 */
+ bc[2] |= (*c >> 7) & 0x1;
+ Mc[2] = (*c >> 5) & 0x3;
+ xmaxc[2] = (*c++ & 0x1F) << 1;
+ xmaxc[2] |= (*c >> 7) & 0x1;
+ xmc[26] = (*c >> 4) & 0x7;
+ xmc[27] = (*c >> 1) & 0x7;
+ xmc[28] = (*c++ & 0x1) << 2;
+ xmc[28] |= (*c >> 6) & 0x3;
+ xmc[29] = (*c >> 3) & 0x7;
+ xmc[30] = *c++ & 0x7;
+ xmc[31] = (*c >> 5) & 0x7;
+ xmc[32] = (*c >> 2) & 0x7;
+ xmc[33] = (*c++ & 0x3) << 1;
+ xmc[33] |= (*c >> 7) & 0x1;
+ xmc[34] = (*c >> 4) & 0x7;
+ xmc[35] = (*c >> 1) & 0x7;
+ xmc[36] = (*c++ & 0x1) << 2;
+ xmc[36] |= (*c >> 6) & 0x3;
+ xmc[37] = (*c >> 3) & 0x7;
+ xmc[38] = *c++ & 0x7;
+
+ Nc[3] = (*c >> 1) & 0x7F;
+ bc[3] = (*c++ & 0x1) << 1;
+ bc[3] |= (*c >> 7) & 0x1;
+ Mc[3] = (*c >> 5) & 0x3;
+ xmaxc[3] = (*c++ & 0x1F) << 1;
+ xmaxc[3] |= (*c >> 7) & 0x1;
+
+ xmc[39] = (*c >> 4) & 0x7;
+ xmc[40] = (*c >> 1) & 0x7;
+ xmc[41] = (*c++ & 0x1) << 2;
+ xmc[41] |= (*c >> 6) & 0x3;
+ xmc[42] = (*c >> 3) & 0x7;
+ xmc[43] = *c++ & 0x7; /* 30 */
+ xmc[44] = (*c >> 5) & 0x7;
+ xmc[45] = (*c >> 2) & 0x7;
+ xmc[46] = (*c++ & 0x3) << 1;
+ xmc[46] |= (*c >> 7) & 0x1;
+ xmc[47] = (*c >> 4) & 0x7;
+ xmc[48] = (*c >> 1) & 0x7;
+ xmc[49] = (*c++ & 0x1) << 2;
+ xmc[49] |= (*c >> 6) & 0x3;
+ xmc[50] = (*c >> 3) & 0x7;
+ xmc[51] = *c & 0x7; /* 33 */
+
+ fprintf(f,
+ "LARc:\t%2.2d %2.2d %2.2d %2.2d %2.2d %2.2d %2.2d %2.2d\n",
+ LARc[0],LARc[1],LARc[2],LARc[3],LARc[4],LARc[5],LARc[6],LARc[7]);
+
+ fprintf(f, "#1: Nc %4.4d bc %d Mc %d xmaxc %d\n",
+ Nc[0], bc[0], Mc[0], xmaxc[0]);
+ fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+ xmc[0],xmc[1],xmc[2],xmc[3],xmc[4],xmc[5],xmc[6],
+ xmc[7],xmc[8],xmc[9],xmc[10],xmc[11],xmc[12] );
+
+ fprintf(f, "#2: Nc %4.4d bc %d Mc %d xmaxc %d\n",
+ Nc[1], bc[1], Mc[1], xmaxc[1]);
+ fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+ xmc[13+0],xmc[13+1],xmc[13+2],xmc[13+3],xmc[13+4],xmc[13+5],
+ xmc[13+6], xmc[13+7],xmc[13+8],xmc[13+9],xmc[13+10],xmc[13+11],
+ xmc[13+12] );
+
+ fprintf(f, "#3: Nc %4.4d bc %d Mc %d xmaxc %d\n",
+ Nc[2], bc[2], Mc[2], xmaxc[2]);
+ fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+ xmc[26+0],xmc[26+1],xmc[26+2],xmc[26+3],xmc[26+4],xmc[26+5],
+ xmc[26+6], xmc[26+7],xmc[26+8],xmc[26+9],xmc[26+10],xmc[26+11],
+ xmc[26+12] );
+
+ fprintf(f, "#4: Nc %4.4d bc %d Mc %d xmaxc %d\n",
+ Nc[3], bc[3], Mc[3], xmaxc[3]);
+ fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+ xmc[39+0],xmc[39+1],xmc[39+2],xmc[39+3],xmc[39+4],xmc[39+5],
+ xmc[39+6], xmc[39+7],xmc[39+8],xmc[39+9],xmc[39+10],xmc[39+11],
+ xmc[39+12] );
+
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/long_term.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,954 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/long_term.c,v 1.6 1996/07/02 12:33:19 jutta Exp $ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+/*
+ * 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION
+ */
+
+
+/*
+ * This module computes the LTP gain (bc) and the LTP lag (Nc)
+ * for the long term analysis filter. This is done by calculating a
+ * maximum of the cross-correlation function between the current
+ * sub-segment short term residual signal d[0..39] (output of
+ * the short term analysis filter; for simplification the index
+ * of this array begins at 0 and ends at 39 for each sub-segment of the
+ * RPE-LTP analysis) and the previous reconstructed short term
+ * residual signal dp[ -120 .. -1 ]. A dynamic scaling must be
+ * performed to avoid overflow.
+ */
+
+ /* The next procedure exists in six versions. First two integer
+ * version (if USE_FLOAT_MUL is not defined); then four floating
+ * point versions, twice with proper scaling (USE_FLOAT_MUL defined),
+ * once without (USE_FLOAT_MUL and FAST defined, and fast run-time
+ * option used). Every pair has first a Cut version (see the -C
+ * option to toast or the LTP_CUT option to gsm_option()), then the
+ * uncut one. (For a detailed explanation of why this is altogether
+ * a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered
+ * Harmful''.)
+ */
+
+#ifndef USE_FLOAT_MUL
+
+#ifdef LTP_CUT
+
+static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out),
+
+ struct gsm_state * st,
+
+ register word * d, /* [0..39] IN */
+ register word * dp, /* [-120..-1] IN */
+ word * bc_out, /* OUT */
+ word * Nc_out /* OUT */
+)
+{
+ register int k, lambda;
+ word Nc, bc;
+ word wt[40];
+
+ longword L_result;
+ longword L_max, L_power;
+ word R, S, dmax, scal, best_k;
+ word ltp_cut;
+
+ register word temp, wt_k;
+
+ /* Search of the optimum scaling of d[0..39].
+ */
+ dmax = 0;
+ for (k = 0; k <= 39; k++) {
+ temp = d[k];
+ temp = GSM_ABS( temp );
+ if (temp > dmax) {
+ dmax = temp;
+ best_k = k;
+ }
+ }
+ temp = 0;
+ if (dmax == 0) scal = 0;
+ else {
+ assert(dmax > 0);
+ temp = gsm_norm( (longword)dmax << 16 );
+ }
+ if (temp > 6) scal = 0;
+ else scal = 6 - temp;
+ assert(scal >= 0);
+
+ /* Search for the maximum cross-correlation and coding of the LTP lag
+ */
+ L_max = 0;
+ Nc = 40; /* index for the maximum cross-correlation */
+ wt_k = SASR(d[best_k], scal);
+
+ for (lambda = 40; lambda <= 120; lambda++) {
+ L_result = (longword)wt_k * dp[best_k - lambda];
+ if (L_result > L_max) {
+ Nc = lambda;
+ L_max = L_result;
+ }
+ }
+ *Nc_out = Nc;
+ L_max <<= 1;
+
+ /* Rescaling of L_max
+ */
+ assert(scal <= 100 && scal >= -100);
+ L_max = L_max >> (6 - scal); /* sub(6, scal) */
+
+ assert( Nc <= 120 && Nc >= 40);
+
+ /* Compute the power of the reconstructed short term residual
+ * signal dp[..]
+ */
+ L_power = 0;
+ for (k = 0; k <= 39; k++) {
+
+ register longword L_temp;
+
+ L_temp = SASR( dp[k - Nc], 3 );
+ L_power += L_temp * L_temp;
+ }
+ L_power <<= 1; /* from L_MULT */
+
+ /* Normalization of L_max and L_power
+ */
+
+ if (L_max <= 0) {
+ *bc_out = 0;
+ return;
+ }
+ if (L_max >= L_power) {
+ *bc_out = 3;
+ return;
+ }
+
+ temp = gsm_norm( L_power );
+
+ R = SASR( L_max << temp, 16 );
+ S = SASR( L_power << temp, 16 );
+
+ /* Coding of the LTP gain
+ */
+
+ /* Table 4.3a must be used to obtain the level DLB[i] for the
+ * quantization of the LTP gain b to get the coded version bc.
+ */
+ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+ *bc_out = bc;
+}
+
+#endif /* LTP_CUT */
+
+static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
+ register word * d, /* [0..39] IN */
+ register word * dp, /* [-120..-1] IN */
+ word * bc_out, /* OUT */
+ word * Nc_out /* OUT */
+)
+{
+ register int k, lambda;
+ word Nc, bc;
+ word wt[40];
+
+ longword L_max, L_power;
+ word R, S, dmax, scal;
+ register word temp;
+
+ /* Search of the optimum scaling of d[0..39].
+ */
+ dmax = 0;
+
+ for (k = 0; k <= 39; k++) {
+ temp = d[k];
+ temp = GSM_ABS( temp );
+ if (temp > dmax) dmax = temp;
+ }
+
+ temp = 0;
+ if (dmax == 0) scal = 0;
+ else {
+ assert(dmax > 0);
+ temp = gsm_norm( (longword)dmax << 16 );
+ }
+
+ if (temp > 6) scal = 0;
+ else scal = 6 - temp;
+
+ assert(scal >= 0);
+
+ /* Initialization of a working array wt
+ */
+
+ for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal );
+
+ /* Search for the maximum cross-correlation and coding of the LTP lag
+ */
+ L_max = 0;
+ Nc = 40; /* index for the maximum cross-correlation */
+
+ for (lambda = 40; lambda <= 120; lambda++) {
+
+# undef STEP
+# define STEP(k) (longword)wt[k] * dp[k - lambda]
+
+ register longword L_result;
+
+ L_result = STEP(0) ; L_result += STEP(1) ;
+ L_result += STEP(2) ; L_result += STEP(3) ;
+ L_result += STEP(4) ; L_result += STEP(5) ;
+ L_result += STEP(6) ; L_result += STEP(7) ;
+ L_result += STEP(8) ; L_result += STEP(9) ;
+ L_result += STEP(10) ; L_result += STEP(11) ;
+ L_result += STEP(12) ; L_result += STEP(13) ;
+ L_result += STEP(14) ; L_result += STEP(15) ;
+ L_result += STEP(16) ; L_result += STEP(17) ;
+ L_result += STEP(18) ; L_result += STEP(19) ;
+ L_result += STEP(20) ; L_result += STEP(21) ;
+ L_result += STEP(22) ; L_result += STEP(23) ;
+ L_result += STEP(24) ; L_result += STEP(25) ;
+ L_result += STEP(26) ; L_result += STEP(27) ;
+ L_result += STEP(28) ; L_result += STEP(29) ;
+ L_result += STEP(30) ; L_result += STEP(31) ;
+ L_result += STEP(32) ; L_result += STEP(33) ;
+ L_result += STEP(34) ; L_result += STEP(35) ;
+ L_result += STEP(36) ; L_result += STEP(37) ;
+ L_result += STEP(38) ; L_result += STEP(39) ;
+
+ if (L_result > L_max) {
+
+ Nc = lambda;
+ L_max = L_result;
+ }
+ }
+
+ *Nc_out = Nc;
+
+ L_max <<= 1;
+
+ /* Rescaling of L_max
+ */
+ assert(scal <= 100 && scal >= -100);
+ L_max = L_max >> (6 - scal); /* sub(6, scal) */
+
+ assert( Nc <= 120 && Nc >= 40);
+
+ /* Compute the power of the reconstructed short term residual
+ * signal dp[..]
+ */
+ L_power = 0;
+ for (k = 0; k <= 39; k++) {
+
+ register longword L_temp;
+
+ L_temp = SASR( dp[k - Nc], 3 );
+ L_power += L_temp * L_temp;
+ }
+ L_power <<= 1; /* from L_MULT */
+
+ /* Normalization of L_max and L_power
+ */
+
+ if (L_max <= 0) {
+ *bc_out = 0;
+ return;
+ }
+ if (L_max >= L_power) {
+ *bc_out = 3;
+ return;
+ }
+
+ temp = gsm_norm( L_power );
+
+ R = SASR( L_max << temp, 16 );
+ S = SASR( L_power << temp, 16 );
+
+ /* Coding of the LTP gain
+ */
+
+ /* Table 4.3a must be used to obtain the level DLB[i] for the
+ * quantization of the LTP gain b to get the coded version bc.
+ */
+ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+ *bc_out = bc;
+}
+
+#else /* USE_FLOAT_MUL */
+
+#ifdef LTP_CUT
+
+static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out),
+ struct gsm_state * st, /* IN */
+ register word * d, /* [0..39] IN */
+ register word * dp, /* [-120..-1] IN */
+ word * bc_out, /* OUT */
+ word * Nc_out /* OUT */
+)
+{
+ register int k, lambda;
+ word Nc, bc;
+ word ltp_cut;
+
+ float wt_float[40];
+ float dp_float_base[120], * dp_float = dp_float_base + 120;
+
+ longword L_max, L_power;
+ word R, S, dmax, scal;
+ register word temp;
+
+ /* Search of the optimum scaling of d[0..39].
+ */
+ dmax = 0;
+
+ for (k = 0; k <= 39; k++) {
+ temp = d[k];
+ temp = GSM_ABS( temp );
+ if (temp > dmax) dmax = temp;
+ }
+
+ temp = 0;
+ if (dmax == 0) scal = 0;
+ else {
+ assert(dmax > 0);
+ temp = gsm_norm( (longword)dmax << 16 );
+ }
+
+ if (temp > 6) scal = 0;
+ else scal = 6 - temp;
+
+ assert(scal >= 0);
+ ltp_cut = (longword)SASR(dmax, scal) * st->ltp_cut / 100;
+
+
+ /* Initialization of a working array wt
+ */
+
+ for (k = 0; k < 40; k++) {
+ register word w = SASR( d[k], scal );
+ if (w < 0 ? w > -ltp_cut : w < ltp_cut) {
+ wt_float[k] = 0.0;
+ }
+ else {
+ wt_float[k] = w;
+ }
+ }
+ for (k = -120; k < 0; k++) dp_float[k] = dp[k];
+
+ /* Search for the maximum cross-correlation and coding of the LTP lag
+ */
+ L_max = 0;
+ Nc = 40; /* index for the maximum cross-correlation */
+
+ for (lambda = 40; lambda <= 120; lambda += 9) {
+
+ /* Calculate L_result for l = lambda .. lambda + 9.
+ */
+ register float *lp = dp_float - lambda;
+
+ register float W;
+ register float a = lp[-8], b = lp[-7], c = lp[-6],
+ d = lp[-5], e = lp[-4], f = lp[-3],
+ g = lp[-2], h = lp[-1];
+ register float E;
+ register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
+ S5 = 0, S6 = 0, S7 = 0, S8 = 0;
+
+# undef STEP
+# define STEP(K, a, b, c, d, e, f, g, h) \
+ if ((W = wt_float[K]) != 0.0) { \
+ E = W * a; S8 += E; \
+ E = W * b; S7 += E; \
+ E = W * c; S6 += E; \
+ E = W * d; S5 += E; \
+ E = W * e; S4 += E; \
+ E = W * f; S3 += E; \
+ E = W * g; S2 += E; \
+ E = W * h; S1 += E; \
+ a = lp[K]; \
+ E = W * a; S0 += E; } else (a = lp[K])
+
+# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h)
+# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a)
+# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b)
+# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c)
+# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d)
+# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e)
+# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f)
+# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g)
+
+ STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
+ STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
+
+ STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
+ STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
+
+ STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
+ STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
+
+ STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
+ STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
+
+ STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
+ STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
+
+ if (S0 > L_max) { L_max = S0; Nc = lambda; }
+ if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
+ if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
+ if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
+ if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
+ if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
+ if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
+ if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
+ if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
+
+ }
+ *Nc_out = Nc;
+
+ L_max <<= 1;
+
+ /* Rescaling of L_max
+ */
+ assert(scal <= 100 && scal >= -100);
+ L_max = L_max >> (6 - scal); /* sub(6, scal) */
+
+ assert( Nc <= 120 && Nc >= 40);
+
+ /* Compute the power of the reconstructed short term residual
+ * signal dp[..]
+ */
+ L_power = 0;
+ for (k = 0; k <= 39; k++) {
+
+ register longword L_temp;
+
+ L_temp = SASR( dp[k - Nc], 3 );
+ L_power += L_temp * L_temp;
+ }
+ L_power <<= 1; /* from L_MULT */
+
+ /* Normalization of L_max and L_power
+ */
+
+ if (L_max <= 0) {
+ *bc_out = 0;
+ return;
+ }
+ if (L_max >= L_power) {
+ *bc_out = 3;
+ return;
+ }
+
+ temp = gsm_norm( L_power );
+
+ R = SASR( L_max << temp, 16 );
+ S = SASR( L_power << temp, 16 );
+
+ /* Coding of the LTP gain
+ */
+
+ /* Table 4.3a must be used to obtain the level DLB[i] for the
+ * quantization of the LTP gain b to get the coded version bc.
+ */
+ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+ *bc_out = bc;
+}
+
+#endif /* LTP_CUT */
+
+static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
+ register word * d, /* [0..39] IN */
+ register word * dp, /* [-120..-1] IN */
+ word * bc_out, /* OUT */
+ word * Nc_out /* OUT */
+)
+{
+ register int k, lambda;
+ word Nc, bc;
+
+ float wt_float[40];
+ float dp_float_base[120], * dp_float = dp_float_base + 120;
+
+ longword L_max, L_power;
+ word R, S, dmax, scal;
+ register word temp;
+
+ /* Search of the optimum scaling of d[0..39].
+ */
+ dmax = 0;
+
+ for (k = 0; k <= 39; k++) {
+ temp = d[k];
+ temp = GSM_ABS( temp );
+ if (temp > dmax) dmax = temp;
+ }
+
+ temp = 0;
+ if (dmax == 0) scal = 0;
+ else {
+ assert(dmax > 0);
+ temp = gsm_norm( (longword)dmax << 16 );
+ }
+
+ if (temp > 6) scal = 0;
+ else scal = 6 - temp;
+
+ assert(scal >= 0);
+
+ /* Initialization of a working array wt
+ */
+
+ for (k = 0; k < 40; k++) wt_float[k] = SASR( d[k], scal );
+ for (k = -120; k < 0; k++) dp_float[k] = dp[k];
+
+ /* Search for the maximum cross-correlation and coding of the LTP lag
+ */
+ L_max = 0;
+ Nc = 40; /* index for the maximum cross-correlation */
+
+ for (lambda = 40; lambda <= 120; lambda += 9) {
+
+ /* Calculate L_result for l = lambda .. lambda + 9.
+ */
+ register float *lp = dp_float - lambda;
+
+ register float W;
+ register float a = lp[-8], b = lp[-7], c = lp[-6],
+ d = lp[-5], e = lp[-4], f = lp[-3],
+ g = lp[-2], h = lp[-1];
+ register float E;
+ register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
+ S5 = 0, S6 = 0, S7 = 0, S8 = 0;
+
+# undef STEP
+# define STEP(K, a, b, c, d, e, f, g, h) \
+ W = wt_float[K]; \
+ E = W * a; S8 += E; \
+ E = W * b; S7 += E; \
+ E = W * c; S6 += E; \
+ E = W * d; S5 += E; \
+ E = W * e; S4 += E; \
+ E = W * f; S3 += E; \
+ E = W * g; S2 += E; \
+ E = W * h; S1 += E; \
+ a = lp[K]; \
+ E = W * a; S0 += E
+
+# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h)
+# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a)
+# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b)
+# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c)
+# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d)
+# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e)
+# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f)
+# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g)
+
+ STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
+ STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
+
+ STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
+ STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
+
+ STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
+ STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
+
+ STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
+ STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
+
+ STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
+ STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
+
+ if (S0 > L_max) { L_max = S0; Nc = lambda; }
+ if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
+ if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
+ if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
+ if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
+ if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
+ if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
+ if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
+ if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
+ }
+ *Nc_out = Nc;
+
+ L_max <<= 1;
+
+ /* Rescaling of L_max
+ */
+ assert(scal <= 100 && scal >= -100);
+ L_max = L_max >> (6 - scal); /* sub(6, scal) */
+
+ assert( Nc <= 120 && Nc >= 40);
+
+ /* Compute the power of the reconstructed short term residual
+ * signal dp[..]
+ */
+ L_power = 0;
+ for (k = 0; k <= 39; k++) {
+
+ register longword L_temp;
+
+ L_temp = SASR( dp[k - Nc], 3 );
+ L_power += L_temp * L_temp;
+ }
+ L_power <<= 1; /* from L_MULT */
+
+ /* Normalization of L_max and L_power
+ */
+
+ if (L_max <= 0) {
+ *bc_out = 0;
+ return;
+ }
+ if (L_max >= L_power) {
+ *bc_out = 3;
+ return;
+ }
+
+ temp = gsm_norm( L_power );
+
+ R = SASR( L_max << temp, 16 );
+ S = SASR( L_power << temp, 16 );
+
+ /* Coding of the LTP gain
+ */
+
+ /* Table 4.3a must be used to obtain the level DLB[i] for the
+ * quantization of the LTP gain b to get the coded version bc.
+ */
+ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+ *bc_out = bc;
+}
+
+#ifdef FAST
+#ifdef LTP_CUT
+
+static void Cut_Fast_Calculation_of_the_LTP_parameters P5((st,
+ d,dp,bc_out,Nc_out),
+ struct gsm_state * st, /* IN */
+ register word * d, /* [0..39] IN */
+ register word * dp, /* [-120..-1] IN */
+ word * bc_out, /* OUT */
+ word * Nc_out /* OUT */
+)
+{
+ register int k, lambda;
+ register float wt_float;
+ word Nc, bc;
+ word wt_max, best_k, ltp_cut;
+
+ float dp_float_base[120], * dp_float = dp_float_base + 120;
+
+ register float L_result, L_max, L_power;
+
+ wt_max = 0;
+
+ for (k = 0; k < 40; ++k) {
+ if ( d[k] > wt_max) wt_max = d[best_k = k];
+ else if (-d[k] > wt_max) wt_max = -d[best_k = k];
+ }
+
+ assert(wt_max >= 0);
+ wt_float = (float)wt_max;
+
+ for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];
+
+ /* Search for the maximum cross-correlation and coding of the LTP lag
+ */
+ L_max = 0;
+ Nc = 40; /* index for the maximum cross-correlation */
+
+ for (lambda = 40; lambda <= 120; lambda++) {
+ L_result = wt_float * dp_float[best_k - lambda];
+ if (L_result > L_max) {
+ Nc = lambda;
+ L_max = L_result;
+ }
+ }
+
+ *Nc_out = Nc;
+ if (L_max <= 0.) {
+ *bc_out = 0;
+ return;
+ }
+
+ /* Compute the power of the reconstructed short term residual
+ * signal dp[..]
+ */
+ dp_float -= Nc;
+ L_power = 0;
+ for (k = 0; k < 40; ++k) {
+ register float f = dp_float[k];
+ L_power += f * f;
+ }
+
+ if (L_max >= L_power) {
+ *bc_out = 3;
+ return;
+ }
+
+ /* Coding of the LTP gain
+ * Table 4.3a must be used to obtain the level DLB[i] for the
+ * quantization of the LTP gain b to get the coded version bc.
+ */
+ lambda = L_max / L_power * 32768.;
+ for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
+ *bc_out = bc;
+}
+
+#endif /* LTP_CUT */
+
+static void Fast_Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
+ register word * d, /* [0..39] IN */
+ register word * dp, /* [-120..-1] IN */
+ word * bc_out, /* OUT */
+ word * Nc_out /* OUT */
+)
+{
+ register int k, lambda;
+ word Nc, bc;
+
+ float wt_float[40];
+ float dp_float_base[120], * dp_float = dp_float_base + 120;
+
+ register float L_max, L_power;
+
+ for (k = 0; k < 40; ++k) wt_float[k] = (float)d[k];
+ for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];
+
+ /* Search for the maximum cross-correlation and coding of the LTP lag
+ */
+ L_max = 0;
+ Nc = 40; /* index for the maximum cross-correlation */
+
+ for (lambda = 40; lambda <= 120; lambda += 9) {
+
+ /* Calculate L_result for l = lambda .. lambda + 9.
+ */
+ register float *lp = dp_float - lambda;
+
+ register float W;
+ register float a = lp[-8], b = lp[-7], c = lp[-6],
+ d = lp[-5], e = lp[-4], f = lp[-3],
+ g = lp[-2], h = lp[-1];
+ register float E;
+ register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
+ S5 = 0, S6 = 0, S7 = 0, S8 = 0;
+
+# undef STEP
+# define STEP(K, a, b, c, d, e, f, g, h) \
+ W = wt_float[K]; \
+ E = W * a; S8 += E; \
+ E = W * b; S7 += E; \
+ E = W * c; S6 += E; \
+ E = W * d; S5 += E; \
+ E = W * e; S4 += E; \
+ E = W * f; S3 += E; \
+ E = W * g; S2 += E; \
+ E = W * h; S1 += E; \
+ a = lp[K]; \
+ E = W * a; S0 += E
+
+# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h)
+# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a)
+# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b)
+# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c)
+# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d)
+# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e)
+# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f)
+# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g)
+
+ STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
+ STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
+
+ STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
+ STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
+
+ STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
+ STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
+
+ STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
+ STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
+
+ STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
+ STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
+
+ if (S0 > L_max) { L_max = S0; Nc = lambda; }
+ if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
+ if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
+ if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
+ if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
+ if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
+ if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
+ if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
+ if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
+ }
+ *Nc_out = Nc;
+
+ if (L_max <= 0.) {
+ *bc_out = 0;
+ return;
+ }
+
+ /* Compute the power of the reconstructed short term residual
+ * signal dp[..]
+ */
+ dp_float -= Nc;
+ L_power = 0;
+ for (k = 0; k < 40; ++k) {
+ register float f = dp_float[k];
+ L_power += f * f;
+ }
+
+ if (L_max >= L_power) {
+ *bc_out = 3;
+ return;
+ }
+
+ /* Coding of the LTP gain
+ * Table 4.3a must be used to obtain the level DLB[i] for the
+ * quantization of the LTP gain b to get the coded version bc.
+ */
+ lambda = L_max / L_power * 32768.;
+ for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
+ *bc_out = bc;
+}
+
+#endif /* FAST */
+#endif /* USE_FLOAT_MUL */
+
+
+/* 4.2.12 */
+
+static void Long_term_analysis_filtering P6((bc,Nc,dp,d,dpp,e),
+ word bc, /* IN */
+ word Nc, /* IN */
+ register word * dp, /* previous d [-120..-1] IN */
+ register word * d, /* d [0..39] IN */
+ register word * dpp, /* estimate [0..39] OUT */
+ register word * e /* long term res. signal [0..39] OUT */
+)
+/*
+ * In this part, we have to decode the bc parameter to compute
+ * the samples of the estimate dpp[0..39]. The decoding of bc needs the
+ * use of table 4.3b. The long term residual signal e[0..39]
+ * is then calculated to be fed to the RPE encoding section.
+ */
+{
+ register int k;
+ register longword ltmp;
+
+# undef STEP
+# define STEP(BP) \
+ for (k = 0; k <= 39; k++) { \
+ dpp[k] = GSM_MULT_R( BP, dp[k - Nc]); \
+ e[k] = GSM_SUB( d[k], dpp[k] ); \
+ }
+
+ switch (bc) {
+ case 0: STEP( 3277 ); break;
+ case 1: STEP( 11469 ); break;
+ case 2: STEP( 21299 ); break;
+ case 3: STEP( 32767 ); break;
+ }
+}
+
+void Gsm_Long_Term_Predictor P7((S,d,dp,e,dpp,Nc,bc), /* 4x for 160 samples */
+
+ struct gsm_state * S,
+
+ word * d, /* [0..39] residual signal IN */
+ word * dp, /* [-120..-1] d' IN */
+
+ word * e, /* [0..39] OUT */
+ word * dpp, /* [0..39] OUT */
+ word * Nc, /* correlation lag OUT */
+ word * bc /* gain factor OUT */
+)
+{
+
+// Wirlab
+ (void)S;
+
+ assert( d ); assert( dp ); assert( e );
+ assert( dpp); assert( Nc ); assert( bc );
+
+#if defined(FAST) && defined(USE_FLOAT_MUL)
+ if (S->fast)
+#if defined (LTP_CUT)
+ if (S->ltp_cut)
+ Cut_Fast_Calculation_of_the_LTP_parameters(S,
+ d, dp, bc, Nc);
+ else
+#endif /* LTP_CUT */
+ Fast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc );
+ else
+#endif /* FAST & USE_FLOAT_MUL */
+#ifdef LTP_CUT
+ if (S->ltp_cut)
+ Cut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc);
+ else
+#endif
+ Calculation_of_the_LTP_parameters(d, dp, bc, Nc);
+
+ Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e );
+}
+
+/* 4.3.2 */
+void Gsm_Long_Term_Synthesis_Filtering P5((S,Ncr,bcr,erp,drp),
+ struct gsm_state * S,
+
+ word Ncr,
+ word bcr,
+ register word * erp, /* [0..39] IN */
+ register word * drp /* [-120..-1] IN, [-120..40] OUT */
+)
+/*
+ * This procedure uses the bcr and Ncr parameter to realize the
+ * long term synthesis filtering. The decoding of bcr needs
+ * table 4.3b.
+ */
+{
+
+ register longword ltmp; /* for ADD */
+ register int k;
+ word brp, drpp, Nr;
+
+ /* Check the limits of Nr.
+ */
+ Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr;
+ S->nrp = Nr;
+ assert(Nr >= 40 && Nr <= 120);
+
+ /* Decoding of the LTP gain bcr
+ */
+ brp = gsm_QLB[ bcr ];
+
+ /* Computation of the reconstructed short term residual
+ * signal drp[0..39]
+ */
+ assert(brp != MIN_WORD);
+
+ for (k = 0; k <= 39; k++) {
+ drpp = GSM_MULT_R( brp, drp[ k - Nr ] );
+ drp[k] = GSM_ADD( erp[k], drpp );
+ }
+
+ /*
+ * Update of the reconstructed short term residual signal
+ * drp[ -1..-120 ]
+ */
+
+ for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ];
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/lpc.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,345 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/lpc.c,v 1.5 1994/12/30 23:14:54 jutta Exp $ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+#undef P
+
+/*
+ * 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION
+ */
+
+/* 4.2.4 */
+
+
+static void Autocorrelation P2((s, L_ACF),
+ word * s, /* [0..159] IN/OUT */
+ longword * L_ACF) /* [0..8] OUT */
+/*
+ * The goal is to compute the array L_ACF[k]. The signal s[i] must
+ * be scaled in order to avoid an overflow situation.
+ */
+{
+ register int k, i;
+
+ word temp, smax, scalauto;
+
+#ifdef USE_FLOAT_MUL
+ float float_s[160];
+#endif
+
+ /* Dynamic scaling of the array s[0..159]
+ */
+
+ /* Search for the maximum.
+ */
+ smax = 0;
+ for (k = 0; k <= 159; k++) {
+ temp = GSM_ABS( s[k] );
+ if (temp > smax) smax = temp;
+ }
+
+ /* Computation of the scaling factor.
+ */
+ if (smax == 0) scalauto = 0;
+ else {
+ assert(smax > 0);
+ scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */
+ }
+
+ /* Scaling of the array s[0...159]
+ */
+
+ if (scalauto > 0) {
+
+# ifdef USE_FLOAT_MUL
+# define SCALE(n) \
+ case n: for (k = 0; k <= 159; k++) \
+ float_s[k] = (float) \
+ (s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\
+ break;
+# else
+# define SCALE(n) \
+ case n: for (k = 0; k <= 159; k++) \
+ s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\
+ break;
+# endif /* USE_FLOAT_MUL */
+
+ switch (scalauto) {
+ SCALE(1)
+ SCALE(2)
+ SCALE(3)
+ SCALE(4)
+ }
+# undef SCALE
+ }
+# ifdef USE_FLOAT_MUL
+ else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k];
+# endif
+
+ /* Compute the L_ACF[..].
+ */
+ {
+# ifdef USE_FLOAT_MUL
+ register float * sp = float_s;
+ register float sl = *sp;
+
+# define STEP(k) L_ACF[k] += (longword)(sl * sp[ -(k) ]);
+# else
+ word * sp = s;
+ word sl = *sp;
+
+# define STEP(k) L_ACF[k] += ((longword)sl * sp[ -(k) ]);
+# endif
+
+# define NEXTI sl = *++sp
+
+
+ for (k = 9; k--; L_ACF[k] = 0) ;
+
+ STEP (0);
+ NEXTI;
+ STEP(0); STEP(1);
+ NEXTI;
+ STEP(0); STEP(1); STEP(2);
+ NEXTI;
+ STEP(0); STEP(1); STEP(2); STEP(3);
+ NEXTI;
+ STEP(0); STEP(1); STEP(2); STEP(3); STEP(4);
+ NEXTI;
+ STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5);
+ NEXTI;
+ STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6);
+ NEXTI;
+ STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7);
+
+ for (i = 8; i <= 159; i++) {
+
+ NEXTI;
+
+ STEP(0);
+ STEP(1); STEP(2); STEP(3); STEP(4);
+ STEP(5); STEP(6); STEP(7); STEP(8);
+ }
+
+ for (k = 9; k--; L_ACF[k] <<= 1) ;
+
+ }
+ /* Rescaling of the array s[0..159]
+ */
+ if (scalauto > 0) {
+ assert(scalauto <= 4);
+ for (k = 160; k--; *s++ <<= scalauto) ;
+ }
+}
+
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+
+static void Fast_Autocorrelation P2((s, L_ACF),
+ word * s, /* [0..159] IN/OUT */
+ longword * L_ACF) /* [0..8] OUT */
+{
+ register int k, i;
+ float f_L_ACF[9];
+ float scale;
+
+ float s_f[160];
+ register float *sf = s_f;
+
+ for (i = 0; i < 160; ++i) sf[i] = s[i];
+ for (k = 0; k <= 8; k++) {
+ register float L_temp2 = 0;
+ register float *sfl = sf - k;
+ for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i];
+ f_L_ACF[k] = L_temp2;
+ }
+ scale = MAX_LONGWORD / f_L_ACF[0];
+
+ for (k = 0; k <= 8; k++) {
+ L_ACF[k] = f_L_ACF[k] * scale;
+ }
+}
+#endif /* defined (USE_FLOAT_MUL) && defined (FAST) */
+
+/* 4.2.5 */
+
+static void Reflection_coefficients P2( (L_ACF, r),
+ longword * L_ACF, /* 0...8 IN */
+ register word * r /* 0...7 OUT */
+)
+{
+ register int i, m, n;
+ register word temp;
+ register longword ltmp;
+ word ACF[9]; /* 0..8 */
+ word P[ 9]; /* 0..8 */
+ word K[ 9]; /* 2..8 */
+
+ /* Schur recursion with 16 bits arithmetic.
+ */
+
+ if (L_ACF[0] == 0) {
+ for (i = 8; i--; *r++ = 0) ;
+ return;
+ }
+
+ assert( L_ACF[0] != 0 );
+ temp = gsm_norm( L_ACF[0] );
+
+ assert(temp >= 0 && temp < 32);
+
+ /* ? overflow ? */
+ for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 );
+
+ /* Initialize array P[..] and K[..] for the recursion.
+ */
+
+ for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ];
+ for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ];
+
+ /* Compute reflection coefficients
+ */
+ for (n = 1; n <= 8; n++, r++) {
+
+ temp = P[1];
+ temp = GSM_ABS(temp);
+ if (P[0] < temp) {
+ for (i = n; i <= 8; i++) *r++ = 0;
+ return;
+ }
+
+ *r = gsm_div( temp, P[0] );
+
+ assert(*r >= 0);
+ if (P[1] > 0) *r = -*r; /* r[n] = sub(0, r[n]) */
+ assert (*r != MIN_WORD);
+ if (n == 8) return;
+
+ /* Schur recursion
+ */
+ temp = GSM_MULT_R( P[1], *r );
+ P[0] = GSM_ADD( P[0], temp );
+
+ for (m = 1; m <= 8 - n; m++) {
+ temp = GSM_MULT_R( K[ m ], *r );
+ P[m] = GSM_ADD( P[ m+1 ], temp );
+
+ temp = GSM_MULT_R( P[ m+1 ], *r );
+ K[m] = GSM_ADD( K[ m ], temp );
+ }
+ }
+}
+
+/* 4.2.6 */
+
+static void Transformation_to_Log_Area_Ratios P1((r),
+ register word * r /* 0..7 IN/OUT */
+)
+/*
+ * The following scaling for r[..] and LAR[..] has been used:
+ *
+ * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1.
+ * LAR[..] = integer( real_LAR[..] * 16384 );
+ * with -1.625 <= real_LAR <= 1.625
+ */
+{
+ register word temp;
+ register int i;
+
+
+ /* Computation of the LAR[0..7] from the r[0..7]
+ */
+ for (i = 1; i <= 8; i++, r++) {
+
+ temp = *r;
+ temp = GSM_ABS(temp);
+ assert(temp >= 0);
+
+ if (temp < 22118) {
+ temp >>= 1;
+ } else if (temp < 31130) {
+ assert( temp >= 11059 );
+ temp -= 11059;
+ } else {
+ assert( temp >= 26112 );
+ temp -= 26112;
+ temp <<= 2;
+ }
+
+ *r = *r < 0 ? -temp : temp;
+ assert( *r != MIN_WORD );
+ }
+}
+
+/* 4.2.7 */
+
+static void Quantization_and_coding P1((LAR),
+ register word * LAR /* [0..7] IN/OUT */
+)
+{
+ register word temp;
+ longword ltmp;
+
+
+ /* This procedure needs four tables; the following equations
+ * give the optimum scaling for the constants:
+ *
+ * A[0..7] = integer( real_A[0..7] * 1024 )
+ * B[0..7] = integer( real_B[0..7] * 512 )
+ * MAC[0..7] = maximum of the LARc[0..7]
+ * MIC[0..7] = minimum of the LARc[0..7]
+ */
+
+# undef STEP
+# define STEP( A, B, MAC, MIC ) \
+ temp = GSM_MULT( A, *LAR ); \
+ temp = GSM_ADD( temp, B ); \
+ temp = GSM_ADD( temp, 256 ); \
+ temp = SASR( temp, 9 ); \
+ *LAR = temp>MAC ? MAC - MIC : (temp<MIC ? 0 : temp - MIC); \
+ LAR++;
+
+ STEP( 20480, 0, 31, -32 );
+ STEP( 20480, 0, 31, -32 );
+ STEP( 20480, 2048, 15, -16 );
+ STEP( 20480, -2560, 15, -16 );
+
+ STEP( 13964, 94, 7, -8 );
+ STEP( 15360, -1792, 7, -8 );
+ STEP( 8534, -341, 3, -4 );
+ STEP( 9036, -1144, 3, -4 );
+
+# undef STEP
+}
+
+void Gsm_LPC_Analysis P3((S, s,LARc),
+ struct gsm_state *S,
+ word * s, /* 0..159 signals IN/OUT */
+ word * LARc) /* 0..7 LARc's OUT */
+{
+ longword L_ACF[9];
+
+// Wirlab
+ (void)S;
+
+
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+ if (S->fast) Fast_Autocorrelation (s, L_ACF );
+ else
+#endif
+ Autocorrelation (s, L_ACF );
+ Reflection_coefficients (L_ACF, LARc );
+ Transformation_to_Log_Area_Ratios (LARc);
+ Quantization_and_coding (LARc);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/preprocess.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/preprocess.c,v 1.2 1994/05/10 20:18:45 jutta Exp $ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+/* 4.2.0 .. 4.2.3 PREPROCESSING SECTION
+ *
+ * After A-law to linear conversion (or directly from the
+ * Ato D converter) the following scaling is assumed for
+ * input to the RPE-LTP algorithm:
+ *
+ * in: 0.1.....................12
+ * S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.*
+ *
+ * Where S is the sign bit, v a valid bit, and * a "don't care" bit.
+ * The original signal is called sop[..]
+ *
+ * out: 0.1................... 12
+ * S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0
+ */
+
+
+void Gsm_Preprocess P3((S, s, so),
+ struct gsm_state * S,
+ word * s,
+ word * so ) /* [0..159] IN/OUT */
+{
+
+ word z1 = S->z1;
+ longword L_z2 = S->L_z2;
+ word mp = S->mp;
+
+ word s1;
+ longword L_s2;
+
+ longword L_temp;
+
+ word msp, lsp;
+ word SO;
+
+ longword ltmp; /* for ADD */
+ ulongword utmp; /* for L_ADD */
+
+ register int k = 160;
+
+ while (k--) {
+
+ /* 4.2.1 Downscaling of the input signal
+ */
+ SO = SASR( *s, 3 ) << 2;
+ s++;
+
+ assert (SO >= -0x4000); /* downscaled by */
+ assert (SO <= 0x3FFC); /* previous routine. */
+
+
+ /* 4.2.2 Offset compensation
+ *
+ * This part implements a high-pass filter and requires extended
+ * arithmetic precision for the recursive part of this filter.
+ * The input of this procedure is the array so[0...159] and the
+ * output the array sof[ 0...159 ].
+ */
+ /* Compute the non-recursive part
+ */
+
+ s1 = SO - z1; /* s1 = gsm_sub( *so, z1 ); */
+ z1 = SO;
+
+ assert(s1 != MIN_WORD);
+
+ /* Compute the recursive part
+ */
+ L_s2 = s1;
+ L_s2 <<= 15;
+
+ /* Execution of a 31 bv 16 bits multiplication
+ */
+
+ msp = SASR( L_z2, 15 );
+ lsp = L_z2-((longword)msp<<15); /* gsm_L_sub(L_z2,(msp<<15)); */
+
+ L_s2 += GSM_MULT_R( lsp, 32735 );
+ L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/
+ L_z2 = GSM_L_ADD( L_temp, L_s2 );
+
+ /* Compute sof[k] with rounding
+ */
+ L_temp = GSM_L_ADD( L_z2, 16384 );
+
+ /* 4.2.3 Preemphasis
+ */
+
+ msp = GSM_MULT_R( mp, -28180 );
+ mp = SASR( L_temp, 15 );
+ *so++ = GSM_ADD( mp, msp );
+ }
+
+ S->z1 = z1;
+ S->L_z2 = L_z2;
+ S->mp = mp;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/private.h Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,268 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/private.h,v 1.6 1996/07/02 10:15:26 jutta Exp $*/
+
+#ifndef PRIVATE_H
+#define PRIVATE_H
+
+typedef short word; /* 16 bit signed int */
+typedef long longword; /* 32 bit signed int */
+
+typedef unsigned short uword; /* unsigned word */
+typedef unsigned long ulongword; /* unsigned longword */
+
+struct gsm_state {
+
+ word dp0[ 280 ];
+
+ word z1; /* preprocessing.c, Offset_com. */
+ longword L_z2; /* Offset_com. */
+ int mp; /* Preemphasis */
+
+ word u[8]; /* short_term_aly_filter.c */
+ word LARpp[2][8]; /* */
+ word j; /* */
+
+ word ltp_cut; /* long_term.c, LTP crosscorr. */
+ word nrp; /* 40 */ /* long_term.c, synthesis */
+ word v[9]; /* short_term.c, synthesis */
+ word msr; /* decoder.c, Postprocessing */
+
+ char verbose; /* only used if !NDEBUG */
+ char fast; /* only used if FAST */
+
+ char wav_fmt; /* only used if WAV49 defined */
+ unsigned char frame_index; /* odd/even chaining */
+ unsigned char frame_chain; /* half-byte to carry forward */
+};
+
+
+#define MIN_WORD (-32767 - 1)
+#define MAX_WORD 32767
+
+#define MIN_LONGWORD (-2147483647 - 1)
+#define MAX_LONGWORD 2147483647
+
+#ifdef SASR /* flag: >> is a signed arithmetic shift right */
+#undef SASR
+#define SASR(x, by) ((x) >> (by))
+#else
+#define SASR(x, by) ((x) >= 0 ? (x) >> (by) : (~(-((x) + 1) >> (by))))
+#endif /* SASR */
+
+#include "proto.h"
+
+/*
+ * Prototypes from add.c
+ */
+extern word gsm_mult P((word a, word b));
+extern longword gsm_L_mult P((word a, word b));
+extern word gsm_mult_r P((word a, word b));
+
+extern word gsm_div P((word num, word denum));
+
+extern word gsm_add P(( word a, word b ));
+extern longword gsm_L_add P(( longword a, longword b ));
+
+extern word gsm_sub P((word a, word b));
+extern longword gsm_L_sub P((longword a, longword b));
+
+extern word gsm_abs P((word a));
+
+extern word gsm_norm P(( longword a ));
+
+extern longword gsm_L_asl P((longword a, int n));
+extern word gsm_asl P((word a, int n));
+
+extern longword gsm_L_asr P((longword a, int n));
+extern word gsm_asr P((word a, int n));
+
+/*
+ * Inlined functions from add.h
+ */
+
+/*
+ * #define GSM_MULT_R(a, b) (* word a, word b, !(a == b == MIN_WORD) *) \
+ * (0x0FFFF & SASR(((longword)(a) * (longword)(b) + 16384), 15))
+ */
+#define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */ \
+ (SASR( ((longword)(a) * (longword)(b) + 16384), 15 ))
+
+# define GSM_MULT(a,b) /* word a, word b, !(a == b == MIN_WORD) */ \
+ (SASR( ((longword)(a) * (longword)(b)), 15 ))
+
+# define GSM_L_MULT(a, b) /* word a, word b */ \
+ (((longword)(a) * (longword)(b)) << 1)
+
+# define GSM_L_ADD(a, b) \
+ ( (a) < 0 ? ( (b) >= 0 ? (a) + (b) \
+ : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \
+ >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 ) \
+ : ((b) <= 0 ? (a) + (b) \
+ : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \
+ ? MAX_LONGWORD : utmp))
+
+/*
+ * # define GSM_ADD(a, b) \
+ * ((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \
+ * ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp)
+ */
+/* Nonportable, but faster: */
+
+#define GSM_ADD(a, b) \
+ ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \
+ MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp)
+
+# define GSM_SUB(a, b) \
+ ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \
+ ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp)
+
+# define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a))
+
+/* Use these if necessary:
+
+# define GSM_MULT_R(a, b) gsm_mult_r(a, b)
+# define GSM_MULT(a, b) gsm_mult(a, b)
+# define GSM_L_MULT(a, b) gsm_L_mult(a, b)
+
+# define GSM_L_ADD(a, b) gsm_L_add(a, b)
+# define GSM_ADD(a, b) gsm_add(a, b)
+# define GSM_SUB(a, b) gsm_sub(a, b)
+
+# define GSM_ABS(a) gsm_abs(a)
+
+*/
+
+/*
+ * More prototypes from implementations..
+ */
+extern void Gsm_Coder P((
+ struct gsm_state * S,
+ word * s, /* [0..159] samples IN */
+ word * LARc, /* [0..7] LAR coefficients OUT */
+ word * Nc, /* [0..3] LTP lag OUT */
+ word * bc, /* [0..3] coded LTP gain OUT */
+ word * Mc, /* [0..3] RPE grid selection OUT */
+ word * xmaxc,/* [0..3] Coded maximum amplitude OUT */
+ word * xMc /* [13*4] normalized RPE samples OUT */));
+
+extern void Gsm_Long_Term_Predictor P(( /* 4x for 160 samples */
+ struct gsm_state * S,
+ word * d, /* [0..39] residual signal IN */
+ word * dp, /* [-120..-1] d' IN */
+ word * e, /* [0..40] OUT */
+ word * dpp, /* [0..40] OUT */
+ word * Nc, /* correlation lag OUT */
+ word * bc /* gain factor OUT */));
+
+extern void Gsm_LPC_Analysis P((
+ struct gsm_state * S,
+ word * s, /* 0..159 signals IN/OUT */
+ word * LARc)); /* 0..7 LARc's OUT */
+
+extern void Gsm_Preprocess P((
+ struct gsm_state * S,
+ word * s, word * so));
+
+extern void Gsm_Encoding P((
+ struct gsm_state * S,
+ word * e,
+ word * ep,
+ word * xmaxc,
+ word * Mc,
+ word * xMc));
+
+extern void Gsm_Short_Term_Analysis_Filter P((
+ struct gsm_state * S,
+ word * LARc, /* coded log area ratio [0..7] IN */
+ word * d /* st res. signal [0..159] IN/OUT */));
+
+extern void Gsm_Decoder P((
+ struct gsm_state * S,
+ word * LARcr, /* [0..7] IN */
+ word * Ncr, /* [0..3] IN */
+ word * bcr, /* [0..3] IN */
+ word * Mcr, /* [0..3] IN */
+ word * xmaxcr, /* [0..3] IN */
+ word * xMcr, /* [0..13*4] IN */
+ word * s)); /* [0..159] OUT */
+
+extern void Gsm_Decoding P((
+ struct gsm_state * S,
+ word xmaxcr,
+ word Mcr,
+ word * xMcr, /* [0..12] IN */
+ word * erp)); /* [0..39] OUT */
+
+extern void Gsm_Long_Term_Synthesis_Filtering P((
+ struct gsm_state* S,
+ word Ncr,
+ word bcr,
+ word * erp, /* [0..39] IN */
+ word * drp)); /* [-120..-1] IN, [0..40] OUT */
+
+void Gsm_RPE_Decoding P((
+ struct gsm_state *S,
+ word xmaxcr,
+ word Mcr,
+ word * xMcr, /* [0..12], 3 bits IN */
+ word * erp)); /* [0..39] OUT */
+
+void Gsm_RPE_Encoding P((
+ struct gsm_state * S,
+ word * e, /* -5..-1][0..39][40..44 IN/OUT */
+ word * xmaxc, /* OUT */
+ word * Mc, /* OUT */
+ word * xMc)); /* [0..12] OUT */
+
+extern void Gsm_Short_Term_Synthesis_Filter P((
+ struct gsm_state * S,
+ word * LARcr, /* log area ratios [0..7] IN */
+ word * drp, /* received d [0...39] IN */
+ word * s)); /* signal s [0..159] OUT */
+
+extern void Gsm_Update_of_reconstructed_short_time_residual_signal P((
+ word * dpp, /* [0...39] IN */
+ word * ep, /* [0...39] IN */
+ word * dp)); /* [-120...-1] IN/OUT */
+
+/*
+ * Tables from table.c
+ */
+#ifndef GSM_TABLE_C
+
+extern word gsm_A[8], gsm_B[8], gsm_MIC[8], gsm_MAC[8];
+extern word gsm_INVA[8];
+extern word gsm_DLB[4], gsm_QLB[4];
+extern word gsm_H[11];
+extern word gsm_NRFAC[8];
+extern word gsm_FAC[8];
+
+#endif /* GSM_TABLE_C */
+
+/*
+ * Debugging
+ */
+#ifdef NDEBUG
+
+# define gsm_debug_words(a, b, c, d) /* nil */
+# define gsm_debug_longwords(a, b, c, d) /* nil */
+# define gsm_debug_word(a, b) /* nil */
+# define gsm_debug_longword(a, b) /* nil */
+
+#else /* !NDEBUG => DEBUG */
+
+ extern void gsm_debug_words P((char * name, int, int, word *));
+ extern void gsm_debug_longwords P((char * name, int, int, longword *));
+ extern void gsm_debug_longword P((char * name, longword));
+ extern void gsm_debug_word P((char * name, word));
+
+#endif /* !NDEBUG */
+
+#include "unproto.h"
+
+#endif /* PRIVATE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/proto.h Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/proto.h,v 1.1 1992/10/28 00:11:08 jutta Exp $*/
+
+#ifndef PROTO_H
+#define PROTO_H
+
+#if __cplusplus
+# define NeedFunctionPrototypes 1
+#endif
+
+#if __STDC__
+# define NeedFunctionPrototypes 1
+#endif
+
+#ifdef _NO_PROTO
+# undef NeedFunctionPrototypes
+#endif
+
+#undef P /* gnu stdio.h actually defines this... */
+#undef P0
+#undef P1
+#undef P2
+#undef P3
+#undef P4
+#undef P5
+#undef P6
+#undef P7
+#undef P8
+
+#if NeedFunctionPrototypes
+
+# define P( protos ) protos
+
+# define P0() (void)
+# define P1(x, a) (a)
+# define P2(x, a, b) (a, b)
+# define P3(x, a, b, c) (a, b, c)
+# define P4(x, a, b, c, d) (a, b, c, d)
+# define P5(x, a, b, c, d, e) (a, b, c, d, e)
+# define P6(x, a, b, c, d, e, f) (a, b, c, d, e, f)
+# define P7(x, a, b, c, d, e, f, g) (a, b, c, d, e, f, g)
+# define P8(x, a, b, c, d, e, f, g, h) (a, b, c, d, e, f, g, h)
+
+#else /* !NeedFunctionPrototypes */
+
+# define P( protos ) ( /* protos */ )
+
+# define P0() ()
+# define P1(x, a) x a;
+# define P2(x, a, b) x a; b;
+# define P3(x, a, b, c) x a; b; c;
+# define P4(x, a, b, c, d) x a; b; c; d;
+# define P5(x, a, b, c, d, e) x a; b; c; d; e;
+# define P6(x, a, b, c, d, e, f) x a; b; c; d; e; f;
+# define P7(x, a, b, c, d, e, f, g) x a; b; c; d; e; f; g;
+# define P8(x, a, b, c, d, e, f, g, h) x a; b; c; d; e; f; g; h;
+
+#endif /* !NeedFunctionPrototypes */
+
+#endif /* PROTO_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/rpe.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,496 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/rpe.c,v 1.3 1994/05/10 20:18:46 jutta Exp $ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+/* 4.2.13 .. 4.2.17 RPE ENCODING SECTION
+ */
+
+/* 4.2.13 */
+
+static void Weighting_filter P2((e, x),
+ register word * e, /* signal [-5..0.39.44] IN */
+ word * x /* signal [0..39] OUT */
+)
+/*
+ * The coefficients of the weighting filter are stored in a table
+ * (see table 4.4). The following scaling is used:
+ *
+ * H[0..10] = integer( real_H[ 0..10] * 8192 );
+ */
+{
+ /* word wt[ 50 ]; */
+
+ register longword L_result;
+ register int k /* , i */ ;
+
+ /* Initialization of a temporary working array wt[0...49]
+ */
+
+ /* for (k = 0; k <= 4; k++) wt[k] = 0;
+ * for (k = 5; k <= 44; k++) wt[k] = *e++;
+ * for (k = 45; k <= 49; k++) wt[k] = 0;
+ *
+ * (e[-5..-1] and e[40..44] are allocated by the caller,
+ * are initially zero and are not written anywhere.)
+ */
+ e -= 5;
+
+ /* Compute the signal x[0..39]
+ */
+ for (k = 0; k <= 39; k++) {
+
+ L_result = 8192 >> 1;
+
+ /* for (i = 0; i <= 10; i++) {
+ * L_temp = GSM_L_MULT( wt[k+i], gsm_H[i] );
+ * L_result = GSM_L_ADD( L_result, L_temp );
+ * }
+ */
+
+#undef STEP
+#define STEP( i, H ) (e[ k + i ] * (longword)H)
+
+ /* Every one of these multiplications is done twice --
+ * but I don't see an elegant way to optimize this.
+ * Do you?
+ */
+
+#ifdef STUPID_COMPILER
+ L_result += STEP( 0, -134 ) ;
+ L_result += STEP( 1, -374 ) ;
+ /* + STEP( 2, 0 ) */
+ L_result += STEP( 3, 2054 ) ;
+ L_result += STEP( 4, 5741 ) ;
+ L_result += STEP( 5, 8192 ) ;
+ L_result += STEP( 6, 5741 ) ;
+ L_result += STEP( 7, 2054 ) ;
+ /* + STEP( 8, 0 ) */
+ L_result += STEP( 9, -374 ) ;
+ L_result += STEP( 10, -134 ) ;
+#else
+ L_result +=
+ STEP( 0, -134 )
+ + STEP( 1, -374 )
+ /* + STEP( 2, 0 ) */
+ + STEP( 3, 2054 )
+ + STEP( 4, 5741 )
+ + STEP( 5, 8192 )
+ + STEP( 6, 5741 )
+ + STEP( 7, 2054 )
+ /* + STEP( 8, 0 ) */
+ + STEP( 9, -374 )
+ + STEP(10, -134 )
+ ;
+#endif
+
+ /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *)
+ * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *)
+ *
+ * x[k] = SASR( L_result, 16 );
+ */
+
+ /* 2 adds vs. >>16 => 14, minus one shift to compensate for
+ * those we lost when replacing L_MULT by '*'.
+ */
+
+ L_result = SASR( L_result, 13 );
+ x[k] = ( L_result < MIN_WORD ? MIN_WORD
+ : (L_result > MAX_WORD ? MAX_WORD : L_result ));
+ }
+}
+
+/* 4.2.14 */
+
+static void RPE_grid_selection P3((x,xM,Mc_out),
+ word * x, /* [0..39] IN */
+ word * xM, /* [0..12] OUT */
+ word * Mc_out /* OUT */
+)
+/*
+ * The signal x[0..39] is used to select the RPE grid which is
+ * represented by Mc.
+ */
+{
+ /* register word temp1; */
+ register int /* m, */ i;
+ register longword L_result, L_temp;
+ longword EM; /* xxx should be L_EM? */
+ word Mc;
+
+ longword L_common_0_3;
+
+ EM = 0;
+ Mc = 0;
+
+ /* for (m = 0; m <= 3; m++) {
+ * L_result = 0;
+ *
+ *
+ * for (i = 0; i <= 12; i++) {
+ *
+ * temp1 = SASR( x[m + 3*i], 2 );
+ *
+ * assert(temp1 != MIN_WORD);
+ *
+ * L_temp = GSM_L_MULT( temp1, temp1 );
+ * L_result = GSM_L_ADD( L_temp, L_result );
+ * }
+ *
+ * if (L_result > EM) {
+ * Mc = m;
+ * EM = L_result;
+ * }
+ * }
+ */
+
+#undef STEP
+#define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \
+ L_result += L_temp * L_temp;
+
+ /* common part of 0 and 3 */
+
+ L_result = 0;
+ STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 );
+ STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 );
+ STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12);
+ L_common_0_3 = L_result;
+
+ /* i = 0 */
+
+ STEP( 0, 0 );
+ L_result <<= 1; /* implicit in L_MULT */
+ EM = L_result;
+
+ /* i = 1 */
+
+ L_result = 0;
+ STEP( 1, 0 );
+ STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 );
+ STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 );
+ STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12);
+ L_result <<= 1;
+ if (L_result > EM) {
+ Mc = 1;
+ EM = L_result;
+ }
+
+ /* i = 2 */
+
+ L_result = 0;
+ STEP( 2, 0 );
+ STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 );
+ STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 );
+ STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12);
+ L_result <<= 1;
+ if (L_result > EM) {
+ Mc = 2;
+ EM = L_result;
+ }
+
+ /* i = 3 */
+
+ L_result = L_common_0_3;
+ STEP( 3, 12 );
+ L_result <<= 1;
+ if (L_result > EM) {
+ Mc = 3;
+ EM = L_result;
+ }
+
+ /**/
+
+ /* Down-sampling by a factor 3 to get the selected xM[0..12]
+ * RPE sequence.
+ */
+ for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i];
+ *Mc_out = Mc;
+}
+
+/* 4.12.15 */
+
+static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out),
+ word xmaxc, /* IN */
+ word * exp_out, /* OUT */
+ word * mant_out ) /* OUT */
+{
+ word exp, mant;
+
+ /* Compute exponent and mantissa of the decoded version of xmaxc
+ */
+
+ exp = 0;
+ if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1;
+ mant = xmaxc - (exp << 3);
+
+ if (mant == 0) {
+ exp = -4;
+ mant = 7;
+ }
+ else {
+ while (mant <= 7) {
+ mant = mant << 1 | 1;
+ exp--;
+ }
+ mant -= 8;
+ }
+
+ assert( exp >= -4 && exp <= 6 );
+ assert( mant >= 0 && mant <= 7 );
+
+ *exp_out = exp;
+ *mant_out = mant;
+}
+
+static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out),
+ word * xM, /* [0..12] IN */
+
+ word * xMc, /* [0..12] OUT */
+ word * mant_out, /* OUT */
+ word * exp_out, /* OUT */
+ word * xmaxc_out /* OUT */
+)
+{
+ int i, itest;
+
+ word xmax, xmaxc, temp, temp1, temp2;
+ word exp, mant;
+
+
+ /* Find the maximum absolute value xmax of xM[0..12].
+ */
+
+ xmax = 0;
+ for (i = 0; i <= 12; i++) {
+ temp = xM[i];
+ temp = GSM_ABS(temp);
+ if (temp > xmax) xmax = temp;
+ }
+
+ /* Qantizing and coding of xmax to get xmaxc.
+ */
+
+ exp = 0;
+ temp = SASR( xmax, 9 );
+ itest = 0;
+
+ for (i = 0; i <= 5; i++) {
+
+ itest |= (temp <= 0);
+ temp = SASR( temp, 1 );
+
+ assert(exp <= 5);
+ if (itest == 0) exp++; /* exp = add (exp, 1) */
+ }
+
+ assert(exp <= 6 && exp >= 0);
+ temp = exp + 5;
+
+ assert(temp <= 11 && temp >= 0);
+ xmaxc = gsm_add( SASR(xmax, temp), exp << 3 );
+
+ /* Quantizing and coding of the xM[0..12] RPE sequence
+ * to get the xMc[0..12]
+ */
+
+ APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant );
+
+ /* This computation uses the fact that the decoded version of xmaxc
+ * can be calculated by using the exponent and the mantissa part of
+ * xmaxc (logarithmic table).
+ * So, this method avoids any division and uses only a scaling
+ * of the RPE samples by a function of the exponent. A direct
+ * multiplication by the inverse of the mantissa (NRFAC[0..7]
+ * found in table 4.5) gives the 3 bit coded version xMc[0..12]
+ * of the RPE samples.
+ */
+
+
+ /* Direct computation of xMc[0..12] using table 4.5
+ */
+
+ assert( exp <= 4096 && exp >= -4096);
+ assert( mant >= 0 && mant <= 7 );
+
+ temp1 = 6 - exp; /* normalization by the exponent */
+ temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */
+
+ for (i = 0; i <= 12; i++) {
+
+ assert(temp1 >= 0 && temp1 < 16);
+
+ temp = xM[i] << temp1;
+ temp = GSM_MULT( temp, temp2 );
+ temp = SASR(temp, 12);
+ xMc[i] = temp + 4; /* see note below */
+ }
+
+ /* NOTE: This equation is used to make all the xMc[i] positive.
+ */
+
+ *mant_out = mant;
+ *exp_out = exp;
+ *xmaxc_out = xmaxc;
+}
+
+/* 4.2.16 */
+
+static void APCM_inverse_quantization P4((xMc,mant,exp,xMp),
+ register word * xMc, /* [0..12] IN */
+ word mant,
+ word exp,
+ register word * xMp) /* [0..12] OUT */
+/*
+ * This part is for decoding the RPE sequence of coded xMc[0..12]
+ * samples to obtain the xMp[0..12] array. Table 4.6 is used to get
+ * the mantissa of xmaxc (FAC[0..7]).
+ */
+{
+ int i;
+ word temp, temp1, temp2, temp3;
+ longword ltmp;
+
+ assert( mant >= 0 && mant <= 7 );
+
+ temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */
+ temp2 = gsm_sub( 6, exp ); /* see 4.2-15 for exp */
+ temp3 = gsm_asl( 1, gsm_sub( temp2, 1 ));
+
+ for (i = 13; i--;) {
+
+ assert( *xMc <= 7 && *xMc >= 0 ); /* 3 bit unsigned */
+
+ /* temp = gsm_sub( *xMc++ << 1, 7 ); */
+ temp = (*xMc++ << 1) - 7; /* restore sign */
+ assert( temp <= 7 && temp >= -7 ); /* 4 bit signed */
+
+ temp <<= 12; /* 16 bit signed */
+ temp = GSM_MULT_R( temp1, temp );
+ temp = GSM_ADD( temp, temp3 );
+ *xMp++ = gsm_asr( temp, temp2 );
+ }
+}
+
+/* 4.2.17 */
+
+static void RPE_grid_positioning P3((Mc,xMp,ep),
+ word Mc, /* grid position IN */
+ register word * xMp, /* [0..12] IN */
+ register word * ep /* [0..39] OUT */
+)
+/*
+ * This procedure computes the reconstructed long term residual signal
+ * ep[0..39] for the LTP analysis filter. The inputs are the Mc
+ * which is the grid position selection and the xMp[0..12] decoded
+ * RPE samples which are upsampled by a factor of 3 by inserting zero
+ * values.
+ */
+{
+ int i = 13;
+
+ assert(0 <= Mc && Mc <= 3);
+
+ switch (Mc) {
+ case 3: *ep++ = 0;
+ case 2: do {
+ *ep++ = 0;
+ case 1: *ep++ = 0;
+ case 0: *ep++ = *xMp++;
+ } while (--i);
+ }
+ while (++Mc < 4) *ep++ = 0;
+
+ /*
+
+ int i, k;
+ for (k = 0; k <= 39; k++) ep[k] = 0;
+ for (i = 0; i <= 12; i++) {
+ ep[ Mc + (3*i) ] = xMp[i];
+ }
+ */
+}
+
+/* 4.2.18 */
+
+/* This procedure adds the reconstructed long term residual signal
+ * ep[0..39] to the estimated signal dpp[0..39] from the long term
+ * analysis filter to compute the reconstructed short term residual
+ * signal dp[-40..-1]; also the reconstructed short term residual
+ * array dp[-120..-41] is updated.
+ */
+
+#if 0 /* Has been inlined in code.c */
+void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp),
+ word * dpp, /* [0...39] IN */
+ word * ep, /* [0...39] IN */
+ word * dp) /* [-120...-1] IN/OUT */
+{
+ int k;
+
+ for (k = 0; k <= 79; k++)
+ dp[ -120 + k ] = dp[ -80 + k ];
+
+ for (k = 0; k <= 39; k++)
+ dp[ -40 + k ] = gsm_add( ep[k], dpp[k] );
+}
+#endif /* Has been inlined in code.c */
+
+void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc),
+
+ struct gsm_state * S,
+
+ word * e, /* -5..-1][0..39][40..44 IN/OUT */
+ word * xmaxc, /* OUT */
+ word * Mc, /* OUT */
+ word * xMc) /* [0..12] OUT */
+{
+ word x[40];
+ word xM[13], xMp[13];
+ word mant, exp;
+// Wirlab
+ (void)S;
+
+
+
+ Weighting_filter(e, x);
+ RPE_grid_selection(x, xM, Mc);
+
+ APCM_quantization( xM, xMc, &mant, &exp, xmaxc);
+ APCM_inverse_quantization( xMc, mant, exp, xMp);
+
+ RPE_grid_positioning( *Mc, xMp, e );
+
+}
+
+void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp),
+ struct gsm_state * S,
+
+ word xmaxcr,
+ word Mcr,
+ word * xMcr, /* [0..12], 3 bits IN */
+ word * erp /* [0..39] OUT */
+)
+{
+ word exp, mant;
+ word xMp[ 13 ];
+// Wirlab
+ (void)S;
+
+
+
+ APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant );
+ APCM_inverse_quantization( xMcr, mant, exp, xMp );
+ RPE_grid_positioning( Mcr, xMp, erp );
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/short_term.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,429 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/short_term.c,v 1.2 1994/05/10 20:18:47 jutta Exp $ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+/*
+ * SHORT TERM ANALYSIS FILTERING SECTION
+ */
+
+/* 4.2.8 */
+
+static void Decoding_of_the_coded_Log_Area_Ratios P2((LARc,LARpp),
+ word * LARc, /* coded log area ratio [0..7] IN */
+ word * LARpp) /* out: decoded .. */
+{
+ register word temp1 /* , temp2 */;
+ register long ltmp; /* for GSM_ADD */
+
+ /* This procedure requires for efficient implementation
+ * two tables.
+ *
+ * INVA[1..8] = integer( (32768 * 8) / real_A[1..8])
+ * MIC[1..8] = minimum value of the LARc[1..8]
+ */
+
+ /* Compute the LARpp[1..8]
+ */
+
+ /* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) {
+ *
+ * temp1 = GSM_ADD( *LARc, *MIC ) << 10;
+ * temp2 = *B << 1;
+ * temp1 = GSM_SUB( temp1, temp2 );
+ *
+ * assert(*INVA != MIN_WORD);
+ *
+ * temp1 = GSM_MULT_R( *INVA, temp1 );
+ * *LARpp = GSM_ADD( temp1, temp1 );
+ * }
+ */
+
+#undef STEP
+#define STEP( B, MIC, INVA ) \
+ temp1 = GSM_ADD( *LARc++, MIC ) << 10; \
+ temp1 = GSM_SUB( temp1, B << 1 ); \
+ temp1 = GSM_MULT_R( INVA, temp1 ); \
+ *LARpp++ = GSM_ADD( temp1, temp1 );
+
+ STEP( 0, -32, 13107 );
+ STEP( 0, -32, 13107 );
+ STEP( 2048, -16, 13107 );
+ STEP( -2560, -16, 13107 );
+
+ STEP( 94, -8, 19223 );
+ STEP( -1792, -8, 17476 );
+ STEP( -341, -4, 31454 );
+ STEP( -1144, -4, 29708 );
+
+ /* NOTE: the addition of *MIC is used to restore
+ * the sign of *LARc.
+ */
+}
+
+/* 4.2.9 */
+/* Computation of the quantized reflection coefficients
+ */
+
+/* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8]
+ */
+
+/*
+ * Within each frame of 160 analyzed speech samples the short term
+ * analysis and synthesis filters operate with four different sets of
+ * coefficients, derived from the previous set of decoded LARs(LARpp(j-1))
+ * and the actual set of decoded LARs (LARpp(j))
+ *
+ * (Initial value: LARpp(j-1)[1..8] = 0.)
+ */
+
+static void Coefficients_0_12 P3((LARpp_j_1, LARpp_j, LARp),
+ register word * LARpp_j_1,
+ register word * LARpp_j,
+ register word * LARp)
+{
+ register int i;
+ register longword ltmp;
+
+ for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) {
+ *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ));
+ *LARp = GSM_ADD( *LARp, SASR( *LARpp_j_1, 1));
+ }
+}
+
+static void Coefficients_13_26 P3((LARpp_j_1, LARpp_j, LARp),
+ register word * LARpp_j_1,
+ register word * LARpp_j,
+ register word * LARp)
+{
+ register int i;
+ register longword ltmp;
+ for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
+ *LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 ));
+ }
+}
+
+static void Coefficients_27_39 P3((LARpp_j_1, LARpp_j, LARp),
+ register word * LARpp_j_1,
+ register word * LARpp_j,
+ register word * LARp)
+{
+ register int i;
+ register longword ltmp;
+
+ for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
+ *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ));
+ *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 ));
+ }
+}
+
+
+static void Coefficients_40_159 P2((LARpp_j, LARp),
+ register word * LARpp_j,
+ register word * LARp)
+{
+ register int i;
+
+ for (i = 1; i <= 8; i++, LARp++, LARpp_j++)
+ *LARp = *LARpp_j;
+}
+
+/* 4.2.9.2 */
+
+static void LARp_to_rp P1((LARp),
+ register word * LARp) /* [0..7] IN/OUT */
+/*
+ * The input of this procedure is the interpolated LARp[0..7] array.
+ * The reflection coefficients, rp[i], are used in the analysis
+ * filter and in the synthesis filter.
+ */
+{
+ register int i;
+ register word temp;
+ register longword ltmp;
+
+ for (i = 1; i <= 8; i++, LARp++) {
+
+ /* temp = GSM_ABS( *LARp );
+ *
+ * if (temp < 11059) temp <<= 1;
+ * else if (temp < 20070) temp += 11059;
+ * else temp = GSM_ADD( temp >> 2, 26112 );
+ *
+ * *LARp = *LARp < 0 ? -temp : temp;
+ */
+
+ if (*LARp < 0) {
+ temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp);
+ *LARp = - ((temp < 11059) ? temp << 1
+ : ((temp < 20070) ? temp + 11059
+ : GSM_ADD( temp >> 2, 26112 )));
+ } else {
+ temp = *LARp;
+ *LARp = (temp < 11059) ? temp << 1
+ : ((temp < 20070) ? temp + 11059
+ : GSM_ADD( temp >> 2, 26112 ));
+ }
+ }
+}
+
+
+/* 4.2.10 */
+static void Short_term_analysis_filtering P4((S,rp,k_n,s),
+ struct gsm_state * S,
+ register word * rp, /* [0..7] IN */
+ register int k_n, /* k_end - k_start */
+ register word * s /* [0..n-1] IN/OUT */
+)
+/*
+ * This procedure computes the short term residual signal d[..] to be fed
+ * to the RPE-LTP loop from the s[..] signal and from the local rp[..]
+ * array (quantized reflection coefficients). As the call of this
+ * procedure can be done in many ways (see the interpolation of the LAR
+ * coefficient), it is assumed that the computation begins with index
+ * k_start (for arrays d[..] and s[..]) and stops with index k_end
+ * (k_start and k_end are defined in 4.2.9.1). This procedure also
+ * needs to keep the array u[0..7] in memory for each call.
+ */
+{
+ register word * u = S->u;
+ register int i;
+ register word di, zzz, ui, sav, rpi;
+ register longword ltmp;
+
+ for (; k_n--; s++) {
+
+ di = sav = *s;
+
+ for (i = 0; i < 8; i++) { /* YYY */
+
+ ui = u[i];
+ rpi = rp[i];
+ u[i] = sav;
+
+ zzz = GSM_MULT_R(rpi, di);
+ sav = GSM_ADD( ui, zzz);
+
+ zzz = GSM_MULT_R(rpi, ui);
+ di = GSM_ADD( di, zzz );
+ }
+
+ *s = di;
+ }
+}
+
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+
+static void Fast_Short_term_analysis_filtering P4((S,rp,k_n,s),
+ struct gsm_state * S,
+ register word * rp, /* [0..7] IN */
+ register int k_n, /* k_end - k_start */
+ register word * s /* [0..n-1] IN/OUT */
+)
+{
+ register word * u = S->u;
+ register int i;
+
+ float uf[8],
+ rpf[8];
+
+ register float scalef = 3.0517578125e-5;
+ register float sav, di, temp;
+
+ for (i = 0; i < 8; ++i) {
+ uf[i] = u[i];
+ rpf[i] = rp[i] * scalef;
+ }
+ for (; k_n--; s++) {
+ sav = di = *s;
+ for (i = 0; i < 8; ++i) {
+ register float rpfi = rpf[i];
+ register float ufi = uf[i];
+
+ uf[i] = sav;
+ temp = rpfi * di + ufi;
+ di += rpfi * ufi;
+ sav = temp;
+ }
+ *s = di;
+ }
+ for (i = 0; i < 8; ++i) u[i] = uf[i];
+}
+#endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */
+
+static void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),
+ struct gsm_state * S,
+ register word * rrp, /* [0..7] IN */
+ register int k, /* k_end - k_start */
+ register word * wt, /* [0..k-1] IN */
+ register word * sr /* [0..k-1] OUT */
+)
+{
+ register word * v = S->v;
+ register int i;
+ register word sri, tmp1, tmp2;
+ register longword ltmp; /* for GSM_ADD & GSM_SUB */
+
+ while (k--) {
+ sri = *wt++;
+ for (i = 8; i--;) {
+
+ /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) );
+ */
+ tmp1 = rrp[i];
+ tmp2 = v[i];
+ tmp2 = ( tmp1 == MIN_WORD && tmp2 == MIN_WORD
+ ? MAX_WORD
+ : 0x0FFFF & (( (longword)tmp1 * (longword)tmp2
+ + 16384) >> 15)) ;
+
+ sri = GSM_SUB( sri, tmp2 );
+
+ /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) );
+ */
+ tmp1 = ( tmp1 == MIN_WORD && sri == MIN_WORD
+ ? MAX_WORD
+ : 0x0FFFF & (( (longword)tmp1 * (longword)sri
+ + 16384) >> 15)) ;
+
+ v[i+1] = GSM_ADD( v[i], tmp1);
+ }
+ *sr++ = v[0] = sri;
+ }
+}
+
+
+#if defined(FAST) && defined(USE_FLOAT_MUL)
+
+static void Fast_Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),
+ struct gsm_state * S,
+ register word * rrp, /* [0..7] IN */
+ register int k, /* k_end - k_start */
+ register word * wt, /* [0..k-1] IN */
+ register word * sr /* [0..k-1] OUT */
+)
+{
+ register word * v = S->v;
+ register int i;
+
+ float va[9], rrpa[8];
+ register float scalef = 3.0517578125e-5, temp;
+
+ for (i = 0; i < 8; ++i) {
+ va[i] = v[i];
+ rrpa[i] = (float)rrp[i] * scalef;
+ }
+ while (k--) {
+ register float sri = *wt++;
+ for (i = 8; i--;) {
+ sri -= rrpa[i] * va[i];
+ if (sri < -32768.) sri = -32768.;
+ else if (sri > 32767.) sri = 32767.;
+
+ temp = va[i] + rrpa[i] * sri;
+ if (temp < -32768.) temp = -32768.;
+ else if (temp > 32767.) temp = 32767.;
+ va[i+1] = temp;
+ }
+ *sr++ = va[0] = sri;
+ }
+ for (i = 0; i < 9; ++i) v[i] = va[i];
+}
+
+#endif /* defined(FAST) && defined(USE_FLOAT_MUL) */
+
+void Gsm_Short_Term_Analysis_Filter P3((S,LARc,s),
+
+ struct gsm_state * S,
+
+ word * LARc, /* coded log area ratio [0..7] IN */
+ word * s /* signal [0..159] IN/OUT */
+)
+{
+ word * LARpp_j = S->LARpp[ S->j ];
+ word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ];
+
+ word LARp[8];
+
+#undef FILTER
+#if defined(FAST) && defined(USE_FLOAT_MUL)
+# define FILTER (* (S->fast \
+ ? Fast_Short_term_analysis_filtering \
+ : Short_term_analysis_filtering ))
+
+#else
+# define FILTER Short_term_analysis_filtering
+#endif
+
+ Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j );
+
+ Coefficients_0_12( LARpp_j_1, LARpp_j, LARp );
+ LARp_to_rp( LARp );
+ FILTER( S, LARp, 13, s);
+
+ Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
+ LARp_to_rp( LARp );
+ FILTER( S, LARp, 14, s + 13);
+
+ Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
+ LARp_to_rp( LARp );
+ FILTER( S, LARp, 13, s + 27);
+
+ Coefficients_40_159( LARpp_j, LARp);
+ LARp_to_rp( LARp );
+ FILTER( S, LARp, 120, s + 40);
+}
+
+void Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s),
+ struct gsm_state * S,
+
+ word * LARcr, /* received log area ratios [0..7] IN */
+ word * wt, /* received d [0..159] IN */
+
+ word * s /* signal s [0..159] OUT */
+)
+{
+ word * LARpp_j = S->LARpp[ S->j ];
+ word * LARpp_j_1 = S->LARpp[ S->j ^=1 ];
+
+ word LARp[8];
+
+#undef FILTER
+#if defined(FAST) && defined(USE_FLOAT_MUL)
+
+# define FILTER (* (S->fast \
+ ? Fast_Short_term_synthesis_filtering \
+ : Short_term_synthesis_filtering ))
+#else
+# define FILTER Short_term_synthesis_filtering
+#endif
+
+ Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j );
+
+ Coefficients_0_12( LARpp_j_1, LARpp_j, LARp );
+ LARp_to_rp( LARp );
+ FILTER( S, LARp, 13, wt, s );
+
+ Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
+ LARp_to_rp( LARp );
+ FILTER( S, LARp, 14, wt + 13, s + 13 );
+
+ Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
+ LARp_to_rp( LARp );
+ FILTER( S, LARp, 13, wt + 27, s + 27 );
+
+ Coefficients_40_159( LARpp_j, LARp );
+ LARp_to_rp( LARp );
+ FILTER(S, LARp, 120, wt + 40, s + 40);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/table.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/table.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */
+
+/* Most of these tables are inlined at their point of use.
+ */
+
+/* 4.4 TABLES USED IN THE FIXED POINT IMPLEMENTATION OF THE RPE-LTP
+ * CODER AND DECODER
+ *
+ * (Most of them inlined, so watch out.)
+ */
+
+#define GSM_TABLE_C
+#include "private.h"
+#include "gsm.h"
+
+/* Table 4.1 Quantization of the Log.-Area Ratios
+ */
+/* i 1 2 3 4 5 6 7 8 */
+word gsm_A[8] = {20480, 20480, 20480, 20480, 13964, 15360, 8534, 9036};
+word gsm_B[8] = { 0, 0, 2048, -2560, 94, -1792, -341, -1144};
+word gsm_MIC[8] = { -32, -32, -16, -16, -8, -8, -4, -4 };
+word gsm_MAC[8] = { 31, 31, 15, 15, 7, 7, 3, 3 };
+
+
+/* Table 4.2 Tabulation of 1/A[1..8]
+ */
+word gsm_INVA[8]={ 13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708 };
+
+
+/* Table 4.3a Decision level of the LTP gain quantizer
+ */
+/* bc 0 1 2 3 */
+word gsm_DLB[4] = { 6554, 16384, 26214, 32767 };
+
+
+/* Table 4.3b Quantization levels of the LTP gain quantizer
+ */
+/* bc 0 1 2 3 */
+word gsm_QLB[4] = { 3277, 11469, 21299, 32767 };
+
+
+/* Table 4.4 Coefficients of the weighting filter
+ */
+/* i 0 1 2 3 4 5 6 7 8 9 10 */
+word gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 };
+
+
+/* Table 4.5 Normalized inverse mantissa used to compute xM/xmax
+ */
+/* i 0 1 2 3 4 5 6 7 */
+word gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 };
+
+
+/* Table 4.6 Normalized direct mantissa used to compute xM/xmax
+ */
+/* i 0 1 2 3 4 5 6 7 */
+word gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/toast_alaw.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,334 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /home/kbs/jutta/src/gsm/gsm-1.0/src/RCS/toast_alaw.c,v 1.2 1996/07/05 17:23:46 jutta Exp $ */
+
+#include "toast.h"
+
+/* toast_alaw.c -- manipulate A-law encoded sound.
+ */
+
+extern FILE * in, * out;
+
+#define A2S(x) (a2s[ (unsigned char )(x) ])
+#define S2A(x) (s2a[ ((unsigned short)(x)) >> 4 ])
+
+static unsigned short a2s[] = {
+
+ 60032, 60288, 59520, 59776, 61056, 61312, 60544, 60800,
+ 57984, 58240, 57472, 57728, 59008, 59264, 58496, 58752,
+ 62784, 62912, 62528, 62656, 63296, 63424, 63040, 63168,
+ 61760, 61888, 61504, 61632, 62272, 62400, 62016, 62144,
+ 43520, 44544, 41472, 42496, 47616, 48640, 45568, 46592,
+ 35328, 36352, 33280, 34304, 39424, 40448, 37376, 38400,
+ 54528, 55040, 53504, 54016, 56576, 57088, 55552, 56064,
+ 50432, 50944, 49408, 49920, 52480, 52992, 51456, 51968,
+ 65192, 65208, 65160, 65176, 65256, 65272, 65224, 65240,
+ 65064, 65080, 65032, 65048, 65128, 65144, 65096, 65112,
+ 65448, 65464, 65416, 65432, 65512, 65528, 65480, 65496,
+ 65320, 65336, 65288, 65304, 65384, 65400, 65352, 65368,
+ 64160, 64224, 64032, 64096, 64416, 64480, 64288, 64352,
+ 63648, 63712, 63520, 63584, 63904, 63968, 63776, 63840,
+ 64848, 64880, 64784, 64816, 64976, 65008, 64912, 64944,
+ 64592, 64624, 64528, 64560, 64720, 64752, 64656, 64688,
+ 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
+ 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
+ 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
+ 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
+ 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
+ 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
+ 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
+ 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
+ 344, 328, 376, 360, 280, 264, 312, 296,
+ 472, 456, 504, 488, 408, 392, 440, 424,
+ 88, 72, 120, 104, 24, 8, 56, 40,
+ 216, 200, 248, 232, 152, 136, 184, 168,
+ 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
+ 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
+ 688, 656, 752, 720, 560, 528, 624, 592,
+ 944, 912, 1008, 976, 816, 784, 880, 848
+
+};
+
+
+static unsigned char s2a[] = {
+
+ 213,212,215,214,209,208,211,210,221,220,223,222,217,216,219,218,
+ 197,196,199,198,193,192,195,194,205,204,207,206,201,200,203,202,
+ 245,245,244,244,247,247,246,246,241,241,240,240,243,243,242,242,
+ 253,253,252,252,255,255,254,254,249,249,248,248,251,251,250,250,
+ 229,229,229,229,228,228,228,228,231,231,231,231,230,230,230,230,
+ 225,225,225,225,224,224,224,224,227,227,227,227,226,226,226,226,
+ 237,237,237,237,236,236,236,236,239,239,239,239,238,238,238,238,
+ 233,233,233,233,232,232,232,232,235,235,235,235,234,234,234,234,
+ 149,149,149,149,149,149,149,149,148,148,148,148,148,148,148,148,
+ 151,151,151,151,151,151,151,151,150,150,150,150,150,150,150,150,
+ 145,145,145,145,145,145,145,145,144,144,144,144,144,144,144,144,
+ 147,147,147,147,147,147,147,147,146,146,146,146,146,146,146,146,
+ 157,157,157,157,157,157,157,157,156,156,156,156,156,156,156,156,
+ 159,159,159,159,159,159,159,159,158,158,158,158,158,158,158,158,
+ 153,153,153,153,153,153,153,153,152,152,152,152,152,152,152,152,
+ 155,155,155,155,155,155,155,155,154,154,154,154,154,154,154,154,
+ 133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+ 132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+ 135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+ 134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+ 130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+ 141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+ 140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+ 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+ 137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+ 136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+ 139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+ 138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+ 181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+ 181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+ 180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+ 180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+ 183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+ 183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+ 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+ 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+ 177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+ 177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+ 176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+ 176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+ 179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+ 179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+ 178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+ 178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+ 189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+ 189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+ 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+ 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+ 191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+ 191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+ 190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+ 190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+ 185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+ 185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+ 184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+ 184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+ 187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+ 187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+ 186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+ 186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+ 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+ 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+ 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+ 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+ 164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+ 164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+ 164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+ 164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+ 167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+ 167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+ 167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+ 167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+ 166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+ 166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+ 166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+ 166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+ 161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+ 161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+ 161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+ 161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+ 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+ 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+ 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+ 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+ 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+ 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+ 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+ 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+ 173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+ 173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+ 173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+ 173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+ 172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+ 172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+ 172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+ 172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+ 175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+ 175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+ 175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+ 175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+ 174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+ 174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+ 174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+ 174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+ 169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+ 169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+ 169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+ 169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+ 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+ 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+ 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+ 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+ 171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+ 171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+ 171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+ 171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+ 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+ 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+ 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+ 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
+ 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+ 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25,
+ 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31,
+ 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29,
+ 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19,
+ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17,
+ 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+ 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21,
+ 106,106,106,106,107,107,107,107,104,104,104,104,105,105,105,105,
+ 110,110,110,110,111,111,111,111,108,108,108,108,109,109,109,109,
+ 98, 98, 98, 98, 99, 99, 99, 99, 96, 96, 96, 96, 97, 97, 97, 97,
+ 102,102,102,102,103,103,103,103,100,100,100,100,101,101,101,101,
+ 122,122,123,123,120,120,121,121,126,126,127,127,124,124,125,125,
+ 114,114,115,115,112,112,113,113,118,118,119,119,116,116,117,117,
+ 74, 75, 72, 73, 78, 79, 76, 77, 66, 67, 64, 65, 70, 71, 68, 69,
+ 90, 91, 88, 89, 94, 95, 92, 93, 82, 83, 80, 81, 86, 87, 84, 85
+};
+
+int alaw_input P1((buf), gsm_signal * buf)
+{
+ int i, c;
+
+ for (i = 0; i < 160 && (c = fgetc(in)) != EOF; i++) buf[i] = A2S( c );
+ if (c == EOF && ferror(in)) return -1;
+ return i;
+}
+
+int alaw_output P1((buf), gsm_signal * buf)
+{
+ int i;
+
+ for (i = 0; i < 160; i++, buf++)
+ if (fputc( S2A( *buf ), out) == EOF) return -1;
+ return 0;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/toast_audio.c Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/toast_audio.c,v 1.6 1995/03/07 21:21:24 jutta Exp $ */
+
+#include "toast.h"
+
+/* toast_audio -- functions to manipulate SunOS audio files.
+ *
+ * This is reverse engineered from our present soundfiles
+ * and in no way portable, durable or aesthetically pleasing.
+ */
+
+extern FILE * in, * out;
+extern char * inname;
+extern char * progname;
+
+extern int (*output) P((gsm_signal *)),
+ (*input ) P((gsm_signal *));
+
+extern int alaw_input P((gsm_signal *)),
+ ulaw_input P((gsm_signal *)),
+ linear_input P((gsm_signal *));
+
+extern int ulaw_output P((gsm_signal *));
+
+static int put_u32 P2((f, u), FILE * f, unsigned long u)
+{
+ /* Write a 32-bit unsigned value msb first.
+ */
+ if ( putc( (char)((u>>24) & 0x0FF), f) == EOF
+ || putc( (char)((u>>16) & 0x0FF), f) == EOF
+ || putc( (char)((u>> 8) & 0x0FF), f) == EOF
+ || putc( (char)( u & 0x0FF), f) == EOF) return -1;
+
+ return 0;
+}
+
+static int get_u32 P2((f, up), FILE * f, unsigned long * up)
+{
+ /* Read a 32-bit unsigned value msb first.
+ */
+ int i;
+ unsigned long u;
+
+ if ( (i = getc(f)) == EOF
+ || ((u = (unsigned char)i), (i = getc(f)) == EOF)
+ || ((u = (u<<8)|(unsigned char)i), (i = getc(f)) == EOF)
+ || ((u = (u<<8)|(unsigned char)i), (i = getc(f)) == EOF)) return -1;
+ *up = (u<<8)|(unsigned char)i;
+ return 0;
+}
+
+int audio_init_input P0()
+{
+ unsigned long len, enc; /* unsigned 32 bits */
+
+ if ( fgetc(in) != '.'
+ || fgetc(in) != 's'
+ || fgetc(in) != 'n'
+ || fgetc(in) != 'd'
+ || get_u32( in, &len )
+ || get_u32( in, &enc ) /* skip this */
+ || get_u32( in, &enc )) {
+ fprintf(stderr,
+ "%s: bad (missing?) header in Sun audio file \"%s\";\n\
+ Try one of -u, -a, -l instead (%s -h for help).\n",
+ progname, inname ? inname : "stdin", progname);
+ return -1;
+ }
+
+ switch (enc) {
+ case 1: input = ulaw_input; break;
+ case 2: input = alaw_input; break;
+ case 3: input = linear_input; break;
+ default:
+ fprintf(stderr,
+"%s: warning: file format #%lu for %s not implemented, defaulting to u-law.\n",
+ progname, enc, inname);
+ input = ulaw_input;
+ break;
+ }
+
+ while (len > 4*4)
+ if (getc(in) == EOF) {
+ fprintf(stderr,
+ "%s: EOF in header of Sun audio file \"%s\";\n\
+ Try one of -u, -a, -l instead (%s -h for help).\n",
+ progname, inname ? inname : "stdin", progname);
+ return -1;
+ }
+ else len--;
+
+ return 0;
+}
+
+int audio_init_output P0()
+{
+ if ( fputs(".snd", out) == EOF
+ || put_u32(out, 32)
+ || put_u32(out, ~(unsigned long)0)
+ || put_u32(out, 1)
+ || put_u32(out, 8000)
+ || put_u32(out, 1)
+ || put_u32(out, 0)
+ || put_u32(out, 0)) return -1;
+
+ return 0;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jni/gsm/unproto.h Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,23 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/unproto.h,v 1.1 1992/10/28 00:11:08 jutta Exp $*/
+
+#ifdef PROTO_H /* sic */
+#undef PROTO_H
+
+#undef P
+#undef P0
+#undef P1
+#undef P2
+#undef P3
+#undef P4
+#undef P5
+#undef P6
+#undef P7
+#undef P8
+
+#endif /* PROTO_H */
Binary file libs/armeabi/libOSNetworkSystem.so has changed
Binary file libs/asmack-android-10-beem.jar has changed
Binary file libs/asmack-android-7-beem.jar has changed
--- a/project.properties Thu May 10 16:11:18 2012 +0200
+++ b/project.properties Tue Jun 05 16:44:38 2012 +0200
@@ -8,4 +8,4 @@
# project structure.
# Project target.
-target=android-8
+target=android-10
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/res/layout/call.xml Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_height="fill_parent" android:layout_width="fill_parent"
+ android:orientation="vertical">
+ <LinearLayout android:layout_width="fill_parent"
+ android:layout_height="fill_parent" android:orientation="vertical"
+ android:layout_weight="1">
+ <ImageView android:id="@+id/call_logo_anim" android:src="@drawable/beem_icon_launcher_color"
+ android:layout_height="fill_parent" android:layout_width="fill_parent"
+ android:layout_weight="1" />
+ <TextView android:id="@+id/call_info" android:layout_width="fill_parent"
+ android:layout_height="fill_parent" android:text="Message pour savoir ou en est la conversation"
+ android:layout_gravity="bottom" android:layout_weight="1"
+ android:gravity="center" />
+ </LinearLayout>
+ <Button android:id="@+id/call_cancel_button"
+ android:layout_height="wrap_content" android:layout_width="fill_parent"
+ android:layout_gravity="bottom" android:text="~ Close Call ~" />
+ <Button android:id="@+id/call_accept_button"
+ android:layout_height="wrap_content" android:layout_width="fill_parent"
+ android:layout_gravity="bottom" android:text="~ Accept Call ~" android:visible="true" />
+</LinearLayout>
+
--- a/res/layout/jingle_call_activity.xml Thu May 10 16:11:18 2012 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent" android:layout_height="wrap_content"
- android:orientation="vertical">
-<!-- <TextView android:text="Jid:" android:id="@+id/jingledemocalljidlabel"
- android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
- <EditText android:id="@+id/jingledemocalljid"
- android:layout_width="fill_parent" android:layout_height="wrap_content"></EditText>
- <TextView android:text="Password:" android:id="@+id/jingledemocallpasswordlabel"
- android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
- <EditText android:id="@+id/jingledemocallpassword"
- android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="textPassword" ></EditText>
-
- <Button android:text="Connexion" android:id="@+id/jingledemocallconnectbutton"
- android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
- <TextView android:text="Call who :" android:id="@+id/jingledemocallreceiverlabel"
- android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
-
-<EditText android:text="" android:id="@+id/jingledemocallreceiver" android:layout_width="fill_parent" android:layout_height="wrap_content"></EditText>
-
-<Button android:text="Call" android:id="@+id/jingledemocallbutton" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> -->
-<ImageView android:id="@+id/log_as_logo"
- android:layout_width="fill_parent" android:layout_height="wrap_content"
- android:layout_marginBottom="25px" android:layout_marginTop="42px" />
-</LinearLayout>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/res/layout/ongoing_call_notification.xml Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+ 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.
+-->
+
+<!-- Layout file for the custom "expanded view" used by the ongoing call
+ Notification; see NotificationMgr.updateInCallNotification(). -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:baselineAligned="false"
+ android:gravity="center_vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="65sp"
+ android:background="@android:drawable/status_bar_item_background"
+ >
+
+ <ImageView android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingLeft="4dip"
+ android:layout_marginRight="6dip" />
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ >
+ <!-- The appearance of these 2 lines of text matches the other
+ kinds of notifications (see status_bar_latest_event.xml).
+ TODO: There should probably be common styles for these, though. -->
+ <Chronometer android:id="@+id/text1"
+ android:textStyle="bold"
+ android:textSize="18sp"
+ android:textColor="#ff000000"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ />
+ <TextView android:id="@+id/text2"
+ android:textSize="14sp"
+ android:textColor="#ff000000"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:text="@string/app_name"
+ />
+ </LinearLayout>
+</LinearLayout>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/res/menu/call.xml Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,10 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/call_speaker_on" android:visible="true"
+ android:title="~ speaker on ~" android:icon="@android:drawable/ic_lock_silent_mode_off" />
+ <item android:id="@+id/call_speaker_off" android:visible="true"
+ android:title="~ speaker off ~" android:icon="@android:drawable/ic_lock_silent_mode" />
+ <item android:id="@+id/call_hold_on" android:visible="true"
+ android:title="~ hold on ~ " android:icon="@android:drawable/ic_lock_lock" />
+ <item android:id="@+id/call_hold_off" android:visible="true"
+ android:title="~ hold off ~ " android:icon="@android:drawable/ic_menu_call" />
+</menu>
--- a/res/menu/contactlist_context.xml Thu May 10 16:11:18 2012 +0200
+++ b/res/menu/contactlist_context.xml Tue Jun 05 16:44:38 2012 +0200
@@ -5,7 +5,8 @@
</menu>
</item>
<item android:id="@+id/contact_list_context_menu_call_item"
- android:title="@string/CDCall" android:visible="false" />
+ android:title="@string/CDCall" android:visible="true"
+ ><menu></menu></item>
<item android:id="@+id/contact_list_context_menu_user_info"
android:title="@string/CDInfos">
<menu>
Binary file res/raw/ringback.ogg has changed
--- a/res/values-fr/strings.xml Thu May 10 16:11:18 2012 +0200
+++ b/res/values-fr/strings.xml Tue Jun 05 16:44:38 2012 +0200
@@ -171,6 +171,7 @@
<string name="contact_list_name">Beem - Contacts</string>
<string name="contact_list_tag">Beem - ContactList Activity</string>
<string name="user_info_name">Beem - Informations</string>
+ <string name="call_screen">Beem - Appel</string>
<!--
Buttons
--- a/res/values/strings.xml Thu May 10 16:11:18 2012 +0200
+++ b/res/values/strings.xml Tue Jun 05 16:44:38 2012 +0200
@@ -166,6 +166,7 @@
<string name="contact_list_name">Beem - Contacts</string>
<string name="contact_list_tag">Beem - ContactList Activity</string>
<string name="user_info_name">Beem - User Info</string>
+ <string name="call_screen">Beem - Call Screen</string>
<!-- Buttons -->
<string name="button_create_account">Create this account</string>
--- a/src/com/beem/project/beem/BeemService.java Thu May 10 16:11:18 2012 +0200
+++ b/src/com/beem/project/beem/BeemService.java Tue Jun 05 16:44:38 2012 +0200
@@ -63,6 +63,7 @@
import android.provider.Settings;
import android.util.Log;
+import com.beem.project.beem.jingle.JingleService;
import com.beem.project.beem.service.XmppConnectionAdapter;
import com.beem.project.beem.service.XmppFacade;
import com.beem.project.beem.service.aidl.IXmppFacade;
@@ -112,6 +113,7 @@
private NotificationManager mNotificationManager;
private XmppConnectionAdapter mConnection;
+ private JingleService mJingle;
private SharedPreferences mSettings;
private String mLogin;
private String mPassword;
@@ -233,8 +235,9 @@
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Roster.setDefaultSubscriptionMode(SubscriptionMode.manual);
- mBind = new XmppFacade(this);
- Log.d(TAG, "Create BeemService");
+ mJingle = new JingleService(this);
+ mBind = new XmppFacade(this, mJingle);
+ Log.d(TAG, "ONCREATE");
}
/**
@@ -319,6 +322,7 @@
* @param adaptee XmppConnection used for jingle.
*/
public void initJingle(XMPPConnection adaptee) {
+ mJingle.initWhenConntected(adaptee);
}
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/jingle/JingleService.java Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,311 @@
+/*
+ BEEM is a videoconference application on the Android Platform.
+
+ Copyright (C) 2009 by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ This file is part of BEEM.
+
+ BEEM is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ BEEM is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BEEM. If not, see <http://www.gnu.org/licenses/>.
+
+ Please send bug reports with examples or suggestions to
+ contact@beem-project.com or http://dev.beem-project.com/
+
+ Epitech, hereby disclaims all copyright interest in the program "Beem"
+ written by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ Nicolas Sadirac, November 26, 2009
+ President of Epitech.
+
+ Flavien Astraud, November 26, 2009
+ Head of the EIP Laboratory.
+
+ */
+package com.beem.project.beem.jingle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jivesoftware.smack.XMPPConnection;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smackx.jingle.JingleManager;
+import org.jivesoftware.smackx.jingle.JingleSession;
+import org.jivesoftware.smackx.jingle.JingleSessionRequest;
+import org.jivesoftware.smackx.jingle.listeners.JingleSessionListener;
+import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener;
+import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
+import org.jivesoftware.smackx.jingle.media.PayloadType;
+import org.jivesoftware.smackx.jingle.nat.BasicTransportManager;
+import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.beem.project.beem.service.aidl.IBeemJingleListener;
+import com.beem.project.beem.service.aidl.IJingle;
+import com.beem.project.beem.ui.Call;
+
+/**
+ * Beem Jingle Service, manage jingle call.
+ * @author nikita
+ */
+public class JingleService extends IJingle.Stub {
+ private static final String TAG = "JingleService";
+ private JingleManager mJingleManager;
+ private final List<JingleMediaManager> mMediaManagers;
+ private final RemoteCallbackList<IBeemJingleListener> mRemoteJingleListeners = new RemoteCallbackList<IBeemJingleListener>();
+ private JingleSession mIn;
+
+ private JingleSession mOut;
+ private JingleSessionRequest mRequest;
+ private Context mContext;
+ private boolean isCaller;
+ private RTPAudioSession mAudioSession;
+
+ /**
+ * JingleService constructor.
+ * @param xmppConnection a valid XMPPConnection
+ */
+ public JingleService(final Context ctx) {
+ BasicTransportManager bt = new BasicTransportManager();
+ mMediaManagers = new ArrayList<JingleMediaManager>();
+ mMediaManagers.add(new MicrophoneRTPManager(bt, ctx));
+ mContext = ctx;
+ }
+
+ /**
+ * finish to construct the instance.
+ * @param conn the xmppConnection used with constructor
+ */
+ public void initWhenConntected(XMPPConnection conn) {
+ mJingleManager = new JingleManager(conn, mMediaManagers);
+ mJingleManager.addJingleSessionRequestListener(new BeemJingleSessionRequestListener());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addJingleListener(IBeemJingleListener listen) throws RemoteException {
+ if (listen != null)
+ mRemoteJingleListeners.register(listen);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeJingleListener(IBeemJingleListener listen) throws RemoteException {
+ if (listen != null)
+ mRemoteJingleListeners.unregister(listen);
+ }
+
+ /**
+ * begin a jingle call.
+ * @param receiver the call receiver
+ */
+ @Override
+ public void call(final String receiver) throws RemoteException {
+ Log.d(TAG, "Place Call");
+ try {
+ mOut = mJingleManager.createOutgoingJingleSession(receiver);
+ mOut.addListener(new BeemJingleSessionListener());
+ mOut.startOutgoing();
+ isCaller = true;
+ } catch (XMPPException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ @Override
+ public void acceptCall() throws RemoteException {
+ Log.d(TAG, "Accept Call");
+ try {
+ mRequest.accept();
+ mIn.start();
+ } catch (XMPPException e) {
+ e.printStackTrace();
+ }
+ isCaller = false;
+ }
+
+ @Override
+ public void setSpeakerMode(int mode) throws RemoteException {
+ mAudioSession.setSpeakerMode(mode);
+ }
+
+ /**
+ * close a jingle call.
+ */
+ @Override
+ public void closeCall() throws RemoteException {
+ mAudioSession = null;
+ if (isCaller) {
+ try {
+ mOut.terminate("Cancelled");
+ mOut.close();
+ } catch (XMPPException e) {
+ e.printStackTrace();
+ }
+ mOut = null;
+ } else {
+ try {
+ mRequest.reject();
+ mIn.terminate();
+ mIn.close();
+ } catch (XMPPException e) {
+ e.printStackTrace();
+ }
+ mIn = null;
+ }
+ }
+
+ /**
+ * Listen on session events.
+ * @author nikita
+ */
+ private class BeemJingleSessionListener implements JingleSessionListener {
+
+ /**
+ * constructor.
+ */
+ public BeemJingleSessionListener() {
+ super();
+ }
+
+ @Override
+ public void sessionClosed(String reason, JingleSession jingleSession) {
+ System.out.println("Session " + jingleSession.getResponder() + " closed because " + reason);
+
+ final int n = mRemoteJingleListeners.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ IBeemJingleListener listener = mRemoteJingleListeners.getBroadcastItem(i);
+ try {
+ listener.sessionClosed(reason);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+ mRemoteJingleListeners.finishBroadcast();
+ }
+
+ @Override
+ public void sessionClosedOnError(XMPPException e, JingleSession jingleSession) {
+ System.out.println("Session " + jingleSession.getResponder() + " closed");
+
+ final int n = mRemoteJingleListeners.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ IBeemJingleListener listener = mRemoteJingleListeners.getBroadcastItem(i);
+ try {
+ listener.sessionClosedOnError(e.getMessage());
+ } catch (RemoteException err) {
+ err.printStackTrace();
+ }
+ }
+ mRemoteJingleListeners.finishBroadcast();
+ }
+
+ @Override
+ public void sessionDeclined(String reason, JingleSession jingleSession) {
+ Log.d(TAG, "Session " + jingleSession.getResponder() + " declined because " + reason);
+
+ final int n = mRemoteJingleListeners.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ IBeemJingleListener listener = mRemoteJingleListeners.getBroadcastItem(i);
+ try {
+ listener.sessionDeclined(reason);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+ mRemoteJingleListeners.finishBroadcast();
+
+ }
+
+ @Override
+ public void sessionEstablished(PayloadType pt, TransportCandidate remoteCandidate,
+ TransportCandidate localCandidate, JingleSession jingleSession) {
+ Log.d(TAG, "Session " + jingleSession.getResponder() + " established");
+ mAudioSession = (RTPAudioSession) jingleSession.getSession().getMediaSession(MicrophoneRTPManager.MEDIA_NAME);
+ final int n = mRemoteJingleListeners.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ IBeemJingleListener listener = mRemoteJingleListeners.getBroadcastItem(i);
+ try {
+ listener.sessionEstablished();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+ mRemoteJingleListeners.finishBroadcast();
+ }
+
+ @Override
+ public void sessionMediaReceived(JingleSession jingleSession, String participant) {
+ Log.d(TAG, "Session Media received from " + participant);
+ }
+
+ @Override
+ public void sessionRedirected(String redirection, JingleSession jingleSession) {
+ }
+ }
+
+
+ /**
+ * Listen for a Jingle session request.
+ * @author nikita
+ */
+ private class BeemJingleSessionRequestListener implements JingleSessionRequestListener {
+
+ /**
+ * Constructor.
+ */
+ public BeemJingleSessionRequestListener() {
+ super();
+ }
+
+ @Override
+ public void sessionRequested(JingleSessionRequest request) {
+ mRequest = request;
+ try {
+ mIn = mJingleManager.createIncomingJingleSession(mRequest);
+ mIn.addListener(new BeemJingleSessionListener());
+ mIn.startIncoming();
+ } catch (XMPPException e) {
+ e.printStackTrace();
+ }
+ System.out.println("Jingle Session request from " + request.getFrom());
+ isCaller = false;
+ Intent intent = new Intent(mContext, Call.class);
+ intent.setData(Uri.parse("jingle:"+request.getFrom()));
+ intent.putExtra("isCaller", false);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/jingle/MicrophoneRTPManager.java Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,117 @@
+/*
+ BEEM is a videoconference application on the Android Platform.
+
+ Copyright (C) 2009 by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ This file is part of BEEM.
+
+ BEEM is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ BEEM is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BEEM. If not, see <http://www.gnu.org/licenses/>.
+
+ Please send bug reports with examples or suggestions to
+ contact@beem-project.com or http://dev.beem-project.com/
+
+ Epitech, hereby disclaims all copyright interest in the program "Beem"
+ written by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ Nicolas Sadirac, November 26, 2009
+ President of Epitech.
+
+ Flavien Astraud, November 26, 2009
+ Head of the EIP Laboratory.
+
+*/
+package com.beem.project.beem.jingle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jivesoftware.smackx.jingle.JingleSession;
+import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
+import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
+import org.jivesoftware.smackx.jingle.media.PayloadType;
+import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
+import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
+
+import android.content.Context;
+import android.provider.MediaStore.Audio;
+
+/**
+ * RTPMediaManager, gere les payloads et renvoie une session RTP.
+ * @author nikita
+ */
+public class MicrophoneRTPManager extends JingleMediaManager {
+ /**
+ * RTP media name.
+ */
+ public static final String MEDIA_NAME = "Microphone";
+
+ private List<PayloadType> mPayloads;
+
+ private Context mCtx;
+
+ /**
+ * Manage Microphone data transmission trough RTP.
+ * @param transportManager current jingle transport manager(basic,upnp,ice...).
+ */
+ public MicrophoneRTPManager(final JingleTransportManager transportManager, Context ctx) {
+ super(transportManager);
+ setupPayloads();
+ mCtx = ctx;
+ }
+
+ /* (non-Javadoc)
+ * @see org.jivesoftware.smackx.jingle.media.JingleMediaManager#createMediaSession(org.jivesoftware.smackx.jingle.media.PayloadType, org.jivesoftware.smackx.jingle.nat.TransportCandidate, org.jivesoftware.smackx.jingle.nat.TransportCandidate, org.jivesoftware.smackx.jingle.JingleSession)
+ */
+ @Override
+ public JingleMediaSession createMediaSession(PayloadType payloadType, TransportCandidate remote,
+ TransportCandidate local, JingleSession jingleSession) {
+ return new RTPAudioSession(payloadType, remote, local, null, jingleSession, mCtx);
+ }
+
+ /* (non-Javadoc)
+ * @see org.jivesoftware.smackx.jingle.media.JingleMediaManager#getName()
+ */
+ @Override
+ public String getName() {
+ return MEDIA_NAME;
+ }
+
+ /* (non-Javadoc)
+ * @see org.jivesoftware.smackx.jingle.media.JingleMediaManager#getPayloads()
+ */
+ @Override
+ public List<PayloadType> getPayloads() {
+ return mPayloads;
+ }
+
+ /**
+ * Supported payload list.
+ */
+ private void setupPayloads() {
+ mPayloads = new ArrayList<PayloadType>();
+ mPayloads.add(new PayloadType.Audio(8, "PCMA", 1, 8000));
+// mPayloads.add(new PayloadType.Audio(9, "G722"));
+// mPayloads.add(new PayloadType.Audio(3, "GSM", 1, 8000));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/jingle/RTPAudioSession.java Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,89 @@
+package com.beem.project.beem.jingle;
+
+import org.jivesoftware.smackx.jingle.JingleSession;
+import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
+import org.jivesoftware.smackx.jingle.media.PayloadType;
+import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
+import org.sipdroid.media.RtpStreamReceiver;
+import org.sipdroid.media.RtpStreamSender;
+import org.sipdroid.net.SipdroidSocket;
+
+import android.content.Context;
+import android.util.Log;
+
+/**
+ * Manage microphone RTP session.
+ * @author nikita
+ */
+public class RTPAudioSession extends JingleMediaSession {
+
+ private RtpStreamSender mSender=null;
+ private RtpStreamReceiver mReceiver=null;
+
+ /**
+ * constructor.
+ * @param payloadType the payload typ used
+ * @param remote the remote transport info
+ * @param local the local tranport info
+ * @param mediaLocator don't know
+ * @param jingleSession the current jingle session
+ * @param ctx
+ */
+ public RTPAudioSession(final PayloadType pt, final TransportCandidate remote,
+ final TransportCandidate local, final String mediaLocator, final JingleSession jingleSession, Context ctx) {
+ super(pt, remote, local, mediaLocator, jingleSession);
+ Log.d("AUDIO", String.format("payload type : %s ipdest %s port dest %d port src %d",pt.getName(), remote.getIp(), remote.getPort(), local.getPort()));
+
+ SipdroidSocket rtpSocket = null;
+ try {
+ rtpSocket = new SipdroidSocket(local.getPort());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ mSender = new RtpStreamSender(true, 8, 8000, 160, rtpSocket, remote.getIp(), remote.getPort());
+ mReceiver = new RtpStreamReceiver(rtpSocket, 8);
+ }
+
+ @Override
+ public void initialize() {
+ }
+
+ public void setSpeakerMode(final int mode) {
+ mReceiver.speaker(mode);
+ }
+
+ @Override
+ public void setTrasmit(boolean active) {
+ }
+
+ @Override
+ public void startReceive() {
+ if (mReceiver != null) {
+ mReceiver.start();
+ }
+ }
+
+ @Override
+ public void startTrasmit() {
+ if (mSender != null) {
+ mSender.start();
+ }
+ }
+
+ @Override
+ public void stopReceive() {
+ if (mReceiver != null) {
+ mReceiver.halt();
+ mReceiver = null;
+ }
+
+ }
+
+ @Override
+ public void stopTrasmit() {
+ if (mSender != null) {
+ mSender.halt();
+ mSender = null;
+ }
+ }
+}
--- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java Thu May 10 16:11:18 2012 +0200
+++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java Tue Jun 05 16:44:38 2012 +0200
@@ -480,7 +480,9 @@
sdm.addFeature("http://jabber.org/protocol/disco#info");
//nikita: must be uncommented when the feature will be enabled
- //sdm.addFeature("jabber:iq:privacy");
+ sdm.addFeature("urn:xmpp:jingle:1");
+ sdm.addFeature("urn:xmpp:jingle:apps:rtp:1");
+ sdm.addFeature("urn:xmpp:jingle:apps:rtp:audio");
sdm.addFeature("http://jabber.org/protocol/caps");
sdm.addFeature("urn:xmpp:avatar:metadata");
sdm.addFeature("urn:xmpp:avatar:metadata+notify");
--- a/src/com/beem/project/beem/service/XmppFacade.java Thu May 10 16:11:18 2012 +0200
+++ b/src/com/beem/project/beem/service/XmppFacade.java Tue Jun 05 16:44:38 2012 +0200
@@ -46,12 +46,14 @@
import android.net.Uri;
import android.os.RemoteException;
+import com.beem.project.beem.jingle.JingleService;
import com.beem.project.beem.BeemService;
import com.beem.project.beem.service.aidl.IChatManager;
import com.beem.project.beem.service.aidl.IPrivacyListManager;
import com.beem.project.beem.service.aidl.IRoster;
import com.beem.project.beem.service.aidl.IXmppConnection;
import com.beem.project.beem.service.aidl.IXmppFacade;
+import com.beem.project.beem.service.aidl.IJingle;
import com.beem.project.beem.utils.PresenceType;
import org.jivesoftware.smack.packet.Presence;
@@ -62,15 +64,19 @@
*/
public class XmppFacade extends IXmppFacade.Stub {
+ private final JingleService mJingle;
private XmppConnectionAdapter mConnexion;
private final BeemService service;
/**
+ * Constructor for XMPPFacade.
+ * @param service the service providing the facade
+ * @param jingle the jingle session
* Create an XmppFacade.
*
- * @param service the service providing the facade
*/
- public XmppFacade(final BeemService service) {
+ public XmppFacade(final BeemService service, final JingleService jingle) {
+ this.mJingle = jingle;
this.service = service;
}
@@ -127,6 +133,14 @@
initConnection();
return mConnexion.getChatManager();
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IJingle getJingleService() throws RemoteException {
+ return mJingle;
+ }
/**
* {@inheritDoc}
@@ -155,7 +169,7 @@
}
/* (non-Javadoc)
- * @see com.beem.project.beem.service.aidl.IXmppFacade#call(java.lang.String)
+ * @see com.beem.project.beem.service.aidl.IXmppFacade#getVcardAvatar(java.lang.String)
*/
@Override
public void call(String jid) throws RemoteException {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/service/aidl/IBeemJingleListener.aidl Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,77 @@
+/*
+ BEEM is a videoconference application on the Android Platform.
+
+ Copyright (C) 2009 by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ This file is part of BEEM.
+
+ BEEM is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ BEEM is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BEEM. If not, see <http://www.gnu.org/licenses/>.
+
+ Please send bug reports with examples or suggestions to
+ contact@beem-project.com or http://dev.beem-project.com/
+
+ Epitech, hereby disclaims all copyright interest in the program "Beem"
+ written by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ Nicolas Sadirac, November 26, 2009
+ President of Epitech.
+
+ Flavien Astraud, November 26, 2009
+ Head of the EIP Laboratory.
+
+*/
+package com.beem.project.beem.service.aidl;
+
+/**
+ * Interface to listen for jingle sessions events
+ * @author Nikita Kozlov <nikita@beem-project.com>
+ */
+interface IBeemJingleListener {
+
+ /**
+ * Callback to call when the session is closed
+ */
+ void sessionClosed(in String reason);
+
+ /**
+ * Callback to call when the session is declined
+ */
+ void sessionDeclined(in String reason);
+
+
+ /**
+ * Callback to call when the session is closed on error
+ */
+ void sessionClosedOnError(in String error);
+
+ /**
+ * Callback to call when session is established
+ */
+ void sessionEstablished();
+
+ /**
+ * Callback to call when session is requested
+ */
+ void sessionRequested(in String fromJID);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/service/aidl/IJingle.aidl Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,75 @@
+/*
+ BEEM is a videoconference application on the Android Platform.
+
+ Copyright (C) 2009 by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ This file is part of BEEM.
+
+ BEEM is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ BEEM is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BEEM. If not, see <http://www.gnu.org/licenses/>.
+
+ Please send bug reports with examples or suggestions to
+ contact@beem-project.com or http://dev.beem-project.com/
+
+ Epitech, hereby disclaims all copyright interest in the program "Beem"
+ written by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ Nicolas Sadirac, November 26, 2009
+ President of Epitech.
+
+ Flavien Astraud, November 26, 2009
+ Head of the EIP Laboratory.
+
+*/
+package com.beem.project.beem.service.aidl;
+
+import com.beem.project.beem.service.aidl.IBeemJingleListener;
+
+
+interface IJingle {
+
+ void addJingleListener(in IBeemJingleListener listen);
+ void removeJingleListener(in IBeemJingleListener listen);
+
+ /**
+ * make a jingle audio call
+ * @param jid the receiver id
+ */
+ void call(in String jid);
+
+ /**
+ * Accept call a jingle audio call
+ */
+ void acceptCall();
+
+ /**
+ * close a jingle audio call
+ */
+ void closeCall();
+
+ /**
+ * Set speaker mode
+ */
+ void setSpeakerMode(in int mode);
+
+}
--- a/src/com/beem/project/beem/service/aidl/IXmppFacade.aidl Thu May 10 16:11:18 2012 +0200
+++ b/src/com/beem/project/beem/service/aidl/IXmppFacade.aidl Tue Jun 05 16:44:38 2012 +0200
@@ -43,6 +43,7 @@
*/
package com.beem.project.beem.service.aidl;
+import com.beem.project.beem.service.aidl.IJingle;
import com.beem.project.beem.service.aidl.IXmppConnection;
import com.beem.project.beem.service.aidl.IRoster;
import com.beem.project.beem.service.aidl.IChatManager;
@@ -83,6 +84,11 @@
* Get the chat manager.
*/
IChatManager getChatManager();
+
+ /**
+ * Get the Jingle service.
+ */
+ IJingle getJingleService();
/**
* Change the status of the user.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/ui/Call.java Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,354 @@
+/*
+ BEEM is a videoconference application on the Android Platform.
+
+ Copyright (C) 2009 by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ This file is part of BEEM.
+
+ BEEM is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ BEEM is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BEEM. If not, see <http://www.gnu.org/licenses/>.
+
+ Please send bug reports with examples or suggestions to
+ contact@beem-project.com or http://dev.beem-project.com/
+
+ Epitech, hereby disclaims all copyright interest in the program "Beem"
+ written by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ Nicolas Sadirac, November 26, 2009
+ President of Epitech.
+
+ Flavien Astraud, November 26, 2009
+ Head of the EIP Laboratory.
+
+ */
+package com.beem.project.beem.ui;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.media.AudioManager;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.Vibrator;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.beem.project.beem.R;
+import com.beem.project.beem.service.Contact;
+import com.beem.project.beem.service.aidl.IBeemJingleListener;
+import com.beem.project.beem.service.aidl.IJingle;
+import com.beem.project.beem.service.aidl.IXmppFacade;
+
+/**
+ * This class is an activity which display an animation during the connection with the server.
+ * @author Da Risk <darisk972@gmail.com>
+ */
+public class Call extends Activity {
+
+ private static final Intent SERVICE_INTENT = new Intent();
+ static {
+ SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService"));
+ }
+ private ImageView mLogo;
+ private TextView mCallInfo;
+ private Animation mRotateAnim;
+ private final ServiceConnection mServConn = new BeemServiceConnection();
+ private BeemJingleSessionListener mJingleListener = new BeemJingleSessionListener();
+ private IXmppFacade mXmppFacade;
+ private final Handler mHandler = new Handler();
+ private Button mCloseCall;
+ private Button mAcceptCall;
+ private IJingle mJingle;
+ private Intent mIntent;
+
+ final static long[] vibratePattern = {0,1000,1000};
+
+ public static final int UA_STATE_IDLE = 0;
+ public static final int UA_STATE_INCOMING_CALL = 1;
+ public static final int UA_STATE_OUTGOING_CALL = 2;
+ public static final int UA_STATE_INCALL = 3;
+ public static final int UA_STATE_HOLD = 4;
+
+ public static int call_state = UA_STATE_IDLE;
+ public static int docked = -1,headset = -1;
+ public static Ringtone oRingtone;
+ public static Context mContext;
+
+ public static void stopRingtone() {
+ android.os.Vibrator v = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
+ v.cancel();
+ if (oRingtone != null) {
+ Ringtone ringtone = oRingtone;
+ oRingtone = null;
+ ringtone.stop();
+ }
+ }
+
+ public static void startRingtone() {
+ android.os.Vibrator v = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
+ v.vibrate(vibratePattern,1);
+ oRingtone = RingtoneManager.getRingtone(mContext, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE));
+ oRingtone.play();
+ }
+
+ /**
+ * Constructor.
+ */
+ public Call() {
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Call.mContext = this;
+ setContentView(R.layout.call);
+ mIntent = this.getIntent();
+
+ mLogo = (ImageView) findViewById(R.id.call_logo_anim);
+ mRotateAnim = AnimationUtils.loadAnimation(this, R.anim.rotate_and_scale);
+ mCloseCall = (Button) findViewById(R.id.call_cancel_button);
+ mCloseCall.setOnClickListener(new ClickListener());
+ if (mIntent.getBooleanExtra("isCaller", false)) {
+ mAcceptCall = (Button) findViewById(R.id.call_accept_button);
+ mAcceptCall.setVisibility(View.GONE);
+ call_state = UA_STATE_OUTGOING_CALL;
+ } else {
+ mAcceptCall = (Button) findViewById(R.id.call_accept_button);
+ mAcceptCall.setOnClickListener(new ClickListener());
+ call_state = UA_STATE_INCOMING_CALL;
+ Call.startRingtone();
+ }
+ mCallInfo = (TextView) findViewById(R.id.call_info);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mLogo.startAnimation(mRotateAnim);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ if (mXmppFacade == null)
+ bindService(Call.SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ if (mXmppFacade != null) {
+ try {
+ mJingle.removeJingleListener(mJingleListener);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ unbindService(mServConn);
+ mXmppFacade = null;
+ }
+ }
+
+ @Override
+ public final boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.call, menu);
+ return true;
+ }
+
+ /**
+ * Callback for menu item selected.
+ * @param item the item selected
+ * @return true on success, false otherwise
+ */
+ @Override
+ public final boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.call_speaker_on:
+ try {
+ mJingle.setSpeakerMode(AudioManager.MODE_NORMAL);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ return true;
+ case R.id.call_speaker_off:
+ try {
+ mJingle.setSpeakerMode(AudioManager.MODE_IN_CALL);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ return true;
+ case R.id.call_hold_on:
+ Call.call_state = UA_STATE_HOLD;
+ return true;
+ case R.id.call_hold_off:
+ Call.call_state = UA_STATE_INCALL;
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Click event listener on cancel button.
+ */
+ private class ClickListener implements OnClickListener {
+
+ /**
+ * Constructor.
+ */
+ ClickListener() {
+ }
+
+ @Override
+ public void onClick(View v) {
+ try {
+ if (v == mCloseCall) {
+ mJingle.closeCall();
+ stopRingtone();
+ Call.call_state = UA_STATE_IDLE;
+ } else if (v == mAcceptCall) {
+ mJingle.acceptCall();
+ stopRingtone();
+ Call.call_state = UA_STATE_INCALL;
+ }
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ finish();
+ }
+ }
+
+ private class BeemJingleSessionListener extends IBeemJingleListener.Stub {
+
+ /**
+ * Refresh the call activity.
+ */
+ private class RunnableChange implements Runnable {
+
+ private String mStr;
+ /**
+ * Constructor.
+ */
+ public RunnableChange(String str) {
+ mStr = str;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ mCallInfo.setText(mStr);
+ }
+ }
+
+ public BeemJingleSessionListener() {
+ }
+
+ @Override
+ public void sessionClosed(final String reason) {
+ android.util.Log.d("TEST", "TEST " + reason);
+ Call.stopRingtone();
+ call_state = UA_STATE_IDLE;
+ mHandler.post(new RunnableChange(reason));
+ }
+
+ @Override
+ public void sessionDeclined(final String reason) {
+ android.util.Log.d("TEST", "TEST4 " + reason);
+ Call.stopRingtone();
+ call_state = UA_STATE_IDLE;
+ mHandler.post(new RunnableChange(reason));
+ }
+
+ @Override
+ public void sessionClosedOnError(final String error) {
+ android.util.Log.d("TEST", "TEST5 " + error);
+ Call.stopRingtone();
+ call_state = UA_STATE_IDLE;
+ mHandler.post(new RunnableChange(error));
+ }
+
+ @Override
+ public void sessionEstablished() {
+ android.util.Log.d("TEST", "TEST2 ");
+ call_state = UA_STATE_INCALL;
+ Call.stopRingtone();
+ mHandler.post(new RunnableChange("established"));
+ }
+
+ @Override
+ public void sessionRequested(final String fromJID) {
+ android.util.Log.d("TEST", "TEST3 " + fromJID);
+ mHandler.post(new RunnableChange(fromJID));
+ }
+ }
+
+ /**
+ * The service connection used to connect to the Beem service.
+ */
+ private class BeemServiceConnection implements ServiceConnection {
+
+ private Contact mContact;
+
+ /**
+ * Constructor.
+ */
+ public BeemServiceConnection() {
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ mXmppFacade = IXmppFacade.Stub.asInterface(service);
+ try {
+ mJingle = mXmppFacade.getJingleService();
+ mJingle.addJingleListener(mJingleListener);
+ mContact = new Contact(getIntent().getData());
+ mJingle.call(mContact.getJIDWithRes());
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ mXmppFacade = null;
+ mJingle = null;
+ }
+ }
+}
--- a/src/com/beem/project/beem/ui/ContactList.java Thu May 10 16:11:18 2012 +0200
+++ b/src/com/beem/project/beem/ui/ContactList.java Tue Jun 05 16:44:38 2012 +0200
@@ -179,7 +179,6 @@
}
}
-
@Override
protected void onCreate(Bundle saveBundle) {
super.onCreate(saveBundle);
--- a/src/com/beem/project/beem/ui/ContactListFragment.java Thu May 10 16:11:18 2012 +0200
+++ b/src/com/beem/project/beem/ui/ContactListFragment.java Tue Jun 05 16:44:38 2012 +0200
@@ -133,7 +133,17 @@
result = true;
break;
case R.id.contact_list_context_menu_call_item:
- hostActivity.doContextMenuAction(item.getItemId(), mSelectedContact);
+ res = mSelectedContact.getMRes();
+ if (res.isEmpty()) {
+ break;
+ }
+ for (String resv : res) {
+ in = new Intent(hostActivity, Call.class);
+ in.setData(mSelectedContact.toUri(resv));
+ in.putExtra("isCaller", true);
+ item.getSubMenu().add(resv).setIntent(in);
+ }
+ result = true;
break;
case R.id.contact_list_context_menu_user_info:
item.getSubMenu().setHeaderTitle(mSelectedContact.getJID());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/utils/Random.java Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2005 Luca Veltri - University of Parma - Italy
+ *
+ * This file is part of MjSip (http://www.mjsip.org)
+ *
+ * MjSip is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MjSip is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MjSip; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author(s):
+ * Luca Veltri (luca.veltri@unipr.it)
+ */
+
+package com.beem.project.beem.utils;
+
+/**
+ * Class Random collects some static methods for generating random numbers and
+ * other stuff.
+ */
+public class Random {
+ /** The random seed */
+ static final long seed = System.currentTimeMillis();
+ // static final long seed=0;
+
+ static java.util.Random rand = new java.util.Random(seed);
+
+ // static java.util.Random rand=new java.util.Random();
+
+ /** Returns a random integer between 0 and n-1 */
+ /*
+ * static public int nextInt(int n) { seed=(seed*37)%987654321; return
+ * (int)(seed%n); }
+ */
+
+ /** Returns true or false respectively with probability p/100 and (1-p/100) */
+ /*
+ * static boolean percent(int p) { return integer(100)<p; }
+ */
+
+ /** Sets the seed of this random number generator using a single long seed */
+ public static void setSeed(long seed) {
+ rand.setSeed(seed);
+ }
+
+ /** Returns a random integer */
+ public static int nextInt() {
+ return rand.nextInt();
+ }
+
+ /** Returns a random integer between 0 and n-1 */
+ public static int nextInt(int n) {
+ return Math.abs(rand.nextInt()) % n;
+ }
+
+ /** Returns a random long */
+ public static long nextLong() {
+ return rand.nextLong();
+ }
+
+ /** Returns a random boolean */
+ public static boolean nextBoolean() {
+ return rand.nextInt(2) == 1;
+ }
+
+ /** Returns a random array of bytes */
+ public static byte[] nextBytes(int len) {
+ byte[] buff = new byte[len];
+ for (int i = 0; i < len; i++)
+ buff[i] = (byte) nextInt(256);
+ return buff;
+ }
+
+ /** Returns a random String */
+ public static String nextString(int len) {
+ byte[] buff = new byte[len];
+ for (int i = 0; i < len; i++) {
+ int n = nextInt(62);
+ buff[i] = (byte) ((n < 10) ? 48 + n : ((n < 36) ? 55 + n : 61 + n));
+ }
+ return new String(buff);
+ }
+
+ /** Returns a random numeric String */
+ public static String nextNumString(int len) {
+ byte[] buff = new byte[len];
+ for (int i = 0; i < len; i++)
+ buff[i] = (byte) (48 + nextInt(10));
+ return new String(buff);
+ }
+
+ /** Returns a random hexadecimal String */
+ public static String nextHexString(int len) {
+ byte[] buff = new byte[len];
+ for (int i = 0; i < len; i++) {
+ int n = nextInt(16);
+ buff[i] = (byte) ((n < 10) ? 48 + n : 87 + n);
+ }
+ return new String(buff);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/sipdroid/media/G711.java Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,397 @@
+package org.sipdroid.media;
+
+/**
+ * G.711 codec. This class provides methods for u-law, A-law and linear PCM
+ * conversions.
+ */
+public class G711 {
+ /*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+ static final short[] a2s = new short[256];
+ static final int[] _a2s = {
+
+ 60032, 60288, 59520, 59776, 61056, 61312, 60544, 60800,
+ 57984, 58240, 57472, 57728, 59008, 59264, 58496, 58752,
+ 62784, 62912, 62528, 62656, 63296, 63424, 63040, 63168,
+ 61760, 61888, 61504, 61632, 62272, 62400, 62016, 62144,
+ 43520, 44544, 41472, 42496, 47616, 48640, 45568, 46592,
+ 35328, 36352, 33280, 34304, 39424, 40448, 37376, 38400,
+ 54528, 55040, 53504, 54016, 56576, 57088, 55552, 56064,
+ 50432, 50944, 49408, 49920, 52480, 52992, 51456, 51968,
+ 65192, 65208, 65160, 65176, 65256, 65272, 65224, 65240,
+ 65064, 65080, 65032, 65048, 65128, 65144, 65096, 65112,
+ 65448, 65464, 65416, 65432, 65512, 65528, 65480, 65496,
+ 65320, 65336, 65288, 65304, 65384, 65400, 65352, 65368,
+ 64160, 64224, 64032, 64096, 64416, 64480, 64288, 64352,
+ 63648, 63712, 63520, 63584, 63904, 63968, 63776, 63840,
+ 64848, 64880, 64784, 64816, 64976, 65008, 64912, 64944,
+ 64592, 64624, 64528, 64560, 64720, 64752, 64656, 64688,
+ 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
+ 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
+ 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
+ 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
+ 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
+ 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
+ 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
+ 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
+ 344, 328, 376, 360, 280, 264, 312, 296,
+ 472, 456, 504, 488, 408, 392, 440, 424,
+ 88, 72, 120, 104, 24, 8, 56, 40,
+ 216, 200, 248, 232, 152, 136, 184, 168,
+ 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
+ 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
+ 688, 656, 752, 720, 560, 528, 624, 592,
+ 944, 912, 1008, 976, 816, 784, 880, 848
+
+ };
+
+ static final byte[] s2a = new byte[65536];
+ static final int[] _s2a = {
+
+ 213,212,215,214,209,208,211,210,221,220,223,222,217,216,219,218,
+ 197,196,199,198,193,192,195,194,205,204,207,206,201,200,203,202,
+ 245,245,244,244,247,247,246,246,241,241,240,240,243,243,242,242,
+ 253,253,252,252,255,255,254,254,249,249,248,248,251,251,250,250,
+ 229,229,229,229,228,228,228,228,231,231,231,231,230,230,230,230,
+ 225,225,225,225,224,224,224,224,227,227,227,227,226,226,226,226,
+ 237,237,237,237,236,236,236,236,239,239,239,239,238,238,238,238,
+ 233,233,233,233,232,232,232,232,235,235,235,235,234,234,234,234,
+ 149,149,149,149,149,149,149,149,148,148,148,148,148,148,148,148,
+ 151,151,151,151,151,151,151,151,150,150,150,150,150,150,150,150,
+ 145,145,145,145,145,145,145,145,144,144,144,144,144,144,144,144,
+ 147,147,147,147,147,147,147,147,146,146,146,146,146,146,146,146,
+ 157,157,157,157,157,157,157,157,156,156,156,156,156,156,156,156,
+ 159,159,159,159,159,159,159,159,158,158,158,158,158,158,158,158,
+ 153,153,153,153,153,153,153,153,152,152,152,152,152,152,152,152,
+ 155,155,155,155,155,155,155,155,154,154,154,154,154,154,154,154,
+ 133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+ 132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+ 135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+ 134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+ 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+ 130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+ 141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+ 140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+ 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+ 137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+ 136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+ 139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+ 138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+ 181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+ 181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+ 180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+ 180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+ 183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+ 183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+ 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+ 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+ 177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+ 177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+ 176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+ 176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+ 179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+ 179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+ 178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+ 178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+ 189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+ 189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+ 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+ 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+ 191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+ 191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+ 190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+ 190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+ 185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+ 185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+ 184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+ 184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+ 187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+ 187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+ 186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+ 186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+ 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+ 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+ 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+ 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+ 164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+ 164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+ 164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+ 164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+ 167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+ 167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+ 167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+ 167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+ 166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+ 166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+ 166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+ 166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+ 161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+ 161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+ 161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+ 161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+ 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+ 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+ 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+ 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+ 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+ 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+ 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+ 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+ 173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+ 173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+ 173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+ 173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+ 172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+ 172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+ 172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+ 172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+ 175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+ 175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+ 175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+ 175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+ 174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+ 174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+ 174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+ 174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+ 169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+ 169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+ 169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+ 169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+ 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+ 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+ 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+ 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+ 171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+ 171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+ 171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+ 171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+ 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+ 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+ 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+ 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
+ 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+ 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25,
+ 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31,
+ 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29,
+ 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19,
+ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17,
+ 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+ 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21,
+ 106,106,106,106,107,107,107,107,104,104,104,104,105,105,105,105,
+ 110,110,110,110,111,111,111,111,108,108,108,108,109,109,109,109,
+ 98, 98, 98, 98, 99, 99, 99, 99, 96, 96, 96, 96, 97, 97, 97, 97,
+ 102,102,102,102,103,103,103,103,100,100,100,100,101,101,101,101,
+ 122,122,123,123,120,120,121,121,126,126,127,127,124,124,125,125,
+ 114,114,115,115,112,112,113,113,118,118,119,119,116,116,117,117,
+ 74, 75, 72, 73, 78, 79, 76, 77, 66, 67, 64, 65, 70, 71, 68, 69,
+ 90, 91, 88, 89, 94, 95, 92, 93, 82, 83, 80, 81, 86, 87, 84, 85
+ };
+
+ //change G711 ulaw start
+ static final int _u2a[] = { /* u- to A-law conversions */
+ 1, 1, 2, 2, 3, 3, 4, 4,
+ 5, 5, 6, 6, 7, 7, 8, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 27, 29, 31, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 44,
+ 46, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62,
+ 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 81, 82, 83, 84, 85, 86, 87, 88,
+ 89, 90, 91, 92, 93, 94, 95, 96,
+ 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112,
+ 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128};
+
+ static final int _a2u[] = { /* A- to u-law conversions */
+ 1, 3, 5, 7, 9, 11, 13, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 32, 33, 33, 34, 34, 35, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 48, 49, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 75, 76, 77, 78, 79, 80,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127};
+
+ //change end
+
+ public static void init() {
+ }
+
+ static {
+ int i;
+ for (i = 0; i < 256; i++)
+ a2s[i] = (short)_a2s[i];
+ for (i = 0; i < 65536; i++)
+ s2a[i] = (byte)_s2a[i >> 4];
+ }
+
+ public static void alaw2linear(byte alaw[],short lin[],int frames) {
+ int i;
+ for (i = 0; i < frames; i++)
+ lin[i] = a2s[alaw[i+12] & 0xff];
+ }
+
+ public static void linear2alaw(short lin[],int offset,byte alaw[],int frames) {
+ int i;
+ for (i = 0; i < frames; i++)
+ alaw[i+12] = s2a[lin[i+offset] & 0xffff];
+ }
+
+ //change g711 ulaw start
+ protected static int alaw2ulaw(int aval)
+ { aval&=0xff;
+ return ((aval & 0x80)!=0)? (0xFF^_a2u[aval^0xD5]) : (0x7F^_a2u[aval^0x55]);
+ }
+
+ protected static int ulaw2alaw(int uval)
+ { uval&=0xff;
+ return ((uval&0x80)!=0)? (0xD5^(_u2a[0xFF^uval]-1)) : (0x55^(_u2a[0x7F^uval]-1));
+ }
+
+ public static void ulaw2linear(byte ulaw[],short lin[],int frames) {
+ int i;
+ for (i = 0; i < frames; i++)
+ lin[i] = a2s[ulaw2alaw(ulaw[i+12] & 0xff)];
+ }
+ public static void linear2ulaw(short lin[],int offset,byte ulaw[],int frames) {
+ int i;
+ for (i = 0; i < frames; i++)
+ ulaw[i+12] = (byte)alaw2ulaw(s2a[lin[i+offset] & 0xffff]);
+ }
+ //change end
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/sipdroid/media/RtpStreamReceiver.java Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) 2009 The Sipdroid Open Source Project
+ * Copyright (C) 2005 Luca Veltri - University of Parma - Italy
+ *
+ * This file is part of Sipdroid (http://www.sipdroid.org)
+ *
+ * Sipdroid is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this source code; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package org.sipdroid.media;
+
+import java.io.IOException;
+import java.net.SocketException;
+
+import com.beem.project.beem.jingle.JingleService;
+import com.beem.project.beem.ui.Call;
+import org.sipdroid.net.RtpPacket;
+import org.sipdroid.net.RtpSocket;
+import org.sipdroid.net.SipdroidSocket;
+import org.sipdroid.pjlib.Codec;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.SharedPreferences.Editor;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.media.ToneGenerator;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.preference.PreferenceManager;
+import android.provider.Settings;
+
+/**
+ * RtpStreamReceiver is a generic stream receiver. It receives packets from RTP
+ * and writes them into an OutputStream.
+ */
+public class RtpStreamReceiver extends Thread {
+
+ /** Whether working in debug mode. */
+ public static boolean DEBUG = true;
+
+ /** Payload type */
+ int p_type;
+
+ /** Size of the read buffer */
+ public static final int BUFFER_SIZE = 1024;
+
+ /** Maximum blocking time, spent waiting for reading new bytes [milliseconds] */
+ public static final int SO_TIMEOUT = 200;
+
+ /** The RtpSocket */
+ private RtpSocket rtp_socket = null;
+
+ /** Whether it is running */
+ private boolean running;
+ private AudioManager am;
+ private ContentResolver cr;
+ public static int speakermode;
+ private JingleService mJingle;
+
+ /**
+ * Constructs a RtpStreamReceiver.
+ *
+ * @param output_stream
+ * the stream sink
+ * @param socket
+ * the local receiver SipdroidSocket
+ */
+ public RtpStreamReceiver(SipdroidSocket socket, int payload_type) {
+ init(socket);
+ p_type = payload_type;
+ }
+
+ /** Inits the RtpStreamReceiver */
+ private void init(SipdroidSocket socket) {
+ if (socket != null)
+ rtp_socket = new RtpSocket(socket);
+ }
+
+ /** Whether is running */
+ public boolean isRunning() {
+ return running;
+ }
+
+ /** Stops running */
+ public void halt() {
+ running = false;
+ }
+
+ public int speaker(int mode) {
+ int old = speakermode;
+
+ if (Call.headset > 0 && mode == AudioManager.MODE_NORMAL)
+ return old;
+ saveVolume();
+ setMode(speakermode = mode);
+ restoreVolume();
+ return old;
+ }
+
+ double smin = 200,s;
+ public static int nearend;
+
+ void calc(short[] lin,int off,int len) {
+ int i,j;
+ double sm = 30000,r;
+
+ for (i = 0; i < len; i += 5) {
+ j = lin[i+off];
+ s = 0.03*Math.abs(j) + 0.97*s;
+ if (s < sm) sm = s;
+ if (s > smin) nearend = 3000/5;
+ else if (nearend > 0) nearend--;
+ }
+ for (i = 0; i < len; i++) {
+ j = lin[i+off];
+ if (j > 6550)
+ lin[i+off] = 6550*5;
+ else if (j < -6550)
+ lin[i+off] = -6550*5;
+ else
+ lin[i+off] = (short)(j*5);
+ }
+ r = (double)len/100000;
+ smin = sm*r + smin*(1-r);
+ }
+
+ static void setStreamVolume(final int stream,final int vol,final int flags) {
+ (new Thread() {
+ public void run() {
+ AudioManager am = (AudioManager) Call.mContext.getSystemService(Context.AUDIO_SERVICE);
+ am.setStreamVolume(stream, vol, flags);
+ if (stream == AudioManager.STREAM_MUSIC) restored = true;
+ }
+ }).start();
+ }
+
+ static boolean restored;
+
+ public static float getEarGain() {
+ try {
+ return Float.valueOf(PreferenceManager.getDefaultSharedPreferences(Call.mContext).getString(Call.headset > 0?"heargain":"eargain", "0.25"));
+ } catch (NumberFormatException i) {
+ return (float)0.25;
+ }
+ }
+
+ void restoreVolume() {
+ switch (am.getMode()) {
+ case AudioManager.MODE_IN_CALL:
+ setStreamVolume(AudioManager.STREAM_RING,(int)(
+ am.getStreamMaxVolume(AudioManager.STREAM_RING)*
+ getEarGain()), 0);
+ track.setStereoVolume(AudioTrack.getMaxVolume()*
+ getEarGain()
+ ,AudioTrack.getMaxVolume()*
+ getEarGain());
+ break;
+ case AudioManager.MODE_NORMAL:
+ track.setStereoVolume(AudioTrack.getMaxVolume(),AudioTrack.getMaxVolume());
+ break;
+ }
+ setStreamVolume(AudioManager.STREAM_MUSIC,
+ PreferenceManager.getDefaultSharedPreferences(Call.mContext).getInt("volume"+speakermode,
+ am.getStreamMaxVolume(AudioManager.STREAM_MUSIC)*
+ (speakermode == AudioManager.MODE_NORMAL?4:3)/4
+ ),0);
+ }
+
+ void saveVolume() {
+ if (restored) {
+ Editor edit = PreferenceManager.getDefaultSharedPreferences(Call.mContext).edit();
+ edit.putInt("volume"+speakermode,am.getStreamVolume(AudioManager.STREAM_MUSIC));
+ edit.commit();
+ }
+ }
+
+ void saveSettings() {
+ if (!PreferenceManager.getDefaultSharedPreferences(Call.mContext).getBoolean("oldvalid",false)) {
+ int oldvibrate = am.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
+ int oldvibrate2 = am.getVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION);
+ if (!PreferenceManager.getDefaultSharedPreferences(Call.mContext).contains("oldvibrate2"))
+ oldvibrate2 = AudioManager.VIBRATE_SETTING_ON;
+ int oldpolicy = android.provider.Settings.System.getInt(cr, android.provider.Settings.System.WIFI_SLEEP_POLICY,
+ Settings.System.WIFI_SLEEP_POLICY_DEFAULT);
+ Editor edit = PreferenceManager.getDefaultSharedPreferences(Call.mContext).edit();
+ edit.putInt("oldvibrate", oldvibrate);
+ edit.putInt("oldvibrate2", oldvibrate2);
+ edit.putInt("oldpolicy", oldpolicy);
+ edit.putInt("oldring",am.getStreamVolume(AudioManager.STREAM_RING));
+ edit.putBoolean("oldvalid", true);
+ edit.commit();
+ }
+ }
+
+ public static void setMode(int mode) {
+ Editor edit = PreferenceManager.getDefaultSharedPreferences(Call.mContext).edit();
+ edit.putBoolean("setmode", mode != AudioManager.MODE_NORMAL);
+ edit.commit();
+ AudioManager am = (AudioManager) Call.mContext.getSystemService(Context.AUDIO_SERVICE);
+ am.setMode(mode);
+ }
+
+ public static void restoreMode() {
+ if (PreferenceManager.getDefaultSharedPreferences(Call.mContext).getBoolean("setmode",true)) {
+ setMode(AudioManager.MODE_NORMAL);
+ }
+ }
+
+ public static void restoreSettings() {
+ if (PreferenceManager.getDefaultSharedPreferences(Call.mContext).getBoolean("oldvalid",true)) {
+ AudioManager am = (AudioManager) Call.mContext.getSystemService(Context.AUDIO_SERVICE);
+ ContentResolver cr = Call.mContext.getContentResolver();
+ int oldvibrate = PreferenceManager.getDefaultSharedPreferences(Call.mContext).getInt("oldvibrate",0);
+ int oldvibrate2 = PreferenceManager.getDefaultSharedPreferences(Call.mContext).getInt("oldvibrate2",0);
+ int oldpolicy = PreferenceManager.getDefaultSharedPreferences(Call.mContext).getInt("oldpolicy",0);
+ am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,oldvibrate);
+ am.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION,oldvibrate2);
+ Settings.System.putInt(cr, Settings.System.WIFI_SLEEP_POLICY, oldpolicy);
+ setStreamVolume(AudioManager.STREAM_RING, PreferenceManager.getDefaultSharedPreferences(Call.mContext).getInt("oldring",0), 0);
+ Editor edit = PreferenceManager.getDefaultSharedPreferences(Call.mContext).edit();
+ edit.putBoolean("oldvalid", false);
+ edit.commit();
+ PowerManager pm = (PowerManager) Call.mContext.getSystemService(Context.POWER_SERVICE);
+ PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
+ PowerManager.ACQUIRE_CAUSES_WAKEUP, "Sipdroid.RtpStreamReceiver");
+ wl.acquire(1000);
+ }
+ restoreMode();
+ }
+
+ public static float good, late, lost, loss;
+ public static int timeout;
+
+ void empty() {
+ try {
+ rtp_socket.getDatagramSocket().setSoTimeout(1);
+ for (;;)
+ rtp_socket.receive(rtp_packet);
+ } catch (SocketException e2) {
+ e2.printStackTrace();
+ } catch (IOException e) {
+ }
+ try {
+ rtp_socket.getDatagramSocket().setSoTimeout(1000);
+ } catch (SocketException e2) {
+ e2.printStackTrace();
+ }
+ }
+
+ RtpPacket rtp_packet;
+ AudioTrack track;
+
+ /** Runs it in a new Thread. */
+ public void run() {
+ boolean nodata = PreferenceManager.getDefaultSharedPreferences(Call.mContext).getBoolean("nodata",false);
+
+ if (rtp_socket == null) {
+ if (DEBUG)
+ println("ERROR: RTP socket is null");
+ return;
+ }
+
+ byte[] buffer = new byte[BUFFER_SIZE+12];
+ byte[] buffer_gsm = new byte[33+12];
+ int i;
+ rtp_packet = new RtpPacket(buffer, 0);
+
+ if (DEBUG)
+ println("Reading blocks of max " + buffer.length + " bytes");
+
+ running = true;
+ speakermode = Call.docked > 0?AudioManager.MODE_NORMAL:AudioManager.MODE_IN_CALL;
+ restored = false;
+
+ android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO);
+ am = (AudioManager) Call.mContext.getSystemService(Context.AUDIO_SERVICE);
+ cr = Call.mContext.getContentResolver();
+ saveSettings();
+ Settings.System.putInt(cr, Settings.System.WIFI_SLEEP_POLICY,Settings.System.WIFI_SLEEP_POLICY_NEVER);
+ am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_OFF);
+ am.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION,AudioManager.VIBRATE_SETTING_OFF);
+ int oldvol = am.getStreamVolume(AudioManager.STREAM_MUSIC);
+ track = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
+ BUFFER_SIZE*2*2, AudioTrack.MODE_STREAM);
+ short lin[] = new short[BUFFER_SIZE];
+ short lin2[] = new short[BUFFER_SIZE];
+ int user, server, lserver, luser, cnt, todo, headroom, len = 0, seq = 0, cnt2 = 0, m = 1,
+ expseq, getseq, vm = 1, gap, gseq;
+ timeout = 1;
+ boolean islate;
+ user = 0;
+ lserver = 0;
+ luser = -8000;
+ cnt = 0;
+ switch (p_type) {
+ case 3:
+ Codec.init();
+ break;
+ case 0:
+ case 8:
+ G711.init();
+ break;
+ }
+ ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_MUSIC,(int)(ToneGenerator.MAX_VOLUME*2*0.95));
+ track.play();
+ if (Call.headset > 0 && Call.oRingtone != null) {
+ ToneGenerator tg2 = new ToneGenerator(AudioManager.STREAM_RING,(int)(ToneGenerator.MAX_VOLUME*2*0.95));
+ tg2.startTone(ToneGenerator.TONE_SUP_RINGTONE);
+ System.gc();
+ tg2.stopTone();
+ } else
+ System.gc();
+ while (running) {
+ if (Call.call_state == Call.UA_STATE_HOLD) {
+ tg.stopTone();
+ track.pause();
+ while (running && Call.call_state == Call.UA_STATE_HOLD) {
+ try {
+ sleep(1000);
+ } catch (InterruptedException e1) {
+ e1.printStackTrace();
+ }
+ }
+ track.play();
+ System.gc();
+ timeout = 1;
+ seq = 0;
+ }
+ try {
+ rtp_socket.receive(rtp_packet);
+ if (timeout != 0) {
+ tg.stopTone();
+ track.pause();
+ user += track.write(lin2,0,BUFFER_SIZE);
+ user += track.write(lin2,0,BUFFER_SIZE);
+ track.play();
+ cnt += 2*BUFFER_SIZE;
+ empty();
+ }
+ timeout = 0;
+ } catch (IOException e) {
+ if (timeout == 0 && nodata) {
+ tg.startTone(ToneGenerator.TONE_SUP_RINGTONE);
+ }
+ rtp_socket.getDatagramSocket().disconnect();
+ if (++timeout > 22) {
+ try {
+ mJingle.closeCall();
+ } catch (RemoteException e1) {
+ e1.printStackTrace();
+ }
+ break;
+ }
+ }
+ if (running && timeout == 0) {
+ gseq = rtp_packet.getSequenceNumber();
+ if (seq == gseq) {
+ m++;
+ continue;
+ }
+
+ server = track.getPlaybackHeadPosition();
+ headroom = user-server;
+
+ if (headroom > 1500)
+ cnt += len;
+ else
+ cnt = 0;
+
+ if (lserver == server)
+ cnt2++;
+ else
+ cnt2 = 0;
+
+ if (cnt <= 500 || cnt2 >= 2 || headroom - 875 < len) {
+ switch (rtp_packet.getPayloadType()) {
+ case 0:
+ len = rtp_packet.getPayloadLength();
+ G711.ulaw2linear(buffer, lin, len);
+ break;
+ case 8:
+ len = rtp_packet.getPayloadLength();
+ G711.alaw2linear(buffer, lin, len);
+ break;
+ case 3:
+ for (i = 12; i < 45; i++)
+ buffer_gsm[i] = buffer[i];
+ len = Codec.decode(buffer_gsm, lin, 0);
+ break;
+ }
+
+ if (speakermode == AudioManager.MODE_NORMAL)
+ calc(lin,0,len);
+ }
+
+ if (headroom < 250) {
+ todo = 875 - headroom;
+ println("insert "+todo);
+ islate = true;
+ user += track.write(lin2,0,todo);
+ } else
+ islate = false;
+
+ if (cnt > 500 && cnt2 < 2) {
+ todo = headroom - 875;
+ println("cut "+todo);
+ if (todo < len)
+ user += track.write(lin,todo,len-todo);
+ } else
+ user += track.write(lin,0,len);
+
+ seq = gseq;
+
+ if (user >= luser + 8000 && Call.call_state == Call.UA_STATE_INCALL) {
+ if (luser == -8000 || am.getMode() != speakermode) {
+ saveVolume();
+ setMode(speakermode);
+ restoreVolume();
+ }
+ luser = user;
+ }
+ lserver = server;
+ }
+ }
+ track.stop();
+ saveVolume();
+ setStreamVolume(AudioManager.STREAM_MUSIC,oldvol,0);
+ restoreSettings();
+ setStreamVolume(AudioManager.STREAM_MUSIC,oldvol,0);
+ tg.stopTone();
+ tg = new ToneGenerator(AudioManager.STREAM_RING,ToneGenerator.MAX_VOLUME/4*3);
+ tg.startTone(ToneGenerator.TONE_PROP_PROMPT);
+ try {
+ sleep(500);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ tg.stopTone();
+
+ rtp_socket.close();
+ rtp_socket = null;
+
+ if (DEBUG)
+ println("rtp receiver terminated");
+ }
+
+ /** Debug output */
+ private static void println(String str) {
+ System.out.println("RtpStreamReceiver: " + str);
+ }
+
+ public static int byte2int(byte b) { // return (b>=0)? b : -((b^0xFF)+1);
+ // return (b>=0)? b : b+0x100;
+ return (b + 0x100) % 0x100;
+ }
+
+ public static int byte2int(byte b1, byte b2) {
+ return (((b1 + 0x100) % 0x100) << 8) + (b2 + 0x100) % 0x100;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/sipdroid/media/RtpStreamSender.java Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2009 The Sipdroid Open Source Project
+ * Copyright (C) 2005 Luca Veltri - University of Parma - Italy
+ *
+ * This file is part of Sipdroid (http://www.sipdroid.org)
+ *
+ * Sipdroid is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this source code; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package org.sipdroid.media;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.util.Random;
+
+
+import org.sipdroid.pjlib.Codec;
+
+import org.sipdroid.media.RtpStreamReceiver;
+import org.sipdroid.net.RtpPacket;
+import org.sipdroid.net.RtpSocket;
+import org.sipdroid.net.SipdroidSocket;
+
+import com.beem.project.beem.ui.Call;
+import com.beem.project.beem.utils.BeemConnectivity;
+
+import android.content.Context;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioRecord;
+import android.media.MediaRecorder;
+import android.preference.PreferenceManager;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+
+/**
+ * RtpStreamSender is a generic stream sender. It takes an InputStream and sends
+ * it through RTP.
+ */
+public class RtpStreamSender extends Thread {
+ /** Whether working in debug mode. */
+ public static boolean DEBUG = true;
+
+ /** The RtpSocket */
+ RtpSocket rtp_socket = null;
+
+ /** Payload type */
+ int p_type;
+
+ /** Number of frame per second */
+ long frame_rate;
+
+ /** Number of bytes per frame */
+ int frame_size;
+
+ /**
+ * Whether it works synchronously with a local clock, or it it acts as slave
+ * of the InputStream
+ */
+ boolean do_sync = true;
+
+ /**
+ * Synchronization correction value, in milliseconds. It accellarates the
+ * sending rate respect to the nominal value, in order to compensate program
+ * latencies.
+ */
+ int sync_adj = 0;
+
+ /** Whether it is running */
+ boolean running = false;
+ boolean muted = false;
+
+ /**
+ * Constructs a RtpStreamSender.
+ *
+ * @param input_stream
+ * the stream to be sent
+ * @param do_sync
+ * whether time synchronization must be performed by the
+ * RtpStreamSender, or it is performed by the InputStream (e.g.
+ * the system audio input)
+ * @param payload_type
+ * the payload type
+ * @param frame_rate
+ * the frame rate, i.e. the number of frames that should be sent
+ * per second; it is used to calculate the nominal packet time
+ * and,in case of do_sync==true, the next departure time
+ * @param frame_size
+ * the size of the payload
+ * @param src_socket
+ * the socket used to send the RTP packet
+ * @param dest_addr
+ * the destination address
+ * @param dest_port
+ * the destination port
+ */
+ public RtpStreamSender(boolean do_sync,
+ int payload_type, long frame_rate, int frame_size,
+ SipdroidSocket src_socket, String dest_addr, int dest_port) {
+ init(do_sync, payload_type, frame_rate, frame_size,
+ src_socket, dest_addr, dest_port);
+ }
+
+ /** Inits the RtpStreamSender */
+ private void init(boolean do_sync,
+ int payload_type, long frame_rate, int frame_size,
+ SipdroidSocket src_socket, String dest_addr,
+ int dest_port) {
+ this.p_type = payload_type;
+ this.frame_rate = frame_rate;
+ this.frame_size = frame_size;
+ this.do_sync = do_sync;
+ try {
+ rtp_socket = new RtpSocket(src_socket, InetAddress
+ .getByName(dest_addr), dest_port);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /** Sets the synchronization adjustment time (in milliseconds). */
+ public void setSyncAdj(int millisecs) {
+ sync_adj = millisecs;
+ }
+
+ /** Whether is running */
+ public boolean isRunning() {
+ return running;
+ }
+
+ public boolean mute() {
+ return muted = !muted;
+ }
+
+ public static int delay = 0;
+
+ /** Stops running */
+ public void halt() {
+ running = false;
+ }
+
+ Random random;
+ double smin = 200,s;
+ int nearend;
+
+ void calc(short[] lin,int off,int len) {
+ int i,j;
+ double sm = 30000,r;
+
+ for (i = 0; i < len; i += 5) {
+ j = lin[i+off];
+ s = 0.03*Math.abs(j) + 0.97*s;
+ if (s < sm) sm = s;
+ if (s > smin) nearend = 3000/5;
+ else if (nearend > 0) nearend--;
+ }
+ for (i = 0; i < len; i++) {
+ j = lin[i+off];
+ if (j > 6550)
+ lin[i+off] = 6550*5;
+ else if (j < -6550)
+ lin[i+off] = -6550*5;
+ else
+ lin[i+off] = (short)(j*5);
+ }
+ r = (double)len/100000;
+ smin = sm*r + smin*(1-r);
+ }
+
+ void calc1(short[] lin,int off,int len) {
+ int i,j;
+
+ for (i = 0; i < len; i++) {
+ j = lin[i+off];
+ lin[i+off] = (short)(j>>1);
+ }
+ }
+
+ void calc5(short[] lin,int off,int len) {
+ int i,j;
+
+ for (i = 0; i < len; i++) {
+ j = lin[i+off];
+ if (j > 16350)
+ lin[i+off] = 16350<<1;
+ else if (j < -16350)
+ lin[i+off] = -16350<<1;
+ else
+ lin[i+off] = (short)(j<<1);
+ }
+ }
+
+ void calc10(short[] lin,int off,int len) {
+ int i,j;
+
+ for (i = 0; i < len; i++) {
+ j = lin[i+off];
+ if (j > 8150)
+ lin[i+off] = 8150<<2;
+ else if (j < -8150)
+ lin[i+off] = -8150<<2;
+ else
+ lin[i+off] = (short)(j<<2);
+ }
+ }
+
+ void noise(short[] lin,int off,int len,double power) {
+ int i,r = (int)(power*2);
+ short ran;
+
+ if (r == 0) r = 1;
+ for (i = 0; i < len; i += 4) {
+ ran = (short)(random.nextInt(r*2)-r);
+ lin[i+off] = ran;
+ lin[i+off+1] = ran;
+ lin[i+off+2] = ran;
+ lin[i+off+3] = ran;
+ }
+ }
+ public static float getMicGain() {
+ if (Call.headset > 0)
+ return Float.valueOf(PreferenceManager.getDefaultSharedPreferences(Call.mContext).getString("hmicgain", "1.0"));
+ return Float.valueOf(PreferenceManager.getDefaultSharedPreferences(Call.mContext).getString("micgain", "0.25"));
+ }
+
+ /** Runs it in a new Thread. */
+ public void run() {
+ if (rtp_socket == null)
+ return;
+ byte[] buffer = new byte[frame_size + 12];
+ RtpPacket rtp_packet = new RtpPacket(buffer, 0);
+ rtp_packet.setPayloadType(p_type);
+ int seqn = 0;
+ long time = 0;
+ double p = 0;
+ TelephonyManager tm = (TelephonyManager) Call.mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ boolean improve = PreferenceManager.getDefaultSharedPreferences(Call.mContext).getBoolean("improve",false);
+ boolean useGSM = !PreferenceManager.getDefaultSharedPreferences(Call.mContext).getString("compression","edge").equals("never");
+ int micgain = (int)(getMicGain()*10);
+ running = true;
+
+ if (DEBUG)
+ println("Reading blocks of " + buffer.length + " bytes");
+
+ android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
+ AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
+ AudioRecord.getMinBufferSize(8000,
+ AudioFormat.CHANNEL_CONFIGURATION_MONO,
+ AudioFormat.ENCODING_PCM_16BIT)*3/2);
+ short[] lin = new short[frame_size*11];
+ int num,ring = 0;
+ random = new Random();
+ InputStream alerting = null;
+ try {
+ alerting = Call.mContext.getAssets().open("alerting");
+ } catch (IOException e2) {
+ e2.printStackTrace();
+ }
+ switch (p_type) {
+ case 3:
+ Codec.init();
+ break;
+ case 0:
+ case 8:
+ G711.init();
+ break;
+ }
+ record.startRecording();
+ while (running) {
+ if (muted || Call.call_state == Call.UA_STATE_HOLD) {
+ record.stop();
+ while (running && (muted || Call.call_state == Call.UA_STATE_HOLD)) {
+ try {
+ sleep(1000);
+ } catch (InterruptedException e1) {
+ e1.printStackTrace();
+ }
+ }
+ record.startRecording();
+ }
+ num = record.read(lin,(ring+delay)%(frame_size*11),frame_size);
+
+ if (RtpStreamReceiver.speakermode == AudioManager.MODE_NORMAL) {
+ calc(lin,(ring+delay)%(frame_size*11),num);
+ if (RtpStreamReceiver.nearend != 0)
+ noise(lin,(ring+delay)%(frame_size*11),num,p);
+ else if (RtpStreamReceiver.nearend == 0)
+ p = 0.9*p + 0.1*s;
+ } else switch (micgain) {
+ case 1:
+ calc1(lin,(ring+delay)%(frame_size*11),num);
+ break;
+ case 5:
+ calc5(lin,(ring+delay)%(frame_size*11),num);
+ break;
+ case 10:
+ calc10(lin,(ring+delay)%(frame_size*11),num);
+ break;
+ }
+ if (Call.call_state != Call.UA_STATE_INCALL && alerting != null) {
+ try {
+ if (alerting.available() < num)
+ alerting.reset();
+ alerting.read(buffer,12,num);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ switch (p_type) {// have to add ulaw case?
+ case 3:
+ G711.alaw2linear(buffer, lin, num);
+ num = Codec.encode(lin, 0, buffer, num);
+ break;
+ case 0:
+ G711.alaw2linear(buffer, lin, num);
+ G711.linear2ulaw(lin, 0, buffer, num);
+ break;
+ }
+ } else {
+ switch (p_type) {
+ case 3:
+ num = Codec.encode(lin, ring%(frame_size*11), buffer, num);
+ break;
+ case 0:
+ G711.linear2ulaw(lin, ring%(frame_size*11), buffer, num);
+ break;
+ case 8:
+ G711.linear2alaw(lin, ring%(frame_size*11), buffer, num);
+ break;
+ }
+ }
+ ring += frame_size;
+ rtp_packet.setSequenceNumber(seqn++);
+ rtp_packet.setTimestamp(time);
+ rtp_packet.setPayloadLength(num);
+ try {
+ rtp_socket.send(rtp_packet);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ time += frame_size;
+ /*if (useGSM && p_type == 8 && !BeemConnectivity.isWifi(Call.mContext) && tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_EDGE) {
+ rtp_packet.setPayloadType(p_type = 3);
+ if (frame_size == 1024) {
+ frame_size = 960;
+ ring = 0;
+ }
+ }*/
+ }
+ record.stop();
+
+ rtp_socket.close();
+ rtp_socket = null;
+
+ if (DEBUG)
+ println("rtp sender terminated");
+ }
+
+ /** Debug output */
+ private static void println(String str) {
+ System.out.println("RtpStreamSender: " + str);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/sipdroid/net/RtpPacket.java Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2009 The Sipdroid Open Source Project
+ * Copyright (C) 2005 Luca Veltri - University of Parma - Italy
+ *
+ * This file is part of Sipdroid (http://www.sipdroid.org)
+ *
+ * Sipdroid is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this source code; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package org.sipdroid.net;
+
+import com.beem.project.beem.utils.Random;
+
+/**
+ * RtpPacket implements a RTP packet.
+ */
+public class RtpPacket {
+ /* RTP packet buffer containing both the RTP header and payload */
+ byte[] packet;
+
+ /* RTP packet length */
+ int packet_len;
+
+ /* RTP header length */
+ // int header_len;
+ /** Gets the RTP packet */
+ public byte[] getPacket() {
+ return packet;
+ }
+
+ /** Gets the RTP packet length */
+ public int getLength() {
+ return packet_len;
+ }
+
+ /** Gets the RTP header length */
+ public int getHeaderLength() {
+ if (packet_len >= 12)
+ return 12 + 4 * getCscrCount();
+ else
+ return packet_len; // broken packet
+ }
+
+ /** Gets the RTP header length */
+ public int getPayloadLength() {
+ if (packet_len >= 12)
+ return packet_len - getHeaderLength();
+ else
+ return 0; // broken packet
+ }
+
+ /** Sets the RTP payload length */
+ public void setPayloadLength(int len) {
+ packet_len = getHeaderLength() + len;
+ }
+
+ // version (V): 2 bits
+ // padding (P): 1 bit
+ // extension (X): 1 bit
+ // CSRC count (CC): 4 bits
+ // marker (M): 1 bit
+ // payload type (PT): 7 bits
+ // sequence number: 16 bits
+ // timestamp: 32 bits
+ // SSRC: 32 bits
+ // CSRC list: 0 to 15 items, 32 bits each
+
+ /** Gets the version (V) */
+ public int getVersion() {
+ if (packet_len >= 12)
+ return (packet[0] >> 6 & 0x03);
+ else
+ return 0; // broken packet
+ }
+
+ /** Sets the version (V) */
+ public void setVersion(int v) {
+ if (packet_len >= 12)
+ packet[0] = (byte) ((packet[0] & 0x3F) | ((v & 0x03) << 6));
+ }
+
+ /** Whether has padding (P) */
+ public boolean hasPadding() {
+ if (packet_len >= 12)
+ return getBit(packet[0], 5);
+ else
+ return false; // broken packet
+ }
+
+ /** Set padding (P) */
+ public void setPadding(boolean p) {
+ if (packet_len >= 12)
+ packet[0] = setBit(p, packet[0], 5);
+ }
+
+ /** Whether has extension (X) */
+ public boolean hasExtension() {
+ if (packet_len >= 12)
+ return getBit(packet[0], 4);
+ else
+ return false; // broken packet
+ }
+
+ /** Set extension (X) */
+ public void setExtension(boolean x) {
+ if (packet_len >= 12)
+ packet[0] = setBit(x, packet[0], 4);
+ }
+
+ /** Gets the CSCR count (CC) */
+ public int getCscrCount() {
+ if (packet_len >= 12)
+ return (packet[0] & 0x0F);
+ else
+ return 0; // broken packet
+ }
+
+ /** Whether has marker (M) */
+ public boolean hasMarker() {
+ if (packet_len >= 12)
+ return getBit(packet[1], 7);
+ else
+ return false; // broken packet
+ }
+
+ /** Set marker (M) */
+ public void setMarker(boolean m) {
+ if (packet_len >= 12)
+ packet[1] = setBit(m, packet[1], 7);
+ }
+
+ /** Gets the payload type (PT) */
+ public int getPayloadType() {
+ if (packet_len >= 12)
+ return (packet[1] & 0x7F);
+ else
+ return -1; // broken packet
+ }
+
+ /** Sets the payload type (PT) */
+ public void setPayloadType(int pt) {
+ if (packet_len >= 12)
+ packet[1] = (byte) ((packet[1] & 0x80) | (pt & 0x7F));
+ }
+
+ /** Gets the sequence number */
+ public int getSequenceNumber() {
+ if (packet_len >= 12)
+ return getInt(packet, 2, 4);
+ else
+ return 0; // broken packet
+ }
+
+ /** Sets the sequence number */
+ public void setSequenceNumber(int sn) {
+ if (packet_len >= 12)
+ setInt(sn, packet, 2, 4);
+ }
+
+ /** Gets the timestamp */
+ public long getTimestamp() {
+ if (packet_len >= 12)
+ return getLong(packet, 4, 8);
+ else
+ return 0; // broken packet
+ }
+
+ /** Sets the timestamp */
+ public void setTimestamp(long timestamp) {
+ if (packet_len >= 12)
+ setLong(timestamp, packet, 4, 8);
+ }
+
+ /** Gets the SSCR */
+ public long getSscr() {
+ if (packet_len >= 12)
+ return getLong(packet, 8, 12);
+ else
+ return 0; // broken packet
+ }
+
+ /** Sets the SSCR */
+ public void setSscr(long ssrc) {
+ if (packet_len >= 12)
+ setLong(ssrc, packet, 8, 12);
+ }
+
+ /** Gets the CSCR list */
+ public long[] getCscrList() {
+ int cc = getCscrCount();
+ long[] cscr = new long[cc];
+ for (int i = 0; i < cc; i++)
+ cscr[i] = getLong(packet, 12 + 4 * i, 16 + 4 * i);
+ return cscr;
+ }
+
+ /** Sets the CSCR list */
+ public void setCscrList(long[] cscr) {
+ if (packet_len >= 12) {
+ int cc = cscr.length;
+ if (cc > 15)
+ cc = 15;
+ packet[0] = (byte) (((packet[0] >> 4) << 4) + cc);
+ cscr = new long[cc];
+ for (int i = 0; i < cc; i++)
+ setLong(cscr[i], packet, 12 + 4 * i, 16 + 4 * i);
+ // header_len=12+4*cc;
+ }
+ }
+
+ /** Sets the payload */
+ public void setPayload(byte[] payload, int len) {
+ if (packet_len >= 12) {
+ int header_len = getHeaderLength();
+ for (int i = 0; i < len; i++)
+ packet[header_len + i] = payload[i];
+ packet_len = header_len + len;
+ }
+ }
+
+ /** Gets the payload */
+ public byte[] getPayload() {
+ int header_len = getHeaderLength();
+ int len = packet_len - header_len;
+ byte[] payload = new byte[len];
+ for (int i = 0; i < len; i++)
+ payload[i] = packet[header_len + i];
+ return payload;
+ }
+
+ /** Creates a new RTP packet */
+ public RtpPacket(byte[] buffer, int packet_length) {
+ packet = buffer;
+ packet_len = packet_length;
+ if (packet_len < 12)
+ packet_len = 12;
+ init(0x0F);
+ }
+
+ /** init the RTP packet header (only PT) */
+ public void init(int ptype) {
+ init(ptype, Random.nextLong());
+ }
+
+ /** init the RTP packet header (PT and SSCR) */
+ public void init(int ptype, long sscr) {
+ init(ptype, Random.nextInt(), Random.nextLong(), sscr);
+ }
+
+ /** init the RTP packet header (PT, SQN, TimeStamp, SSCR) */
+ public void init(int ptype, int seqn, long timestamp, long sscr) {
+ setVersion(2);
+ setPayloadType(ptype);
+ setSequenceNumber(seqn);
+ setTimestamp(timestamp);
+ setSscr(sscr);
+ }
+
+ // *********************** Private and Static ***********************
+
+ /** Gets int value */
+ private static int getInt(byte b) {
+ return ((int) b + 256) % 256;
+ }
+
+ /** Gets long value */
+ private static long getLong(byte[] data, int begin, int end) {
+ long n = 0;
+ for (; begin < end; begin++) {
+ n <<= 8;
+ n += data[begin];
+ }
+ return n;
+ }
+
+ /** Sets long value */
+ private static void setLong(long n, byte[] data, int begin, int end) {
+ for (end--; end >= begin; end--) {
+ data[end] = (byte) (n % 256);
+ n >>= 8;
+ }
+ }
+
+ /** Gets Int value */
+ private static int getInt(byte[] data, int begin, int end) {
+ return (int) getLong(data, begin, end);
+ }
+
+ /** Sets Int value */
+ private static void setInt(int n, byte[] data, int begin, int end) {
+ setLong(n, data, begin, end);
+ }
+
+ /** Gets bit value */
+ private static boolean getBit(byte b, int bit) {
+ return (b >> bit) == 1;
+ }
+
+ /** Sets bit value */
+ private static byte setBit(boolean value, byte b, int bit) {
+ if (value)
+ return (byte) (b | (1 << bit));
+ else
+ return (byte) ((b | (1 << bit)) ^ (1 << bit));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/sipdroid/net/RtpSocket.java Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2009 The Sipdroid Open Source Project
+ * Copyright (C) 2005 Luca Veltri - University of Parma - Italy
+ *
+ * This file is part of Sipdroid (http://www.sipdroid.org)
+ *
+ * Sipdroid is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this source code; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package org.sipdroid.net;
+
+import java.net.InetAddress;
+import java.net.DatagramPacket;
+import java.io.IOException;
+
+
+
+/**
+ * RtpSocket implements a RTP socket for receiving and sending RTP packets.
+ * <p>
+ * RtpSocket is associated to a DatagramSocket that is used to send and/or
+ * receive RtpPackets.
+ */
+public class RtpSocket {
+ /** UDP socket */
+ SipdroidSocket socket;
+ DatagramPacket datagram;
+
+ /** Remote address */
+ InetAddress r_addr;
+
+ /** Remote port */
+ int r_port;
+
+ /** Creates a new RTP socket (only receiver) */
+ public RtpSocket(SipdroidSocket datagram_socket) {
+ socket = datagram_socket;
+ r_addr = null;
+ r_port = 0;
+ datagram = new DatagramPacket(new byte[1],1);
+ }
+
+ /** Creates a new RTP socket (sender and receiver) */
+ public RtpSocket(SipdroidSocket datagram_socket,
+ InetAddress remote_address, int remote_port) {
+ socket = datagram_socket;
+ r_addr = remote_address;
+ r_port = remote_port;
+ datagram = new DatagramPacket(new byte[1],1);
+ }
+
+ /** Returns the RTP SipdroidSocket */
+ public SipdroidSocket getDatagramSocket() {
+ return socket;
+ }
+
+ /** Receives a RTP packet from this socket */
+ public void receive(RtpPacket rtpp) throws IOException {
+ datagram.setData(rtpp.packet);
+ datagram.setLength(rtpp.packet.length);
+ socket.receive(datagram);
+ if (!socket.isConnected())
+ socket.connect(datagram.getAddress(),datagram.getPort());
+ rtpp.packet_len = datagram.getLength();
+ }
+
+ /** Sends a RTP packet from this socket */
+ public void send(RtpPacket rtpp) throws IOException {
+ datagram.setData(rtpp.packet);
+ datagram.setLength(rtpp.packet_len);
+ datagram.setAddress(r_addr);
+ datagram.setPort(r_port);
+ socket.send(datagram);
+ }
+
+ /** Closes this socket */
+ public void close() { // socket.close();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/sipdroid/net/SipdroidSocket.java Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2009 The Sipdroid Open Source Project
+ *
+ * This file is part of Sipdroid (http://www.sipdroid.org)
+ *
+ * Sipdroid is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this source code; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package org.sipdroid.net;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.net.SocketOptions;
+import java.net.UnknownHostException;
+
+import org.sipdroid.net.impl.OSNetworkSystem;
+import org.sipdroid.net.impl.PlainDatagramSocketImpl;
+
+public class SipdroidSocket extends DatagramSocket {
+
+ PlainDatagramSocketImpl impl;
+ public static boolean loaded = false;
+
+ public SipdroidSocket(int port) throws SocketException, UnknownHostException {
+ super(!loaded?port:0);
+ if (loaded) {
+ impl = new PlainDatagramSocketImpl();
+ impl.create();
+ impl.bind(port,InetAddress.getByName("0"));
+ }
+ }
+
+ public void close() {
+ super.close();
+ if (loaded) impl.close();
+ }
+
+ public void setSoTimeout(int val) throws SocketException {
+ if (loaded) impl.setOption(SocketOptions.SO_TIMEOUT, val);
+ else super.setSoTimeout(val);
+ }
+
+ public void receive(DatagramPacket pack) throws IOException {
+ if (loaded) impl.receive(pack);
+ else super.receive(pack);
+ }
+
+ public void send(DatagramPacket pack) throws IOException {
+ if (loaded) impl.send(pack);
+ else super.send(pack);
+ }
+
+ public boolean isConnected() {
+ if (loaded) return true;
+ else return super.isConnected();
+ }
+
+ public void disconnect() {
+ if (!loaded) super.disconnect();
+ }
+
+ public void connect(InetAddress addr,int port) {
+ if (!loaded) super.connect(addr,port);
+ }
+
+ static {
+ try {
+ System.loadLibrary("OSNetworkSystem");
+ OSNetworkSystem.getOSNetworkSystem().oneTimeInitialization(true);
+ SipdroidSocket.loaded = true;
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/sipdroid/net/impl/OSNetworkSystem.java Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,748 @@
+/*
+ * Copyright (C) 2009 The Sipdroid Open Source Project
+ *
+ * This file is part of Sipdroid (http://www.sipdroid.org)
+ *
+ * Sipdroid is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this source code; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+// BEGIN android-note
+// address length was changed from long to int for performance reasons.
+// END android-note
+
+package org.sipdroid.net.impl;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+import java.net.UnknownHostException;
+import java.nio.channels.Channel;
+// BEGIN android-removed
+// import java.nio.channels.SelectableChannel;
+// END android-removed
+/*
+ *
+ * This Class is used for native code wrap, the implement class of
+ * INetworkSystem.
+ *
+ */
+public final class OSNetworkSystem {
+
+ // ----------------------------------------------------
+ // Class Variables
+ // ----------------------------------------------------
+
+ private static final int ERRORCODE_SOCKET_TIMEOUT = -209;
+
+ private static OSNetworkSystem ref = new OSNetworkSystem();
+
+ private static final int INETADDR_REACHABLE = 0;
+
+ private static boolean isNetworkInited = false;
+
+ // ----------------------------------------------------
+ // Class Constructor
+ // ----------------------------------------------------
+
+ // can not be instantiated.
+ private OSNetworkSystem() {
+ super();
+ }
+
+ /*
+ * @return a static ref of this class
+ */
+ public static OSNetworkSystem getOSNetworkSystem() {
+ return ref;
+ }
+
+ // Useing when cache set/get is OK
+ // public static native void oneTimeInitializationDatagram(
+ // boolean jcl_IPv6_support);
+ //
+ // public static native void oneTimeInitializationSocket(
+ // boolean jcl_IPv6_support);
+
+ // --------------------------------------------------
+ // java codes that wrap native codes
+ // --------------------------------------------------
+
+ public void createSocket(FileDescriptor fd, boolean preferIPv4Stack)
+ throws IOException {
+ createSocketImpl(fd, preferIPv4Stack);
+ }
+
+ public void createDatagramSocket(FileDescriptor fd, boolean preferIPv4Stack)
+ throws SocketException {
+ createDatagramSocketImpl(fd, preferIPv4Stack);
+ }
+
+ public int read(FileDescriptor aFD, byte[] data, int offset, int count,
+ int timeout) throws IOException {
+ return readSocketImpl(aFD, data, offset, count, timeout);
+ }
+
+ public int readDirect(FileDescriptor aFD, int address, int offset, int count,
+ int timeout) throws IOException {
+ return readSocketDirectImpl(aFD, address, offset, count, timeout);
+ }
+
+ public int write(FileDescriptor aFD, byte[] data, int offset, int count)
+ throws IOException {
+ return writeSocketImpl(aFD, data, offset, count);
+ }
+
+ public int writeDirect(FileDescriptor aFD, int address, int offset,
+ int count) throws IOException {
+ return writeSocketDirectImpl(aFD, address, offset, count);
+ }
+
+ public void setNonBlocking(FileDescriptor aFD, boolean block)
+ throws IOException {
+ setNonBlockingImpl(aFD, block);
+ }
+
+ public void connectDatagram(FileDescriptor aFD, int port, int trafficClass,
+ InetAddress inetAddress) throws SocketException {
+ connectDatagramImpl2(aFD, port, trafficClass, inetAddress);
+ }
+
+ public int connect(FileDescriptor aFD, int trafficClass,
+ InetAddress inetAddress, int port) throws IOException{
+ return connectSocketImpl(aFD, trafficClass, inetAddress, port);
+ }
+
+ // BEGIN android-changed
+ public int connectWithTimeout(FileDescriptor aFD, int timeout,
+ int trafficClass, InetAddress inetAddress, int port, int step,
+ byte[] context) throws IOException{
+ return connectWithTimeoutSocketImpl(aFD, timeout, trafficClass,
+ inetAddress, port, step, context);
+ }
+ // END android-changed
+
+ public void connectStreamWithTimeoutSocket(FileDescriptor aFD, int aport,
+ int timeout, int trafficClass, InetAddress inetAddress)
+ throws IOException {
+ connectStreamWithTimeoutSocketImpl(aFD, aport, timeout, trafficClass,
+ inetAddress);
+ }
+
+ public void bind(FileDescriptor aFD, int port, InetAddress inetAddress)
+ throws SocketException {
+ socketBindImpl(aFD, port, inetAddress);
+ }
+
+ public boolean bind2(FileDescriptor aFD, int port, boolean bindToDevice,
+ InetAddress inetAddress) throws SocketException {
+ return socketBindImpl2(aFD, port, bindToDevice, inetAddress);
+ }
+
+ public void accept(FileDescriptor fdServer, SocketImpl newSocket,
+ FileDescriptor fdnewSocket, int timeout) throws IOException {
+ acceptSocketImpl(fdServer, newSocket, fdnewSocket, timeout);
+ }
+
+ public int sendDatagram(FileDescriptor fd, byte[] data, int offset,
+ int length, int port, boolean bindToDevice, int trafficClass,
+ InetAddress inetAddress) throws IOException {
+ return sendDatagramImpl(fd, data, offset, length, port, bindToDevice,
+ trafficClass, inetAddress);
+ }
+
+ public int sendDatagramDirect(FileDescriptor fd, int address, int offset,
+ int length, int port, boolean bindToDevice, int trafficClass,
+ InetAddress inetAddress) throws IOException {
+ return sendDatagramDirectImpl(fd, address, offset, length, port, bindToDevice,
+ trafficClass, inetAddress);
+ }
+
+ public int sendDatagram2(FileDescriptor fd, byte[] data, int offset,
+ int length, int port, InetAddress inetAddress) throws IOException {
+ return sendDatagramImpl2(fd, data, offset, length, port, inetAddress);
+ }
+
+ public int receiveDatagram(FileDescriptor aFD, DatagramPacket packet,
+ byte[] data, int offset, int length, int receiveTimeout,
+ boolean peek) throws IOException {
+ return receiveDatagramImpl(aFD, packet, data, offset, length,
+ receiveTimeout, peek);
+ }
+
+ public int receiveDatagramDirect(FileDescriptor aFD, DatagramPacket packet,
+ int address, int offset, int length, int receiveTimeout,
+ boolean peek) throws IOException {
+ return receiveDatagramDirectImpl(aFD, packet, address, offset, length,
+ receiveTimeout, peek);
+ }
+
+ public int recvConnectedDatagram(FileDescriptor aFD, DatagramPacket packet,
+ byte[] data, int offset, int length, int receiveTimeout,
+ boolean peek) throws IOException {
+ return recvConnectedDatagramImpl(aFD, packet, data, offset, length,
+ receiveTimeout, peek);
+ }
+
+ public int recvConnectedDatagramDirect(FileDescriptor aFD, DatagramPacket packet, int address,
+ int offset, int length, int receiveTimeout, boolean peek)
+ throws IOException {
+ return recvConnectedDatagramDirectImpl(aFD, packet, address, offset, length, receiveTimeout, peek);
+ }
+
+ public int peekDatagram(FileDescriptor aFD, InetAddress sender,
+ int receiveTimeout) throws IOException {
+ return peekDatagramImpl(aFD, sender, receiveTimeout);
+ }
+
+ public int sendConnectedDatagram(FileDescriptor fd, byte[] data,
+ int offset, int length, boolean bindToDevice) throws IOException {
+ return sendConnectedDatagramImpl(fd, data, offset, length, bindToDevice);
+ }
+
+ public int sendConnectedDatagramDirect(FileDescriptor fd, int address,
+ int offset, int length, boolean bindToDevice) throws IOException {
+ return sendConnectedDatagramDirectImpl(fd, address, offset, length, bindToDevice);
+ }
+
+ public void disconnectDatagram(FileDescriptor aFD) throws SocketException {
+ disconnectDatagramImpl(aFD);
+ }
+
+ public void createMulticastSocket(FileDescriptor aFD,
+ boolean preferIPv4Stack) throws SocketException {
+ createMulticastSocketImpl(aFD, preferIPv4Stack);
+ }
+
+ public void createServerStreamSocket(FileDescriptor aFD,
+ boolean preferIPv4Stack) throws SocketException {
+ createServerStreamSocketImpl(aFD, preferIPv4Stack);
+ }
+
+ public int receiveStream(FileDescriptor aFD, byte[] data, int offset,
+ int count, int timeout) throws IOException {
+ return receiveStreamImpl(aFD, data, offset, count, timeout);
+ }
+
+ public int sendStream(FileDescriptor fd, byte[] data, int offset, int count)
+ throws IOException {
+ return sendStreamImpl(fd, data, offset, count);
+ }
+
+ public void shutdownInput(FileDescriptor descriptor) throws IOException {
+ shutdownInputImpl(descriptor);
+ }
+
+ public void shutdownOutput(FileDescriptor descriptor) throws IOException {
+ shutdownOutputImpl(descriptor);
+ }
+
+ public boolean supportsUrgentData(FileDescriptor fd) {
+ return supportsUrgentDataImpl(fd);
+ }
+
+ public void sendUrgentData(FileDescriptor fd, byte value) {
+ sendUrgentDataImpl(fd, value);
+ }
+
+ public int availableStream(FileDescriptor aFD) throws SocketException {
+ return availableStreamImpl(aFD);
+ }
+
+ // BEGIN android-removed
+ // public void acceptStreamSocket(FileDescriptor fdServer,
+ // SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
+ // throws IOException {
+ // acceptStreamSocketImpl(fdServer, newSocket, fdnewSocket, timeout);
+ // }
+ //
+ // public void createStreamSocket(FileDescriptor aFD, boolean preferIPv4Stack)
+ // throws SocketException {
+ // createStreamSocketImpl(aFD, preferIPv4Stack);
+ // }
+ // END android-removed
+
+ public void listenStreamSocket(FileDescriptor aFD, int backlog)
+ throws SocketException {
+ listenStreamSocketImpl(aFD, backlog);
+ }
+
+ // BEGIN android-removed
+ // public boolean isReachableByICMP(final InetAddress dest,
+ // InetAddress source, final int ttl, final int timeout) {
+ // return INETADDR_REACHABLE == isReachableByICMPImpl(dest, source, ttl,
+ // timeout);
+ // }
+ // END android-removed
+
+ /*
+ *
+ * @param
+ * readChannels all channels interested in read and accept
+ * @param
+ * writeChannels all channels interested in write and connect
+ * @param timeout
+ * timeout in millis @return a set of channels that are ready for operation
+ * @throws
+ * SocketException @return int array, each int approve one of the * channel if OK
+ */
+
+ public int[] select(FileDescriptor[] readFDs,
+ FileDescriptor[] writeFDs, long timeout)
+ throws SocketException {
+ int countRead = readFDs.length;
+ int countWrite = writeFDs.length;
+ int result = 0;
+ if (0 == countRead + countWrite) {
+ return (new int[0]);
+ }
+ int[] flags = new int[countRead + countWrite];
+
+ // handle timeout in native
+ result = selectImpl(readFDs, writeFDs, countRead, countWrite, flags,
+ timeout);
+
+ if (0 <= result) {
+ return flags;
+ }
+ if (ERRORCODE_SOCKET_TIMEOUT == result) {
+ return new int[0];
+ }
+ throw new SocketException();
+
+ }
+
+ public InetAddress getSocketLocalAddress(FileDescriptor aFD,
+ boolean preferIPv6Addresses) {
+ return getSocketLocalAddressImpl(aFD, preferIPv6Addresses);
+ }
+
+ /*
+ * Query the IP stack for the local port to which this socket is bound.
+ *
+ * @param aFD the socket descriptor @param preferIPv6Addresses address
+ * preference for nodes that support both IPv4 and IPv6 @return int the
+ * local port to which the socket is bound
+ */
+ public int getSocketLocalPort(FileDescriptor aFD,
+ boolean preferIPv6Addresses) {
+ return getSocketLocalPortImpl(aFD, preferIPv6Addresses);
+ }
+
+ /*
+ * Query the IP stack for the nominated socket option.
+ *
+ * @param aFD the socket descriptor @param opt the socket option type
+ * @return the nominated socket option value
+ *
+ * @throws SocketException if the option is invalid
+ */
+ public Object getSocketOption(FileDescriptor aFD, int opt)
+ throws SocketException {
+ return getSocketOptionImpl(aFD, opt);
+ }
+
+ /*
+ * Set the nominated socket option in the IP stack.
+ *
+ * @param aFD the socket descriptor @param opt the option selector @param
+ * optVal the nominated option value
+ *
+ * @throws SocketException if the option is invalid or cannot be set
+ */
+ public void setSocketOption(FileDescriptor aFD, int opt, Object optVal)
+ throws SocketException {
+ setSocketOptionImpl(aFD, opt, optVal);
+ }
+
+ public int getSocketFlags() {
+ return getSocketFlagsImpl();
+ }
+
+ /*
+ * Close the socket in the IP stack.
+ *
+ * @param aFD the socket descriptor
+ */
+ public void socketClose(FileDescriptor aFD) throws IOException {
+ socketCloseImpl(aFD);
+ }
+
+ public InetAddress getHostByAddr(byte[] addr) throws UnknownHostException {
+ return getHostByAddrImpl(addr);
+ }
+
+ public InetAddress getHostByName(String addr, boolean preferIPv6Addresses)
+ throws UnknownHostException {
+ return getHostByNameImpl(addr, preferIPv6Addresses);
+ }
+
+ public void setInetAddress(InetAddress sender, byte[] address) {
+ setInetAddressImpl(sender, address);
+ }
+
+ // ---------------------------------------------------
+ // Native Codes
+ // ---------------------------------------------------
+
+ static native void createSocketImpl(FileDescriptor fd,
+ boolean preferIPv4Stack);
+
+ /*
+ * Allocate a datagram socket in the IP stack. The socket is associated with
+ * the <code>aFD</code>.
+ *
+ * @param aFD the FileDescriptor to associate with the socket @param
+ * preferIPv4Stack IP stack preference if underlying platform is V4/V6
+ * @exception SocketException upon an allocation error
+ */
+ static native void createDatagramSocketImpl(FileDescriptor aFD,
+ boolean preferIPv4Stack) throws SocketException;
+
+ static native int readSocketImpl(FileDescriptor aFD, byte[] data,
+ int offset, int count, int timeout) throws IOException;
+
+ static native int readSocketDirectImpl(FileDescriptor aFD, int address,
+ int offset, int count, int timeout) throws IOException;
+
+ static native int writeSocketImpl(FileDescriptor fd, byte[] data,
+ int offset, int count) throws IOException;
+
+ static native int writeSocketDirectImpl(FileDescriptor fd, int address,
+ int offset, int count) throws IOException;
+
+ static native void setNonBlockingImpl(FileDescriptor aFD,
+ boolean block);
+
+ static native int connectSocketImpl(FileDescriptor aFD,
+ int trafficClass, InetAddress inetAddress, int port);
+
+ // BEGIN android-changed
+ static native int connectWithTimeoutSocketImpl(
+ FileDescriptor aFD, int timeout, int trafficClass,
+ InetAddress hostname, int port, int step, byte[] context);
+ // END android-changed
+
+ static native void connectStreamWithTimeoutSocketImpl(FileDescriptor aFD,
+ int aport, int timeout, int trafficClass, InetAddress inetAddress)
+ throws IOException;
+
+ static native void socketBindImpl(FileDescriptor aFD, int port,
+ InetAddress inetAddress) throws SocketException;
+
+ static native void listenStreamSocketImpl(FileDescriptor aFD, int backlog)
+ throws SocketException;
+
+ static native int availableStreamImpl(FileDescriptor aFD)
+ throws SocketException;
+
+ static native void acceptSocketImpl(FileDescriptor fdServer,
+ SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
+ throws IOException;
+
+ static native boolean supportsUrgentDataImpl(FileDescriptor fd);
+
+ static native void sendUrgentDataImpl(FileDescriptor fd, byte value);
+
+ /*
+ * Connect the socket to a port and address
+ *
+ * @param aFD the FileDescriptor to associate with the socket @param port
+ * the port to connect to @param trafficClass the traffic Class to be used
+ * then the connection is made @param inetAddress address to connect to.
+ *
+ * @exception SocketException if the connect fails
+ */
+ static native void connectDatagramImpl2(FileDescriptor aFD,
+ int port, int trafficClass, InetAddress inetAddress)
+ throws SocketException;
+
+ /*
+ * Disconnect the socket to a port and address
+ *
+ * @param aFD the FileDescriptor to associate with the socket
+ *
+ * @exception SocketException if the disconnect fails
+ */
+ static native void disconnectDatagramImpl(FileDescriptor aFD)
+ throws SocketException;
+
+ /*
+ * Allocate a datagram socket in the IP stack. The socket is associated with
+ * the <code>aFD</code>.
+ *
+ * @param aFD the FileDescriptor to associate with the socket @param
+ * preferIPv4Stack IP stack preference if underlying platform is V4/V6
+ * @exception SocketException upon an allocation error
+ */
+
+ /*
+ * Bind the socket to the port/localhost in the IP stack.
+ *
+ * @param aFD the socket descriptor @param port the option selector @param
+ * bindToDevice bind the socket to the specified interface @param
+ * inetAddress address to connect to. @return if bind successful @exception
+ * SocketException thrown if bind operation fails
+ */
+ static native boolean socketBindImpl2(FileDescriptor aFD,
+ int port, boolean bindToDevice, InetAddress inetAddress)
+ throws SocketException;
+
+ /*
+ * Peek on the socket, update <code>sender</code> address and answer the
+ * sender port.
+ *
+ * @param aFD the socket FileDescriptor @param sender an InetAddress, to be
+ * updated with the sender's address @param receiveTimeout the maximum
+ * length of time the socket should block, reading @return int the sender
+ * port
+ *
+ * @exception IOException upon an read error or timeout
+ */
+ static native int peekDatagramImpl(FileDescriptor aFD,
+ InetAddress sender, int receiveTimeout) throws IOException;
+
+ /*
+ * Recieve data on the socket into the specified buffer. The packet fields
+ * <code>data</code> & <code>length</code> are passed in addition to
+ * <code>packet</code> to eliminate the JNI field access calls.
+ *
+ * @param aFD the socket FileDescriptor @param packet the DatagramPacket to
+ * receive into @param data the data buffer of the packet @param offset the
+ * offset in the data buffer @param length the length of the data buffer in
+ * the packet @param receiveTimeout the maximum length of time the socket
+ * should block, reading @param peek indicates to peek at the data @return
+ * number of data received @exception IOException upon an read error or
+ * timeout
+ */
+ static native int receiveDatagramImpl(FileDescriptor aFD,
+ DatagramPacket packet, byte[] data, int offset, int length,
+ int receiveTimeout, boolean peek) throws IOException;
+
+ static native int receiveDatagramDirectImpl(FileDescriptor aFD,
+ DatagramPacket packet, int address, int offset, int length,
+ int receiveTimeout, boolean peek) throws IOException;
+
+ /*
+ * Recieve data on the connected socket into the specified buffer. The
+ * packet fields <code>data</code> & <code>length</code> are passed in
+ * addition to <code>packet</code> to eliminate the JNI field access
+ * calls.
+ *
+ * @param aFD the socket FileDescriptor @param packet the DatagramPacket to
+ * receive into @param data the data buffer of the packet @param offset the
+ * offset in the data buffer @param length the length of the data buffer in
+ * the packet @param receiveTimeout the maximum length of time the socket
+ * should block, reading @param peek indicates to peek at the data @return
+ * number of data received @exception IOException upon an read error or
+ * timeout
+ */
+ static native int recvConnectedDatagramImpl(FileDescriptor aFD,
+ DatagramPacket packet, byte[] data, int offset, int length,
+ int receiveTimeout, boolean peek) throws IOException;
+
+ static native int recvConnectedDatagramDirectImpl(FileDescriptor aFD,
+ DatagramPacket packet, int address, int offset, int length,
+ int receiveTimeout, boolean peek) throws IOException;
+
+ /*
+ * Send the <code>data</code> to the nominated target <code>address</code>
+ * and <code>port</code>. These values are derived from the
+ * DatagramPacket to reduce the field calls within JNI.
+ *
+ * @param fd the socket FileDescriptor @param data the data buffer of the
+ * packet @param offset the offset in the data buffer @param length the
+ * length of the data buffer in the packet @param port the target host port
+ * @param bindToDevice if bind to device @param trafficClass the traffic
+ * class to be used when the datagram is sent @param inetAddress address to
+ * connect to. @return number of data send
+ *
+ * @exception IOException upon an read error or timeout
+ */
+ static native int sendDatagramImpl(FileDescriptor fd,
+ byte[] data, int offset, int length, int port,
+ boolean bindToDevice, int trafficClass, InetAddress inetAddress)
+ throws IOException;
+
+ static native int sendDatagramDirectImpl(FileDescriptor fd,
+ int address, int offset, int length, int port,
+ boolean bindToDevice, int trafficClass, InetAddress inetAddress)
+ throws IOException;
+
+ /*
+ * Send the <code>data</code> to the address and port to which the was
+ * connnected and <code>port</code>.
+ *
+ * @param fd the socket FileDescriptor @param data the data buffer of the
+ * packet @param offset the offset in the data buffer @param length the
+ * length of the data buffer in the packet @param bindToDevice not used,
+ * current kept in case needed as was the case for sendDatagramImpl @return
+ * number of data send @exception IOException upon an read error or timeout
+ */
+ static native int sendConnectedDatagramImpl(FileDescriptor fd,
+ byte[] data, int offset, int length, boolean bindToDevice)
+ throws IOException;
+
+ static native int sendConnectedDatagramDirectImpl(FileDescriptor fd,
+ int address, int offset, int length, boolean bindToDevice)
+ throws IOException;
+
+ /*
+ * Answer the result of attempting to create a server stream socket in the
+ * IP stack. Any special options required for server sockets will be set by
+ * this method.
+ *
+ * @param aFD the socket FileDescriptor @param preferIPv4Stack if use IPV4
+ * @exception SocketException if an error occurs while creating the socket
+ */
+ static native void createServerStreamSocketImpl(FileDescriptor aFD,
+ boolean preferIPv4Stack) throws SocketException;
+
+ /*
+ * Answer the result of attempting to create a multicast socket in the IP
+ * stack. Any special options required for server sockets will be set by
+ * this method.
+ *
+ * @param aFD the socket FileDescriptor @param preferIPv4Stack if use IPV4
+ * @exception SocketException if an error occurs while creating the socket
+ */
+ static native void createMulticastSocketImpl(FileDescriptor aFD,
+ boolean preferIPv4Stack) throws SocketException;
+
+ /*
+ * Recieve at most <code>count</code> bytes into the buffer <code>data</code>
+ * at the <code>offset</code> on the socket.
+ *
+ * @param aFD the socket FileDescriptor @param data the receive buffer
+ * @param offset the offset into the buffer @param count the max number of
+ * bytes to receive @param timeout the max time the read operation should
+ * block waiting for data @return int the actual number of bytes read
+ * @throws IOException @exception SocketException if an error occurs while
+ * reading
+ */
+ static native int receiveStreamImpl(FileDescriptor aFD, byte[] data,
+ int offset, int count, int timeout) throws IOException;
+
+ /*
+ * Send <code>count</code> bytes from the buffer <code>data</code> at
+ * the <code>offset</code>, on the socket.
+ *
+ * @param fd
+ *
+ * @param data the send buffer @param offset the offset into the buffer
+ * @param count the number of bytes to receive @return int the actual number
+ * of bytes sent @throws IOException @exception SocketException if an error
+ * occurs while writing
+ */
+ static native int sendStreamImpl(FileDescriptor fd, byte[] data,
+ int offset, int count) throws IOException;
+
+ private native void shutdownInputImpl(FileDescriptor descriptor)
+ throws IOException;
+
+ private native void shutdownOutputImpl(FileDescriptor descriptor)
+ throws IOException;
+
+ // BEGIN android-removed
+ // static native void acceptStreamSocketImpl(FileDescriptor fdServer,
+ // SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
+ // throws IOException;
+ //
+ // static native void createStreamSocketImpl(FileDescriptor aFD,
+ // boolean preferIPv4Stack) throws SocketException;
+ // END android-removed
+
+ static native int sendDatagramImpl2(FileDescriptor fd, byte[] data,
+ int offset, int length, int port, InetAddress inetAddress)
+ throws IOException;
+
+ static native int selectImpl(FileDescriptor[] readfd,
+ FileDescriptor[] writefd, int cread, int cwirte, int[] flags,
+ long timeout);
+
+ static native InetAddress getSocketLocalAddressImpl(FileDescriptor aFD,
+ boolean preferIPv6Addresses);
+
+ /*
+ * Query the IP stack for the local port to which this socket is bound.
+ *
+ * @param aFD the socket descriptor @param preferIPv6Addresses address
+ * preference for nodes that support both IPv4 and IPv6 @return int the
+ * local port to which the socket is bound
+ */
+ static native int getSocketLocalPortImpl(FileDescriptor aFD,
+ boolean preferIPv6Addresses);
+
+ /*
+ * Query the IP stack for the nominated socket option.
+ *
+ * @param aFD the socket descriptor @param opt the socket option type
+ * @return the nominated socket option value
+ *
+ * @throws SocketException if the option is invalid
+ */
+ static native Object getSocketOptionImpl(FileDescriptor aFD, int opt)
+ throws SocketException;
+
+ /*
+ * Set the nominated socket option in the IP stack.
+ *
+ * @param aFD the socket descriptor @param opt the option selector @param
+ * optVal the nominated option value
+ *
+ * @throws SocketException if the option is invalid or cannot be set
+ */
+ static native void setSocketOptionImpl(FileDescriptor aFD, int opt,
+ Object optVal) throws SocketException;
+
+ static native int getSocketFlagsImpl();
+
+ /*
+ * Close the socket in the IP stack.
+ *
+ * @param aFD the socket descriptor
+ */
+ static native void socketCloseImpl(FileDescriptor aFD);
+
+ static native InetAddress getHostByAddrImpl(byte[] addr)
+ throws UnknownHostException;
+
+ static native InetAddress getHostByNameImpl(String addr,
+ boolean preferIPv6Addresses) throws UnknownHostException;
+
+ native void setInetAddressImpl(InetAddress sender, byte[] address);
+
+ // BEGIN android-removed
+ // native int isReachableByICMPImpl(InetAddress addr, InetAddress local,
+ // int ttl, int timeout);
+ // END android-removed
+
+ native Channel inheritedChannelImpl();
+
+ public Channel inheritedChannel() {
+ return inheritedChannelImpl();
+ }
+
+ public void oneTimeInitialization(boolean jcl_supports_ipv6){
+ if (!isNetworkInited){
+ oneTimeInitializationImpl(jcl_supports_ipv6);
+ isNetworkInited = true;
+ }
+ }
+
+ native void oneTimeInitializationImpl (boolean jcl_supports_ipv6);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/sipdroid/net/impl/PlainDatagramSocketImpl.java Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2009 The Sipdroid Open Source Project
+ *
+ * This file is part of Sipdroid (http://www.sipdroid.org)
+ *
+ * Sipdroid is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this source code; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package org.sipdroid.net.impl;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocketImpl;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketOptions;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+import java.security.AccessController;
+
+/**
+ * The default, concrete instance of datagram sockets. This class does not
+ * support security checks. Alternative types of DatagramSocketImpl's may be
+ * used by setting the <code>impl.prefix</code> system property.
+ */
+public class PlainDatagramSocketImpl extends DatagramSocketImpl {
+
+ static final int MULTICAST_IF = 1;
+
+ static final int MULTICAST_TTL = 2;
+
+ static final int TCP_NODELAY = 4;
+
+ static final int FLAG_SHUTDOWN = 8;
+
+ private final static int SO_BROADCAST = 32;
+
+ final static int IP_MULTICAST_ADD = 19;
+
+ final static int IP_MULTICAST_DROP = 20;
+
+ final static int IP_MULTICAST_TTL = 17;
+
+ /**
+ * for datagram and multicast sockets we have to set REUSEADDR and REUSEPORT
+ * when REUSEADDR is set for other types of sockets we need to just set
+ * REUSEADDR therefore we have this other option which sets both if
+ * supported by the platform. this cannot be in SOCKET_OPTIONS because since
+ * it is a public interface it ends up being public even if it is not
+ * declared public
+ */
+ static final int REUSEADDR_AND_REUSEPORT = 10001;
+
+ private boolean bindToDevice;
+
+ private byte[] ipaddress = { 0, 0, 0, 0 };
+
+ private int ttl = 1;
+
+ private OSNetworkSystem netImpl = OSNetworkSystem.getOSNetworkSystem();
+
+ private volatile boolean isNativeConnected;
+
+ public int receiveTimeout;
+
+ public boolean streaming = true;
+
+ public boolean shutdownInput;
+
+ /**
+ * used to keep address to which the socket was connected to at the native
+ * level
+ */
+ private InetAddress connectedAddress;
+
+ private int connectedPort = -1;
+
+ /**
+ * used to store the trafficClass value which is simply returned as the
+ * value that was set. We also need it to pass it to methods that specify an
+ * address packets are going to be sent to
+ */
+ private int trafficClass;
+
+ public PlainDatagramSocketImpl(FileDescriptor fd, int localPort) {
+ super();
+ this.fd = fd;
+ this.localPort = localPort;
+ }
+
+ public PlainDatagramSocketImpl() {
+ super();
+ fd = new FileDescriptor();
+ }
+
+ @Override
+ public void bind(int port, InetAddress addr) throws SocketException {
+ String prop = null; //AccessController.doPrivileged(new PriviAction<String>("bindToDevice")); //$NON-NLS-1$
+ boolean useBindToDevice = prop != null && prop.toLowerCase().equals("true"); //$NON-NLS-1$
+ bindToDevice = netImpl.bind2(fd, port, useBindToDevice, addr);
+ if (0 != port) {
+ localPort = port;
+ } else {
+// localPort = netImpl.getSocketLocalPort(fd, NetUtil.preferIPv6Addresses());
+ }
+
+ try {
+ // Ignore failures
+ setOption(SO_BROADCAST, Boolean.TRUE);
+ } catch (IOException e) {
+ }
+ }
+
+ @Override
+ public void close() {
+ synchronized (fd) {
+ if (fd.valid()) {
+ try {
+ netImpl.socketClose(fd);
+ } catch (IOException e) {
+ }
+ fd = new FileDescriptor();
+ }
+ }
+ }
+
+ @Override
+ public void create() throws SocketException {
+ netImpl.createDatagramSocket(fd, false); //NetUtil.preferIPv4Stack());
+ }
+
+ @Override
+ protected void finalize() {
+ close();
+ }
+
+ @Override
+ public Object getOption(int optID) throws SocketException {
+ if (optID == SocketOptions.SO_TIMEOUT) {
+ return Integer.valueOf(receiveTimeout);
+ } else if (optID == SocketOptions.IP_TOS) {
+ return Integer.valueOf(trafficClass);
+ } else {
+ // Call the native first so there will be
+ // an exception if the socket if closed.
+ Object result = netImpl.getSocketOption(fd, optID);
+ if (optID == SocketOptions.IP_MULTICAST_IF
+ && (netImpl.getSocketFlags() & MULTICAST_IF) != 0) {
+ try {
+ return InetAddress.getByAddress(ipaddress);
+ } catch (UnknownHostException e) {
+ return null;
+ }
+ }
+ return result;
+ }
+ }
+
+ @Override
+ public int getTimeToLive() throws IOException {
+ // Call the native first so there will be an exception if the socket if
+ // closed.
+ int result = (((Byte) getOption(IP_MULTICAST_TTL)).byteValue()) & 0xFF;
+ if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
+ return ttl;
+ }
+ return result;
+ }
+
+ @Override
+ public byte getTTL() throws IOException {
+ // Call the native first so there will be an exception if the socket if
+ // closed.
+ byte result = ((Byte) getOption(IP_MULTICAST_TTL)).byteValue();
+ if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
+ return (byte) ttl;
+ }
+ return result;
+ }
+
+ @Override
+ public void join(InetAddress addr) throws IOException {
+// setOption(IP_MULTICAST_ADD, new GenericIPMreq(addr));
+ }
+
+ @Override
+ public void joinGroup(SocketAddress addr, NetworkInterface netInterface) throws IOException {
+ if (addr instanceof InetSocketAddress) {
+ InetAddress groupAddr = ((InetSocketAddress) addr).getAddress();
+// setOption(IP_MULTICAST_ADD, new GenericIPMreq(groupAddr, netInterface));
+ }
+ }
+
+ @Override
+ public void leave(InetAddress addr) throws IOException {
+// setOption(IP_MULTICAST_DROP, new GenericIPMreq(addr));
+ }
+
+ @Override
+ public void leaveGroup(SocketAddress addr, NetworkInterface netInterface)
+ throws IOException {
+ if (addr instanceof InetSocketAddress) {
+ InetAddress groupAddr = ((InetSocketAddress) addr).getAddress();
+// setOption(IP_MULTICAST_DROP, new GenericIPMreq(groupAddr, netInterface));
+ }
+ }
+
+ @Override
+ protected int peek(InetAddress sender) throws IOException {
+ if (isNativeConnected) {
+ /*
+ * in this case we know the port and address from which the data
+ * must have be been received as the socket is connected. However,
+ * we still need to do the receive in order to know that there was
+ * data received. We use a short buffer as we don't actually need
+ * the packet, only the knowledge that it is there
+ */
+ byte[] storageArray = new byte[10];
+ DatagramPacket pack = new DatagramPacket(storageArray, storageArray.length);
+ netImpl.recvConnectedDatagram(fd, pack, pack.getData(), pack.getOffset(), pack
+ .getLength(), receiveTimeout, true); // peek
+ // to set the sender ,we now use a native function
+ // sender.ipaddress = connectedAddress.getAddress();
+ netImpl.setInetAddress(sender, connectedAddress.getAddress());
+ return connectedPort;
+ }
+ return netImpl.peekDatagram(fd, sender, receiveTimeout);
+ }
+
+ @Override
+ public void receive(DatagramPacket pack) throws java.io.IOException {
+ try {
+ if (isNativeConnected) {
+ // do not peek
+ netImpl.recvConnectedDatagram(fd, pack, pack.getData(), pack.getOffset(), pack
+ .getLength(), receiveTimeout, false);
+ updatePacketRecvAddress(pack);
+ } else {
+ // receiveDatagramImpl2
+ netImpl.receiveDatagram(fd, pack, pack.getData(), pack.getOffset(), pack
+ .getLength(), receiveTimeout, false);
+ }
+ } catch (InterruptedIOException e) {
+ throw new SocketTimeoutException(e.getMessage());
+ }
+ }
+
+ @Override
+ public void send(DatagramPacket packet) throws IOException {
+
+ if (isNativeConnected) {
+ netImpl.sendConnectedDatagram(fd, packet.getData(), packet.getOffset(), packet
+ .getLength(), bindToDevice);
+ } else {
+ // sendDatagramImpl2
+ netImpl.sendDatagram(fd, packet.getData(), packet.getOffset(), packet.getLength(),
+ packet.getPort(), bindToDevice, trafficClass, packet.getAddress());
+ }
+ }
+
+ /**
+ * Set the nominated socket option. As the timeouts are not set as options
+ * in the IP stack, the value is stored in an instance field.
+ *
+ * @throws SocketException thrown if the option value is unsupported or
+ * invalid
+ */
+ @Override
+ public void setOption(int optID, Object val) throws SocketException {
+ /*
+ * for datagram sockets on some platforms we have to set both the
+ * REUSEADDR AND REUSEPORT so for REUSEADDR set this option option which
+ * tells the VM to set the two values as appropriate for the platform
+ */
+ if (optID == SocketOptions.SO_REUSEADDR) {
+ optID = REUSEADDR_AND_REUSEPORT;
+ }
+
+ if (optID == SocketOptions.SO_TIMEOUT) {
+ receiveTimeout = ((Integer) val).intValue();
+ } else {
+ int flags = netImpl.getSocketFlags();
+ try {
+ netImpl.setSocketOption(fd, optID | (flags << 16), val);
+ } catch (SocketException e) {
+ // we don't throw an exception for IP_TOS even if the platform
+ // won't let us set the requested value
+ if (optID != SocketOptions.IP_TOS) {
+ throw e;
+ }
+ }
+ if (optID == SocketOptions.IP_MULTICAST_IF && (flags & MULTICAST_IF) != 0) {
+ InetAddress inet = (InetAddress) val;
+// if (NetUtil.bytesToInt(inet.getAddress(), 0) == 0 || inet.isLoopbackAddress()) {
+// ipaddress = ((InetAddress) val).getAddress();
+// } else
+ {
+ InetAddress local = null;
+ try {
+ local = InetAddress.getLocalHost();
+ } catch (UnknownHostException e) {
+ throw new SocketException("getLocalHost(): " + e.toString());
+ }
+ if (inet.equals(local)) {
+ ipaddress = ((InetAddress) val).getAddress();
+ } else {
+ throw new SocketException(val + " != getLocalHost(): " + local);
+ }
+ }
+ }
+ /*
+ * save this value as it is actually used differently for IPv4 and
+ * IPv6 so we cannot get the value using the getOption. The option
+ * is actually only set for IPv4 and a masked version of the value
+ * will be set as only a subset of the values are allowed on the
+ * socket. Therefore we need to retain it to return the value that
+ * was set. We also need the value to be passed into a number of
+ * natives so that it can be used properly with IPv6
+ */
+ if (optID == SocketOptions.IP_TOS) {
+ trafficClass = ((Integer) val).intValue();
+ }
+ }
+ }
+
+ @Override
+ public void setTimeToLive(int ttl) throws java.io.IOException {
+ setOption(IP_MULTICAST_TTL, Byte.valueOf((byte) (ttl & 0xFF)));
+ if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
+ this.ttl = ttl;
+ }
+ }
+
+ @Override
+ public void setTTL(byte ttl) throws java.io.IOException {
+ setOption(IP_MULTICAST_TTL, Byte.valueOf(ttl));
+ if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
+ this.ttl = ttl;
+ }
+ }
+
+ @Override
+ public void connect(InetAddress inetAddr, int port) throws SocketException {
+
+ // connectDatagram impl2
+ netImpl.connectDatagram(fd, port, trafficClass, inetAddr);
+
+ // if we get here then we are connected at the native level
+ try {
+ connectedAddress = InetAddress.getByAddress(inetAddr.getAddress());
+ } catch (UnknownHostException e) {
+ // this is never expected to happen as we should not have gotten
+ // here if the address is not resolvable
+ throw new SocketException("K0317 "+inetAddr.getHostName()); //$NON-NLS-1$
+ }
+ connectedPort = port;
+ isNativeConnected = true;
+ }
+
+ @Override
+ public void disconnect() {
+ try {
+ netImpl.disconnectDatagram(fd);
+ } catch (Exception e) {
+ // there is currently no way to return an error so just eat any
+ // exception
+ }
+ connectedPort = -1;
+ connectedAddress = null;
+ isNativeConnected = false;
+ }
+
+ @Override
+ public int peekData(DatagramPacket pack) throws IOException {
+ try {
+ if (isNativeConnected) {
+ netImpl.recvConnectedDatagram(fd, pack, pack.getData(), pack.getOffset(), pack
+ .getLength(), receiveTimeout, true); // peek
+ updatePacketRecvAddress(pack);
+ } else {
+ // receiveDatagram 2
+ netImpl.receiveDatagram(fd, pack, pack.getData(), pack.getOffset(), pack
+ .getLength(), receiveTimeout, true); // peek
+ }
+ } catch (InterruptedIOException e) {
+ throw new SocketTimeoutException(e.toString());
+ }
+ return pack.getPort();
+ }
+
+ /**
+ * Set the received address and port in the packet. We do this when the
+ * Datagram socket is connected at the native level and the
+ * recvConnnectedDatagramImpl does not update the packet with address from
+ * which the packet was received
+ *
+ * @param packet
+ * the packet to be updated
+ */
+ private void updatePacketRecvAddress(DatagramPacket packet) {
+ packet.setAddress(connectedAddress);
+ packet.setPort(connectedPort);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/sipdroid/pjlib/Codec.java Tue Jun 05 16:44:38 2012 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 The Sipdroid Open Source Project
+ *
+ * This file is part of Sipdroid (http://www.sipdroid.org)
+ *
+ * Sipdroid is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this source code; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package org.sipdroid.pjlib;
+
+import java.lang.String;
+
+public class Codec {
+ public static native int open(String codec_id);
+ public static native int decode(byte alaw[], short lin[], int frames);
+ public static native int encode(short lin[], int offset, byte alaw[], int frames);
+ public static native int close();
+
+ public static void init() {
+ }
+
+ public static boolean loaded;
+
+ static {
+ try {
+ System.loadLibrary("pjlib_linker_jni");
+ open("gsm");
+ loaded = true;
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+}