aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShuyi Chen <shuyichen@google.com>2013-05-22 13:10:40 -0700
committerShuyi Chen <shuyichen@google.com>2013-05-22 13:10:40 -0700
commit8f4ce9ea0de51fee918bffe19c434612d6bbb2d7 (patch)
treeaa6b731d2b1c404e048839fc3ace150eaef2512d
parent406fc12177de3a9f13c197838235c2fa3e0f16f0 (diff)
downloadsmack-8f4ce9ea0de51fee918bffe19c434612d6bbb2d7.tar.gz
Add asmack build environemnt.
Downloaded from https://github.com/Flowdalic/asmack/archive/master.zip. Change-Id: I93fb953348f2d2c058113874923777530a24bcc6
-rw-r--r--asmack-master/.gitignore2
-rw-r--r--asmack-master/CHANGELOG12
-rw-r--r--asmack-master/LICENSE291
-rw-r--r--asmack-master/README.asmack71
-rw-r--r--asmack-master/README.markdown100
-rwxr-xr-xasmack-master/build.bash570
-rw-r--r--asmack-master/build.xml80
-rw-r--r--asmack-master/jingle/60-jingle-ext.patch171
-rw-r--r--asmack-master/jingle/60-remove-jingle_mediaimpl.patch4039
-rw-r--r--asmack-master/lib/.gitignore1
-rw-r--r--asmack-master/lib/httpclient-4.1.3.jarbin0 -> 352585 bytes
-rw-r--r--asmack-master/lib/httpcore-4.1.4.jarbin0 -> 181409 bytes
-rw-r--r--asmack-master/lib/jstun.jarbin0 -> 68349 bytes
-rw-r--r--asmack-master/lib/xpp3-1.1.4c.jarbin0 -> 120069 bytes
-rw-r--r--asmack-master/local.properties.example1
-rwxr-xr-xasmack-master/patch/00-relocate-javax.security.sh8
-rwxr-xr-xasmack-master/patch/00-remove-javax-dns.sh3
-rwxr-xr-xasmack-master/patch/10-remove-unused-harmony.sh10
-rwxr-xr-xasmack-master/patch/11-remove-nls-harmony.sh5
-rw-r--r--asmack-master/patch/12-harmony-nls-msg.patch59
-rw-r--r--asmack-master/patch/13-mock-configuration.patch33
-rwxr-xr-xasmack-master/patch/20-remove-mxparser.sh5
-rwxr-xr-xasmack-master/patch/21-remove-unused-smack.sh6
-rw-r--r--asmack-master/patch/22-remove-beans.Property-deps.patch30
-rw-r--r--asmack-master/patch/23-strip-unused-xml-transform.patch50
-rw-r--r--asmack-master/patch/24-disable-sasl-methods.patch20
-rw-r--r--asmack-master/patch/30-switch-debugging-implementations.patch17
-rwxr-xr-xasmack-master/patch/31-remove-dns-wrapper.sh4
-rwxr-xr-xasmack-master/patch/32-remove-jbosh-xlightweb.sh4
-rw-r--r--asmack-master/patch/33-jbosh-android.patch446
-rw-r--r--asmack-master/patch/34-pin-jbosh-http-sender.patch11
-rw-r--r--asmack-master/patch/35-pin-jbosh-boddy-parser.patch11
-rwxr-xr-xasmack-master/patch/40-enable-custom-sasl.sh4
-rw-r--r--asmack-master/patch/41-fix-digest-md5.patch13
-rw-r--r--asmack-master/patch/beem/10-PubSubManager-non-final.patch13
-rw-r--r--asmack-master/patch/beem/50-improved-pubsub.patch46
-rw-r--r--asmack-master/patch/beem/COPYING202
-rw-r--r--asmack-master/patch/beem/README.txt9
-rw-r--r--asmack-master/patch/oldpatch/45-protected-xmpp-socket.patch11
-rw-r--r--asmack-master/static-src/custom/META-INF/services/com.kenai.jbosh.HTTPSender1
-rw-r--r--asmack-master/static-src/custom/com/kenai/jbosh/QName.java269
-rw-r--r--asmack-master/static-src/custom/de/measite/smack/AndroidDebugger.java185
-rw-r--r--asmack-master/static-src/custom/de/measite/smack/Sasl.java108
-rw-r--r--asmack-master/static-src/custom/de/measite/smack/SaslClientFactory.java60
-rw-r--r--asmack-master/static-src/custom/org/jivesoftware/smack/AndroidConnectionConfiguration.java113
-rw-r--r--asmack-master/static-src/custom/org/jivesoftware/smack/SmackAndroid.java59
-rw-r--r--asmack-master/static-src/custom/org/jivesoftware/smackx/ConfigureProviderManager.java207
-rw-r--r--asmack-master/static-src/custom/org/jivesoftware/smackx/InitStaticCode.java51
-rw-r--r--asmack-master/static-src/custom/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java92
-rw-r--r--asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/DigestChallenge.java393
-rw-r--r--asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/DigestMD5SaslClient.java820
-rw-r--r--asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/DirectiveList.java363
-rw-r--r--asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/ParsedDirective.java56
-rw-r--r--asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/ResponseAuth.java83
-rw-r--r--asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/TokenParser.java208
55 files changed, 9426 insertions, 0 deletions
diff --git a/asmack-master/.gitignore b/asmack-master/.gitignore
new file mode 100644
index 0000000..cc97859
--- /dev/null
+++ b/asmack-master/.gitignore
@@ -0,0 +1,2 @@
+build
+local.properties
diff --git a/asmack-master/CHANGELOG b/asmack-master/CHANGELOG
new file mode 100644
index 0000000..e5f9f21
--- /dev/null
+++ b/asmack-master/CHANGELOG
@@ -0,0 +1,12 @@
+Release 0.8.2
+ - Removed the whitespace ping code SMACK-412
+ - SMACK-419 PacketWriter: Only flush the BufferedWriter if the packet queue is empty
+ - SMACK-417 If both PacketReader and PacketWriter fail at the same time, connectionClosedonError() is called two times
+ - The default ping intervall is now configured in seconds and not milliseconds
+
+Release 0.8.1.1
+ - Improved 'caps' XEP-0115 support
+ - Fixes an NPE in 0.8.1
+
+Release 0.8
+ - First release to test the release process
diff --git a/asmack-master/LICENSE b/asmack-master/LICENSE
new file mode 100644
index 0000000..d50ac8e
--- /dev/null
+++ b/asmack-master/LICENSE
@@ -0,0 +1,291 @@
+Licences
+
+All code in this repository is licensed under either
+(1) Apache License Version 2.0
+(2) THE OPENLDAP PUBLIC LICENSE (only src/novell-openldap-jldap)
+
+No GNU code will be included. Other patches are always welcome.
+
+
+
+ The OpenLDAP Public License
+ Version 2.8, 17 August 2003
+
+Redistribution and use of this software and associated documentation
+("Software"), with or without modification, are permitted provided
+that the following conditions are met:
+
+1. Redistributions in source form must retain copyright statements
+ and notices,
+
+2. Redistributions in binary form must reproduce applicable copyright
+ statements and notices, this list of conditions, and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution, and
+
+3. Redistributions must contain a verbatim copy of this document.
+
+The OpenLDAP Foundation may revise this license from time to time.
+Each revision is distinguished by a version number. You may use
+this Software under terms of this license revision or under the
+terms of any subsequent revision of the license.
+
+THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS
+CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S)
+OR OWNER(S) OF THE SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+The names of the authors and copyright holders must not be used in
+advertising or otherwise to promote the sale, use or other dealing
+in this Software without specific, written prior permission. Title
+to copyright in this Software shall at all times remain with copyright
+holders.
+
+OpenLDAP is a registered trademark of the OpenLDAP Foundation.
+
+Copyright 1999-2003 The OpenLDAP Foundation, Redwood City,
+California, USA. All Rights Reserved. Permission to copy and
+distribute verbatim copies of this document is granted.
+
+
+
+
+ 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.
+
++++++++++++
++ dnsjava +
++++++++++++
+
+Copyright (c) 1998-2011, Brian Wellington.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/asmack-master/README.asmack b/asmack-master/README.asmack
new file mode 100644
index 0000000..9ca40b7
--- /dev/null
+++ b/asmack-master/README.asmack
@@ -0,0 +1,71 @@
+aSmack README
+=============
+
+Version: $VERSION_TAG
+Build date: $BUILD_DATE
+
+Important Notes
+===============
+
+Read this, or aSmack won't work for you!
+
+Static Code
+-----------
+
+In order to work correctly on Android, you need to register Smack's
+XMPP Providers and Extensions manually and init some static code
+blocks before you doing any XMPP activty. Calling
+SmackAndroid.init(Context) (in org.jivesoftware.smack) will do this
+for you.
+
+ConnectionConfiguration
+-----------------------
+
+Please use the provided AndroidConnectionConfiguration class if
+possible to create a new connection.
+
+Compression
+-----------
+
+If you want compressed XMPP streams you have to add
+[jzlib-1.0.7](http://www.jcraft.com/jzlib/) to your project. Note that
+every version higher then 1.0.7 wont work.
+More Info: https://github.com/Flowdalic/smack/issues/12
+
+Problems / Debugging
+==============================
+
+aSmack Wiki
+-----------
+
+More information about XMPP File Transfers, SSL Certificates and other
+stuff related to aSmack can be found in the wiki:
+https://github.com/Flowdalic/asmack/wiki
+
+How to debug your problem
+-------------------------
+
+We always provide source zips. Attach them to the jar in your favorite
+IDE. Enable debugging mode with [BOSH|XMPP]Connection.DEBUG and
+config.setDebug. See also:
+http://www.igniterealtime.org/builds/smack/docs/latest/documentation/debugging.html
+
+Reporting a bug
+---------------
+
+Your issue should contain
+1. a logcat
+2. a server to reproduce
+3. the code you are using (for FOSS project we'll accept reposituroy URLs)
+
+If you record a logcat and make sure to remove your credentials
+(usually a base64 block inside <auth></auth>).
+
+There is no guarantee that we will reply immediatly. But we will try
+to investigate the problem. Feel free to join ##smack @ freenode and
+ask for help (you may have to idle for some time before you get a
+reply).
+
+Component Revision Information for this Release
+===============================================
+
diff --git a/asmack-master/README.markdown b/asmack-master/README.markdown
new file mode 100644
index 0000000..751291b
--- /dev/null
+++ b/asmack-master/README.markdown
@@ -0,0 +1,100 @@
+aSmack - buildsystem for Smack on Android
+=========================================
+
+*This repository doesn't contain much code, it's a build environment!*
+
+Tracking trunk can be hard. Doing massive changes on top of trunk can
+be near impossible. We are mixing 6 open source projects to provide a
+working xmpp library for Android. All trunk-based.
+
+This repository contains a source fetching, patching and building
+script. As well as all the minor changes to make an Android version
+fly. See the patches/ folder for a detailed list of changes and
+scripts.
+
+Compiled JARs
+=============
+
+Can be found @ http://asmack.freakempire.de/
+
+Make sure to [*read the
+README*](https://github.com/Flowdalic/asmack/blob/master/README.asmack)
+for every release.
+
+Support
+=======
+[![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=Flowdalic&url=https://github.com/flowdalic/asmack&title=asmack&language=&tags=github&category=software)
+
+Compiling aSmack
+================
+
+1. copy local.properties.example to local.properties and set the
+Android SDK path (e.g. sdk-location=/opt/android-sdk-update-manager/
+on a gentoo system)
+
+2. Run build.bash
+
+aSmack uses a [special fork of
+smack](https://github.com/Flowdalic/smack). You can read about the
+results you will get when using one of the various branches provides
+in the
+[README](https://github.com/Flowdalic/smack/blob/master/README.markdown).
+
+Apps that use this fork of aSmack
+=================================
+- [GTalkSMS](http://code.google.com/p/gtalksms/) uses many features of Smack and XMPP on Android:
+ - File Transfer
+ - DNS SRV
+ - MUC
+ - Entity Caps
+ - and many more
+
+- [yaxim](https://github.com/ge0rg/yaxim)
+- your app?
+
+Contribution
+============
+
+If possible, please base patches on smack, not on aSmack. You can use
+the 'upstream' branch from [smack @
+github](https://github.com/Flowdalic/smack). Only in some cases the
+'master' branch should be used.
+
+If your code follows [Smack's contributor guidelines](
+http://community.igniterealtime.org/docs/DOC-1984), is good documented
+and comes with some testcases, then it's possible to commit it
+upstream. Simply join ##smack @ freenode and ask for a code review.
+
+Contributors
+============
+
+We do not keep a seperate CONTRIBUTORS file, and we discourage @author
+tags. However you're free to add your full name to every git commit,
+and we will preserver this. Let us know if you've helped on
+non-technical stuff and we'll find a way to give you the deserved
+credit.
+
+Contact
+=======
+
+Join ##smack @ freenode
+
+Licences / Used libraries
+=========================
+
+We only accept Apache and BSD-like licences.
+We are currently using code from
+
+ * Apache Harmony (sasl/xml) (Apache Licence)
+ * smack (xmpp) (Apache Licence)
+ * novell-openldap-jldap (sasl) ([OpenLDAP Licence][1])
+ * Apache qpid (sasl) (Apache Licence)
+ * jbosh (BOSH) (Apache Licence)
+ * dnsjava (dns srv lookups) (BSD)
+ * custom code (various glue stuff) (WTFPL | BSD | Apache)
+
+This should work for just about every project. Contact us if you have
+problems with the licence.
+
+ [1]: http://www.openldap.org/devel/cvsweb.cgi/~checkout~/LICENSE?rev=1.23.2.1&hideattic=1&sortbydate=0 "OpenLDAP Licence"
+
diff --git a/asmack-master/build.bash b/asmack-master/build.bash
new file mode 100755
index 0000000..874f238
--- /dev/null
+++ b/asmack-master/build.bash
@@ -0,0 +1,570 @@
+#!/bin/bash
+
+svnfetch() {
+ REV="${3:-HEAD}"
+ echo "Fetching from ${1} to ${2} at revision ${REV}"
+ cd $SRC_DIR
+ if ! [ -f "${2}/.svn/entries" ]; then
+ mkdir "${2}"
+ cd "${2}"
+ svn co --non-interactive --trust-server-cert "${1}" -r "${REV}" "."
+ else
+ cd "${2}"
+ svn cleanup
+ svn up -r "${REV}"
+ fi
+}
+
+gitfetch() {
+ echo "Fetching ${2} branch/commit from ${1} to ${3} via git"
+ cd $SRC_DIR
+ if ! [ -f "${3}/.git/config" ]; then
+ git clone "${1}" "${3}"
+ cd "${3}"
+ git checkout "${2}"
+ else
+ cd "${3}"
+ git fetch
+ git checkout "${2}"
+ fi
+
+ if [ $? -ne 0 ]; then
+ exit
+ fi
+}
+
+hgfetch() {
+(
+ echo "Fetching ${2} branch from ${1} to ${3} via mercurial"
+ cd src
+ if [ -e "${2}/.hg" ] ; then
+ cd ${2}
+ hg pull
+ else
+ hg clone "${1}" "${2}"
+ fi
+ hg up -r ${3}
+)
+ if [ $? -ne 0 ]; then
+ exit
+ fi
+}
+
+
+testsmackgit() {
+ cd $SRC_DIR
+ if [ -f .used-smack-git-repo ] && [ $(cat .used-smack-git-repo) != $SMACK_REPO ] ; then
+ echo "Used smack repository has changed!"
+ echo "Old: $(cat .used-smack-git-repo) New: ${SMACK_REPO}."
+ echo "Deleting old local copy"
+ rm -rf smack
+ fi
+ echo "${SMACK_REPO}" > .used-smack-git-repo
+}
+
+fetchall() {
+ echo "## Step 15: fetching sources"
+ if $SMACK_LOCAL ; then
+ # always clean the local copy first
+ rm -rf ${SRC_DIR}/smack
+ mkdir ${SRC_DIR}/smack
+ cd $SMACK_REPO
+ git archive $SMACK_BRANCH | tar -x -C ${SRC_DIR}/smack
+ if [ $? -ne 0 ]; then
+ exit
+ fi
+ else
+ execute gitfetch "$SMACK_REPO" "$SMACK_BRANCH" "smack"
+ fi
+
+ if ! $UPDATE_REMOTE ; then
+ echo "Won't update or fetch third party resources"
+ wait
+ return
+ fi
+
+ execute svnfetch "http://svn.apache.org/repos/asf/qpid/trunk/qpid/java/management/common/src/main/" "qpid"
+ execute svnfetch "http://svn.apache.org/repos/asf/harmony/enhanced/java/trunk/classlib/modules/auth/src/main/java/common/" "harmony"
+ execute svnfetch "https://dnsjava.svn.sourceforge.net/svnroot/dnsjava/trunk" "dnsjava"
+ execute gitfetch "git://kenai.com/jbosh~origin" "master" "jbosh"
+ # jldap doesn't compile with the latest version (missing deps?), therefore it's a fixed version for now
+ # execute gitfetch "git://git.openldap.org/openldap-jldap.git" "master" "novell-openldap-jldap"
+ wait
+}
+
+createVersionTag() {
+ # Skip this step is no version tag is given
+ [[ -z $VERSION_TAG ]] && return
+
+ local v
+ cat <<EOF > $TAG_FILE
+#!/bin/bash
+
+# This file contains the version information of the components that
+# were used to build this aSmack version
+
+declare -g -A COMPONENT_VERSIONS
+EOF
+
+ for d in $(ls $SRC_DIR) ; do
+ cd $SRC_DIR
+
+ # Don't record the components version for static-src
+ for static in $(ls ${ASMACK_BASE}/static-src) ; do
+ # Don't record the version if it's from the static sources
+ [ $d == $static ] && continue
+ done
+
+ if [[ -d $d/.git ]] ; then
+ v=$(cd $d && git rev-parse HEAD)
+ key=$d
+ COMPONENT_VERSIONS["$d"]=$v
+ elif [[ -d $d/.svn ]] ; then
+ v=$(cd $d && svn info |grep Revision |cut -f 2 -d ' ')
+ key=$d
+ COMPONENT_VERSIONS["$d"]=$v
+ fi
+ done
+
+ if $SMACK_LOCAL ; then
+ cd $SMACK_REPO
+ v=$(git rev-parse HEAD)
+ COMPONENT_VERSIONS[smack]=$v
+ fi
+
+ cd ${ASMACK_BASE}
+ v=$(git rev-parse HEAD)
+ COMPONENT_VERSIONS[asmack]=$v
+
+ for i in "${!COMPONENT_VERSIONS[@]}" ; do
+ echo "COMPONENT_VERSIONS[$i]=${COMPONENT_VERSIONS[$i]}" >> $TAG_FILE
+ done
+}
+
+copyfolder() {
+ cd ${ASMACK_BASE}
+ (
+ cd "${1}"
+ tar -cSsp --exclude-vcs "${3}"
+ ) | (
+ cd "${2}"
+ tar -xSsp
+ )
+ wait
+}
+
+createbuildsrc() {
+ echo "## Step 20: creating build/src"
+ cd "${ASMACK_BASE}"
+ rm -rf build/src
+ mkdir -p build/src/trunk
+
+ execute copyfolder "src/smack/source/" "build/src/trunk" "."
+ execute copyfolder "src/qpid/java" "build/src/trunk" "org/apache/qpid/management/common/sasl"
+ execute copyfolder "src/novell-openldap-jldap" "build/src/trunk" "."
+ execute copyfolder "src/dnsjava" "build/src/trunk" "org"
+ execute copyfolder "src/harmony" "build/src/trunk" "."
+ execute copyfolder "src/jbosh/src/main/java" "build/src/trunk" "."
+ if $BUILD_JINGLE ; then
+ execute copyfolder "src/smack/jingle/extension/source/" "build/src/trunk" "."
+ fi
+ wait
+ # custom overwrites some files from smack, so this has to be done as last
+ copyfolder "src/custom" "build/src/trunk" "."
+}
+
+patchsrc() {
+ echo "## Step 25: patch build/src"
+ cd ${ASMACK_BASE}/build/src/trunk/
+ for PATCH in `(cd "../../../${1}" ; find -maxdepth 1 -type f)|sort` ; do
+ echo $PATCH
+ if [[ $PATCH == *.sh ]]; then
+ "../../../${1}/$PATCH" || exit 1
+ elif [[ $PATCH == *.patch ]]; then
+ patch -p0 < "../../../${1}/$PATCH" || exit 1
+ fi
+ done
+}
+
+build() {
+ echo "## Step 30: compile"
+ buildandroid
+ if [ $? -ne 0 ]; then
+ exit 1
+ fi
+}
+
+buildandroid() {
+ local sdklocation
+ local version
+ local sdks
+ local minSdkVer=8
+
+ cd $ASMACK_BASE
+
+ if [ ! -f local.properties ] ; then
+ echo "Could not find local.properties file"
+ echo "See local.properties.example"
+ exit 1
+ fi
+
+ sdklocation=$(grep sdk-location local.properties| cut -d= -f2)
+ if [ -z "$sdklocation" ] ; then
+ echo "Android SDK not found. Don't build android version"
+ exit 1
+ fi
+ for f in ${sdklocation/\$\{user.home\}/$HOME}/platforms/* ; do
+ version=`basename $f`
+ if [[ "$version" != android-* ]] ; then
+ echo "$sdklocation contains no Android SDKs"
+ exit 1
+ fi
+ if [[ ${version#android-} -ge $minSdkVer ]] ; then
+ if [ -n $BUILD_ANDROID_VERSIONS ] ; then
+ for build_version in $BUILD_ANDROID_VERSIONS ; do
+ [ ${version#android-} != $build_version ] && continue 2
+ done
+ fi
+ echo "Building for ${version}"
+ sdks="${sdks} ${version}\n"
+ fi
+
+ done
+
+ if [ -z "${sdks}" ] ; then
+ echo "No SDKs of a suitable minimal API (${minSdkVer}) version found"
+ exit 1
+ fi
+
+ local asmack_suffix
+ if [[ -n ${VERSION_TAG} ]] && [[ -n ${1} ]] ; then
+ asmack_suffix="${1}-${VERSION_TAG}"
+ elif [[ -n ${VERSION_TAG} ]] ; then
+ asmack_suffix="-${VERSION_TAG}"
+ else
+ asmack_suffix="${1}"
+ fi
+ if ! echo -e ${sdks} \
+ | xargs -I{} -n 1 $XARGS_ARGS ant \
+ -Dandroid.version={} \
+ -Djar.suffix="${asmack_suffix}" \
+ compile-android ; then
+ exit 1
+ fi
+}
+
+buildcustom() {
+ for dir in `find patch -maxdepth 1 -mindepth 1 -type d`; do
+ buildsrc
+ patchsrc "patch"
+ if $BUILD_JINGLE ; then
+ patchsrc "jingle"
+ JINGLE_ARGS="-Djingle=lib/jstun.jar"
+ fi
+ patchsrc "${dir}"
+ local custom
+ custom=$(echo ${dir} | sed 's:patch/:-:')
+ ant -Djar.suffix="${custom}" $JINGLE_ARGS
+ buildandroid "${custom}"
+ done
+}
+
+parseopts() {
+ while getopts a:b:r:t:cdhjpux OPTION "$@"; do
+ case $OPTION in
+ a)
+ BUILD_ANDROID_VERSIONS="${OPTARG}"
+ ;;
+ r)
+ SMACK_REPO="${OPTARG}"
+ ;;
+ b)
+ SMACK_BRANCH="${OPTARG}"
+ ;;
+ d)
+ set -x
+ XARGS_ARGS="-t"
+ ;;
+ j)
+ BUILD_JINGLE=true
+ ;;
+ u)
+ UPDATE_REMOTE=false
+ ;;
+ c)
+ BUILD_CUSTOM=true
+ ;;
+ p)
+ PARALLEL_BUILD=true
+ ;;
+ t)
+ VERSION_TAG="${OPTARG}"
+ ;;
+ x)
+ PUBLISH_RELEASE=true
+ ;;
+ h)
+ echo "$0 -d -c -u -j -r <repo> -b <branch>"
+ echo "-d: Enable debug"
+ echo "-j: Build jingle code"
+ echo "-c: Apply custom patchs from patch directory"
+ echo "-u: DON'T update remote third party resources"
+ echo "-r <repo>: Git repository (can be local or remote) for underlying smack repository"
+ echo "-b <branch>: Git branch used to build aSmack from underlying smack repository"
+ echo "-p use parallel build where possible"
+ echo "-t <version>: Create a new version tag. You should build aSmack before calling this"
+ echo "-x: Publish the release"
+ echo "-a <SDK Version(s)>: Build only for the given Android SDK versions"
+ exit
+ ;;
+ esac
+ done
+}
+
+prepareRelease() {
+ if [[ -z ${VERSION_TAG} ]]; then
+ echo "Version tag is not set. Not going to prepare a release"
+ return
+ fi
+
+ if [ -d $RELEASE_DIR ] ; then
+ rm -rf $RELEASE_DIR
+ fi
+ mkdir -p $RELEASE_DIR
+
+ mv ${ASMACK_BASE}/build/*.{jar,zip} ${RELEASE_DIR}/
+ cp $TAG_FILE ${RELEASE_DIR}/
+ cp ${ASMACK_BASE}/CHANGELOG ${RELEASE_DIR}
+
+ if [ -n $GPG_KEY ] ; then
+ find $RELEASE_DIR -maxdepth 1 -and \( -name '*.jar' -or -name '*.zip' \) -print0 \
+ | xargs -n 1 -0 $XARGS_ARGS gpg --local-user $GPG_KEY --detach-sign
+ fi
+
+ find $RELEASE_DIR -maxdepth 1 -and \( -name '*.jar' -or -name '*.zip' \) -print0 \
+ | xargs -I{} -n 1 -0 $XARGS_ARGS sh -c 'md5sum {} > {}.md5'
+
+ local release_readme
+ release_readme=${RELEASE_DIR}/README
+
+ sed \
+ -e "s/\$VERSION_TAG/${VERSION_TAG}/" \
+ -e "s/\$BUILD_DATE/${BUILD_DATE}/" \
+ README.asmack > $release_readme
+
+ # Pretty print the component versions at the end of README
+ # Note that there is an exclamation mark at the beginning of the
+ # associative array to access the keys
+ for i in "${!COMPONENT_VERSIONS[@]}" ; do
+ local tabs
+ if [[ ${#i} -le 6 ]] ; then
+ tabs="\t\t"
+ else
+ tabs="\t"
+ fi
+ echo -e "${i}:${tabs}${COMPONENT_VERSIONS[$i]}" >> $release_readme
+ done
+}
+
+publishRelease() {
+ if [[ -z ${VERSION_TAG} ]]; then
+ echo "Version tag is not set. Not going to prepare a release"
+ return
+ fi
+
+ if [[ -z ${PUBLISH_RELEASE} ]]; then
+ echo "User doesn't want to publish this release"
+ return
+ fi
+
+ if [[ -z $PUBLISH_HOST || -z $PUBLISH_DIR ]]; then
+ echo "WARNING: Not going to publish this release as either $PUBLISH_HOST or $PUBLISH_DIR is not set"
+ return
+ fi
+
+ cd ${ASMACK_RELEASES}
+ cat <<EOF | sftp $PUBLISH_HOST
+rm ${PUBLISH_DIR}/${VERSION_TAG}/*
+mkdir ${PUBLISH_DIR}/${VERSION_TAG}
+put -r $VERSION_TAG $PUBLISH_DIR
+EOF
+}
+
+islocalrepo() {
+ local R="^(git|ssh)"
+ if [[ $1 =~ $R ]]; then
+ return 1
+ else
+ return 0
+ fi
+}
+
+initialize() {
+ echo "## Step 00: initialize"
+ if ! [ -d build/src/trunk ]; then
+ mkdir -p build/src/trunk
+ fi
+ if [ ! -d src/ ]; then
+ mkdir src
+ fi
+ find build \( -name '*.jar' -or -name '*.zip' \) -print0 | xargs -0 rm -f
+ rm -rf src/custom
+}
+
+cleanup() {
+ echo "## Deleting all temporary files"
+ rm -rf build
+ rm -rf src
+}
+
+copystaticsrc() {
+ cp -ur static-src/* src/
+}
+
+cmdExists() {
+ command -v $1 &> /dev/null
+ return $?
+}
+
+prettyPrintSeconds() {
+ local ttime
+ if (( $1 > 59 )); then
+ ttime=$(printf "%dm %ds\n" $(($1/60%60)) $(($1%60)) )
+ else
+ ttime=$(printf "%ds\n" $(($1)) )
+ fi
+ echo "Execution took $ttime"
+}
+
+execute() {
+ if [ -n "$BACKGROUND" ]; then
+ "$@" &
+ else
+ "$@"
+ fi
+}
+
+setdefaults() {
+ # Default configuration, can be changed with script arguments
+ SMACK_REPO=git://github.com/Flowdalic/smack.git
+ SMACK_BRANCH=master
+ SMACK_LOCAL=false
+ UPDATE_REMOTE=true
+ BUILD_CUSTOM=false
+ BUILD_JINGLE=false
+ JINGLE_ARGS=""
+ PARALLEL_BUILD=false
+ VERSION_TAG=""
+ PUBLISH_RELEASE=""
+ PUBLISH_HOST=""
+ PUBLISH_DIR=""
+ BUILD_ANDROID_VERSIONS=""
+
+ # Often used variables
+ ASMACK_BASE=$(pwd)
+ ASMACK_RELEASES=${ASMACK_BASE}/releases
+ SRC_DIR=${ASMACK_BASE}/src
+ VERSION_TAG_DIR=${ASMACK_BASE}/version-tags
+ STARTTIME=$(date -u "+%s")
+ BUILD_DATE=$(date)
+ # Declare an associative array that is in global scope ('-g')
+ declare -g -A COMPONENT_VERSIONS
+}
+
+parseconfig() {
+ if [ -f ${ASMACK_BASE}/config ]; then
+ source ${ASMACK_BASE}/config
+ fi
+}
+
+setconfig() {
+ if [ ${PARALLEL_BUILD} == "true" ]; then
+ XARGS_ARGS="${XARGS_ARGS} -P4"
+ BACKGROUND="true"
+ else
+ XARGS_ARGS=""
+ BACKGROUND=""
+ fi
+
+ if islocalrepo $SMACK_REPO; then
+ SMACK_LOCAL=true
+ SMACK_REPO=`readlink -f $SMACK_REPO`
+ fi
+
+ if [[ -n ${VERSION_TAG} ]]; then
+ if ! grep ${VERSION_TAG} CHANGELOG; then
+ echo "Could not find the tag in the CHANGELOG file. Please write a short summary of changes"
+ exit 1
+ fi
+ if ! git diff --exit-code; then
+ echo "Unstaged changes found, please stages your changes"
+ exit 1
+ fi
+ if ! git diff --cached --exit-code; then
+ echo "Staged, but uncommited changes found, please commit"
+ exit 1
+ fi
+ RELEASE_DIR=${ASMACK_RELEASES}/${VERSION_TAG}
+ TAG_FILE=${VERSION_TAG_DIR}/${VERSION_TAG}.tag
+ fi
+}
+
+printconfig() {
+ echo "Smack git repository $SMACK_REPO with branch $SMACK_BRANCH"
+ echo -e "SMACK_LOCAL:$SMACK_LOCAL\tUPDATE_REMOTE:$UPDATE_REMOTE\tBUILD_CUSTOM:$BUILD_CUSTOM\tBUILD_JINGLE:$BUILD_JINGLE"
+ echo -e "PARALLEL_BUILD:$PARALLEL_BUILD\tBASE:$ASMACK_BASE"
+}
+
+checkPrerequisites() {
+ if [[ $BASH_VERSION < 4 ]] ; then
+ echo "aSmack's build.bash needs at least bash version 4"
+ exit 1
+ fi
+
+ if ! tar --version |grep GNU &> /dev/null ; then
+ echo "aSmack's build.bash needs GNU tar"
+ exit 1
+ fi
+}
+
+# Main
+
+setdefaults
+parseopts $@
+checkPrerequisites
+parseconfig
+setconfig
+printconfig
+initialize
+copystaticsrc
+testsmackgit
+fetchall
+createVersionTag
+createbuildsrc
+patchsrc "patch"
+if $BUILD_JINGLE ; then
+ patchsrc "jingle"
+ JINGLE_ARGS="-Djingle=lib/jstun.jar"
+fi
+build
+
+if $BUILD_CUSTOM ; then
+ buildcustom
+fi
+
+if cmdExists advzip ; then
+ echo "advzip found, compressing files"
+ find build \( -name '*.jar' -or -name '*.zip' \) -print0 | xargs -n 1 -0 $XARGS_ARGS advzip -z4
+else
+ echo "Could not find the advzip command."
+ echo "advzip will further reduce the size of the generated jar and zip files,"
+ echo "consider installing advzip"
+fi
+
+prepareRelease
+publishRelease
+
+STOPTIME=$(date -u "+%s")
+RUNTIME=$(( $STOPTIME - $STARTTIME ))
+prettyPrintSeconds $RUNTIME
+printconfig
diff --git a/asmack-master/build.xml b/asmack-master/build.xml
new file mode 100644
index 0000000..9ecfb84
--- /dev/null
+++ b/asmack-master/build.xml
@@ -0,0 +1,80 @@
+<project name="asmack" default="compile" basedir=".">
+
+<property name="jar.suffix" value="" />
+<property name="jingle" value="" />
+<property file="local.properties" />
+<property name="android.version" value="" />
+<target name="compile-jse" description="Compile for java se">
+ <delete dir="build/classes" failonerror="false" />
+ <mkdir dir="build/classes" />
+ <mkdir dir="build/classes/trunk" />
+ <javac
+ target="6"
+ source="6"
+ srcdir="build/src/trunk"
+ destdir="build/classes/trunk"
+ classpath="lib/xpp3-1.1.4c.jar:lib/httpclient-4.1.3.jar:lib/httpcore-4.1.4.jar"
+ debug="true"
+ debuglevel="source,lines"
+ excludes="**/de/measite/smack/AndroidDebugger.java"
+ />
+ <copy todir="build/classes/trunk"><fileset dir="build/src/trunk" includes="META-INF/**" /></copy>
+ <jar
+ basedir="build/classes/trunk"
+ destfile="build/asmack-jse${jar.suffix}.jar"
+ filesonly="true"
+ level="9"
+ />
+ <zip
+ basedir="build/src/trunk"
+ destfile="build/asmack-jse-source${jar.suffix}.zip"
+ excludes="**/de/measite/smack/AndroidDebugger.java"
+ filesonly="true"
+ level="9"
+ />
+</target>
+
+<target name="check-android-exists" >
+ <available property="android.exists" file="${sdk-location}/platforms/${android.version}/android.jar" />
+ <fail unless="${android.exists}" message="Android version ${android.version} does not is not available : ${sdk-location}/platforms/${android.version}/android.jar is not found" />
+</target>
+
+<target name="compile-android" description="Compile for android" depends="check-android-exists" >
+ <delete dir="build/classes/${android.version}" failonerror="false" />
+ <mkdir dir="build/classes/${android.version}" />
+ <mkdir dir="build/classes/${android.version}/trunk" />
+ <javac
+ target="6"
+ source="6"
+ srcdir="build/src/trunk"
+ destdir="build/classes/${android.version}/trunk"
+ bootclasspath="${sdk-location}/platforms/${android.version}/android.jar:${jingle}"
+ debug="true"
+ debuglevel="source,lines"
+ />
+ <copy todir="build/classes/${android.version}/trunk">
+ <fileset dir="build/src/trunk" includes="META-INF/**" />
+ </copy>
+ <jar
+ basedir="build/classes/${android.version}/trunk"
+ destfile="build/asmack-${android.version}${jar.suffix}.jar"
+ filesonly="true"
+ level="9"
+ />
+ <zip
+ basedir="build/src/trunk"
+ destfile="build/asmack-${android.version}-source${jar.suffix}.zip"
+ filesonly="true"
+ level="9"
+ />
+</target>
+
+
+<target
+ name="compile"
+ description="Compile for jse targets"
+ depends="compile-jse"
+/>
+
+</project>
+
diff --git a/asmack-master/jingle/60-jingle-ext.patch b/asmack-master/jingle/60-jingle-ext.patch
new file mode 100644
index 0000000..4e81be5
--- /dev/null
+++ b/asmack-master/jingle/60-jingle-ext.patch
@@ -0,0 +1,171 @@
+Index: org/jivesoftware/smackx/packet/JingleContentInfo.java
+===================================================================
+--- org/jivesoftware/smackx/packet/JingleContentInfo.java (revision 11644)
++++ org/jivesoftware/smackx/packet/JingleContentInfo.java (working copy)
+@@ -96,7 +96,7 @@
+ */
+ public static class Audio extends JingleContentInfo {
+
+- public static final String NAMESPACE = "urn:xmpp:tmp:jingle:apps:rtp";
++ public static final String NAMESPACE = "urn:xmpp:jingle:apps:rtp:1";
+
+ public Audio(final ContentInfo mi) {
+ super(mi);
+Index: org/jivesoftware/smackx/packet/JingleError.java
+===================================================================
+--- org/jivesoftware/smackx/packet/JingleError.java (revision 11644)
++++ org/jivesoftware/smackx/packet/JingleError.java (working copy)
+@@ -27,7 +27,7 @@
+
+ public class JingleError implements PacketExtension {
+
+- public static String NAMESPACE = "urn:xmpp:tmp:jingle:errors";
++ public static String NAMESPACE = "urn:xmpp:jingle:errors:1";
+
+ public static final JingleError OUT_OF_ORDER = new JingleError("out-of-order");
+
+Index: org/jivesoftware/smackx/packet/JingleTransport.java
+===================================================================
+--- org/jivesoftware/smackx/packet/JingleTransport.java (revision 11644)
++++ org/jivesoftware/smackx/packet/JingleTransport.java (working copy)
+@@ -270,7 +270,7 @@
+ * RTP-ICE profile
+ */
+ public static class Ice extends JingleTransport {
+- public static final String NAMESPACE = "urn:xmpp:tmp:jingle:transports:ice-udp";
++ public static final String NAMESPACE = "urn:xmpp:jingle:transports:ice-udp:1";
+
+ public Ice() {
+ super();
+@@ -352,7 +352,7 @@
+ * Raw UDP profile.
+ */
+ public static class RawUdp extends JingleTransport {
+- public static final String NAMESPACE = "http://www.xmpp.org/extensions/xep-0177.html#ns";
++ public static final String NAMESPACE = "urn:xmpp:jingle:transports:raw-udp:1";
+
+ public RawUdp() {
+ super();
+Index: org/jivesoftware/smackx/packet/JingleContentDescription.java
+===================================================================
+--- org/jivesoftware/smackx/packet/JingleContentDescription.java (revision 11644)
++++ org/jivesoftware/smackx/packet/JingleContentDescription.java (working copy)
+@@ -66,6 +66,13 @@
+ public abstract String getNamespace();
+
+ /**
++ * Return the media type.
++ *
++ * @return The media type
++ */
++ public abstract String getMediaType();
++
++ /**
+ * Adds a audio payload type to the packet.
+ *
+ * @param pt the audio payload type to add.
+@@ -153,7 +160,8 @@
+ synchronized (payloads) {
+ if (payloads.size() > 0) {
+ buf.append("<").append(getElementName());
+- buf.append(" xmlns=\"").append(getNamespace()).append("\" >");
++ buf.append(" xmlns=\"").append(getNamespace()).append("\"");
++ buf.append(" media=\"").append(getMediaType()).append("\" >");
+
+ Iterator pt = payloads.listIterator();
+ while (pt.hasNext()) {
+@@ -172,7 +180,8 @@
+ */
+ public static class Audio extends JingleContentDescription {
+
+- public static final String NAMESPACE = "urn:xmpp:tmp:jingle:apps:rtp";
++ public static final String NAMESPACE = "urn:xmpp:jingle:apps:rtp:1";
++ public static final String MEDIA_TYPE = "audio";
+
+ public Audio() {
+ super();
+@@ -189,6 +198,10 @@
+ public String getNamespace() {
+ return NAMESPACE;
+ }
++
++ public String getMediaType() {
++ return MEDIA_TYPE;
++ }
+ }
+
+ /**
+Index: org/jivesoftware/smackx/packet/Jingle.java
+===================================================================
+--- org/jivesoftware/smackx/packet/Jingle.java (revision 11644)
++++ org/jivesoftware/smackx/packet/Jingle.java (working copy)
+@@ -44,7 +44,7 @@
+
+ // static
+
+- public static final String NAMESPACE = "urn:xmpp:tmp:jingle";
++ public static final String NAMESPACE = "urn:xmpp:jingle:1";
+
+ public static final String NODENAME = "jingle";
+
+Index: org/jivesoftware/smackx/packet/JingleDescription.java
+===================================================================
+--- org/jivesoftware/smackx/packet/JingleDescription.java (revision 11644)
++++ org/jivesoftware/smackx/packet/JingleDescription.java (working copy)
+@@ -69,6 +69,13 @@
+ public abstract String getNamespace();
+
+ /**
++ * Return the media type.
++ *
++ * @return The media type
++ */
++ public abstract String getMediaType();
++
++ /**
+ * Adds a audio payload type to the packet.
+ *
+ * @param pt the audio payload type to add.
+@@ -160,7 +167,8 @@
+ synchronized (payloads) {
+ if (payloads.size() > 0) {
+ buf.append("<").append(getElementName());
+- buf.append(" xmlns=\"").append(getNamespace()).append("\" >");
++ buf.append(" xmlns=\"").append(getNamespace()).append("\"");
++ buf.append(" media=\"").append(getMediaType()).append("\" >");
+
+ for (PayloadType payloadType : payloads) {
+ if (payloadType != null) {
+@@ -179,7 +187,8 @@
+ */
+ public static class Audio extends JingleDescription {
+
+- public static final String NAMESPACE = "urn:xmpp:tmp:jingle:apps:rtp";
++ public static final String NAMESPACE = "urn:xmpp:jingle:apps:rtp:1";
++ public static final String MEDIA_TYPE = "audio";
+
+ public Audio() {
+ super();
+@@ -196,5 +205,9 @@
+ public String getNamespace() {
+ return NAMESPACE;
+ }
++
++ public String getMediaType() {
++ return MEDIA_TYPE;
++ }
+ }
+ }
+Index: org/jivesoftware/smackx/jingle/JingleManager.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/JingleManager.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/JingleManager.java (working copy)
+@@ -255,7 +255,7 @@
+ */
+ public static void setJingleServiceEnabled() {
+ ProviderManager providerManager = ProviderManager.getInstance();
+- providerManager.addIQProvider("jingle", "urn:xmpp:tmp:jingle", new JingleProvider());
++ providerManager.addIQProvider("jingle", "urn:xmpp:jingle:1", new JingleProvider());
+
+ // Enable the Jingle support on every established connection
+ // The ServiceDiscoveryManager class should have been already
diff --git a/asmack-master/jingle/60-remove-jingle_mediaimpl.patch b/asmack-master/jingle/60-remove-jingle_mediaimpl.patch
new file mode 100644
index 0000000..9aefc18
--- /dev/null
+++ b/asmack-master/jingle/60-remove-jingle_mediaimpl.patch
@@ -0,0 +1,4039 @@
+Index: org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaSession.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaSession.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaSession.java (working copy)
+@@ -1,92 +0,0 @@
+-/**
+- * $RCSfile: TestMediaSession.java,v $
+- * $Revision: 1.1 $
+- * $Date: 08/11/2006
+- * <p/>
+- * Copyright 2003-2006 Jive Software.
+- * <p/>
+- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+- * you may not use this file except in compliance with the License.
+- * You may obtain a copy of the License at
+- * <p/>
+- * http://www.apache.org/licenses/LICENSE-2.0
+- * <p/>
+- * 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.
+- */
+-package org.jivesoftware.smackx.jingle.mediaimpl.test;
+-
+-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;
+-
+-/**
+- * This Class implements a complete JingleMediaSession for unit testing.
+- *
+- * @author Thiago Camargo
+- */
+-public class TestMediaSession extends JingleMediaSession {
+-
+- /**
+- * Creates a TestMediaSession with defined payload type, remote and local candidates
+- *
+- * @param payloadType Payload of the jmf
+- * @param remote the remote information. The candidate that the jmf will be sent to.
+- * @param local the local information. The candidate that will receive the jmf
+- * @param locator media locator
+- */
+- public TestMediaSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local,
+- final String locator, JingleSession jingleSession) {
+- super(payloadType, remote, local, "Test", jingleSession);
+- initialize();
+- }
+-
+- /**
+- * Initialize the screen share channels.
+- */
+- public void initialize() {
+-
+- }
+-
+- /**
+- * Starts transmission and for NAT Traversal reasons start receiving also.
+- */
+- public void startTrasmit() {
+-
+- }
+-
+- /**
+- * Set transmit activity. If the active is true, the instance should trasmit.
+- * If it is set to false, the instance should pause transmit.
+- *
+- * @param active active state
+- */
+- public void setTrasmit(boolean active) {
+-
+- }
+-
+- /**
+- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
+- */
+- public void startReceive() {
+- // Do nothing
+- }
+-
+- /**
+- * Stops transmission and for NAT Traversal reasons stop receiving also.
+- */
+- public void stopTrasmit() {
+-
+- }
+-
+- /**
+- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
+- */
+- public void stopReceive() {
+-
+- }
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaManager.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaManager.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaManager.java (working copy)
+@@ -1,93 +0,0 @@
+-/**
+- * $RCSfile: TestMediaManager.java,v $
+- * $Revision: 1.3 $
+- * $Date: 25/12/2006
+- * <p/>
+- * Copyright 2003-2006 Jive Software.
+- * <p/>
+- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+- * you may not use this file except in compliance with the License.
+- * You may obtain a copy of the License at
+- * <p/>
+- * http://www.apache.org/licenses/LICENSE-2.0
+- * <p/>
+- * 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.
+- */
+-
+-package org.jivesoftware.smackx.jingle.mediaimpl.test;
+-
+-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 org.jivesoftware.smackx.jingle.JingleSession;
+-
+-import java.util.*;
+-
+-/**
+- * Implements a MediaManager for test purposes.
+- *
+- * @author Thiago Camargo
+- */
+-
+-public class TestMediaManager extends JingleMediaManager {
+-
+- public static final String MEDIA_NAME = "TestMedia";
+-
+- private List<PayloadType> payloads = new ArrayList<PayloadType>();
+-
+- private PayloadType preferredPayloadType = null;
+-
+- public TestMediaManager(JingleTransportManager transportManager) {
+- super(transportManager);
+- }
+-
+- /**
+- * Return all supported Payloads for this Manager.
+- *
+- * @return The Payload List
+- */
+- public List<PayloadType> getPayloads() {
+- return payloads;
+- }
+-
+- public void setPayloads(List<PayloadType> payloads) {
+- this.payloads.addAll(payloads);
+- }
+-
+- /**
+- * Returns a new JingleMediaSession
+- *
+- * @param payloadType payloadType
+- * @param remote remote Candidate
+- * @param local local Candidate
+- * @return JingleMediaSession JingleMediaSession
+- */
+- public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote,
+- final TransportCandidate local, final JingleSession jingleSession) {
+- TestMediaSession session = null;
+-
+- session = new TestMediaSession(payloadType, remote, local, "", jingleSession);
+-
+- return session;
+- }
+-
+- public PayloadType getPreferredPayloadType() {
+- if (preferredPayloadType != null)
+- return preferredPayloadType;
+- return super.getPreferredPayloadType();
+- }
+-
+- public void setPreferredPayloadType(PayloadType preferredPayloadType) {
+- this.preferredPayloadType = preferredPayloadType;
+- }
+-
+- public String getName() {
+- return MEDIA_NAME;
+- }
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/JMFInit.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/JMFInit.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/JMFInit.java (working copy)
+@@ -1,282 +0,0 @@
+-package org.jivesoftware.smackx.jingle.mediaimpl;
+-
+-import java.awt.Frame;
+-import java.awt.TextArea;
+-import java.awt.Toolkit;
+-import java.util.Vector;
+-
+-import javax.media.Format;
+-import javax.media.PlugInManager;
+-import javax.media.Renderer;
+-import javax.media.format.AudioFormat;
+-
+-import org.jivesoftware.smackx.jingle.SmackLogger;
+-
+-import com.sun.media.ExclusiveUse;
+-import com.sun.media.util.Registry;
+-
+-public class JMFInit extends Frame implements Runnable {
+-
+- private static final SmackLogger LOGGER = SmackLogger.getLogger(JMFInit.class);
+-
+- private String tempDir = "/tmp";
+-
+- private boolean done = false;
+-
+- private String userHome;
+-
+- private boolean visible = false;
+-
+- public JMFInit(String[] args, boolean visible) {
+- super("Initializing JMF...");
+-
+- this.visible = visible;
+-
+- Registry.set("secure.allowCaptureFromApplets", true);
+- Registry.set("secure.allowSaveFileFromApplets", true);
+-
+- updateTemp(args);
+-
+- try {
+- Registry.commit();
+- }
+- catch (Exception e) {
+-
+- message("Failed to commit to JMFRegistry!");
+- }
+-
+- Thread detectThread = new Thread(this);
+- detectThread.run();
+-
+- /*
+- * int slept = 0; while (!done && slept < 60 * 1000 * 2) { try {
+- * Thread.currentThread().sleep(500); } catch (InterruptedException ie) { }
+- * slept += 500; }
+- *
+- * if (!done) { console.error("Detection is taking too long!
+- * Aborting!"); message("Detection is taking too long! Aborting!"); }
+- *
+- * try { Thread.currentThread().sleep(2000); } catch
+- * (InterruptedException ie) { }
+- */
+- }
+-
+- public void run() {
+- detectDirectAudio();
+- detectS8DirectAudio();
+- detectCaptureDevices();
+- done = true;
+- }
+-
+- private void updateTemp(String[] args) {
+- if (args != null && args.length > 0) {
+- tempDir = args[0];
+-
+- message("Setting cache directory to " + tempDir);
+- Registry r = new Registry();
+- try {
+- r.set("secure.cacheDir", tempDir);
+- r.commit();
+-
+- message("Updated registry");
+- }
+- catch (Exception e) {
+- message("Couldn't update registry!");
+- }
+- }
+- }
+-
+- private void detectCaptureDevices() {
+- // check if JavaSound capture is available
+- message("Looking for Audio capturer");
+- Class dsauto;
+- try {
+- dsauto = Class.forName("DirectSoundAuto");
+- dsauto.newInstance();
+- message("Finished detecting DirectSound capturer");
+- }
+- catch (ThreadDeath td) {
+- throw td;
+- }
+- catch (Throwable t) {
+- //Do nothing
+- }
+-
+- Class jsauto;
+- try {
+- jsauto = Class.forName("JavaSoundAuto");
+- jsauto.newInstance();
+- message("Finished detecting javasound capturer");
+- }
+- catch (ThreadDeath td) {
+- throw td;
+- }
+- catch (Throwable t) {
+- message("JavaSound capturer detection failed!");
+- }
+-
+- /*
+- // Check if VFWAuto or SunVideoAuto is available
+- message("Looking for video capture devices");
+- Class auto = null;
+- Class autoPlus = null;
+- try {
+- auto = Class.forName("VFWAuto");
+- }
+- catch (Exception e) {
+- }
+- if (auto == null) {
+- try {
+- auto = Class.forName("SunVideoAuto");
+- }
+- catch (Exception ee) {
+-
+- }
+- try {
+- autoPlus = Class.forName("SunVideoPlusAuto");
+- }
+- catch (Exception ee) {
+-
+- }
+- }
+- if (auto == null) {
+- try {
+- auto = Class.forName("V4LAuto");
+- }
+- catch (Exception ee) {
+-
+- }
+- }
+- try {
+- Object instance = auto.newInstance();
+- if (autoPlus != null) {
+- Object instancePlus = autoPlus.newInstance();
+- }
+-
+- message("Finished detecting video capture devices");
+- }
+- catch (ThreadDeath td) {
+- throw td;
+- }
+- catch (Throwable t) {
+-
+- message("Capture device detection failed!");
+- }
+- */
+- }
+-
+- private void detectDirectAudio() {
+- Class cls;
+- int plType = PlugInManager.RENDERER;
+- String dar = "com.sun.media.renderer.audio.DirectAudioRenderer";
+- try {
+- // Check if this is the Windows Performance Pack - hack
+- cls = Class.forName("VFWAuto");
+- // Check if DS capture is supported, otherwise fail DS renderer
+- // since NT doesn't have capture
+- cls = Class.forName("com.sun.media.protocol.dsound.DSound");
+- // Find the renderer class and instantiate it.
+- cls = Class.forName(dar);
+-
+- Renderer rend = (Renderer) cls.newInstance();
+- try {
+- // Set the format and open the device
+- AudioFormat af = new AudioFormat(AudioFormat.LINEAR, 44100, 16,
+- 2);
+- rend.setInputFormat(af);
+- rend.open();
+- Format[] inputFormats = rend.getSupportedInputFormats();
+- // Register the device
+- PlugInManager.addPlugIn(dar, inputFormats, new Format[0],
+- plType);
+- // Move it to the top of the list
+- Vector rendList = PlugInManager.getPlugInList(null, null,
+- plType);
+- int listSize = rendList.size();
+- if (rendList.elementAt(listSize - 1).equals(dar)) {
+- rendList.removeElementAt(listSize - 1);
+- rendList.insertElementAt(dar, 0);
+- PlugInManager.setPlugInList(rendList, plType);
+- PlugInManager.commit();
+- // Log.debug("registered");
+- }
+- rend.close();
+- }
+- catch (Throwable t) {
+- // Log.debug("Error " + t);
+- }
+- }
+- catch (Throwable tt) {
+- //Do nothing
+- }
+- }
+-
+- private void detectS8DirectAudio() {
+- Class cls;
+- int plType = PlugInManager.RENDERER;
+- String dar = "com.sun.media.renderer.audio.DirectAudioRenderer";
+- try {
+- // Check if this is the solaris Performance Pack - hack
+- cls = Class.forName("SunVideoAuto");
+-
+- // Find the renderer class and instantiate it.
+- cls = Class.forName(dar);
+-
+- Renderer rend = (Renderer) cls.newInstance();
+-
+- if (rend instanceof ExclusiveUse
+- && !((ExclusiveUse) rend).isExclusive()) {
+- // sol8+, DAR supports mixing
+- Vector rendList = PlugInManager.getPlugInList(null, null,
+- plType);
+- int listSize = rendList.size();
+- boolean found = false;
+- String rname = null;
+-
+- for (int i = 0; i < listSize; i++) {
+- rname = (String) (rendList.elementAt(i));
+- if (rname.equals(dar)) { // DAR is in the registry
+- found = true;
+- rendList.removeElementAt(i);
+- break;
+- }
+- }
+-
+- if (found) {
+- rendList.insertElementAt(dar, 0);
+- PlugInManager.setPlugInList(rendList, plType);
+- PlugInManager.commit();
+- }
+- }
+- }
+- catch (Throwable tt) {
+- //Do nothing
+- }
+- }
+-
+- private void message(String mesg) {
+- LOGGER.debug(mesg);
+- }
+-
+- private void createGUI() {
+- TextArea textBox = new TextArea(5, 50);
+- add("Center", textBox);
+- textBox.setEditable(false);
+- addNotify();
+- pack();
+-
+- int scrWidth = (int) Toolkit.getDefaultToolkit().getScreenSize()
+- .getWidth();
+- int scrHeight = (int) Toolkit.getDefaultToolkit().getScreenSize()
+- .getHeight();
+-
+- setLocation((scrWidth - getWidth()) / 2, (scrHeight - getHeight()) / 2);
+-
+- setVisible(visible);
+-
+- }
+-
+- public static void start(boolean visible) {
+- new JMFInit(null, visible);
+- }
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java (working copy)
+@@ -1,174 +0,0 @@
+-/**
+- * $RCSfile: Demo.java,v $
+- * $Revision: 1.3 $
+- * $Date: 28/12/2006
+- * <p/>
+- * Copyright 2003-2006 Jive Software.
+- * <p/>
+- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+- * you may not use this file except in compliance with the License.
+- * You may obtain a copy of the License at
+- * <p/>
+- * http://www.apache.org/licenses/LICENSE-2.0
+- * <p/>
+- * 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.
+- */
+-package org.jivesoftware.smackx.jingle.mediaimpl.demo;
+-
+-import org.jivesoftware.smack.Connection;
+-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.JingleSessionRequestListener;
+-import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
+-import org.jivesoftware.smackx.jingle.mediaimpl.jspeex.SpeexMediaManager;
+-import org.jivesoftware.smackx.jingle.mediaimpl.sshare.ScreenShareMediaManager;
+-import org.jivesoftware.smackx.jingle.nat.ICETransportManager;
+-import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
+-
+-import javax.swing.*;
+-import java.awt.event.ActionEvent;
+-import java.util.ArrayList;
+-import java.util.List;
+-
+-/**
+- * Jingle Demo Application. It register in a XMPP Server and let users place calls using a full JID and auto-receive calls.
+- * Parameters: Server User Pass.
+- */
+-public class Demo extends JFrame {
+-
+- private JingleTransportManager transportManager = null;
+- private Connection xmppConnection = null;
+-
+- private String server = null;
+- private String user = null;
+- private String pass = null;
+-
+- private JingleManager jm = null;
+- private JingleSession incoming = null;
+- private JingleSession outgoing = null;
+-
+- private JTextField jid;
+-
+- public Demo(String server, String user, String pass) {
+-
+- this.server = server;
+- this.user = user;
+- this.pass = pass;
+-
+- if (user.equals("jeffw")) {
+- jid = new JTextField("eowyn" + "@" + server + "/Smack");
+- } else {
+- jid = new JTextField("jeffw" + "@" + server + "/Smack");
+- }
+-
+- xmppConnection = new XMPPConnection(server);
+- try {
+- xmppConnection.connect();
+- xmppConnection.login(user, pass);
+- initialize();
+- }
+- catch (XMPPException e) {
+- e.printStackTrace();
+- }
+- }
+-
+- public void initialize() {
+- ICETransportManager icetm0 = new ICETransportManager(xmppConnection, "10.47.47.53", 3478);
+- List<JingleMediaManager> mediaManagers = new ArrayList<JingleMediaManager>();
+- //mediaManagers.add(new JmfMediaManager(icetm0));
+- mediaManagers.add(new SpeexMediaManager(icetm0));
+- mediaManagers.add(new ScreenShareMediaManager(icetm0));
+- jm = new JingleManager(xmppConnection, mediaManagers);
+- jm.addCreationListener(icetm0);
+-
+- jm.addJingleSessionRequestListener(new JingleSessionRequestListener() {
+- public void sessionRequested(JingleSessionRequest request) {
+-
+-// if (incoming != null)
+-// return;
+-
+- try {
+- // Accept the call
+- incoming = request.accept();
+-
+- // Start the call
+- incoming.startIncoming();
+- }
+- catch (XMPPException e) {
+- e.printStackTrace();
+- }
+-
+- }
+- });
+- createGUI();
+- }
+-
+- public void createGUI() {
+-
+- JPanel jPanel = new JPanel();
+-
+- jPanel.add(jid);
+-
+- jPanel.add(new JButton(new AbstractAction("Call") {
+- public void actionPerformed(ActionEvent e) {
+- if (outgoing != null) return;
+- try {
+- outgoing = jm.createOutgoingJingleSession(jid.getText());
+- outgoing.startOutgoing();
+- }
+- catch (XMPPException e1) {
+- e1.printStackTrace();
+- }
+- }
+- }));
+-
+- jPanel.add(new JButton(new AbstractAction("Hangup") {
+- public void actionPerformed(ActionEvent e) {
+- if (outgoing != null)
+- try {
+- outgoing.terminate();
+- }
+- catch (XMPPException e1) {
+- e1.printStackTrace();
+- }
+- finally {
+- outgoing = null;
+- }
+- if (incoming != null)
+- try {
+- incoming.terminate();
+- }
+- catch (XMPPException e1) {
+- e1.printStackTrace();
+- }
+- finally {
+- incoming = null;
+- }
+- }
+- }));
+-
+- this.add(jPanel);
+-
+- }
+-
+- public static void main(String args[]) {
+-
+- Demo demo = null;
+-
+- if (args.length > 2) {
+- demo = new Demo(args[0], args[1], args[2]);
+- demo.pack();
+- demo.setVisible(true);
+- demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+- }
+-
+- }
+-
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java (working copy)
+@@ -1,206 +0,0 @@
+-/**
+- * $RCSfile: ScreenShareSession.java,v $
+- * $Revision: 1.2 $
+- * $Date: 08/11/2006
+- * <p/>
+- * Copyright 2003-2006 Jive Software.
+- * <p/>
+- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+- * you may not use this file except in compliance with the License.
+- * You may obtain a copy of the License at
+- * <p/>
+- * http://www.apache.org/licenses/LICENSE-2.0
+- * <p/>
+- * 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.
+- */
+-package org.jivesoftware.smackx.jingle.mediaimpl.sshare;
+-
+-import java.awt.Rectangle;
+-import java.awt.event.WindowAdapter;
+-import java.awt.event.WindowEvent;
+-import java.io.IOException;
+-import java.net.DatagramSocket;
+-import java.net.InetAddress;
+-import java.net.ServerSocket;
+-import java.net.UnknownHostException;
+-
+-import javax.swing.JFrame;
+-import javax.swing.JPanel;
+-
+-import org.jivesoftware.smackx.jingle.JingleSession;
+-import org.jivesoftware.smackx.jingle.SmackLogger;
+-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
+-import org.jivesoftware.smackx.jingle.media.PayloadType;
+-import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageDecoder;
+-import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageEncoder;
+-import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageReceiver;
+-import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageTransmitter;
+-import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
+-
+-/**
+- * This Class implements a complete JingleMediaSession.
+- * It sould be used to transmit and receive captured images from the Display.
+- * This Class should be automaticly controlled by JingleSession.
+- * For better NAT Traversal support this implementation don't support only receive or only transmit.
+- * To receive you MUST transmit. So the only implemented and functionally methods are startTransmit() and stopTransmit()
+- *
+- * @author Thiago Camargo
+- */
+-public class ScreenShareSession extends JingleMediaSession {
+-
+- private static final SmackLogger LOGGER = SmackLogger.getLogger(ScreenShareSession.class);
+-
+- private ImageTransmitter transmitter = null;
+- private ImageReceiver receiver = null;
+- private int width = 600;
+- private int height = 600;
+-
+- /**
+- * Creates a org.jivesoftware.jingleaudio.jmf.AudioMediaSession with defined payload type, remote and local candidates
+- *
+- * @param payloadType Payload of the jmf
+- * @param remote the remote information. The candidate that the jmf will be sent to.
+- * @param local the local information. The candidate that will receive the jmf
+- * @param locator media locator
+- */
+- public ScreenShareSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local,
+- final String locator, JingleSession jingleSession) {
+- super(payloadType, remote, local, "Screen", jingleSession);
+- initialize();
+- }
+-
+- /**
+- * Initialize the screen share channels.
+- */
+- public void initialize() {
+-
+- JingleSession session = getJingleSession();
+- if ((session != null) && (session.getInitiator().equals(session.getConnection().getUser()))) {
+- // If the initiator of the jingle session is us then we transmit a screen share.
+- try {
+- InetAddress remote = InetAddress.getByName(getRemote().getIp());
+- transmitter = new ImageTransmitter(new DatagramSocket(getLocal().getPort()), remote, getRemote().getPort(),
+- new Rectangle(0, 0, width, height));
+- } catch (Exception e) {
+- e.printStackTrace();
+- }
+-
+- } else {
+- // Otherwise we receive a screen share.
+- JFrame window = new JFrame();
+- JPanel jp = new JPanel();
+- window.add(jp);
+-
+- window.setLocation(0, 0);
+- window.setSize(600, 600);
+-
+- window.addWindowListener(new WindowAdapter() {
+- public void windowClosed(WindowEvent e) {
+- receiver.stop();
+- }
+- });
+-
+- try {
+- receiver = new ImageReceiver(InetAddress.getByName("0.0.0.0"), getRemote().getPort(), getLocal().getPort(), width,
+- height);
+- LOGGER.debug("Receiving on:" + receiver.getLocalPort());
+- } catch (UnknownHostException e) {
+- e.printStackTrace();
+- }
+-
+- jp.add(receiver);
+- receiver.setVisible(true);
+- window.setAlwaysOnTop(true);
+- window.setVisible(true);
+- }
+- }
+-
+- /**
+- * Starts transmission and for NAT Traversal reasons start receiving also.
+- */
+- public void startTrasmit() {
+- new Thread(transmitter).start();
+- }
+-
+- /**
+- * Set transmit activity. If the active is true, the instance should trasmit.
+- * If it is set to false, the instance should pause transmit.
+- *
+- * @param active active state
+- */
+- public void setTrasmit(boolean active) {
+- transmitter.setTransmit(true);
+- }
+-
+- /**
+- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
+- */
+- public void startReceive() {
+- // Do nothing
+- }
+-
+- /**
+- * Stops transmission and for NAT Traversal reasons stop receiving also.
+- */
+- public void stopTrasmit() {
+- if (transmitter != null) {
+- transmitter.stop();
+- }
+- }
+-
+- /**
+- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
+- */
+- public void stopReceive() {
+- if (receiver != null) {
+- receiver.stop();
+- }
+- }
+-
+- /**
+- * Obtain a free port we can use.
+- *
+- * @return A free port number.
+- */
+- protected int getFreePort() {
+- ServerSocket ss;
+- int freePort = 0;
+-
+- for (int i = 0; i < 10; i++) {
+- freePort = (int) (10000 + Math.round(Math.random() * 10000));
+- freePort = freePort % 2 == 0 ? freePort : freePort + 1;
+- try {
+- ss = new ServerSocket(freePort);
+- freePort = ss.getLocalPort();
+- ss.close();
+- return freePort;
+- } catch (IOException e) {
+- e.printStackTrace();
+- }
+- }
+- try {
+- ss = new ServerSocket(0);
+- freePort = ss.getLocalPort();
+- ss.close();
+- } catch (IOException e) {
+- e.printStackTrace();
+- }
+- return freePort;
+- }
+-
+- public void setEncoder(ImageEncoder encoder) {
+- if (encoder != null) {
+- this.transmitter.setEncoder(encoder);
+- }
+- }
+-
+- public void setDecoder(ImageDecoder decoder) {
+- if (decoder != null) {
+- this.receiver.setDecoder(decoder);
+- }
+- }
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageTransmitter.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageTransmitter.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageTransmitter.java (working copy)
+@@ -1,204 +0,0 @@
+-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
+-
+-import java.awt.AWTException;
+-import java.awt.Rectangle;
+-import java.awt.Robot;
+-import java.awt.image.BufferedImage;
+-import java.awt.image.PixelGrabber;
+-import java.io.ByteArrayOutputStream;
+-import java.io.IOException;
+-import java.net.DatagramPacket;
+-import java.net.DatagramSocket;
+-import java.net.InetAddress;
+-import java.util.Arrays;
+-
+-import org.jivesoftware.smackx.jingle.SmackLogger;
+-
+-/**
+- * UDP Image Receiver.
+- * It uses PNG Tiles into UDP packets.
+- *
+- * @author Thiago Rocha Camargo
+- */
+-public class ImageTransmitter implements Runnable {
+-
+- private static final SmackLogger LOGGER = SmackLogger.getLogger(ImageTransmitter.class);
+-
+- private Robot robot;
+- private InetAddress localHost;
+- private InetAddress remoteHost;
+- private int localPort;
+- private int remotePort;
+- public static final int tileWidth = 25;
+- private boolean on = true;
+- private boolean transmit = false;
+- private DatagramSocket socket;
+- private Rectangle area;
+- private int tiles[][][];
+- private int maxI;
+- private int maxJ;
+- private ImageEncoder encoder;
+- public final static int KEYFRAME = 10;
+-
+- public ImageTransmitter(DatagramSocket socket, InetAddress remoteHost, int remotePort, Rectangle area) {
+-
+- try {
+- robot = new Robot();
+-
+- maxI = (int) Math.ceil(area.getWidth() / tileWidth);
+- maxJ = (int) Math.ceil(area.getHeight() / tileWidth);
+-
+- tiles = new int[maxI][maxJ][tileWidth * tileWidth];
+-
+- this.area = area;
+- this.socket = socket;
+- localHost = socket.getLocalAddress();
+- localPort = socket.getLocalPort();
+- this.remoteHost = remoteHost;
+- this.remotePort = remotePort;
+- this.encoder = new DefaultEncoder();
+-
+- transmit = true;
+-
+- }
+- catch (AWTException e) {
+- e.printStackTrace();
+- }
+-
+- }
+-
+- public void start() {
+- byte buf[] = new byte[1024];
+- final DatagramPacket p = new DatagramPacket(buf, 1024);
+-
+- int keyframe = 0;
+-
+- while (on) {
+- if (transmit) {
+-
+- BufferedImage capture = robot.createScreenCapture(area);
+-
+- QuantizeFilter filter = new QuantizeFilter();
+- capture = filter.filter(capture, null);
+-
+- long trace = System.currentTimeMillis();
+-
+- if (++keyframe > KEYFRAME) {
+- keyframe = 0;
+- }
+- LOGGER.debug("KEYFRAME:" + keyframe);
+-
+- for (int i = 0; i < maxI; i++) {
+- for (int j = 0; j < maxJ; j++) {
+-
+- final BufferedImage bufferedImage = capture.getSubimage(i * tileWidth, j * tileWidth, tileWidth, tileWidth);
+-
+- int pixels[] = new int[tileWidth * tileWidth];
+-
+- PixelGrabber pg = new PixelGrabber(bufferedImage, 0, 0, tileWidth, tileWidth, pixels, 0, tileWidth);
+-
+- try {
+- if (pg.grabPixels()) {
+-
+- if (keyframe == KEYFRAME || !Arrays.equals(tiles[i][j], pixels)) {
+-
+- ByteArrayOutputStream baos = encoder.encode(bufferedImage);
+-
+- if (baos != null) {
+-
+- try {
+-
+- Thread.sleep(1);
+-
+- baos.write(i);
+- baos.write(j);
+-
+- byte[] bytesOut = baos.toByteArray();
+-
+- if (bytesOut.length > 1000)
+- LOGGER.error("Bytes out > 1000. Equals " + bytesOut.length);
+-
+- p.setData(bytesOut);
+- p.setAddress(remoteHost);
+- p.setPort(remotePort);
+-
+- try {
+- socket.send(p);
+- }
+- catch (IOException e) {
+- e.printStackTrace();
+- }
+-
+- tiles[i][j] = pixels;
+-
+- }
+- catch (Exception e) {
+- }
+-
+- }
+-
+- }
+-
+- }
+- }
+- catch (InterruptedException e) {
+- e.printStackTrace();
+- }
+- }
+- }
+-
+- trace = (System.currentTimeMillis() - trace);
+- LOGGER.debug("Loop Time:" + trace);
+-
+- if (trace < 500) {
+- try {
+- Thread.sleep(500 - trace);
+- }
+- catch (InterruptedException e) {
+- e.printStackTrace();
+- }
+- }
+- }
+- }
+- }
+-
+- public void run() {
+- start();
+- }
+-
+- /**
+- * Set Transmit Enabled/Disabled
+- *
+- * @param transmit boolean Enabled/Disabled
+- */
+- public void setTransmit(boolean transmit) {
+- this.transmit = transmit;
+- }
+-
+- /**
+- * Get the encoder used to encode Images Tiles
+- *
+- * @return encoder
+- */
+- public ImageEncoder getEncoder() {
+- return encoder;
+- }
+-
+- /**
+- * Set the encoder used to encode Image Tiles
+- *
+- * @param encoder encoder
+- */
+- public void setEncoder(ImageEncoder encoder) {
+- this.encoder = encoder;
+- }
+-
+- /**
+- * Stops Transmitter
+- */
+- public void stop() {
+- this.transmit = false;
+- this.on = false;
+- socket.close();
+- }
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageEncoder.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageEncoder.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageEncoder.java (working copy)
+@@ -1,13 +0,0 @@
+-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
+-
+-import java.awt.image.BufferedImage;
+-import java.io.ByteArrayOutputStream;
+-
+-/**
+- * Image Encoder Interface use this interface if you want to change the default encoder
+- *
+- * @author Thiago Rocha Camargo
+- */
+-public interface ImageEncoder {
+- public ByteArrayOutputStream encode(BufferedImage bufferedImage);
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/PixelUtils.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/PixelUtils.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/PixelUtils.java (working copy)
+@@ -1,223 +0,0 @@
+-/*
+-Copyright 2006 Jerry Huxtable
+-
+-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.
+-*/
+-
+-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
+-
+-import java.awt.*;
+-import java.util.Random;
+-
+-/**
+- * Some more useful math functions for image processing.
+- * These are becoming obsolete as we move to Java2D. Use MiscComposite instead.
+- */
+-public class PixelUtils {
+-
+- public final static int REPLACE = 0;
+- public final static int NORMAL = 1;
+- public final static int MIN = 2;
+- public final static int MAX = 3;
+- public final static int ADD = 4;
+- public final static int SUBTRACT = 5;
+- public final static int DIFFERENCE = 6;
+- public final static int MULTIPLY = 7;
+- public final static int HUE = 8;
+- public final static int SATURATION = 9;
+- public final static int VALUE = 10;
+- public final static int COLOR = 11;
+- public final static int SCREEN = 12;
+- public final static int AVERAGE = 13;
+- public final static int OVERLAY = 14;
+- public final static int CLEAR = 15;
+- public final static int EXCHANGE = 16;
+- public final static int DISSOLVE = 17;
+- public final static int DST_IN = 18;
+- public final static int ALPHA = 19;
+- public final static int ALPHA_TO_GRAY = 20;
+-
+- private static Random randomGenerator = new Random();
+-
+- /**
+- * Clamp a value to the range 0..255
+- */
+- public static int clamp(int c) {
+- if (c < 0)
+- return 0;
+- if (c > 255)
+- return 255;
+- return c;
+- }
+-
+- public static int interpolate(int v1, int v2, float f) {
+- return clamp((int)(v1+f*(v2-v1)));
+- }
+-
+- public static int brightness(int rgb) {
+- int r = (rgb >> 16) & 0xff;
+- int g = (rgb >> 8) & 0xff;
+- int b = rgb & 0xff;
+- return (r+g+b)/3;
+- }
+-
+- public static boolean nearColors(int rgb1, int rgb2, int tolerance) {
+- int r1 = (rgb1 >> 16) & 0xff;
+- int g1 = (rgb1 >> 8) & 0xff;
+- int b1 = rgb1 & 0xff;
+- int r2 = (rgb2 >> 16) & 0xff;
+- int g2 = (rgb2 >> 8) & 0xff;
+- int b2 = rgb2 & 0xff;
+- return Math.abs(r1-r2) <= tolerance && Math.abs(g1-g2) <= tolerance && Math.abs(b1-b2) <= tolerance;
+- }
+-
+- private final static float hsb1[] = new float[3];//FIXME-not thread safe
+- private final static float hsb2[] = new float[3];//FIXME-not thread safe
+-
+- // Return rgb1 painted onto rgb2
+- public static int combinePixels(int rgb1, int rgb2, int op) {
+- return combinePixels(rgb1, rgb2, op, 0xff);
+- }
+-
+- public static int combinePixels(int rgb1, int rgb2, int op, int extraAlpha, int channelMask) {
+- return (rgb2 & ~channelMask) | combinePixels(rgb1 & channelMask, rgb2, op, extraAlpha);
+- }
+-
+- public static int combinePixels(int rgb1, int rgb2, int op, int extraAlpha) {
+- if (op == REPLACE)
+- return rgb1;
+- int a1 = (rgb1 >> 24) & 0xff;
+- int r1 = (rgb1 >> 16) & 0xff;
+- int g1 = (rgb1 >> 8) & 0xff;
+- int b1 = rgb1 & 0xff;
+- int a2 = (rgb2 >> 24) & 0xff;
+- int r2 = (rgb2 >> 16) & 0xff;
+- int g2 = (rgb2 >> 8) & 0xff;
+- int b2 = rgb2 & 0xff;
+-
+- switch (op) {
+- case NORMAL:
+- break;
+- case MIN:
+- r1 = Math.min(r1, r2);
+- g1 = Math.min(g1, g2);
+- b1 = Math.min(b1, b2);
+- break;
+- case MAX:
+- r1 = Math.max(r1, r2);
+- g1 = Math.max(g1, g2);
+- b1 = Math.max(b1, b2);
+- break;
+- case ADD:
+- r1 = clamp(r1+r2);
+- g1 = clamp(g1+g2);
+- b1 = clamp(b1+b2);
+- break;
+- case SUBTRACT:
+- r1 = clamp(r2-r1);
+- g1 = clamp(g2-g1);
+- b1 = clamp(b2-b1);
+- break;
+- case DIFFERENCE:
+- r1 = clamp(Math.abs(r1-r2));
+- g1 = clamp(Math.abs(g1-g2));
+- b1 = clamp(Math.abs(b1-b2));
+- break;
+- case MULTIPLY:
+- r1 = clamp(r1*r2/255);
+- g1 = clamp(g1*g2/255);
+- b1 = clamp(b1*b2/255);
+- break;
+- case DISSOLVE:
+- if ((randomGenerator.nextInt() & 0xff) <= a1) {
+- r1 = r2;
+- g1 = g2;
+- b1 = b2;
+- }
+- break;
+- case AVERAGE:
+- r1 = (r1+r2)/2;
+- g1 = (g1+g2)/2;
+- b1 = (b1+b2)/2;
+- break;
+- case HUE:
+- case SATURATION:
+- case VALUE:
+- case COLOR:
+- Color.RGBtoHSB(r1, g1, b1, hsb1);
+- Color.RGBtoHSB(r2, g2, b2, hsb2);
+- switch (op) {
+- case HUE:
+- hsb2[0] = hsb1[0];
+- break;
+- case SATURATION:
+- hsb2[1] = hsb1[1];
+- break;
+- case VALUE:
+- hsb2[2] = hsb1[2];
+- break;
+- case COLOR:
+- hsb2[0] = hsb1[0];
+- hsb2[1] = hsb1[1];
+- break;
+- }
+- rgb1 = Color.HSBtoRGB(hsb2[0], hsb2[1], hsb2[2]);
+- r1 = (rgb1 >> 16) & 0xff;
+- g1 = (rgb1 >> 8) & 0xff;
+- b1 = rgb1 & 0xff;
+- break;
+- case SCREEN:
+- r1 = 255 - ((255 - r1) * (255 - r2)) / 255;
+- g1 = 255 - ((255 - g1) * (255 - g2)) / 255;
+- b1 = 255 - ((255 - b1) * (255 - b2)) / 255;
+- break;
+- case OVERLAY:
+- int m, s;
+- s = 255 - ((255 - r1) * (255 - r2)) / 255;
+- m = r1 * r2 / 255;
+- r1 = (s * r1 + m * (255 - r1)) / 255;
+- s = 255 - ((255 - g1) * (255 - g2)) / 255;
+- m = g1 * g2 / 255;
+- g1 = (s * g1 + m * (255 - g1)) / 255;
+- s = 255 - ((255 - b1) * (255 - b2)) / 255;
+- m = b1 * b2 / 255;
+- b1 = (s * b1 + m * (255 - b1)) / 255;
+- break;
+- case CLEAR:
+- r1 = g1 = b1 = 0xff;
+- break;
+- case DST_IN:
+- r1 = clamp((r2*a1)/255);
+- g1 = clamp((g2*a1)/255);
+- b1 = clamp((b2*a1)/255);
+- a1 = clamp((a2*a1)/255);
+- return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;
+- case ALPHA:
+- a1 = a1*a2/255;
+- return (a1 << 24) | (r2 << 16) | (g2 << 8) | b2;
+- case ALPHA_TO_GRAY:
+- int na = 255-a1;
+- return (a1 << 24) | (na << 16) | (na << 8) | na;
+- }
+- if (extraAlpha != 0xff || a1 != 0xff) {
+- a1 = a1*extraAlpha/255;
+- int a3 = (255-a1)*a2/255;
+- r1 = clamp((r1*a1+r2*a3)/255);
+- g1 = clamp((g1*a1+g2*a3)/255);
+- b1 = clamp((b1*a1+b2*a3)/255);
+- a1 = clamp(a1+a3);
+- }
+- return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;
+- }
+-
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/Quantizer.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/Quantizer.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/Quantizer.java (working copy)
+@@ -1,53 +0,0 @@
+-/*
+-Copyright 2006 Jerry Huxtable
+-
+-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.
+-*/
+-
+-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
+-
+-/**
+- * The interface for an image quantizer. The addColor method is called (repeatedly
+- * if necessary) with all the image pixels. A color table can then be returned by
+- * calling the buildColorTable method.
+- */
+-public interface Quantizer {
+- /**
+- * Initialize the quantizer. This should be called before adding any pixels.
+- * @param numColors the number of colors we're quantizing to.
+- */
+- public void setup(int numColors);
+-
+- /**
+- * Add pixels to the quantizer.
+- * @param pixels the array of ARGB pixels
+- * @param offset the offset into the array
+- * @param count the count of pixels
+- */
+- public void addPixels(int[] pixels, int offset, int count);
+-
+- /**
+- * Build a color table from the added pixels.
+- * @return an array of ARGB pixels representing a color table
+- */
+- public int[] buildColorTable();
+-
+- /**
+- * Using the previously-built color table, return the index into that table for a pixel.
+- * This is guaranteed to return a valid index - returning the index of a color closer
+- * to that requested if necessary.
+- * @param rgb the pixel to find
+- * @return the pixel's index in the color table
+- */
+- public int getIndexForColor(int rgb);
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultEncoder.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultEncoder.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultEncoder.java (working copy)
+@@ -1,24 +0,0 @@
+-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
+-
+-import javax.imageio.ImageIO;
+-import java.awt.image.BufferedImage;
+-import java.io.ByteArrayOutputStream;
+-import java.io.IOException;
+-
+-/**
+- * Implements a default PNG Encoder
+- */
+-public class DefaultEncoder implements ImageEncoder{
+-
+- public ByteArrayOutputStream encode(BufferedImage bufferedImage) {
+- ByteArrayOutputStream baos = new ByteArrayOutputStream();
+- try {
+- ImageIO.write(bufferedImage, "png", baos);
+- }
+- catch (IOException e) {
+- e.printStackTrace();
+- baos = null;
+- }
+- return baos;
+- }
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/QuantizeFilter.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/QuantizeFilter.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/QuantizeFilter.java (working copy)
+@@ -1,178 +0,0 @@
+-/*
+-Copyright 2006 Jerry Huxtable
+-
+-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.
+-*/
+-
+-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
+-
+-import java.awt.*;
+-
+-/**
+- * A filter which quantizes an image to a set number of colors - useful for producing
+- * images which are to be encoded using an index color model. The filter can perform
+- * Floyd-Steinberg error-diffusion dithering if required. At present, the quantization
+- * is done using an octtree algorithm but I eventually hope to add more quantization
+- * methods such as median cut. Note: at present, the filter produces an image which
+- * uses the RGB color model (because the application it was written for required it).
+- * I hope to extend it to produce an IndexColorModel by request.
+- */
+-public class QuantizeFilter extends WholeImageFilter {
+-
+- /**
+- * Floyd-Steinberg dithering matrix.
+- */
+- protected final static int[] matrix = {
+- 0, 0, 0,
+- 0, 0, 7,
+- 3, 5, 1,
+- };
+- private int sum = 3+5+7+1;
+-
+- private boolean dither;
+- private int numColors = 256;
+- private boolean serpentine = true;
+-
+- /**
+- * Set the number of colors to quantize to.
+- * @param numColors the number of colors. The default is 256.
+- */
+- public void setNumColors(int numColors) {
+- this.numColors = Math.min(Math.max(numColors, 8), 256);
+- }
+-
+- /**
+- * Get the number of colors to quantize to.
+- * @return the number of colors.
+- */
+- public int getNumColors() {
+- return numColors;
+- }
+-
+- /**
+- * Set whether to use dithering or not. If not, the image is posterized.
+- * @param dither true to use dithering
+- */
+- public void setDither(boolean dither) {
+- this.dither = dither;
+- }
+-
+- /**
+- * Return the dithering setting
+- * @return the current setting
+- */
+- public boolean getDither() {
+- return dither;
+- }
+-
+- /**
+- * Set whether to use a serpentine pattern for return or not. This can reduce 'avalanche' artifacts in the output.
+- * @param serpentine true to use serpentine pattern
+- */
+- public void setSerpentine(boolean serpentine) {
+- this.serpentine = serpentine;
+- }
+-
+- /**
+- * Return the serpentine setting
+- * @return the current setting
+- */
+- public boolean getSerpentine() {
+- return serpentine;
+- }
+-
+- public void quantize(int[] inPixels, int[] outPixels, int width, int height, int numColors, boolean dither, boolean serpentine) {
+- int count = width*height;
+- Quantizer quantizer = new OctTreeQuantizer();
+- quantizer.setup(numColors);
+- quantizer.addPixels(inPixels, 0, count);
+- int[] table = quantizer.buildColorTable();
+-
+- if (!dither) {
+- for (int i = 0; i < count; i++)
+- outPixels[i] = table[quantizer.getIndexForColor(inPixels[i])];
+- } else {
+- int index = 0;
+- for (int y = 0; y < height; y++) {
+- boolean reverse = serpentine && (y & 1) == 1;
+- int direction;
+- if (reverse) {
+- index = y*width+width-1;
+- direction = -1;
+- } else {
+- index = y*width;
+- direction = 1;
+- }
+- for (int x = 0; x < width; x++) {
+- int rgb1 = inPixels[index];
+- int rgb2 = table[quantizer.getIndexForColor(rgb1)];
+-
+- outPixels[index] = rgb2;
+-
+- int r1 = (rgb1 >> 16) & 0xff;
+- int g1 = (rgb1 >> 8) & 0xff;
+- int b1 = rgb1 & 0xff;
+-
+- int r2 = (rgb2 >> 16) & 0xff;
+- int g2 = (rgb2 >> 8) & 0xff;
+- int b2 = rgb2 & 0xff;
+-
+- int er = r1-r2;
+- int eg = g1-g2;
+- int eb = b1-b2;
+-
+- for (int i = -1; i <= 1; i++) {
+- int iy = i+y;
+- if (0 <= iy && iy < height) {
+- for (int j = -1; j <= 1; j++) {
+- int jx = j+x;
+- if (0 <= jx && jx < width) {
+- int w;
+- if (reverse)
+- w = matrix[(i+1)*3-j+1];
+- else
+- w = matrix[(i+1)*3+j+1];
+- if (w != 0) {
+- int k = reverse ? index - j : index + j;
+- rgb1 = inPixels[k];
+- r1 = (rgb1 >> 16) & 0xff;
+- g1 = (rgb1 >> 8) & 0xff;
+- b1 = rgb1 & 0xff;
+- r1 += er * w/sum;
+- g1 += eg * w/sum;
+- b1 += eb * w/sum;
+- inPixels[k] = (PixelUtils.clamp(r1) << 16) | (PixelUtils.clamp(g1) << 8) | PixelUtils.clamp(b1);
+- }
+- }
+- }
+- }
+- }
+- index += direction;
+- }
+- }
+- }
+- }
+-
+- protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
+- int[] outPixels = new int[width*height];
+-
+- quantize(inPixels, outPixels, width, height, numColors, dither, serpentine);
+-
+- return outPixels;
+- }
+-
+- public String toString() {
+- return "Colors/Quantize...";
+- }
+-
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageReceiver.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageReceiver.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageReceiver.java (working copy)
+@@ -1,150 +0,0 @@
+-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
+-
+-import java.awt.*;
+-import java.awt.image.BufferedImage;
+-import java.io.ByteArrayInputStream;
+-import java.io.IOException;
+-import java.net.DatagramPacket;
+-import java.net.DatagramSocket;
+-import java.net.InetAddress;
+-import java.net.SocketException;
+-
+-/**
+- * UDP Image Receiver.
+- * It uses PNG Tiles into UDP packets.
+- *
+- * @author Thiago Rocha Camargo
+- */
+-public class ImageReceiver extends Canvas {
+-
+- private boolean on = true;
+- private DatagramSocket socket;
+- private BufferedImage tiles[][];
+- private static final int tileWidth = ImageTransmitter.tileWidth;
+- private InetAddress localHost;
+- private InetAddress remoteHost;
+- private int localPort;
+- private int remotePort;
+- private ImageDecoder decoder;
+-
+- public ImageReceiver(final InetAddress remoteHost, final int remotePort, final int localPort, int width, int height) {
+- tiles = new BufferedImage[width][height];
+-
+- try {
+-
+- socket = new DatagramSocket(localPort);
+- localHost = socket.getLocalAddress();
+- this.remoteHost = remoteHost;
+- this.remotePort = remotePort;
+- this.localPort = localPort;
+- this.decoder = new DefaultDecoder();
+-
+- new Thread(new Runnable() {
+- public void run() {
+- byte buf[] = new byte[1024];
+- DatagramPacket p = new DatagramPacket(buf, 1024);
+- try {
+- while (on) {
+- socket.receive(p);
+-
+- int length = p.getLength();
+-
+- BufferedImage bufferedImage = decoder.decode(new ByteArrayInputStream(p.getData(), 0, length - 2));
+-
+- if (bufferedImage != null) {
+-
+- int x = p.getData()[length - 2];
+- int y = p.getData()[length - 1];
+-
+- drawTile(x, y, bufferedImage);
+-
+- }
+-
+- }
+- }
+- catch (IOException e) {
+- e.printStackTrace();
+- }
+- }
+- }).start();
+-
+- new Thread(new Runnable() {
+- public void run() {
+- byte buf[] = new byte[1024];
+- DatagramPacket p = new DatagramPacket(buf, 1024);
+- try {
+- while (on) {
+-
+- p.setAddress(remoteHost);
+- p.setPort(remotePort);
+- socket.send(p);
+-
+- try {
+- Thread.sleep(1000);
+- }
+- catch (InterruptedException e) {
+- e.printStackTrace();
+- }
+-
+- }
+- }
+- catch (IOException e) {
+- e.printStackTrace();
+- }
+- }
+- }).start();
+-
+- }
+- catch (SocketException e) {
+- e.printStackTrace();
+- }
+- this.setSize(width, height);
+- }
+-
+- public InetAddress getLocalHost() {
+- return localHost;
+- }
+-
+- public InetAddress getRemoteHost() {
+- return remoteHost;
+- }
+-
+- public int getLocalPort() {
+- return localPort;
+- }
+-
+- public int getRemotePort() {
+- return remotePort;
+- }
+-
+- public DatagramSocket getDatagramSocket() {
+- return socket;
+- }
+-
+- public void drawTile(int x, int y, BufferedImage bufferedImage) {
+- tiles[x][y] = bufferedImage;
+- //repaint(x * tileWidth, y * tileWidth, tileWidth, tileWidth);
+- this.getGraphics().drawImage(bufferedImage, tileWidth * x, tileWidth * y, this);
+- }
+-
+- public void paint(Graphics g) {
+- for (int i = 0; i < tiles.length; i++) {
+- for (int j = 0; j < tiles[0].length; j++) {
+- g.drawImage(tiles[i][j], tileWidth * i, tileWidth * j, this);
+- }
+- }
+- }
+-
+- public ImageDecoder getDecoder() {
+- return decoder;
+- }
+-
+- public void setDecoder(ImageDecoder decoder) {
+- this.decoder = decoder;
+- }
+-
+- public void stop(){
+- this.on=false;
+- socket.close();
+- }
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/WholeImageFilter.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/WholeImageFilter.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/WholeImageFilter.java (working copy)
+@@ -1,86 +0,0 @@
+-/*
+-Copyright 2006 Jerry Huxtable
+-
+-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.
+-*/
+-
+-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
+-
+-import java.awt.*;
+-import java.awt.image.BufferedImage;
+-import java.awt.image.ColorModel;
+-import java.awt.image.WritableRaster;
+-
+-/**
+- * A filter which acts as a superclass for filters which need to have the whole image in memory
+- * to do their stuff.
+- */
+-public abstract class WholeImageFilter extends AbstractBufferedImageOp {
+-
+- /**
+- * The output image bounds.
+- */
+- protected Rectangle transformedSpace;
+-
+- /**
+- * The input image bounds.
+- */
+- protected Rectangle originalSpace;
+-
+- /**
+- * Construct a WholeImageFilter.
+- */
+- public WholeImageFilter() {
+- }
+-
+- public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
+- int width = src.getWidth();
+- int height = src.getHeight();
+- int type = src.getType();
+- WritableRaster srcRaster = src.getRaster();
+-
+- originalSpace = new Rectangle(0, 0, width, height);
+- transformedSpace = new Rectangle(0, 0, width, height);
+- transformSpace(transformedSpace);
+-
+- if ( dst == null ) {
+- ColorModel dstCM = src.getColorModel();
+- dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(transformedSpace.width, transformedSpace.height), dstCM.isAlphaPremultiplied(), null);
+- }
+- WritableRaster dstRaster = dst.getRaster();
+-
+- int[] inPixels = getRGB( src, 0, 0, width, height, null );
+- inPixels = filterPixels( width, height, inPixels, transformedSpace );
+- setRGB( dst, 0, 0, transformedSpace.width, transformedSpace.height, inPixels );
+-
+- return dst;
+- }
+-
+- /**
+- * Calculate output bounds for given input bounds.
+- * @param rect input and output rectangle
+- */
+- protected void transformSpace(Rectangle rect) {
+- }
+-
+- /**
+- * Actually filter the pixels.
+- * @param width the image width
+- * @param height the image height
+- * @param inPixels the image pixels
+- * @param transformedSpace the output bounds
+- * @return the output pixels
+- */
+- protected abstract int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace );
+-}
+-
+Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/AbstractBufferedImageOp.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/AbstractBufferedImageOp.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/AbstractBufferedImageOp.java (working copy)
+@@ -1,98 +0,0 @@
+-/*
+-Copyright 2006 Jerry Huxtable
+-
+-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.
+-*/
+-
+-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
+-
+-import java.awt.*;
+-import java.awt.geom.Point2D;
+-import java.awt.geom.Rectangle2D;
+-import java.awt.image.BufferedImage;
+-import java.awt.image.BufferedImageOp;
+-import java.awt.image.ColorModel;
+-
+-/**
+- * A convenience class which implements those methods of BufferedImageOp which are rarely changed.
+- */
+-public abstract class AbstractBufferedImageOp implements BufferedImageOp, Cloneable {
+-
+- public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
+- if ( dstCM == null )
+- dstCM = src.getColorModel();
+- return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dstCM.isAlphaPremultiplied(), null);
+- }
+-
+- public Rectangle2D getBounds2D( BufferedImage src ) {
+- return new Rectangle(0, 0, src.getWidth(), src.getHeight());
+- }
+-
+- public Point2D getPoint2D( Point2D srcPt, Point2D dstPt ) {
+- if ( dstPt == null )
+- dstPt = new Point2D.Double();
+- dstPt.setLocation( srcPt.getX(), srcPt.getY() );
+- return dstPt;
+- }
+-
+- public RenderingHints getRenderingHints() {
+- return null;
+- }
+-
+- /**
+- * A convenience method for getting ARGB pixels from an image. This tries to avoid the performance
+- * penalty of BufferedImage.getRGB unmanaging the image.
+- * @param image a BufferedImage object
+- * @param x the left edge of the pixel block
+- * @param y the right edge of the pixel block
+- * @param width the width of the pixel arry
+- * @param height the height of the pixel arry
+- * @param pixels the array to hold the returned pixels. May be null.
+- * @return the pixels
+- * @see #setRGB
+- */
+- public int[] getRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
+- int type = image.getType();
+- if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
+- return (int [])image.getRaster().getDataElements( x, y, width, height, pixels );
+- return image.getRGB( x, y, width, height, pixels, 0, width );
+- }
+-
+- /**
+- * A convenience method for setting ARGB pixels in an image. This tries to avoid the performance
+- * penalty of BufferedImage.setRGB unmanaging the image.
+- * @param image a BufferedImage object
+- * @param x the left edge of the pixel block
+- * @param y the right edge of the pixel block
+- * @param width the width of the pixel arry
+- * @param height the height of the pixel arry
+- * @param pixels the array of pixels to set
+- * @see #getRGB
+- */
+- public void setRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
+- int type = image.getType();
+- if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
+- image.getRaster().setDataElements( x, y, width, height, pixels );
+- else
+- image.setRGB( x, y, width, height, pixels, 0, width );
+- }
+-
+- public Object clone() {
+- try {
+- return super.clone();
+- }
+- catch ( CloneNotSupportedException e ) {
+- return null;
+- }
+- }
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageDecoder.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageDecoder.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageDecoder.java (working copy)
+@@ -1,15 +0,0 @@
+-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
+-
+-import java.awt.image.BufferedImage;
+-import java.io.ByteArrayInputStream;
+-import java.io.IOException;
+-
+-/**
+- * Image Decoder Interface use this interface if you want to change the default decoder
+- *
+- * @author Thiago Rocha Camargo
+- */
+-public interface ImageDecoder {
+-
+- public BufferedImage decode(ByteArrayInputStream stream) throws IOException;
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/OctTreeQuantizer.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/OctTreeQuantizer.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/OctTreeQuantizer.java (working copy)
+@@ -1,287 +0,0 @@
+-/*
+-Copyright 2006 Jerry Huxtable
+-
+-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.
+-*/
+-
+-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
+-
+-import java.io.PrintStream;
+-import java.util.Vector;
+-
+-import org.jivesoftware.smackx.jingle.SmackLogger;
+-
+-/**
+- * An image Quantizer based on the Octree algorithm. This is a very basic implementation
+- * at present and could be much improved by picking the nodes to reduce more carefully
+- * (i.e. not completely at random) when I get the time.
+- */
+-public class OctTreeQuantizer implements Quantizer {
+-
+- private static final SmackLogger LOGGER = SmackLogger.getLogger(OctTreeQuantizer.class);
+-
+- /**
+- * The greatest depth the tree is allowed to reach
+- */
+- final static int MAX_LEVEL = 5;
+-
+- /**
+- * An Octtree node.
+- */
+- class OctTreeNode {
+- int children;
+- int level;
+- OctTreeNode parent;
+- OctTreeNode leaf[] = new OctTreeNode[8];
+- boolean isLeaf;
+- int count;
+- int totalRed;
+- int totalGreen;
+- int totalBlue;
+- int index;
+-
+- /**
+- * A debugging method which prints the tree out.
+- */
+- public void list(PrintStream s, int level) {
+- String indentStr = "";
+- for (int i = 0; i < level; i++)
+- indentStr += " ";
+- if (count == 0)
+- LOGGER.debug(indentStr + index + ": count=" + count);
+- else
+- LOGGER.debug(indentStr + index + ": count=" + count + " red=" + (totalRed/count) + " green=" + (totalGreen / count) + " blue=" + (totalBlue / count));
+- for (int i = 0; i < 8; i++)
+- if (leaf[i] != null)
+- leaf[i].list(s, level+2);
+- }
+- }
+-
+- private int nodes = 0;
+- private OctTreeNode root;
+- private int reduceColors;
+- private int maximumColors;
+- private int colors = 0;
+- private Vector[] colorList;
+-
+- public OctTreeQuantizer() {
+- setup(256);
+- colorList = new Vector[MAX_LEVEL+1];
+- for (int i = 0; i < MAX_LEVEL+1; i++)
+- colorList[i] = new Vector();
+- root = new OctTreeNode();
+- }
+-
+- /**
+- * Initialize the quantizer. This should be called before adding any pixels.
+- * @param numColors the number of colors we're quantizing to.
+- */
+- public void setup(int numColors) {
+- maximumColors = numColors;
+- reduceColors = Math.max(512, numColors * 2);
+- }
+-
+- /**
+- * Add pixels to the quantizer.
+- * @param pixels the array of ARGB pixels
+- * @param offset the offset into the array
+- * @param count the count of pixels
+- */
+- public void addPixels(int[] pixels, int offset, int count) {
+- for (int i = 0; i < count; i++) {
+- insertColor(pixels[i+offset]);
+- if (colors > reduceColors)
+- reduceTree(reduceColors);
+- }
+- }
+-
+- /**
+- * Get the color table index for a color.
+- * @param rgb the color
+- * @return the index
+- */
+- public int getIndexForColor(int rgb) {
+- int red = (rgb >> 16) & 0xff;
+- int green = (rgb >> 8) & 0xff;
+- int blue = rgb & 0xff;
+-
+- OctTreeNode node = root;
+-
+- for (int level = 0; level <= MAX_LEVEL; level++) {
+- OctTreeNode child;
+- int bit = 0x80 >> level;
+-
+- int index = 0;
+- if ((red & bit) != 0)
+- index += 4;
+- if ((green & bit) != 0)
+- index += 2;
+- if ((blue & bit) != 0)
+- index += 1;
+-
+- child = node.leaf[index];
+-
+- if (child == null)
+- return node.index;
+- else if (child.isLeaf)
+- return child.index;
+- else
+- node = child;
+- }
+- LOGGER.debug("getIndexForColor failed");
+- return 0;
+- }
+-
+- private void insertColor(int rgb) {
+- int red = (rgb >> 16) & 0xff;
+- int green = (rgb >> 8) & 0xff;
+- int blue = rgb & 0xff;
+-
+- OctTreeNode node = root;
+-
+-// LOGGER.debug("insertColor="+Integer.toHexString(rgb));
+- for (int level = 0; level <= MAX_LEVEL; level++) {
+- OctTreeNode child;
+- int bit = 0x80 >> level;
+-
+- int index = 0;
+- if ((red & bit) != 0)
+- index += 4;
+- if ((green & bit) != 0)
+- index += 2;
+- if ((blue & bit) != 0)
+- index += 1;
+-
+- child = node.leaf[index];
+-
+- if (child == null) {
+- node.children++;
+-
+- child = new OctTreeNode();
+- child.parent = node;
+- node.leaf[index] = child;
+- node.isLeaf = false;
+- nodes++;
+- colorList[level].addElement(child);
+-
+- if (level == MAX_LEVEL) {
+- child.isLeaf = true;
+- child.count = 1;
+- child.totalRed = red;
+- child.totalGreen = green;
+- child.totalBlue = blue;
+- child.level = level;
+- colors++;
+- return;
+- }
+-
+- node = child;
+- } else if (child.isLeaf) {
+- child.count++;
+- child.totalRed += red;
+- child.totalGreen += green;
+- child.totalBlue += blue;
+- return;
+- } else
+- node = child;
+- }
+- LOGGER.debug("insertColor failed");
+- }
+-
+- private void reduceTree(int numColors) {
+- for (int level = MAX_LEVEL-1; level >= 0; level--) {
+- Vector v = colorList[level];
+- if (v != null && v.size() > 0) {
+- for (int j = 0; j < v.size(); j++) {
+- OctTreeNode node = (OctTreeNode)v.elementAt(j);
+- if (node.children > 0) {
+- for (int i = 0; i < 8; i++) {
+- OctTreeNode child = node.leaf[i];
+- if (child != null) {
+- if (!child.isLeaf)
+- LOGGER.debug("not a leaf!");
+- node.count += child.count;
+- node.totalRed += child.totalRed;
+- node.totalGreen += child.totalGreen;
+- node.totalBlue += child.totalBlue;
+- node.leaf[i] = null;
+- node.children--;
+- colors--;
+- nodes--;
+- colorList[level+1].removeElement(child);
+- }
+- }
+- node.isLeaf = true;
+- colors++;
+- if (colors <= numColors)
+- return;
+- }
+- }
+- }
+- }
+-
+- LOGGER.debug("Unable to reduce the OctTree");
+- }
+-
+- /**
+- * Build the color table.
+- * @return the color table
+- */
+- public int[] buildColorTable() {
+- int[] table = new int[colors];
+- buildColorTable(root, table, 0);
+- return table;
+- }
+-
+- /**
+- * A quick way to use the quantizer. Just create a table the right size and pass in the pixels.
+- * @param inPixels the input colors
+- * @param table the output color table
+- */
+- public void buildColorTable(int[] inPixels, int[] table) {
+- int count = inPixels.length;
+- maximumColors = table.length;
+- for (int i = 0; i < count; i++) {
+- insertColor(inPixels[i]);
+- if (colors > reduceColors)
+- reduceTree(reduceColors);
+- }
+- if (colors > maximumColors)
+- reduceTree(maximumColors);
+- buildColorTable(root, table, 0);
+- }
+-
+- private int buildColorTable(OctTreeNode node, int[] table, int index) {
+- if (colors > maximumColors)
+- reduceTree(maximumColors);
+-
+- if (node.isLeaf) {
+- int count = node.count;
+- table[index] = 0xff000000 |
+- ((node.totalRed/count) << 16) |
+- ((node.totalGreen/count) << 8) |
+- node.totalBlue/count;
+- node.index = index++;
+- } else {
+- for (int i = 0; i < 8; i++) {
+- if (node.leaf[i] != null) {
+- node.index = index;
+- index = buildColorTable(node.leaf[i], table, index);
+- }
+- }
+- }
+- return index;
+- }
+-
+-}
+-
+Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultDecoder.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultDecoder.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultDecoder.java (working copy)
+@@ -1,16 +0,0 @@
+-package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
+-
+-import javax.imageio.ImageIO;
+-import java.awt.image.BufferedImage;
+-import java.io.ByteArrayInputStream;
+-import java.io.IOException;
+-
+-/**
+- * Implements a default PNG decoder.
+- */
+-public class DefaultDecoder implements ImageDecoder {
+-
+- public BufferedImage decode(ByteArrayInputStream stream) throws IOException {
+- return ImageIO.read(stream);
+- }
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java (working copy)
+@@ -1,115 +0,0 @@
+-/**
+- * $RCSfile: ScreenShareMediaManager.java,v $
+- * $Revision: 1.3 $
+- * $Date: 25/12/2006
+- * <p/>
+- * Copyright 2003-2006 Jive Software.
+- * <p/>
+- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+- * you may not use this file except in compliance with the License.
+- * You may obtain a copy of the License at
+- * <p/>
+- * http://www.apache.org/licenses/LICENSE-2.0
+- * <p/>
+- * 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.
+- */
+-
+-package org.jivesoftware.smackx.jingle.mediaimpl.sshare;
+-
+-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.mediaimpl.sshare.api.ImageDecoder;
+-import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageEncoder;
+-import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
+-import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
+-
+-import java.util.ArrayList;
+-import java.util.List;
+-
+-/**
+- * Implements a JingleMediaManager for ScreenSharing.
+- * It currently uses an Audio payload Type. Which needs to be fixed in the next version.
+- *
+- * @author Thiago Camargo
+- */
+-
+-public class ScreenShareMediaManager extends JingleMediaManager {
+-
+- public static final String MEDIA_NAME = "ScreenShare";
+-
+- private List<PayloadType> payloads = new ArrayList<PayloadType>();
+-
+- private ImageDecoder decoder = null;
+- private ImageEncoder encoder = null;
+-
+- public ScreenShareMediaManager(JingleTransportManager transportManager) {
+- super(transportManager);
+- setupPayloads();
+- }
+-
+- /**
+- * Setup API supported Payloads
+- */
+- private void setupPayloads() {
+- payloads.add(new PayloadType.Audio(30, "sshare"));
+- }
+-
+- /**
+- * Return all supported Payloads for this Manager.
+- *
+- * @return The Payload List
+- */
+- public List<PayloadType> getPayloads() {
+- return payloads;
+- }
+-
+- /**
+- * Returns a new JingleMediaSession
+- *
+- * @param payloadType payloadType
+- * @param remote remote Candidate
+- * @param local local Candidate
+- * @return JingleMediaSession JingleMediaSession
+- */
+- public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) {
+- ScreenShareSession session = null;
+- session = new ScreenShareSession(payloadType, remote, local, "Screen", jingleSession);
+- if (encoder != null) {
+- session.setEncoder(encoder);
+- }
+- if (decoder != null) {
+- session.setDecoder(decoder);
+- }
+- return session;
+- }
+-
+- public PayloadType getPreferredPayloadType() {
+- return super.getPreferredPayloadType();
+- }
+-
+- public ImageDecoder getDecoder() {
+- return decoder;
+- }
+-
+- public void setDecoder(ImageDecoder decoder) {
+- this.decoder = decoder;
+- }
+-
+- public ImageEncoder getEncoder() {
+- return encoder;
+- }
+-
+- public void setEncoder(ImageEncoder encoder) {
+- this.encoder = encoder;
+- }
+-
+- public String getName() {
+- return MEDIA_NAME;
+- }
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java (working copy)
+@@ -1,106 +0,0 @@
+-/**
+- * $RCSfile: MultiMediaManager.java,v $
+- * $Revision: 1.3 $
+- * $Date: 25/12/2006
+- * <p/>
+- * Copyright 2003-2006 Jive Software.
+- * <p/>
+- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+- * you may not use this file except in compliance with the License.
+- * You may obtain a copy of the License at
+- * <p/>
+- * http://www.apache.org/licenses/LICENSE-2.0
+- * <p/>
+- * 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.
+- */
+-
+-package org.jivesoftware.smackx.jingle.mediaimpl.multi;
+-
+-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 java.util.ArrayList;
+-import java.util.List;
+-
+-/**
+- * Implements a MultiMediaManager using other JingleMediaManager implementations.
+- * It supports every Codecs that JingleMediaManagers added has.
+- *
+- * @author Thiago Camargo
+- */
+-
+-public class MultiMediaManager extends JingleMediaManager {
+-
+- public static final String MEDIA_NAME = "Multi";
+-
+- private List<JingleMediaManager> managers = new ArrayList<JingleMediaManager>();
+-
+- private PayloadType preferredPayloadType = null;
+-
+- public MultiMediaManager(JingleTransportManager transportManager) {
+- super(transportManager);
+- }
+-
+- public void addMediaManager(JingleMediaManager manager) {
+- managers.add(manager);
+- }
+-
+- public void removeMediaManager(JingleMediaManager manager) {
+- managers.remove(manager);
+- }
+-
+- /**
+- * Return all supported Payloads for this Manager.
+- *
+- * @return The Payload List
+- */
+- public List<PayloadType> getPayloads() {
+- List<PayloadType> list = new ArrayList<PayloadType>();
+- if (preferredPayloadType != null) list.add(preferredPayloadType);
+- for (JingleMediaManager manager : managers) {
+- for (PayloadType payloadType : manager.getPayloads()) {
+- if (!list.contains(payloadType) && !payloadType.equals(preferredPayloadType))
+- list.add(payloadType);
+- }
+- }
+- return list;
+- }
+-
+- /**
+- * Returns a new JingleMediaSession
+- *
+- * @param payloadType payloadType
+- * @param remote remote Candidate
+- * @param local local Candidate
+- * @return JingleMediaSession JingleMediaSession
+- */
+- public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) {
+- for (JingleMediaManager manager : managers) {
+- if (manager.getPayloads().contains(payloadType)) {
+- return manager.createMediaSession(payloadType, remote, local, jingleSession);
+- }
+- }
+- return null;
+- }
+-
+- public PayloadType getPreferredPayloadType() {
+- if (preferredPayloadType != null) return preferredPayloadType;
+- return super.getPreferredPayloadType();
+- }
+-
+- public void setPreferredPayloadType(PayloadType preferredPayloadType) {
+- this.preferredPayloadType = preferredPayloadType;
+- }
+-
+- public String getName() {
+- return MEDIA_NAME;
+- }
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java (working copy)
+@@ -1,165 +0,0 @@
+-/**
+- * $RCSfile: AudioMediaSession.java,v $
+- * $Revision: 1.1 $
+- * $Date: 08/11/2006
+- * <p/>
+- * Copyright 2003-2006 Jive Software.
+- * <p/>
+- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+- * you may not use this file except in compliance with the License.
+- * You may obtain a copy of the License at
+- * <p/>
+- * http://www.apache.org/licenses/LICENSE-2.0
+- * <p/>
+- * 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.
+- */
+-
+-package org.jivesoftware.smackx.jingle.mediaimpl.jmf;
+-
+-import java.io.IOException;
+-import java.net.ServerSocket;
+-
+-import javax.media.MediaLocator;
+-
+-import org.jivesoftware.smackx.jingle.JingleSession;
+-import org.jivesoftware.smackx.jingle.SmackLogger;
+-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
+-import org.jivesoftware.smackx.jingle.media.PayloadType;
+-import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
+-
+-/**
+- * This Class implements a complete JingleMediaSession.
+- * It sould be used to transmit and receive audio captured from the Mic.
+- * This Class should be automaticly controlled by JingleSession.
+- * But you could also use in any VOIP application.
+- * For better NAT Traversal support this implementation don't support only receive or only transmit.
+- * To receive you MUST transmit. So the only implemented and functionally methods are startTransmit() and stopTransmit()
+- *
+- * @author Thiago Camargo
+- */
+-public class AudioMediaSession extends JingleMediaSession {
+-
+- private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioMediaSession.class);
+-
+- private AudioChannel audioChannel;
+-
+- /**
+- * Creates a org.jivesoftware.jingleaudio.jmf.AudioMediaSession with defined payload type, remote and local candidates
+- *
+- * @param payloadType Payload of the jmf
+- * @param remote the remote information. The candidate that the jmf will be sent to.
+- * @param local the local information. The candidate that will receive the jmf
+- * @param locator media locator
+- */
+- public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote,
+- final TransportCandidate local, String locator, JingleSession jingleSession) {
+- super(payloadType, remote, local, locator==null?"dsound://":locator,jingleSession);
+- initialize();
+- }
+-
+- /**
+- * Initialize the Audio Channel to make it able to send and receive audio
+- */
+- public void initialize() {
+-
+- String ip;
+- String localIp;
+- int localPort;
+- int remotePort;
+-
+- if (this.getLocal().getSymmetric() != null) {
+- ip = this.getLocal().getIp();
+- localIp = this.getLocal().getLocalIp();
+- localPort = getFreePort();
+- remotePort = this.getLocal().getSymmetric().getPort();
+-
+- LOGGER.debug(this.getLocal().getConnection() + " " + ip + ": " + localPort + "->" + remotePort);
+-
+- }
+- else {
+- ip = this.getRemote().getIp();
+- localIp = this.getLocal().getLocalIp();
+- localPort = this.getLocal().getPort();
+- remotePort = this.getRemote().getPort();
+- }
+-
+- audioChannel = new AudioChannel(new MediaLocator(this.getMediaLocator()), localIp, ip, localPort, remotePort, AudioFormatUtils.getAudioFormat(this.getPayloadType()),this);
+- }
+-
+- /**
+- * Starts transmission and for NAT Traversal reasons start receiving also.
+- */
+- public void startTrasmit() {
+- audioChannel.start();
+- }
+-
+- /**
+- * Set transmit activity. If the active is true, the instance should trasmit.
+- * If it is set to false, the instance should pause transmit.
+- *
+- * @param active active state
+- */
+- public void setTrasmit(boolean active) {
+- audioChannel.setTrasmit(active);
+- }
+-
+- /**
+- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
+- */
+- public void startReceive() {
+- // Do nothing
+- }
+-
+- /**
+- * Stops transmission and for NAT Traversal reasons stop receiving also.
+- */
+- public void stopTrasmit() {
+- if (audioChannel != null)
+- audioChannel.stop();
+- }
+-
+- /**
+- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
+- */
+- public void stopReceive() {
+- // Do nothing
+- }
+-
+- /**
+- * Obtain a free port we can use.
+- *
+- * @return A free port number.
+- */
+- protected int getFreePort() {
+- ServerSocket ss;
+- int freePort = 0;
+-
+- for (int i = 0; i < 10; i++) {
+- freePort = (int) (10000 + Math.round(Math.random() * 10000));
+- freePort = freePort % 2 == 0 ? freePort : freePort + 1;
+- try {
+- ss = new ServerSocket(freePort);
+- freePort = ss.getLocalPort();
+- ss.close();
+- return freePort;
+- }
+- catch (IOException e) {
+- e.printStackTrace();
+- }
+- }
+- try {
+- ss = new ServerSocket(0);
+- freePort = ss.getLocalPort();
+- ss.close();
+- }
+- catch (IOException e) {
+- e.printStackTrace();
+- }
+- return freePort;
+- }
+-
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java (working copy)
+@@ -1,171 +0,0 @@
+-/**
+- * $RCSfile: AudioReceiver.java,v $
+- * $Revision: 1.1 $
+- * $Date: 08/11/2006
+- * <p/>
+- * Copyright 2003-2006 Jive Software.
+- * <p/>
+- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+- * you may not use this file except in compliance with the License.
+- * You may obtain a copy of the License at
+- * <p/>
+- * http://www.apache.org/licenses/LICENSE-2.0
+- * <p/>
+- * 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.
+- */
+-
+-package org.jivesoftware.smackx.jingle.mediaimpl.jmf;
+-
+-import javax.media.ControllerErrorEvent;
+-import javax.media.ControllerEvent;
+-import javax.media.ControllerListener;
+-import javax.media.Player;
+-import javax.media.RealizeCompleteEvent;
+-import javax.media.protocol.DataSource;
+-import javax.media.rtp.Participant;
+-import javax.media.rtp.RTPControl;
+-import javax.media.rtp.ReceiveStream;
+-import javax.media.rtp.ReceiveStreamListener;
+-import javax.media.rtp.SessionListener;
+-import javax.media.rtp.event.ByeEvent;
+-import javax.media.rtp.event.NewParticipantEvent;
+-import javax.media.rtp.event.NewReceiveStreamEvent;
+-import javax.media.rtp.event.ReceiveStreamEvent;
+-import javax.media.rtp.event.RemotePayloadChangeEvent;
+-import javax.media.rtp.event.SessionEvent;
+-import javax.media.rtp.event.StreamMappedEvent;
+-
+-import org.jivesoftware.smackx.jingle.SmackLogger;
+-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
+-
+-/**
+- * This class implements receive methods and listeners to be used in AudioChannel
+- *
+- * @author Thiago Camargo
+- */
+-public class AudioReceiver implements ReceiveStreamListener, SessionListener,
+- ControllerListener {
+-
+- private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioReceiver.class);
+-
+- boolean dataReceived = false;
+-
+- Object dataSync;
+- JingleMediaSession jingleMediaSession;
+-
+- public AudioReceiver(final Object dataSync, final JingleMediaSession jingleMediaSession) {
+- this.dataSync = dataSync;
+- this.jingleMediaSession = jingleMediaSession;
+- }
+-
+- /**
+- * JingleSessionListener.
+- */
+- public synchronized void update(SessionEvent evt) {
+- if (evt instanceof NewParticipantEvent) {
+- Participant p = ((NewParticipantEvent) evt).getParticipant();
+- LOGGER.error(" - A new participant had just joined: " + p.getCNAME());
+- }
+- }
+-
+- /**
+- * ReceiveStreamListener
+- */
+- public synchronized void update(ReceiveStreamEvent evt) {
+-
+- Participant participant = evt.getParticipant(); // could be null.
+- ReceiveStream stream = evt.getReceiveStream(); // could be null.
+-
+- if (evt instanceof RemotePayloadChangeEvent) {
+- LOGGER.error(" - Received an RTP PayloadChangeEvent.");
+- LOGGER.error("Sorry, cannot handle payload change.");
+-
+- }
+- else if (evt instanceof NewReceiveStreamEvent) {
+-
+- try {
+- stream = evt.getReceiveStream();
+- DataSource ds = stream.getDataSource();
+-
+- // Find out the formats.
+- RTPControl ctl = (RTPControl) ds.getControl("javax.jmf.rtp.RTPControl");
+- if (ctl != null) {
+- LOGGER.error(" - Recevied new RTP stream: " + ctl.getFormat());
+- }
+- else
+- LOGGER.error(" - Recevied new RTP stream");
+-
+- if (participant == null)
+- LOGGER.error(" The sender of this stream had yet to be identified.");
+- else {
+- LOGGER.error(" The stream comes from: " + participant.getCNAME());
+- }
+-
+- // create a player by passing datasource to the Media Manager
+- Player p = javax.media.Manager.createPlayer(ds);
+- if (p == null)
+- return;
+-
+- p.addControllerListener(this);
+- p.realize();
+- jingleMediaSession.mediaReceived(participant != null ? participant.getCNAME() : "");
+-
+- // Notify intialize() that a new stream had arrived.
+- synchronized (dataSync) {
+- dataReceived = true;
+- dataSync.notifyAll();
+- }
+-
+- }
+- catch (Exception e) {
+- LOGGER.error("NewReceiveStreamEvent exception " + e.getMessage());
+- return;
+- }
+-
+- }
+- else if (evt instanceof StreamMappedEvent) {
+-
+- if (stream != null && stream.getDataSource() != null) {
+- DataSource ds = stream.getDataSource();
+- // Find out the formats.
+- RTPControl ctl = (RTPControl) ds.getControl("javax.jmf.rtp.RTPControl");
+- LOGGER.error(" - The previously unidentified stream ");
+- if (ctl != null)
+- LOGGER.error(" " + ctl.getFormat());
+- LOGGER.error(" had now been identified as sent by: " + participant.getCNAME());
+- }
+- }
+- else if (evt instanceof ByeEvent) {
+-
+- LOGGER.error(" - Got \"bye\" from: " + participant.getCNAME());
+-
+- }
+-
+- }
+-
+- /**
+- * ControllerListener for the Players.
+- */
+- public synchronized void controllerUpdate(ControllerEvent ce) {
+-
+- Player p = (Player) ce.getSourceController();
+-
+- if (p == null)
+- return;
+-
+- // Get this when the internal players are realized.
+- if (ce instanceof RealizeCompleteEvent) {
+- p.start();
+- }
+-
+- if (ce instanceof ControllerErrorEvent) {
+- p.removeControllerListener(this);
+- LOGGER.error("Receiver internal error: " + ce);
+- }
+-
+- }
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java (working copy)
+@@ -1,170 +0,0 @@
+-/**
+- * $RCSfile: JmfMediaManager.java,v $
+- * $Revision: 1.3 $
+- * $Date: 08/11/2006
+- * <p/>
+- * Copyright 2003-2006 Jive Software.
+- * <p/>
+- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+- * you may not use this file except in compliance with the License.
+- * You may obtain a copy of the License at
+- * <p/>
+- * http://www.apache.org/licenses/LICENSE-2.0
+- * <p/>
+- * 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.
+- */
+-
+-package org.jivesoftware.smackx.jingle.mediaimpl.jmf;
+-
+-import java.io.File;
+-import java.io.IOException;
+-import java.util.ArrayList;
+-import java.util.List;
+-
+-import org.jivesoftware.smackx.jingle.JingleSession;
+-import org.jivesoftware.smackx.jingle.SmackLogger;
+-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.mediaimpl.JMFInit;
+-import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
+-import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
+-
+-/**
+- * Implements a jingleMediaManager using JMF based API.
+- * It supports GSM and G723 codecs.
+- * <i>This API only currently works on windows and Mac.</i>
+- *
+- * @author Thiago Camargo
+- */
+-public class JmfMediaManager extends JingleMediaManager {
+-
+- private static final SmackLogger LOGGER = SmackLogger.getLogger(JmfMediaManager.class);
+-
+- public static final String MEDIA_NAME = "JMF";
+-
+-
+- private List<PayloadType> payloads = new ArrayList<PayloadType>();
+- private String mediaLocator = null;
+-
+- /**
+- * Creates a Media Manager instance
+- */
+- public JmfMediaManager(JingleTransportManager transportManager) {
+- super(transportManager);
+- setupPayloads();
+- }
+-
+- /**
+- * Creates a Media Manager instance
+- *
+- * @param mediaLocator Media Locator
+- */
+- public JmfMediaManager(String mediaLocator, JingleTransportManager transportManager) {
+- super(transportManager);
+- this.mediaLocator = mediaLocator;
+- setupPayloads();
+- }
+-
+- /**
+- * Returns a new jingleMediaSession
+- *
+- * @param payloadType payloadType
+- * @param remote remote Candidate
+- * @param local local Candidate
+- * @return JingleMediaSession
+- */
+- public JingleMediaSession createMediaSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) {
+- return new AudioMediaSession(payloadType, remote, local, mediaLocator, jingleSession);
+- }
+-
+- /**
+- * Setup API supported Payloads
+- */
+- private void setupPayloads() {
+- payloads.add(new PayloadType.Audio(3, "gsm"));
+- payloads.add(new PayloadType.Audio(4, "g723"));
+- payloads.add(new PayloadType.Audio(0, "PCMU", 16000));
+- }
+-
+- /**
+- * Return all supported Payloads for this Manager
+- *
+- * @return The Payload List
+- */
+- public List<PayloadType> getPayloads() {
+- return payloads;
+- }
+-
+- /**
+- * Return the media locator or null if not defined
+- *
+- * @return media locator
+- */
+- public String getMediaLocator() {
+- return mediaLocator;
+- }
+-
+- /**
+- * Set the media locator
+- *
+- * @param mediaLocator media locator or null to use default
+- */
+- public void setMediaLocator(String mediaLocator) {
+- this.mediaLocator = mediaLocator;
+- }
+-
+- /**
+- * Runs JMFInit the first time the application is started so that capture
+- * devices are properly detected and initialized by JMF.
+- */
+- public static void setupJMF() {
+- // .jmf is the place where we store the jmf.properties file used
+- // by JMF. if the directory does not exist or it does not contain
+- // a jmf.properties file. or if the jmf.properties file has 0 length
+- // then this is the first time we're running and should continue to
+- // with JMFInit
+- String homeDir = System.getProperty("user.home");
+- File jmfDir = new File(homeDir, ".jmf");
+- String classpath = System.getProperty("java.class.path");
+- classpath += System.getProperty("path.separator")
+- + jmfDir.getAbsolutePath();
+- System.setProperty("java.class.path", classpath);
+-
+- if (!jmfDir.exists())
+- jmfDir.mkdir();
+-
+- File jmfProperties = new File(jmfDir, "jmf.properties");
+-
+- if (!jmfProperties.exists()) {
+- try {
+- jmfProperties.createNewFile();
+- }
+- catch (IOException ex) {
+- LOGGER.debug("Failed to create jmf.properties");
+- ex.printStackTrace();
+- }
+- }
+-
+- // if we're running on linux checkout that libjmutil.so is where it
+- // should be and put it there.
+- runLinuxPreInstall();
+-
+- //if (jmfProperties.length() == 0) {
+- new JMFInit(null, false);
+- //}
+-
+- }
+-
+- private static void runLinuxPreInstall() {
+- // @TODO Implement Linux Pre-Install
+- }
+-
+- public String getName() {
+- return MEDIA_NAME;
+- }
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java (working copy)
+@@ -1,553 +0,0 @@
+-/**
+- * $RCSfile: AudioChannel.java,v $
+- * $Revision: 1.1 $
+- * $Date: 08/11/2006
+- * <p/>
+- * Copyright 2003-2006 Jive Software.
+- * <p/>
+- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+- * you may not use this file except in compliance with the License.
+- * You may obtain a copy of the License at
+- * <p/>
+- * http://www.apache.org/licenses/LICENSE-2.0
+- * <p/>
+- * 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.
+- */
+-package org.jivesoftware.smackx.jingle.mediaimpl.jmf;
+-
+-import java.io.IOException;
+-import java.net.InetAddress;
+-import java.net.UnknownHostException;
+-import java.util.ArrayList;
+-import java.util.List;
+-
+-import javax.media.Codec;
+-import javax.media.Controller;
+-import javax.media.ControllerClosedEvent;
+-import javax.media.ControllerEvent;
+-import javax.media.ControllerListener;
+-import javax.media.Format;
+-import javax.media.MediaLocator;
+-import javax.media.NoProcessorException;
+-import javax.media.Processor;
+-import javax.media.UnsupportedPlugInException;
+-import javax.media.control.BufferControl;
+-import javax.media.control.PacketSizeControl;
+-import javax.media.control.TrackControl;
+-import javax.media.format.AudioFormat;
+-import javax.media.protocol.ContentDescriptor;
+-import javax.media.protocol.DataSource;
+-import javax.media.protocol.PushBufferDataSource;
+-import javax.media.protocol.PushBufferStream;
+-import javax.media.rtp.InvalidSessionAddressException;
+-import javax.media.rtp.RTPManager;
+-import javax.media.rtp.SendStream;
+-import javax.media.rtp.SessionAddress;
+-
+-import org.jivesoftware.smackx.jingle.SmackLogger;
+-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
+-
+-/**
+- * An Easy to use Audio Channel implemented using JMF.
+- * It sends and receives jmf for and from desired IPs and ports.
+- * Also has a rport Symetric behavior for better NAT Traversal.
+- * It send data from a defined port and receive data in the same port, making NAT binds easier.
+- * <p/>
+- * Send from portA to portB and receive from portB in portA.
+- * <p/>
+- * Sending
+- * portA ---> portB
+- * <p/>
+- * Receiving
+- * portB ---> portA
+- * <p/>
+- * <i>Transmit and Receive are interdependents. To receive you MUST trasmit. </i>
+- *
+- * @author Thiago Camargo
+- */
+-public class AudioChannel {
+-
+- private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioChannel.class);
+-
+- private MediaLocator locator;
+- private String localIpAddress;
+- private String remoteIpAddress;
+- private int localPort;
+- private int portBase;
+- private Format format;
+-
+- private Processor processor = null;
+- private RTPManager rtpMgrs[];
+- private DataSource dataOutput = null;
+- private AudioReceiver audioReceiver;
+-
+- private List<SendStream> sendStreams = new ArrayList<SendStream>();
+-
+- private JingleMediaSession jingleMediaSession;
+-
+- private boolean started = false;
+-
+- /**
+- * Creates an Audio Channel for a desired jmf locator. For instance: new MediaLocator("dsound://")
+- *
+- * @param locator media locator
+- * @param localIpAddress local IP address
+- * @param remoteIpAddress remote IP address
+- * @param localPort local port number
+- * @param remotePort remote port number
+- * @param format audio format
+- */
+- public AudioChannel(MediaLocator locator,
+- String localIpAddress,
+- String remoteIpAddress,
+- int localPort,
+- int remotePort,
+- Format format, JingleMediaSession jingleMediaSession) {
+-
+- this.locator = locator;
+- this.localIpAddress = localIpAddress;
+- this.remoteIpAddress = remoteIpAddress;
+- this.localPort = localPort;
+- this.portBase = remotePort;
+- this.format = format;
+- this.jingleMediaSession = jingleMediaSession;
+- }
+-
+- /**
+- * Starts the transmission. Returns null if transmission started ok.
+- * Otherwise it returns a string with the reason why the setup failed.
+- * Starts receive also.
+- *
+- * @return result description
+- */
+- public synchronized String start() {
+- if (started) return null;
+-
+- // Create a processor for the specified jmf locator
+- String result = createProcessor();
+- if (result != null) {
+- started = false;
+- }
+-
+- // Create an RTP session to transmit the output of the
+- // processor to the specified IP address and port no.
+- result = createTransmitter();
+- if (result != null) {
+- processor.close();
+- processor = null;
+- started = false;
+- }
+- else {
+- started = true;
+- }
+-
+- // Start the transmission
+- processor.start();
+-
+- return null;
+- }
+-
+- /**
+- * Stops the transmission if already started.
+- * Stops the receiver also.
+- */
+- public void stop() {
+- if (!started) return;
+- synchronized (this) {
+- try {
+- started = false;
+- if (processor != null) {
+- processor.stop();
+- processor = null;
+-
+- for (RTPManager rtpMgr : rtpMgrs) {
+- rtpMgr.removeReceiveStreamListener(audioReceiver);
+- rtpMgr.removeSessionListener(audioReceiver);
+- rtpMgr.removeTargets("Session ended.");
+- rtpMgr.dispose();
+- }
+-
+- sendStreams.clear();
+-
+- }
+- }
+- catch (Exception e) {
+- e.printStackTrace();
+- }
+- }
+- }
+-
+- private String createProcessor() {
+- if (locator == null)
+- return "Locator is null";
+-
+- DataSource ds;
+-
+- try {
+- ds = javax.media.Manager.createDataSource(locator);
+- }
+- catch (Exception e) {
+- // Try JavaSound Locator as a last resort
+- try {
+- ds = javax.media.Manager.createDataSource(new MediaLocator("javasound://"));
+- }
+- catch (Exception ee) {
+- return "Couldn't create DataSource";
+- }
+- }
+-
+- // Try to create a processor to handle the input jmf locator
+- try {
+- processor = javax.media.Manager.createProcessor(ds);
+- }
+- catch (NoProcessorException npe) {
+- npe.printStackTrace();
+- return "Couldn't create processor";
+- }
+- catch (IOException ioe) {
+- ioe.printStackTrace();
+- return "IOException creating processor";
+- }
+-
+- // Wait for it to configure
+- boolean result = waitForState(processor, Processor.Configured);
+- if (!result){
+- return "Couldn't configure processor";
+- }
+-
+- // Get the tracks from the processor
+- TrackControl[] tracks = processor.getTrackControls();
+-
+- // Do we have atleast one track?
+- if (tracks == null || tracks.length < 1){
+- return "Couldn't find tracks in processor";
+- }
+-
+- // Set the output content descriptor to RAW_RTP
+- // This will limit the supported formats reported from
+- // Track.getSupportedFormats to only valid RTP formats.
+- ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW_RTP);
+- processor.setContentDescriptor(cd);
+-
+- Format supported[];
+- Format chosen = null;
+- boolean atLeastOneTrack = false;
+-
+- // Program the tracks.
+- for (int i = 0; i < tracks.length; i++) {
+- if (tracks[i].isEnabled()) {
+-
+- supported = tracks[i].getSupportedFormats();
+-
+- if (supported.length > 0) {
+- for (Format format : supported) {
+- if (format instanceof AudioFormat) {
+- if (this.format.matches(format))
+- chosen = format;
+- }
+- }
+- if (chosen != null) {
+- tracks[i].setFormat(chosen);
+- LOGGER.error("Track " + i + " is set to transmit as:");
+- LOGGER.error(" " + chosen);
+-
+- if (tracks[i].getFormat() instanceof AudioFormat) {
+- int packetRate = 20;
+- PacketSizeControl pktCtrl = (PacketSizeControl) processor.getControl(PacketSizeControl.class.getName());
+- if (pktCtrl != null) {
+- try {
+- pktCtrl.setPacketSize(getPacketSize(tracks[i].getFormat(), packetRate));
+- }
+- catch (IllegalArgumentException e) {
+- pktCtrl.setPacketSize(80);
+- // Do nothing
+- }
+- }
+-
+- if (tracks[i].getFormat().getEncoding().equals(AudioFormat.ULAW_RTP)) {
+- Codec codec[] = new Codec[3];
+-
+- codec[0] = new com.ibm.media.codec.audio.rc.RCModule();
+- codec[1] = new com.ibm.media.codec.audio.ulaw.JavaEncoder();
+- codec[2] = new com.sun.media.codec.audio.ulaw.Packetizer();
+- ((com.sun.media.codec.audio.ulaw.Packetizer) codec
+- [2]).setPacketSize(160);
+-
+- try {
+- tracks[i].setCodecChain(codec);
+- }
+- catch (UnsupportedPlugInException e) {
+- e.printStackTrace();
+- }
+- }
+-
+- }
+-
+- atLeastOneTrack = true;
+- }
+- else
+- tracks[i].setEnabled(false);
+- }
+- else
+- tracks[i].setEnabled(false);
+- }
+- }
+-
+- if (!atLeastOneTrack)
+- return "Couldn't set any of the tracks to a valid RTP format";
+-
+- result = waitForState(processor, Controller.Realized);
+- if (!result)
+- return "Couldn't realize processor";
+-
+- // Get the output data source of the processor
+- dataOutput = processor.getDataOutput();
+-
+- return null;
+- }
+-
+- /**
+- * Get the best packet size for a given codec and a codec rate
+- *
+- * @param codecFormat
+- * @param milliseconds
+- * @return
+- * @throws IllegalArgumentException
+- */
+- private int getPacketSize(Format codecFormat, int milliseconds) throws IllegalArgumentException {
+- String encoding = codecFormat.getEncoding();
+- if (encoding.equalsIgnoreCase(AudioFormat.GSM) ||
+- encoding.equalsIgnoreCase(AudioFormat.GSM_RTP)) {
+- return milliseconds * 4; // 1 byte per millisec
+- }
+- else if (encoding.equalsIgnoreCase(AudioFormat.ULAW) ||
+- encoding.equalsIgnoreCase(AudioFormat.ULAW_RTP)) {
+- return milliseconds * 8;
+- }
+- else {
+- throw new IllegalArgumentException("Unknown codec type");
+- }
+- }
+-
+- /**
+- * Use the RTPManager API to create sessions for each jmf
+- * track of the processor.
+- *
+- * @return description
+- */
+- private String createTransmitter() {
+-
+- // Cheated. Should have checked the type.
+- PushBufferDataSource pbds = (PushBufferDataSource) dataOutput;
+- PushBufferStream pbss[] = pbds.getStreams();
+-
+- rtpMgrs = new RTPManager[pbss.length];
+- SessionAddress localAddr, destAddr;
+- InetAddress ipAddr;
+- SendStream sendStream;
+- audioReceiver = new AudioReceiver(this, jingleMediaSession);
+- int port;
+-
+- for (int i = 0; i < pbss.length; i++) {
+- try {
+- rtpMgrs[i] = RTPManager.newInstance();
+-
+- port = portBase + 2 * i;
+- ipAddr = InetAddress.getByName(remoteIpAddress);
+-
+- localAddr = new SessionAddress(InetAddress.getByName(this.localIpAddress),
+- localPort);
+-
+- destAddr = new SessionAddress(ipAddr, port);
+-
+- rtpMgrs[i].addReceiveStreamListener(audioReceiver);
+- rtpMgrs[i].addSessionListener(audioReceiver);
+-
+- BufferControl bc = (BufferControl) rtpMgrs[i].getControl("javax.media.control.BufferControl");
+- if (bc != null) {
+- int bl = 160;
+- bc.setBufferLength(bl);
+- }
+-
+- try {
+-
+- rtpMgrs[i].initialize(localAddr);
+-
+- }
+- catch (InvalidSessionAddressException e) {
+- // In case the local address is not allowed to read, we user another local address
+- SessionAddress sessAddr = new SessionAddress();
+- localAddr = new SessionAddress(sessAddr.getDataAddress(),
+- localPort);
+- rtpMgrs[i].initialize(localAddr);
+- }
+-
+- rtpMgrs[i].addTarget(destAddr);
+-
+- LOGGER.error("Created RTP session at " + localPort + " to: " + remoteIpAddress + " " + port);
+-
+- sendStream = rtpMgrs[i].createSendStream(dataOutput, i);
+-
+- sendStreams.add(sendStream);
+-
+- sendStream.start();
+-
+- }
+- catch (Exception e) {
+- e.printStackTrace();
+- return e.getMessage();
+- }
+- }
+-
+- return null;
+- }
+-
+- /**
+- * Set transmit activity. If the active is true, the instance should trasmit.
+- * If it is set to false, the instance should pause transmit.
+- *
+- * @param active active state
+- */
+- public void setTrasmit(boolean active) {
+- for (SendStream sendStream : sendStreams) {
+- try {
+- if (active) {
+- sendStream.start();
+- LOGGER.debug("START");
+- }
+- else {
+- sendStream.stop();
+- LOGGER.debug("STOP");
+- }
+- }
+- catch (IOException e) {
+- e.printStackTrace();
+- }
+-
+- }
+- }
+-
+- /**
+- * *************************************************************
+- * Convenience methods to handle processor's state changes.
+- * **************************************************************
+- */
+-
+- private Integer stateLock = 0;
+- private boolean failed = false;
+-
+- Integer getStateLock() {
+- return stateLock;
+- }
+-
+- void setFailed() {
+- failed = true;
+- }
+-
+- private synchronized boolean waitForState(Processor p, int state) {
+- p.addControllerListener(new StateListener());
+- failed = false;
+-
+- // Call the required method on the processor
+- if (state == Processor.Configured) {
+- p.configure();
+- }
+- else if (state == Processor.Realized) {
+- p.realize();
+- }
+-
+- // Wait until we get an event that confirms the
+- // success of the method, or a failure event.
+- // See StateListener inner class
+- while (p.getState() < state && !failed) {
+- synchronized (getStateLock()) {
+- try {
+- getStateLock().wait();
+- }
+- catch (InterruptedException ie) {
+- return false;
+- }
+- }
+- }
+-
+- return !failed;
+- }
+-
+- /**
+- * *************************************************************
+- * Inner Classes
+- * **************************************************************
+- */
+-
+- class StateListener implements ControllerListener {
+-
+- public void controllerUpdate(ControllerEvent ce) {
+-
+- // If there was an error during configure or
+- // realize, the processor will be closed
+- if (ce instanceof ControllerClosedEvent)
+- setFailed();
+-
+- // All controller events, send a notification
+- // to the waiting thread in waitForState method.
+- if (ce != null) {
+- synchronized (getStateLock()) {
+- getStateLock().notifyAll();
+- }
+- }
+- }
+- }
+-
+- public static void main(String args[]) {
+-
+- InetAddress localhost;
+- try {
+- localhost = InetAddress.getLocalHost();
+-
+- AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://8000"), localhost.getHostAddress(), localhost.getHostAddress(), 7002, 7020, new AudioFormat(AudioFormat.GSM_RTP), null);
+- AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://8000"), localhost.getHostAddress(), localhost.getHostAddress(), 7020, 7002, new AudioFormat(AudioFormat.GSM_RTP), null);
+-
+- audioChannel0.start();
+- audioChannel1.start();
+-
+- try {
+- Thread.sleep(5000);
+- }
+- catch (InterruptedException e) {
+- e.printStackTrace();
+- }
+-
+- audioChannel0.setTrasmit(false);
+- audioChannel1.setTrasmit(false);
+-
+- try {
+- Thread.sleep(5000);
+- }
+- catch (InterruptedException e) {
+- e.printStackTrace();
+- }
+-
+- audioChannel0.setTrasmit(true);
+- audioChannel1.setTrasmit(true);
+-
+- try {
+- Thread.sleep(5000);
+- }
+- catch (InterruptedException e) {
+- e.printStackTrace();
+- }
+-
+- audioChannel0.stop();
+- audioChannel1.stop();
+-
+- }
+- catch (UnknownHostException e) {
+- e.printStackTrace();
+- }
+-
+- }
+-}
+\ No newline at end of file
+Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java (working copy)
+@@ -1,55 +0,0 @@
+-/**
+- * $RCSfile: AudioFormatUtils.java,v $
+- * $Revision: 1.1 $
+- * $Date: 08/11/2006
+- * <p/>
+- * Copyright 2003-2006 Jive Software.
+- * <p/>
+- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+- * you may not use this file except in compliance with the License.
+- * You may obtain a copy of the License at
+- * <p/>
+- * http://www.apache.org/licenses/LICENSE-2.0
+- * <p/>
+- * 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.
+- */
+-package org.jivesoftware.smackx.jingle.mediaimpl.jmf;
+-
+-import org.jivesoftware.smackx.jingle.media.PayloadType;
+-
+-import javax.media.format.AudioFormat;
+-
+-/**
+- * Audio Format Utils.
+- *
+- * @author Thiago Camargo
+- */
+-public class AudioFormatUtils {
+-
+- /**
+- * Return a JMF AudioFormat for a given Jingle Payload type.
+- * Return null if the payload is not supported by this jmf API.
+- *
+- * @param payloadtype payloadtype
+- * @return correspondent audioType
+- */
+- public static AudioFormat getAudioFormat(PayloadType payloadtype) {
+-
+- switch (payloadtype.getId()) {
+- case 0:
+- return new AudioFormat(AudioFormat.ULAW_RTP);
+- case 3:
+- return new AudioFormat(AudioFormat.GSM_RTP);
+- case 4:
+- return new AudioFormat(AudioFormat.G723_RTP);
+- default:
+- return null;
+- }
+-
+- }
+-
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java (working copy)
+@@ -1,134 +0,0 @@
+-/**
+- * $RCSfile: SpeexMediaManager.java,v $
+- * $Revision: 1.3 $
+- * $Date: 25/12/2006
+- * <p/>
+- * Copyright 2003-2006 Jive Software.
+- * <p/>
+- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+- * you may not use this file except in compliance with the License.
+- * You may obtain a copy of the License at
+- * <p/>
+- * http://www.apache.org/licenses/LICENSE-2.0
+- * <p/>
+- * 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.
+- */
+-package org.jivesoftware.smackx.jingle.mediaimpl.jspeex;
+-
+-import java.io.File;
+-import java.io.IOException;
+-import java.util.ArrayList;
+-import java.util.List;
+-
+-import org.jivesoftware.smackx.jingle.JingleSession;
+-import org.jivesoftware.smackx.jingle.SmackLogger;
+-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.mediaimpl.JMFInit;
+-import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
+-import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
+-
+-/**
+- * Implements a jingleMediaManager using JMF based API and JSpeex.
+- * It supports Speex codec.
+- * <i>This API only currently works on windows.</i>
+- *
+- * @author Thiago Camargo
+- */
+-public class SpeexMediaManager extends JingleMediaManager {
+-
+- private static final SmackLogger LOGGER = SmackLogger.getLogger(SpeexMediaManager.class);
+-
+- public static final String MEDIA_NAME = "Speex";
+-
+- private List<PayloadType> payloads = new ArrayList<PayloadType>();
+-
+- public SpeexMediaManager(JingleTransportManager transportManager) {
+- super(transportManager);
+- setupPayloads();
+- setupJMF();
+- }
+-
+- /**
+- * Returns a new jingleMediaSession
+- *
+- * @param payloadType payloadType
+- * @param remote remote Candidate
+- * @param local local Candidate
+- * @return JingleMediaSession
+- */
+- public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) {
+- return new AudioMediaSession(payloadType, remote, local, null,null);
+- }
+-
+- /**
+- * Setup API supported Payloads
+- */
+- private void setupPayloads() {
+- payloads.add(new PayloadType.Audio(15, "speex"));
+- }
+-
+- /**
+- * Return all supported Payloads for this Manager
+- *
+- * @return The Payload List
+- */
+- public List<PayloadType> getPayloads() {
+- return payloads;
+- }
+-
+- /**
+- * Runs JMFInit the first time the application is started so that capture
+- * devices are properly detected and initialized by JMF.
+- */
+- public static void setupJMF() {
+- // .jmf is the place where we store the jmf.properties file used
+- // by JMF. if the directory does not exist or it does not contain
+- // a jmf.properties file. or if the jmf.properties file has 0 length
+- // then this is the first time we're running and should continue to
+- // with JMFInit
+- String homeDir = System.getProperty("user.home");
+- File jmfDir = new File(homeDir, ".jmf");
+- String classpath = System.getProperty("java.class.path");
+- classpath += System.getProperty("path.separator")
+- + jmfDir.getAbsolutePath();
+- System.setProperty("java.class.path", classpath);
+-
+- if (!jmfDir.exists())
+- jmfDir.mkdir();
+-
+- File jmfProperties = new File(jmfDir, "jmf.properties");
+-
+- if (!jmfProperties.exists()) {
+- try {
+- jmfProperties.createNewFile();
+- }
+- catch (IOException ex) {
+- LOGGER.debug("Failed to create jmf.properties");
+- ex.printStackTrace();
+- }
+- }
+-
+- // if we're running on linux checkout that libjmutil.so is where it
+- // should be and put it there.
+- runLinuxPreInstall();
+-
+- if (jmfProperties.length() == 0) {
+- new JMFInit(null, false);
+- }
+-
+- }
+-
+- private static void runLinuxPreInstall() {
+- // @TODO Implement Linux Pre-Install
+- }
+-
+- public String getName() {
+- return MEDIA_NAME;
+- }
+-}
+Index: org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java
+===================================================================
+--- org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java (revision 11644)
++++ org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java (working copy)
+@@ -1,245 +0,0 @@
+-/**
+- * $RCSfile: AudioMediaSession.java,v $
+- * $Revision: 1.1 $
+- * $Date: 25/12/2006
+- * <p/>
+- * Copyright 2003-2006 Jive Software.
+- * <p/>
+- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+- * you may not use this file except in compliance with the License.
+- * You may obtain a copy of the License at
+- * <p/>
+- * http://www.apache.org/licenses/LICENSE-2.0
+- * <p/>
+- * 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.
+- */
+-
+-package org.jivesoftware.smackx.jingle.mediaimpl.jspeex;
+-
+-import java.io.IOException;
+-import java.net.DatagramSocket;
+-import java.net.InetAddress;
+-import java.net.ServerSocket;
+-import java.security.GeneralSecurityException;
+-
+-import javax.media.NoProcessorException;
+-import javax.media.format.UnsupportedFormatException;
+-import javax.media.rtp.rtcp.SenderReport;
+-import javax.media.rtp.rtcp.SourceDescription;
+-
+-import mil.jfcom.cie.media.session.MediaSession;
+-import mil.jfcom.cie.media.session.MediaSessionListener;
+-import mil.jfcom.cie.media.session.StreamPlayer;
+-import mil.jfcom.cie.media.srtp.packetizer.SpeexFormat;
+-
+-import org.jivesoftware.smackx.jingle.JingleSession;
+-import org.jivesoftware.smackx.jingle.SmackLogger;
+-import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
+-import org.jivesoftware.smackx.jingle.media.PayloadType;
+-import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
+-
+-/**
+- * This Class implements a complete JingleMediaSession.
+- * It sould be used to transmit and receive audio captured from the Mic.
+- * This Class should be automaticly controlled by JingleSession.
+- * But you could also use in any VOIP application.
+- * For better NAT Traversal support this implementation don't support only receive or only transmit.
+- * To receive you MUST transmit. So the only implemented and functionally methods are startTransmit() and stopTransmit()
+- *
+- * @author Thiago Camargo
+- */
+-
+-public class AudioMediaSession extends JingleMediaSession implements MediaSessionListener {
+-
+- private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioMediaSession.class);
+-
+- private MediaSession mediaSession;
+-
+- /**
+- * Create a Session using Speex Codec
+- *
+- * @param localhost localHost
+- * @param localPort localPort
+- * @param remoteHost remoteHost
+- * @param remotePort remotePort
+- * @param eventHandler eventHandler
+- * @param quality quality
+- * @param secure secure
+- * @param micOn micOn
+- * @return MediaSession
+- * @throws NoProcessorException
+- * @throws UnsupportedFormatException
+- * @throws IOException
+- * @throws GeneralSecurityException
+- */
+- public static MediaSession createSession(String localhost, int localPort, String remoteHost, int remotePort, MediaSessionListener eventHandler, int quality, boolean secure, boolean micOn) throws NoProcessorException, UnsupportedFormatException, IOException, GeneralSecurityException {
+-
+- SpeexFormat.setFramesPerPacket(1);
+- /**
+- * The master key. Hardcoded for now.
+- */
+- byte[] masterKey = new byte[]{(byte) 0xE1, (byte) 0xF9, 0x7A, 0x0D, 0x3E, 0x01, (byte) 0x8B, (byte) 0xE0, (byte) 0xD6, 0x4F, (byte) 0xA3, 0x2C, 0x06, (byte) 0xDE, 0x41, 0x39};
+-
+- /**
+- * The master salt. Hardcoded for now.
+- */
+- byte[] masterSalt = new byte[]{0x0E, (byte) 0xC6, 0x75, (byte) 0xAD, 0x49, (byte) 0x8A, (byte) 0xFE, (byte) 0xEB, (byte) 0xB6, (byte) 0x96, 0x0B, 0x3A, (byte) 0xAB, (byte) 0xE6};
+-
+- DatagramSocket[] localPorts = MediaSession.getLocalPorts(InetAddress.getByName(localhost), localPort);
+- MediaSession session = MediaSession.createInstance(remoteHost, remotePort, localPorts, quality, secure, masterKey, masterSalt);
+- session.setListener(eventHandler);
+-
+- session.setSourceDescription(new SourceDescription[]{new SourceDescription(SourceDescription.SOURCE_DESC_NAME, "Superman", 1, false), new SourceDescription(SourceDescription.SOURCE_DESC_EMAIL, "cdcie.tester@je.jfcom.mil", 1, false), new SourceDescription(SourceDescription.SOURCE_DESC_LOC, InetAddress.getByName(localhost) + " Port " + session.getLocalDataPort(), 1, false), new SourceDescription(SourceDescription.SOURCE_DESC_TOOL, "JFCOM CDCIE Audio Chat", 1, false)});
+- return session;
+- }
+-
+-
+- /**
+- * Creates a org.jivesoftware.jingleaudio.jspeex.AudioMediaSession with defined payload type, remote and local candidates
+- *
+- * @param payloadType Payload of the jmf
+- * @param remote the remote information. The candidate that the jmf will be sent to.
+- * @param local the local information. The candidate that will receive the jmf
+- * @param locator media locator
+- */
+- public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote,
+- final TransportCandidate local, String locator, JingleSession jingleSession) {
+- super(payloadType, remote, local, locator == null ? "dsound://" : locator, jingleSession);
+- initialize();
+- }
+-
+- /**
+- * Initialize the Audio Channel to make it able to send and receive audio
+- */
+- public void initialize() {
+-
+- String ip;
+- String localIp;
+- int localPort;
+- int remotePort;
+-
+- if (this.getLocal().getSymmetric() != null) {
+- ip = this.getLocal().getIp();
+- localIp = this.getLocal().getLocalIp();
+- localPort = getFreePort();
+- remotePort = this.getLocal().getSymmetric().getPort();
+-
+- LOGGER.debug(this.getLocal().getConnection() + " " + ip + ": " + localPort + "->" + remotePort);
+-
+- }
+- else {
+- ip = this.getRemote().getIp();
+- localIp = this.getLocal().getLocalIp();
+- localPort = this.getLocal().getPort();
+- remotePort = this.getRemote().getPort();
+- }
+-
+- try {
+- mediaSession = createSession(localIp, localPort, ip, remotePort, this, 2, false, true);
+- }
+- catch (NoProcessorException e) {
+- e.printStackTrace();
+- }
+- catch (UnsupportedFormatException e) {
+- e.printStackTrace();
+- }
+- catch (IOException e) {
+- e.printStackTrace();
+- }
+- catch (GeneralSecurityException e) {
+- e.printStackTrace();
+- }
+- }
+-
+- /**
+- * Starts transmission and for NAT Traversal reasons start receiving also.
+- */
+- public void startTrasmit() {
+- try {
+- LOGGER.debug("start");
+- mediaSession.start(true);
+- this.mediaReceived("");
+- }
+- catch (IOException e) {
+- e.printStackTrace();
+- }
+- }
+-
+- /**
+- * Set transmit activity. If the active is true, the instance should trasmit.
+- * If it is set to false, the instance should pause transmit.
+- *
+- * @param active active state
+- */
+- public void setTrasmit(boolean active) {
+- // Do nothing
+- }
+-
+- /**
+- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
+- */
+- public void startReceive() {
+- // Do nothing
+- }
+-
+- /**
+- * Stops transmission and for NAT Traversal reasons stop receiving also.
+- */
+- public void stopTrasmit() {
+- if (mediaSession != null)
+- mediaSession.close();
+- }
+-
+- /**
+- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
+- */
+- public void stopReceive() {
+- // Do nothing
+- }
+-
+- public void newStreamIdentified(StreamPlayer streamPlayer) {
+- }
+-
+- public void senderReportReceived(SenderReport report) {
+- }
+-
+- public void streamClosed(StreamPlayer stream, boolean timeout) {
+- }
+-
+- /**
+- * Obtain a free port we can use.
+- *
+- * @return A free port number.
+- */
+- protected int getFreePort() {
+- ServerSocket ss;
+- int freePort = 0;
+-
+- for (int i = 0; i < 10; i++) {
+- freePort = (int) (10000 + Math.round(Math.random() * 10000));
+- freePort = freePort % 2 == 0 ? freePort : freePort + 1;
+- try {
+- ss = new ServerSocket(freePort);
+- freePort = ss.getLocalPort();
+- ss.close();
+- return freePort;
+- }
+- catch (IOException e) {
+- e.printStackTrace();
+- }
+- }
+- try {
+- ss = new ServerSocket(0);
+- freePort = ss.getLocalPort();
+- ss.close();
+- }
+- catch (IOException e) {
+- e.printStackTrace();
+- }
+- return freePort;
+- }
+-}
diff --git a/asmack-master/lib/.gitignore b/asmack-master/lib/.gitignore
new file mode 100644
index 0000000..905be00
--- /dev/null
+++ b/asmack-master/lib/.gitignore
@@ -0,0 +1 @@
+android-*.jar
diff --git a/asmack-master/lib/httpclient-4.1.3.jar b/asmack-master/lib/httpclient-4.1.3.jar
new file mode 100644
index 0000000..dfa8793
--- /dev/null
+++ b/asmack-master/lib/httpclient-4.1.3.jar
Binary files differ
diff --git a/asmack-master/lib/httpcore-4.1.4.jar b/asmack-master/lib/httpcore-4.1.4.jar
new file mode 100644
index 0000000..1606a2e
--- /dev/null
+++ b/asmack-master/lib/httpcore-4.1.4.jar
Binary files differ
diff --git a/asmack-master/lib/jstun.jar b/asmack-master/lib/jstun.jar
new file mode 100644
index 0000000..8ef0b92
--- /dev/null
+++ b/asmack-master/lib/jstun.jar
Binary files differ
diff --git a/asmack-master/lib/xpp3-1.1.4c.jar b/asmack-master/lib/xpp3-1.1.4c.jar
new file mode 100644
index 0000000..451ac82
--- /dev/null
+++ b/asmack-master/lib/xpp3-1.1.4c.jar
Binary files differ
diff --git a/asmack-master/local.properties.example b/asmack-master/local.properties.example
new file mode 100644
index 0000000..abdf234
--- /dev/null
+++ b/asmack-master/local.properties.example
@@ -0,0 +1 @@
+sdk-location=${user.home}/android/
diff --git a/asmack-master/patch/00-relocate-javax.security.sh b/asmack-master/patch/00-relocate-javax.security.sh
new file mode 100755
index 0000000..0924208
--- /dev/null
+++ b/asmack-master/patch/00-relocate-javax.security.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+mkdir -p org/apache/harmony/
+mv javax org/apache/harmony/
+find org/apache/harmony/ -name '*.java' -exec sed -i 's:package javax:package org.apache.harmony.javax:g' '{}' ';'
+find -name '*.java' -exec sed -i 's:import javax.security.sasl:import org.apache.harmony.javax.security.sasl:g' '{}' ';'
+find -name '*.java' -exec sed -i 's:import javax.security.auth:import org.apache.harmony.javax.security.auth:g' '{}' ';'
+
diff --git a/asmack-master/patch/00-remove-javax-dns.sh b/asmack-master/patch/00-remove-javax-dns.sh
new file mode 100755
index 0000000..a4f8f23
--- /dev/null
+++ b/asmack-master/patch/00-remove-javax-dns.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+rm org/jivesoftware/smack/util/dns/JavaxResolver.java
diff --git a/asmack-master/patch/10-remove-unused-harmony.sh b/asmack-master/patch/10-remove-unused-harmony.sh
new file mode 100755
index 0000000..ae0b4e3
--- /dev/null
+++ b/asmack-master/patch/10-remove-unused-harmony.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+rm -rf org/ietf/
+
+rm -rf org/apache/harmony/auth
+rm -rf org/apache/harmony/javax/security/auth/kerberos/
+rm -rf org/apache/harmony/javax/security/auth/x500/
+
+rm org/apache/harmony/javax/security/auth/Policy.java
+
diff --git a/asmack-master/patch/11-remove-nls-harmony.sh b/asmack-master/patch/11-remove-nls-harmony.sh
new file mode 100755
index 0000000..f1281f5
--- /dev/null
+++ b/asmack-master/patch/11-remove-nls-harmony.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+find org/apache/harmony -name '*.java' -exec sed -i 's:import org.apache.harmony.auth.internal.nls.Messages;::' '{}' ';'
+find org/apache/harmony -name '*.java' -exec sed -i 's:Messages.getString(\("[^"]*"\)):\1:g' '{}' ';'
+
diff --git a/asmack-master/patch/12-harmony-nls-msg.patch b/asmack-master/patch/12-harmony-nls-msg.patch
new file mode 100644
index 0000000..b201f60
--- /dev/null
+++ b/asmack-master/patch/12-harmony-nls-msg.patch
@@ -0,0 +1,59 @@
+diff -ur ../../src-unpatched/trunk/org/apache/harmony/javax/security/auth/login/LoginContext.java ./org/apache/harmony/javax/security/auth/login/LoginContext.java
+--- ../../src-unpatched/trunk/org/apache/harmony/javax/security/auth/login/LoginContext.java 2009-12-06 15:31:24.000000000 +0100
++++ ./org/apache/harmony/javax/security/auth/login/LoginContext.java 2009-12-06 15:36:20.000000000 +0100
+@@ -161,7 +161,7 @@
+ }
+ entries = config.getAppConfigurationEntry("other"); //$NON-NLS-1$
+ if (entries == null) {
+- throw new LoginException(Messages.getString("auth.35", name)); //$NON-NLS-1$
++ throw new LoginException("auth.35 " + name); //$NON-NLS-1$
+ }
+ }
+
+@@ -524,8 +524,8 @@
+ try {
+ klass = Class.forName(klassName, false, contextClassLoader);
+ } catch (ClassNotFoundException ex) {
+- throw (LoginException) new LoginException(Messages.getString(
+- "auth.39", klassName)).initCause(ex); //$NON-NLS-1$
++ throw (LoginException) new LoginException(
++ "auth.39 " + klassName).initCause(ex); //$NON-NLS-1$
+ }
+ }
+
+@@ -533,12 +533,12 @@
+ try {
+ module = (LoginModule) klass.newInstance();
+ } catch (IllegalAccessException ex) {
+- throw (LoginException) new LoginException(Messages.getString(
+- "auth.3A", klassName)) //$NON-NLS-1$
++ throw (LoginException) new LoginException(
++ "auth.3A " + klassName) //$NON-NLS-1$
+ .initCause(ex);
+ } catch (InstantiationException ex) {
+- throw (LoginException) new LoginException(Messages.getString(
+- "auth.3A", klassName)) //$NON-NLS-1$
++ throw (LoginException) new LoginException(
++ "auth.3A" + klassName) //$NON-NLS-1$
+ .initCause(ex);
+ }
+ module.initialize(subject, callbackHandler, sharedState, entry.getOptions());
+diff -ur ../../src-unpatched/trunk/org/apache/harmony/javax/security/auth/Subject.java ./org/apache/harmony/javax/security/auth/Subject.java
+--- ../../src-unpatched/trunk/org/apache/harmony/javax/security/auth/Subject.java 2009-12-06 15:31:24.000000000 +0100
++++ ./org/apache/harmony/javax/security/auth/Subject.java 2009-12-06 15:32:10.000000000 +0100
+@@ -669,7 +669,7 @@
+
+ if (!c.isAssignableFrom(o.getClass())) {
+ throw new IllegalArgumentException(
+- Messages.getString("auth.0C", c.getName())); //$NON-NLS-1$
++ "auth.0C " + c.getName()); //$NON-NLS-1$
+ }
+
+ if (elements.contains(o)) {
+@@ -779,4 +779,4 @@
+ }
+ }
+ }
+-}
+\ No newline at end of file
++}
diff --git a/asmack-master/patch/13-mock-configuration.patch b/asmack-master/patch/13-mock-configuration.patch
new file mode 100644
index 0000000..ce93b26
--- /dev/null
+++ b/asmack-master/patch/13-mock-configuration.patch
@@ -0,0 +1,33 @@
+diff -ur ../../src-unpatched/trunk/org/apache/harmony/javax/security/auth/login/Configuration.java ./org/apache/harmony/javax/security/auth/login/Configuration.java
+--- ../../src-unpatched/trunk/org/apache/harmony/javax/security/auth/login/Configuration.java 2009-12-06 18:40:25.000000000 +0100
++++ ./org/apache/harmony/javax/security/auth/login/Configuration.java 2009-12-06 18:44:23.000000000 +0100
+@@ -20,8 +20,6 @@
+ import java.security.AccessController;
+ import org.apache.harmony.javax.security.auth.AuthPermission;
+
+-import org.apache.harmony.security.fortress.PolicyUtils;
+-
+ public abstract class Configuration {
+
+ // the current configuration
+@@ -56,8 +54,18 @@
+ * exception, wraps it with SecurityException and throws further.
+ */
+ private static final Configuration getDefaultProvider() {
+- return AccessController.doPrivileged(new PolicyUtils.ProviderLoader<Configuration>(
+- LOGIN_CONFIGURATION_PROVIDER, Configuration.class));
++ return new Configuration() {
++
++ @Override
++ public void refresh() {
++ }
++
++ @Override
++ public AppConfigurationEntry[] getAppConfigurationEntry(
++ String applicationName) {
++ return new AppConfigurationEntry[0];
++ }
++ };
+ }
+
+ /**
diff --git a/asmack-master/patch/20-remove-mxparser.sh b/asmack-master/patch/20-remove-mxparser.sh
new file mode 100755
index 0000000..c1d6318
--- /dev/null
+++ b/asmack-master/patch/20-remove-mxparser.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+find org/jivesoftware -name '*.java' -exec sed -i 's:import org.xmlpull.mxp1.MXParser:import org.xmlpull.v1.XmlPullParserFactory:' '{}' ';'
+find org/jivesoftware -name '*.java' -exec sed -i 's:new MXParser():XmlPullParserFactory.newInstance().newPullParser():g' '{}' ';'
+
diff --git a/asmack-master/patch/21-remove-unused-smack.sh b/asmack-master/patch/21-remove-unused-smack.sh
new file mode 100755
index 0000000..078ff04
--- /dev/null
+++ b/asmack-master/patch/21-remove-unused-smack.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+rm org/jivesoftware/smack/debugger/LiteDebugger.java
+rm org/jivesoftware/smackx/debugger/EnhancedDebugger.java
+rm org/jivesoftware/smackx/debugger/EnhancedDebuggerWindow.java
+
diff --git a/asmack-master/patch/22-remove-beans.Property-deps.patch b/asmack-master/patch/22-remove-beans.Property-deps.patch
new file mode 100644
index 0000000..8653716
--- /dev/null
+++ b/asmack-master/patch/22-remove-beans.Property-deps.patch
@@ -0,0 +1,30 @@
+--- ../../src-unpatched/trunk/org/jivesoftware/smack/util/PacketParserUtils.java 2009-12-06 19:45:45.000000000 +0100
++++ org/jivesoftware/smack/util/PacketParserUtils.java 2009-12-06 19:48:13.000000000 +0100
+@@ -25,7 +25,6 @@
+ import org.jivesoftware.smack.provider.ProviderManager;
+ import org.xmlpull.v1.XmlPullParser;
+
+-import java.beans.PropertyDescriptor;
+ import java.io.ByteArrayInputStream;
+ import java.io.ObjectInputStream;
+ import java.util.ArrayList;
+@@ -828,14 +827,14 @@
+ if (eventType == XmlPullParser.START_TAG) {
+ String name = parser.getName();
+ String stringValue = parser.nextText();
+- PropertyDescriptor descriptor = new PropertyDescriptor(name, objectClass);
+- // Load the class type of the property.
+- Class<?> propertyType = descriptor.getPropertyType();
++ Class propertyType = object.getClass().getMethod(
++ "get" + Character.toUpperCase(name.charAt(0)) + name.substring(1)).getReturnType();
+ // Get the value of the property by converting it from a
+ // String to the correct object type.
+ Object value = decode(propertyType, stringValue);
+ // Set the value of the bean.
+- descriptor.getWriteMethod().invoke(object, value);
++ object.getClass().getMethod("set" + Character.toUpperCase(name.charAt(0)) + name.substring(1), propertyType)
++ .invoke(object, value);
+ }
+ else if (eventType == XmlPullParser.END_TAG) {
+ if (parser.getName().equals(elementName)) {
+
diff --git a/asmack-master/patch/23-strip-unused-xml-transform.patch b/asmack-master/patch/23-strip-unused-xml-transform.patch
new file mode 100644
index 0000000..24debbd
--- /dev/null
+++ b/asmack-master/patch/23-strip-unused-xml-transform.patch
@@ -0,0 +1,50 @@
+--- org/jivesoftware/smackx/pubsub/util/XmlUtils.java 2012-06-05 14:35:54.518687907 +0200
++++ org/jivesoftware/smackx/pubsub/util/XmlUtils.java 2012-06-05 21:07:13.038946699 +0200
+@@ -14,47 +14,15 @@
+ package org.jivesoftware.smackx.pubsub.util;
+
+ import java.io.StringReader;
+
+-import javax.xml.transform.OutputKeys;
+-import javax.xml.transform.Transformer;
+-import javax.xml.transform.TransformerFactory;
+-import javax.xml.transform.stream.StreamResult;
+-import javax.xml.transform.stream.StreamSource;
+-
+ /**
+ * Simple utility for pretty printing xml.
+ *
+ * @author Robin Collier
+ */
+ public class XmlUtils
+ {
+- /**
+- *
+- * @param header Just a title for the stanza for readability. Single word no spaces since
+- * it is inserted as the root element in the output.
+- * @param xml The string to pretty print
+- */
+- static public void prettyPrint(String header, String xml)
+- {
+- try
+- {
+- Transformer transformer = TransformerFactory.newInstance().newTransformer();
+- transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+- transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "3");
+-
+- if (header != null)
+- {
+- xml = "\n<" + header + ">" + xml + "</" + header + '>';
+- }
+- transformer.transform(new StreamSource(new StringReader(xml)), new StreamResult(System.out));
+- }
+- catch (Exception e)
+- {
+- System.out.println("Something wrong with xml in \n---------------\n" + xml + "\n---------------");
+- e.printStackTrace();
+- }
+- }
+
+ static public void appendAttribute(StringBuilder builder, String att, String value)
+ {
+ builder.append(" ");
diff --git a/asmack-master/patch/24-disable-sasl-methods.patch b/asmack-master/patch/24-disable-sasl-methods.patch
new file mode 100644
index 0000000..eda5eb0
--- /dev/null
+++ b/asmack-master/patch/24-disable-sasl-methods.patch
@@ -0,0 +1,20 @@
+--- ../../src-unpatched/trunk/org/jivesoftware/smack/SASLAuthentication.java 2009-12-07 00:03:46.000000000 +0100
++++ org/jivesoftware/smack/SASLAuthentication.java 2009-12-07 00:05:46.000000000 +0100
+@@ -91,11 +91,11 @@
+ registerSASLMechanism("PLAIN", SASLPlainMechanism.class);
+ registerSASLMechanism("ANONYMOUS", SASLAnonymous.class);
+
+- supportSASLMechanism("GSSAPI",0);
+- supportSASLMechanism("DIGEST-MD5",1);
+- supportSASLMechanism("CRAM-MD5",2);
+- supportSASLMechanism("PLAIN",3);
+- supportSASLMechanism("ANONYMOUS",4);
++// supportSASLMechanism("GSSAPI",0);
++ supportSASLMechanism("DIGEST-MD5",0);
++// supportSASLMechanism("CRAM-MD5",2);
++ supportSASLMechanism("PLAIN",1);
++ supportSASLMechanism("ANONYMOUS",2);
+
+ }
+
+
diff --git a/asmack-master/patch/30-switch-debugging-implementations.patch b/asmack-master/patch/30-switch-debugging-implementations.patch
new file mode 100644
index 0000000..93be2a0
--- /dev/null
+++ b/asmack-master/patch/30-switch-debugging-implementations.patch
@@ -0,0 +1,17 @@
+--- ../../../src/smack/org/jivesoftware/smack/Connection.java 2010-02-03 23:29:21.000000000 +0100
++++ org/jivesoftware/smack/Connection.java 2010-02-03 23:56:56.000000000 +0100
+@@ -743,12 +743,12 @@
+ if (debuggerClass == null) {
+ try {
+ debuggerClass =
+- Class.forName("org.jivesoftware.smackx.debugger.EnhancedDebugger");
++ Class.forName("de.measite.smack.AndroidDebugger");
+ }
+ catch (Exception ex) {
+ try {
+ debuggerClass =
+- Class.forName("org.jivesoftware.smack.debugger.LiteDebugger");
++ Class.forName("org.jivesoftware.smack.debugger.ConsoleDebugger");
+ }
+ catch (Exception ex2) {
+ ex2.printStackTrace();
diff --git a/asmack-master/patch/31-remove-dns-wrapper.sh b/asmack-master/patch/31-remove-dns-wrapper.sh
new file mode 100755
index 0000000..c8c5ede
--- /dev/null
+++ b/asmack-master/patch/31-remove-dns-wrapper.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+rm org/xbill/DNS/spi/DNSJavaNameServiceDescriptor.java
+
diff --git a/asmack-master/patch/32-remove-jbosh-xlightweb.sh b/asmack-master/patch/32-remove-jbosh-xlightweb.sh
new file mode 100755
index 0000000..53ad364
--- /dev/null
+++ b/asmack-master/patch/32-remove-jbosh-xlightweb.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+rm com/kenai/jbosh/XLightWeb*.java
+
diff --git a/asmack-master/patch/33-jbosh-android.patch b/asmack-master/patch/33-jbosh-android.patch
new file mode 100644
index 0000000..33a9b7d
--- /dev/null
+++ b/asmack-master/patch/33-jbosh-android.patch
@@ -0,0 +1,446 @@
+diff --git com/kenai/jbosh/ApacheHTTPResponse.java com/kenai/jbosh/ApacheHTTPResponse.java
+new file mode 100644
+index 0000000..9f6731f
+--- /dev/null
++++ com/kenai/jbosh/ApacheHTTPResponse.java
+@@ -0,0 +1,253 @@
++/*
++ * Copyright 2009 Guenther Niess
++ *
++ * 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.
++ */
++
++package com.kenai.jbosh;
++
++import java.io.IOException;
++import java.util.concurrent.locks.Lock;
++import java.util.concurrent.locks.ReentrantLock;
++
++import org.apache.http.HttpEntity;
++import org.apache.http.HttpResponse;
++import org.apache.http.client.HttpClient;
++import org.apache.http.client.methods.HttpPost;
++import org.apache.http.entity.ByteArrayEntity;
++
++import org.apache.http.protocol.BasicHttpContext;
++import org.apache.http.protocol.HttpContext;
++import org.apache.http.util.EntityUtils;
++
++final class ApacheHTTPResponse implements HTTPResponse {
++
++ ///////////////////////////////////////////////////////////////////////////
++ // Constants:
++
++ /**
++ * Name of the accept encoding header.
++ */
++ private static final String ACCEPT_ENCODING = "Accept-Encoding";
++
++ /**
++ * Value to use for the ACCEPT_ENCODING header.
++ */
++ private static final String ACCEPT_ENCODING_VAL =
++ ZLIBCodec.getID() + ", " + GZIPCodec.getID();
++
++ /**
++ * Name of the character set to encode the body to/from.
++ */
++ private static final String CHARSET = "UTF-8";
++
++ /**
++ * Content type to use when transmitting the body data.
++ */
++ private static final String CONTENT_TYPE = "text/xml; charset=utf-8";
++
++ ///////////////////////////////////////////////////////////////////////////
++ // Class variables:
++
++ /**
++ * Lock used for internal synchronization.
++ */
++ private final Lock lock = new ReentrantLock();
++
++ /**
++ * The execution state of an HTTP process.
++ */
++ private final HttpContext context;
++
++ /**
++ * HttpClient instance to use to communicate.
++ */
++ private final HttpClient client;
++
++ /**
++ * The HTTP POST request is sent to the server.
++ */
++ private final HttpPost post;
++
++ /**
++ * A flag which indicates if the transmission was already done.
++ */
++ private boolean sent;
++
++ /**
++ * Exception to throw when the response data is attempted to be accessed,
++ * or {@code null} if no exception should be thrown.
++ */
++ private BOSHException toThrow;
++
++ /**
++ * The response body which was received from the server or {@code null}
++ * if that has not yet happened.
++ */
++ private AbstractBody body;
++
++ /**
++ * The HTTP response status code.
++ */
++ private int statusCode;
++
++ ///////////////////////////////////////////////////////////////////////////
++ // Constructors:
++
++ /**
++ * Create and send a new request to the upstream connection manager,
++ * providing deferred access to the results to be returned.
++ *
++ * @param client client instance to use when sending the request
++ * @param cfg client configuration
++ * @param params connection manager parameters from the session creation
++ * response, or {@code null} if the session has not yet been established
++ * @param request body of the client request
++ */
++ ApacheHTTPResponse(
++ final HttpClient client,
++ final BOSHClientConfig cfg,
++ final CMSessionParams params,
++ final AbstractBody request) {
++ super();
++ this.client = client;
++ this.context = new BasicHttpContext();
++ this.post = new HttpPost(cfg.getURI().toString());
++ this.sent = false;
++
++ try {
++ String xml = request.toXML();
++ byte[] data = xml.getBytes(CHARSET);
++
++ String encoding = null;
++ if (cfg.isCompressionEnabled() && params != null) {
++ AttrAccept accept = params.getAccept();
++ if (accept != null) {
++ if (accept.isAccepted(ZLIBCodec.getID())) {
++ encoding = ZLIBCodec.getID();
++ data = ZLIBCodec.encode(data);
++ } else if (accept.isAccepted(GZIPCodec.getID())) {
++ encoding = GZIPCodec.getID();
++ data = GZIPCodec.encode(data);
++ }
++ }
++ }
++
++ ByteArrayEntity entity = new ByteArrayEntity(data);
++ entity.setContentType(CONTENT_TYPE);
++ if (encoding != null) {
++ entity.setContentEncoding(encoding);
++ }
++ post.setEntity(entity);
++ if (cfg.isCompressionEnabled()) {
++ post.setHeader(ACCEPT_ENCODING, ACCEPT_ENCODING_VAL);
++ }
++ } catch (Exception e) {
++ toThrow = new BOSHException("Could not generate request", e);
++ }
++ }
++
++ ///////////////////////////////////////////////////////////////////////////
++ // HTTPResponse interface methods:
++
++ /**
++ * Abort the client transmission and response processing.
++ */
++ public void abort() {
++ if (post != null) {
++ post.abort();
++ toThrow = new BOSHException("HTTP request aborted");
++ }
++ }
++
++ /**
++ * Wait for and then return the response body.
++ *
++ * @return body of the response
++ * @throws InterruptedException if interrupted while awaiting the response
++ * @throws BOSHException on communication failure
++ */
++ public AbstractBody getBody() throws InterruptedException, BOSHException {
++ if (toThrow != null) {
++ throw(toThrow);
++ }
++ lock.lock();
++ try {
++ if (!sent) {
++ awaitResponse();
++ }
++ } finally {
++ lock.unlock();
++ }
++ return body;
++ }
++
++ /**
++ * Wait for and then return the response HTTP status code.
++ *
++ * @return HTTP status code of the response
++ * @throws InterruptedException if interrupted while awaiting the response
++ * @throws BOSHException on communication failure
++ */
++ public int getHTTPStatus() throws InterruptedException, BOSHException {
++ if (toThrow != null) {
++ throw(toThrow);
++ }
++ lock.lock();
++ try {
++ if (!sent) {
++ awaitResponse();
++ }
++ } finally {
++ lock.unlock();
++ }
++ return statusCode;
++ }
++
++ ///////////////////////////////////////////////////////////////////////////
++ // Package-private methods:
++
++ /**
++ * Await the response, storing the result in the instance variables of
++ * this class when they arrive.
++ *
++ * @throws InterruptedException if interrupted while awaiting the response
++ * @throws BOSHException on communication failure
++ */
++ private synchronized void awaitResponse() throws BOSHException {
++ HttpEntity entity = null;
++ try {
++ HttpResponse httpResp = client.execute(post, context);
++ entity = httpResp.getEntity();
++ byte[] data = EntityUtils.toByteArray(entity);
++ String encoding = entity.getContentEncoding() != null ?
++ entity.getContentEncoding().getValue() :
++ null;
++ if (ZLIBCodec.getID().equalsIgnoreCase(encoding)) {
++ data = ZLIBCodec.decode(data);
++ } else if (GZIPCodec.getID().equalsIgnoreCase(encoding)) {
++ data = GZIPCodec.decode(data);
++ }
++ body = StaticBody.fromString(new String(data, CHARSET));
++ statusCode = httpResp.getStatusLine().getStatusCode();
++ sent = true;
++ } catch (IOException iox) {
++ abort();
++ toThrow = new BOSHException("Could not obtain response", iox);
++ throw(toThrow);
++ } catch (RuntimeException ex) {
++ abort();
++ throw(ex);
++ }
++ }
++}
+diff --git com/kenai/jbosh/ApacheHTTPSender.java com/kenai/jbosh/ApacheHTTPSender.java
+new file mode 100644
+index 0000000..2abb4ee
+--- /dev/null
++++ com/kenai/jbosh/ApacheHTTPSender.java
+@@ -0,0 +1,156 @@
++/*
++ * Copyright 2009 Guenther Niess
++ *
++ * 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.
++ */
++
++package com.kenai.jbosh;
++
++import java.util.concurrent.locks.Lock;
++import java.util.concurrent.locks.ReentrantLock;
++
++import org.apache.http.HttpHost;
++import org.apache.http.HttpVersion;
++import org.apache.http.client.HttpClient;
++import org.apache.http.conn.ClientConnectionManager;
++import org.apache.http.conn.params.ConnManagerParams;
++import org.apache.http.conn.params.ConnRoutePNames;
++import org.apache.http.conn.scheme.PlainSocketFactory;
++import org.apache.http.conn.scheme.Scheme;
++import org.apache.http.conn.scheme.SchemeRegistry;
++import org.apache.http.conn.ssl.SSLSocketFactory;
++import org.apache.http.impl.client.DefaultHttpClient;
++import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
++import org.apache.http.params.BasicHttpParams;
++import org.apache.http.params.HttpParams;
++import org.apache.http.params.HttpProtocolParams;
++
++/**
++ * Implementation of the {@code HTTPSender} interface which uses the
++ * Apache HttpClient API to send messages to the connection manager.
++ */
++final class ApacheHTTPSender implements HTTPSender {
++
++ /**
++ * Lock used for internal synchronization.
++ */
++ private final Lock lock = new ReentrantLock();
++
++ /**
++ * Session configuration.
++ */
++ private BOSHClientConfig cfg;
++
++ /**
++ * HttpClient instance to use to communicate.
++ */
++ private HttpClient httpClient;
++
++ ///////////////////////////////////////////////////////////////////////////
++ // Constructors:
++
++ /**
++ * Prevent construction apart from our package.
++ */
++ ApacheHTTPSender() {
++ // Load Apache HTTP client class
++ HttpClient.class.getName();
++ }
++
++ ///////////////////////////////////////////////////////////////////////////
++ // HTTPSender interface methods:
++
++ /**
++ * {@inheritDoc}
++ */
++ public void init(final BOSHClientConfig session) {
++ lock.lock();
++ try {
++ cfg = session;
++ httpClient = initHttpClient(session);
++ } finally {
++ lock.unlock();
++ }
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public void destroy() {
++ lock.lock();
++ try {
++ if (httpClient != null) {
++ httpClient.getConnectionManager().shutdown();
++ }
++ } finally {
++ cfg = null;
++ httpClient = null;
++ lock.unlock();
++ }
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public HTTPResponse send(
++ final CMSessionParams params,
++ final AbstractBody body) {
++ HttpClient mClient;
++ BOSHClientConfig mCfg;
++ lock.lock();
++ try {
++ if (httpClient == null) {
++ httpClient = initHttpClient(cfg);
++ }
++ mClient = httpClient;
++ mCfg = cfg;
++ } finally {
++ lock.unlock();
++ }
++ return new ApacheHTTPResponse(mClient, mCfg, params, body);
++ }
++
++ ///////////////////////////////////////////////////////////////////////////
++ // Package-private methods:
++
++ private synchronized HttpClient initHttpClient(final BOSHClientConfig config) {
++ // Create and initialize HTTP parameters
++ HttpParams params = new BasicHttpParams();
++ ConnManagerParams.setMaxTotalConnections(params, 100);
++ HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
++ HttpProtocolParams.setUseExpectContinue(params, false);
++ if (config != null &&
++ config.getProxyHost() != null &&
++ config.getProxyPort() != 0) {
++ HttpHost proxy = new HttpHost(
++ config.getProxyHost(),
++ config.getProxyPort());
++ params.setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
++ }
++
++ // Create and initialize scheme registry
++ SchemeRegistry schemeRegistry = new SchemeRegistry();
++ schemeRegistry.register(
++ new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
++ SSLSocketFactory sslFactory = SSLSocketFactory.getSocketFactory();
++ sslFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
++ schemeRegistry.register(
++ new Scheme("https", sslFactory, 443));
++
++ // Create an HttpClient with the ThreadSafeClientConnManager.
++ // This connection manager must be used if more than one thread will
++ // be using the HttpClient.
++ ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
++ return new DefaultHttpClient(cm, params);
++ }
++}
+diff --git com/kenai/jbosh/BodyParserXmlPull.java com/kenai/jbosh/BodyParserXmlPull.java
+index cc95236..5f23b06 100644
+--- com/kenai/jbosh/BodyParserXmlPull.java
++++ com/kenai/jbosh/BodyParserXmlPull.java
+@@ -22,7 +22,6 @@ import java.lang.ref.SoftReference;
+ import java.util.logging.Level;
+ import java.util.logging.Logger;
+ import javax.xml.XMLConstants;
+-import javax.xml.namespace.QName;
+ import org.xmlpull.v1.XmlPullParser;
+ import org.xmlpull.v1.XmlPullParserException;
+ import org.xmlpull.v1.XmlPullParserFactory;
+diff --git com/kenai/jbosh/BodyQName.java com/kenai/jbosh/BodyQName.java
+index fc7ab0c..83acdf1 100644
+--- com/kenai/jbosh/BodyQName.java
++++ com/kenai/jbosh/BodyQName.java
+@@ -16,8 +16,6 @@
+
+ package com.kenai.jbosh;
+
+-import javax.xml.namespace.QName;
+-
+ /**
+ * Qualified name of an attribute of the wrapper element. This class is
+ * analagous to the {@code javax.xml.namespace.QName} class.
diff --git a/asmack-master/patch/34-pin-jbosh-http-sender.patch b/asmack-master/patch/34-pin-jbosh-http-sender.patch
new file mode 100644
index 0000000..daf96df
--- /dev/null
+++ b/asmack-master/patch/34-pin-jbosh-http-sender.patch
@@ -0,0 +1,11 @@
+--- com/kenai/jbosh/BOSHClient.java 2010-01-13 20:57:36.000000000 +0100
++++ com/kenai/jbosh/BOSHClient.java 2010-02-04 17:40:45.678169320 +0100
+@@ -232,7 +232,7 @@
+ * HTTPSender instance.
+ */
+ private final HTTPSender httpSender =
+- ServiceLib.loadService(HTTPSender.class);
++ new ApacheHTTPSender();
+
+ /**
+ * Storage for test hook implementation.
diff --git a/asmack-master/patch/35-pin-jbosh-boddy-parser.patch b/asmack-master/patch/35-pin-jbosh-boddy-parser.patch
new file mode 100644
index 0000000..f4c63e8
--- /dev/null
+++ b/asmack-master/patch/35-pin-jbosh-boddy-parser.patch
@@ -0,0 +1,11 @@
+--- com/kenai/jbosh/StaticBody.java 2010-01-13 20:57:36.000000000 +0100
++++ com/kenai/jbosh/StaticBody.java 2010-02-04 17:59:06.037770746 +0100
+@@ -42,7 +42,7 @@
+ * Selected parser to be used to process raw XML messages.
+ */
+ private static final BodyParser PARSER =
+- ServiceLib.loadService(BodyParser.class);
++ new BodyParserXmlPull();
+
+ /**
+ * Size of the internal buffer when copying from a stream.
diff --git a/asmack-master/patch/40-enable-custom-sasl.sh b/asmack-master/patch/40-enable-custom-sasl.sh
new file mode 100755
index 0000000..476bd5b
--- /dev/null
+++ b/asmack-master/patch/40-enable-custom-sasl.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+find -name '*.java' -exec sed -i 's:import org.apache.harmony.javax.security.sasl.Sasl;:import de.measite.smack.Sasl;:g' '{}' ';'
+
diff --git a/asmack-master/patch/41-fix-digest-md5.patch b/asmack-master/patch/41-fix-digest-md5.patch
new file mode 100644
index 0000000..5f7f1dc
--- /dev/null
+++ b/asmack-master/patch/41-fix-digest-md5.patch
@@ -0,0 +1,13 @@
+--- ../../src-unpatched/trunk/com/novell/sasl/client/DigestMD5SaslClient.java 2009-12-07 19:14:10.000000000 +0100
++++ com/novell/sasl/client/DigestMD5SaslClient.java 2009-12-07 19:19:07.000000000 +0100
+@@ -673,8 +673,8 @@
+ digestResponse.append("00000001"); //nounce count
+ digestResponse.append(",qop=");
+ digestResponse.append(m_qopValue);
+- digestResponse.append(",digest-uri=\"ldap/");
+- digestResponse.append(m_serverName);
++ digestResponse.append(",digest-uri=\"");
++ digestResponse.append(m_digestURI);
+ digestResponse.append("\",response=");
+ digestResponse.append(response);
+ digestResponse.append(",charset=utf-8,nonce=\"");
diff --git a/asmack-master/patch/beem/10-PubSubManager-non-final.patch b/asmack-master/patch/beem/10-PubSubManager-non-final.patch
new file mode 100644
index 0000000..4fca228
--- /dev/null
+++ b/asmack-master/patch/beem/10-PubSubManager-non-final.patch
@@ -0,0 +1,13 @@
+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;
diff --git a/asmack-master/patch/beem/50-improved-pubsub.patch b/asmack-master/patch/beem/50-improved-pubsub.patch
new file mode 100644
index 0000000..a3704e7
--- /dev/null
+++ b/asmack-master/patch/beem/50-improved-pubsub.patch
@@ -0,0 +1,46 @@
+--- ../../../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>();
+
+ /**
diff --git a/asmack-master/patch/beem/COPYING b/asmack-master/patch/beem/COPYING
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/asmack-master/patch/beem/COPYING
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/asmack-master/patch/beem/README.txt b/asmack-master/patch/beem/README.txt
new file mode 100644
index 0000000..ce58c89
--- /dev/null
+++ b/asmack-master/patch/beem/README.txt
@@ -0,0 +1,9 @@
+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
+
diff --git a/asmack-master/patch/oldpatch/45-protected-xmpp-socket.patch b/asmack-master/patch/oldpatch/45-protected-xmpp-socket.patch
new file mode 100644
index 0000000..72f2d97
--- /dev/null
+++ b/asmack-master/patch/oldpatch/45-protected-xmpp-socket.patch
@@ -0,0 +1,11 @@
+--- org/jivesoftware/smack/XMPPConnection.java 2010-02-13 11:13:16.478541616 +0100
++++ org/jivesoftware/smack/XMPPConnection.java 2010-02-13 11:58:49.798590947 +0100
+@@ -55,7 +55,7 @@
+ /**
+ * The socket which is used for this connection.
+ */
+- Socket socket;
++ protected Socket socket;
+
+ String connectionID = null;
+ private String user = null;
diff --git a/asmack-master/static-src/custom/META-INF/services/com.kenai.jbosh.HTTPSender b/asmack-master/static-src/custom/META-INF/services/com.kenai.jbosh.HTTPSender
new file mode 100644
index 0000000..3608d8e
--- /dev/null
+++ b/asmack-master/static-src/custom/META-INF/services/com.kenai.jbosh.HTTPSender
@@ -0,0 +1 @@
+com.kenai.jbosh.ApacheHTTPSender
diff --git a/asmack-master/static-src/custom/com/kenai/jbosh/QName.java b/asmack-master/static-src/custom/com/kenai/jbosh/QName.java
new file mode 100644
index 0000000..d395a06
--- /dev/null
+++ b/asmack-master/static-src/custom/com/kenai/jbosh/QName.java
@@ -0,0 +1,269 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Axis" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package com.kenai.jbosh;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+
+/**
+ * <code>QName</code> class represents the value of a qualified name
+ * as specified in <a href="http://www.w3.org/TR/xmlschema-2/#QName">XML
+ * Schema Part2: Datatypes specification</a>.
+ * <p>
+ * The value of a QName contains a <b>namespaceURI</b>, a <b>localPart</b> and a <b>prefix</b>.
+ * The localPart provides the local part of the qualified name. The
+ * namespaceURI is a URI reference identifying the namespace.
+ *
+ * @version 1.1
+ */
+public class QName implements Serializable {
+
+ /** comment/shared empty string */
+ private static final String emptyString = "".intern();
+
+ /** Field namespaceURI */
+ private String namespaceURI;
+
+ /** Field localPart */
+ private String localPart;
+
+ /** Field prefix */
+ private String prefix;
+
+ /**
+ * Constructor for the QName.
+ *
+ * @param localPart Local part of the QName
+ */
+ public QName(String localPart) {
+ this(emptyString, localPart, emptyString);
+ }
+
+ /**
+ * Constructor for the QName.
+ *
+ * @param namespaceURI Namespace URI for the QName
+ * @param localPart Local part of the QName.
+ */
+ public QName(String namespaceURI, String localPart) {
+ this(namespaceURI, localPart, emptyString);
+ }
+
+ /**
+ * Constructor for the QName.
+ *
+ * @param namespaceURI Namespace URI for the QName
+ * @param localPart Local part of the QName.
+ * @param prefix Prefix of the QName.
+ */
+ public QName(String namespaceURI, String localPart, String prefix) {
+ this.namespaceURI = (namespaceURI == null)
+ ? emptyString
+ : namespaceURI.intern();
+ if (localPart == null) {
+ throw new IllegalArgumentException("invalid QName local part");
+ } else {
+ this.localPart = localPart.intern();
+ }
+
+ if (prefix == null) {
+ throw new IllegalArgumentException("invalid QName prefix");
+ } else {
+ this.prefix = prefix.intern();
+ }
+ }
+
+ /**
+ * Gets the Namespace URI for this QName
+ *
+ * @return Namespace URI
+ */
+ public String getNamespaceURI() {
+ return namespaceURI;
+ }
+
+ /**
+ * Gets the Local part for this QName
+ *
+ * @return Local part
+ */
+ public String getLocalPart() {
+ return localPart;
+ }
+
+ /**
+ * Gets the Prefix for this QName
+ *
+ * @return Prefix
+ */
+ public String getPrefix() {
+ return prefix;
+ }
+
+ /**
+ * Returns a string representation of this QName
+ *
+ * @return a string representation of the QName
+ */
+ public String toString() {
+
+ return ((namespaceURI == emptyString)
+ ? localPart
+ : '{' + namespaceURI + '}' + localPart);
+ }
+
+ /**
+ * Tests this QName for equality with another object.
+ * <p>
+ * If the given object is not a QName or is null then this method
+ * returns <tt>false</tt>.
+ * <p>
+ * For two QNames to be considered equal requires that both
+ * localPart and namespaceURI must be equal. This method uses
+ * <code>String.equals</code> to check equality of localPart
+ * and namespaceURI. Any class that extends QName is required
+ * to satisfy this equality contract.
+ * <p>
+ * This method satisfies the general contract of the <code>Object.equals</code> method.
+ *
+ * @param obj the reference object with which to compare
+ *
+ * @return <code>true</code> if the given object is identical to this
+ * QName: <code>false</code> otherwise.
+ */
+ public final boolean equals(Object obj) {
+
+ if (obj == this) {
+ return true;
+ }
+
+ if (!(obj instanceof QName)) {
+ return false;
+ }
+
+ if ((namespaceURI == ((QName) obj).namespaceURI)
+ && (localPart == ((QName) obj).localPart)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns a QName holding the value of the specified String.
+ * <p>
+ * The string must be in the form returned by the QName.toString()
+ * method, i.e. "{namespaceURI}localPart", with the "{namespaceURI}"
+ * part being optional.
+ * <p>
+ * This method doesn't do a full validation of the resulting QName.
+ * In particular, it doesn't check that the resulting namespace URI
+ * is a legal URI (per RFC 2396 and RFC 2732), nor that the resulting
+ * local part is a legal NCName per the XML Namespaces specification.
+ *
+ * @param s the string to be parsed
+ * @throws java.lang.IllegalArgumentException If the specified String cannot be parsed as a QName
+ * @return QName corresponding to the given String
+ */
+ public static QName valueOf(String s) {
+
+ if ((s == null) || s.equals("")) {
+ throw new IllegalArgumentException("invalid QName literal");
+ }
+
+ if (s.charAt(0) == '{') {
+ int i = s.indexOf('}');
+
+ if (i == -1) {
+ throw new IllegalArgumentException("invalid QName literal");
+ }
+
+ if (i == s.length() - 1) {
+ throw new IllegalArgumentException("invalid QName literal");
+ } else {
+ return new QName(s.substring(1, i), s.substring(i + 1));
+ }
+ } else {
+ return new QName(s);
+ }
+ }
+
+ /**
+ * Returns a hash code value for this QName object. The hash code
+ * is based on both the localPart and namespaceURI parts of the
+ * QName. This method satisfies the general contract of the
+ * <code>Object.hashCode</code> method.
+ *
+ * @return a hash code value for this Qname object
+ */
+ public final int hashCode() {
+ return namespaceURI.hashCode() ^ localPart.hashCode();
+ }
+
+ /**
+ * Ensure that deserialization properly interns the results.
+ * @param in the ObjectInputStream to be read
+ */
+ private void readObject(ObjectInputStream in) throws
+ IOException, ClassNotFoundException {
+ in.defaultReadObject();
+
+ namespaceURI = namespaceURI.intern();
+ localPart = localPart.intern();
+ prefix = prefix.intern();
+ }
+}
+
diff --git a/asmack-master/static-src/custom/de/measite/smack/AndroidDebugger.java b/asmack-master/static-src/custom/de/measite/smack/AndroidDebugger.java
new file mode 100644
index 0000000..4dfc622
--- /dev/null
+++ b/asmack-master/static-src/custom/de/measite/smack/AndroidDebugger.java
@@ -0,0 +1,185 @@
+package de.measite.smack;
+
+import org.jivesoftware.smack.debugger.SmackDebugger;
+import org.jivesoftware.smack.ConnectionListener;
+import org.jivesoftware.smack.PacketListener;
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.packet.Packet;
+import org.jivesoftware.smack.util.*;
+
+import android.util.Log;
+
+import java.io.Reader;
+import java.io.Writer;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Very simple debugger that prints to the android log the sent and received stanzas. Use
+ * this debugger with caution since printing to the console is an expensive operation that may
+ * even block the thread since only one thread may print at a time.<p>
+ * <p/>
+ * It is possible to not only print the raw sent and received stanzas but also the interpreted
+ * packets by Smack. By default interpreted packets won't be printed. To enable this feature
+ * just change the <tt>printInterpreted</tt> static variable to <tt>true</tt>.
+ *
+ * @author Gaston Dombiak
+ */
+public class AndroidDebugger implements SmackDebugger {
+
+ public static boolean printInterpreted = false;
+ private SimpleDateFormat dateFormatter = new SimpleDateFormat("hh:mm:ss aaa");
+
+ private Connection connection = null;
+
+ private PacketListener listener = null;
+ private ConnectionListener connListener = null;
+
+ private Writer writer;
+ private Reader reader;
+ private ReaderListener readerListener;
+ private WriterListener writerListener;
+
+ public AndroidDebugger(Connection connection, Writer writer, Reader reader) {
+ this.connection = connection;
+ this.writer = writer;
+ this.reader = reader;
+ createDebug();
+ }
+
+ /**
+ * Creates the listeners that will print in the console when new activity is detected.
+ */
+ private void createDebug() {
+ // Create a special Reader that wraps the main Reader and logs data to the GUI.
+ ObservableReader debugReader = new ObservableReader(reader);
+ readerListener = new ReaderListener() {
+ public void read(String str) {
+ Log.d("SMACK",
+ dateFormatter.format(new Date()) + " RCV (" + connection.hashCode() +
+ "): " +
+ str);
+ }
+ };
+ debugReader.addReaderListener(readerListener);
+
+ // Create a special Writer that wraps the main Writer and logs data to the GUI.
+ ObservableWriter debugWriter = new ObservableWriter(writer);
+ writerListener = new WriterListener() {
+ public void write(String str) {
+ Log.d("SMACK",
+ dateFormatter.format(new Date()) + " SENT (" + connection.hashCode() +
+ "): " +
+ str);
+ }
+ };
+ debugWriter.addWriterListener(writerListener);
+
+ // Assign the reader/writer objects to use the debug versions. The packet reader
+ // and writer will use the debug versions when they are created.
+ reader = debugReader;
+ writer = debugWriter;
+
+ // Create a thread that will listen for all incoming packets and write them to
+ // the GUI. This is what we call "interpreted" packet data, since it's the packet
+ // data as Smack sees it and not as it's coming in as raw XML.
+ listener = new PacketListener() {
+ public void processPacket(Packet packet) {
+ if (printInterpreted) {
+ Log.d("SMACK",
+ dateFormatter.format(new Date()) + " RCV PKT (" +
+ connection.hashCode() +
+ "): " +
+ packet.toXML());
+ }
+ }
+ };
+
+ connListener = new ConnectionListener() {
+ public void connectionClosed() {
+ Log.d("SMACK",
+ dateFormatter.format(new Date()) + " Connection closed (" +
+ connection.hashCode() +
+ ")");
+ }
+
+ public void connectionClosedOnError(Exception e) {
+ Log.d("SMACK",
+ dateFormatter.format(new Date()) +
+ " Connection closed due to an exception (" +
+ connection.hashCode() +
+ ")");
+ e.printStackTrace();
+ }
+ public void reconnectionFailed(Exception e) {
+ Log.d("SMACK",
+ dateFormatter.format(new Date()) +
+ " Reconnection failed due to an exception (" +
+ connection.hashCode() +
+ ")");
+ e.printStackTrace();
+ }
+ public void reconnectionSuccessful() {
+ Log.d("SMACK",
+ dateFormatter.format(new Date()) + " Connection reconnected (" +
+ connection.hashCode() +
+ ")");
+ }
+ public void reconnectingIn(int seconds) {
+ Log.d("SMACK",
+ dateFormatter.format(new Date()) + " Connection (" +
+ connection.hashCode() +
+ ") will reconnect in " + seconds);
+ }
+ };
+ }
+
+ public Reader newConnectionReader(Reader newReader) {
+ ((ObservableReader)reader).removeReaderListener(readerListener);
+ ObservableReader debugReader = new ObservableReader(newReader);
+ debugReader.addReaderListener(readerListener);
+ reader = debugReader;
+ return reader;
+ }
+
+ public Writer newConnectionWriter(Writer newWriter) {
+ ((ObservableWriter)writer).removeWriterListener(writerListener);
+ ObservableWriter debugWriter = new ObservableWriter(newWriter);
+ debugWriter.addWriterListener(writerListener);
+ writer = debugWriter;
+ return writer;
+ }
+
+ public void userHasLogged(String user) {
+ boolean isAnonymous = "".equals(StringUtils.parseName(user));
+ String title =
+ "User logged (" + connection.hashCode() + "): "
+ + (isAnonymous ? "" : StringUtils.parseBareAddress(user))
+ + "@"
+ + connection.getServiceName()
+ + ":"
+ + connection.getPort();
+ title += "/" + StringUtils.parseResource(user);
+ Log.d("SMACK", title);
+ // Add the connection listener to the connection so that the debugger can be notified
+ // whenever the connection is closed.
+ connection.addConnectionListener(connListener);
+ }
+
+ public Reader getReader() {
+ return reader;
+ }
+
+ public Writer getWriter() {
+ return writer;
+ }
+
+ public PacketListener getReaderListener() {
+ return listener;
+ }
+
+ public PacketListener getWriterListener() {
+ return null;
+ }
+}
+
diff --git a/asmack-master/static-src/custom/de/measite/smack/Sasl.java b/asmack-master/static-src/custom/de/measite/smack/Sasl.java
new file mode 100644
index 0000000..a59135d
--- /dev/null
+++ b/asmack-master/static-src/custom/de/measite/smack/Sasl.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2009 Rene Treffer
+ *
+ * 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.
+ *
+ */
+package de.measite.smack;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.harmony.javax.security.auth.callback.CallbackHandler;
+import org.apache.harmony.javax.security.sasl.SaslClient;
+import org.apache.harmony.javax.security.sasl.SaslException;
+import org.apache.harmony.javax.security.sasl.SaslServer;
+import org.apache.harmony.javax.security.sasl.SaslServerFactory;
+
+public class Sasl {
+
+ // SaslClientFactory service name
+ private static final String CLIENTFACTORYSRV = "SaslClientFactory"; //$NON-NLS-1$
+
+ // SaslServerFactory service name
+ private static final String SERVERFACTORYSRV = "SaslServerFactory"; //$NON-NLS-1$
+
+ public static final String POLICY_NOPLAINTEXT = "javax.security.sasl.policy.noplaintext"; //$NON-NLS-1$
+
+ public static final String POLICY_NOACTIVE = "javax.security.sasl.policy.noactive"; //$NON-NLS-1$
+
+ public static final String POLICY_NODICTIONARY = "javax.security.sasl.policy.nodictionary"; //$NON-NLS-1$
+
+ public static final String POLICY_NOANONYMOUS = "javax.security.sasl.policy.noanonymous"; //$NON-NLS-1$
+
+ public static final String POLICY_FORWARD_SECRECY = "javax.security.sasl.policy.forward"; //$NON-NLS-1$
+
+ public static final String POLICY_PASS_CREDENTIALS = "javax.security.sasl.policy.credentials"; //$NON-NLS-1$
+
+ public static final String MAX_BUFFER = "javax.security.sasl.maxbuffer"; //$NON-NLS-1$
+
+ public static final String RAW_SEND_SIZE = "javax.security.sasl.rawsendsize"; //$NON-NLS-1$
+
+ public static final String REUSE = "javax.security.sasl.reuse"; //$NON-NLS-1$
+
+ public static final String QOP = "javax.security.sasl.qop"; //$NON-NLS-1$
+
+ public static final String STRENGTH = "javax.security.sasl.strength"; //$NON-NLS-1$
+
+ public static final String SERVER_AUTH = "javax.security.sasl.server.authentication"; //$NON-NLS-1$
+
+ public static Enumeration<SaslClientFactory> getSaslClientFactories() {
+ Hashtable<SaslClientFactory,Object> factories = new Hashtable<SaslClientFactory,Object>();
+ factories.put(new SaslClientFactory(), new Object());
+ return factories.keys();
+ }
+
+ public static Enumeration<SaslServerFactory> getSaslServerFactories() {
+ return org.apache.harmony.javax.security.sasl.Sasl.getSaslServerFactories();
+ }
+
+ public static SaslServer createSaslServer(String mechanism, String protocol,
+ String serverName, Map<String, ?> prop, CallbackHandler cbh) throws SaslException {
+ return org.apache.harmony.javax.security.sasl.Sasl.createSaslServer(mechanism, protocol, serverName, prop, cbh);
+ }
+
+ public static SaslClient createSaslClient(String[] mechanisms, String authanticationID,
+ String protocol, String serverName, Map<String, ?> prop, CallbackHandler cbh)
+ throws SaslException {
+ if (mechanisms == null) {
+ throw new NullPointerException("auth.33"); //$NON-NLS-1$
+ }
+ SaslClientFactory fact = getSaslClientFactories().nextElement();
+ String[] mech = fact.getMechanismNames(null);
+ boolean is = false;
+ if (mech != null) {
+ for (int j = 0; j < mech.length; j++) {
+ for (int n = 0; n < mechanisms.length; n++) {
+ if (mech[j].equals(mechanisms[n])) {
+ is = true;
+ break;
+ }
+ }
+ }
+ }
+ if (is) {
+ return fact.createSaslClient(
+ mechanisms,
+ authanticationID,
+ protocol,
+ serverName,
+ prop,
+ cbh
+ );
+ }
+ return null;
+ }
+
+}
diff --git a/asmack-master/static-src/custom/de/measite/smack/SaslClientFactory.java b/asmack-master/static-src/custom/de/measite/smack/SaslClientFactory.java
new file mode 100644
index 0000000..2fa1ebd
--- /dev/null
+++ b/asmack-master/static-src/custom/de/measite/smack/SaslClientFactory.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2009 Rene Treffer
+ *
+ * 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.
+ *
+ */
+package de.measite.smack;
+
+import java.util.Map;
+
+import com.novell.sasl.client.DigestMD5SaslClient;
+
+import org.apache.harmony.javax.security.auth.callback.CallbackHandler;
+import org.apache.harmony.javax.security.sasl.SaslClient;
+import org.apache.harmony.javax.security.sasl.SaslException;
+import org.apache.qpid.management.common.sasl.PlainSaslClient;
+
+public class SaslClientFactory implements
+ org.apache.harmony.javax.security.sasl.SaslClientFactory {
+
+ @Override
+ public SaslClient createSaslClient(String[] mechanisms,
+ String authorizationId, String protocol, String serverName,
+ Map<String, ?> props, CallbackHandler cbh) throws SaslException {
+ for (String mech: mechanisms) {
+ if ("PLAIN".equals(mech)) {
+ return new PlainSaslClient(authorizationId, cbh);
+ } else
+ if ("DIGEST-MD5".equals(mech)) {
+ return DigestMD5SaslClient.getClient(
+ authorizationId,
+ protocol,
+ serverName,
+ props,
+ cbh
+ );
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String[] getMechanismNames(Map<String, ?> props) {
+ return new String[]{
+ "PLAIN",
+ "DIGEST-MD5"
+ };
+ }
+
+}
diff --git a/asmack-master/static-src/custom/org/jivesoftware/smack/AndroidConnectionConfiguration.java b/asmack-master/static-src/custom/org/jivesoftware/smack/AndroidConnectionConfiguration.java
new file mode 100644
index 0000000..6ec05e0
--- /dev/null
+++ b/asmack-master/static-src/custom/org/jivesoftware/smack/AndroidConnectionConfiguration.java
@@ -0,0 +1,113 @@
+package org.jivesoftware.smack;
+
+import java.io.File;
+
+import android.os.Build;
+
+import org.jivesoftware.smack.proxy.ProxyInfo;
+import org.jivesoftware.smack.util.DNSUtil;
+import org.jivesoftware.smack.util.dns.HostAddress;
+
+import java.util.List;
+
+/**
+ * This class wraps DNS SRV lookups for a new ConnectionConfiguration in a
+ * new thread, since Android API >= 11 (Honeycomb) does not allow network
+ * activity in the main thread.
+ *
+ * @author Florian Schmaus fschmaus@gmail.com
+ *
+ */
+public class AndroidConnectionConfiguration extends ConnectionConfiguration {
+ private static final int DEFAULT_TIMEOUT = 10000;
+
+ /**
+ * Creates a new ConnectionConfiguration for the specified service name.
+ * A DNS SRV lookup will be performed to find out the actual host address
+ * and port to use for the connection.
+ *
+ * @param serviceName the name of the service provided by an XMPP server.
+ */
+ public AndroidConnectionConfiguration(String serviceName) throws XMPPException {
+ super();
+ AndroidInit(serviceName, DEFAULT_TIMEOUT);
+ }
+
+ /**
+ *
+ * @param serviceName
+ * @param timeout
+ * @throws XMPPException
+ */
+ public AndroidConnectionConfiguration(String serviceName, int timeout) throws XMPPException {
+ super();
+ AndroidInit(serviceName, timeout);
+ }
+
+ public AndroidConnectionConfiguration(String host, int port, String name) {
+ super(host, port, name);
+ AndroidInit();
+ }
+
+ private void AndroidInit() {
+ // API 14 is Ice Cream Sandwich
+ if (Build.VERSION.SDK_INT >= 14) {
+ setTruststoreType("AndroidCAStore");
+ setTruststorePassword(null);
+ setTruststorePath(null);
+ } else {
+ setTruststoreType("BKS");
+ String path = System.getProperty("javax.net.ssl.trustStore");
+ if (path == null)
+ path = System.getProperty("java.home") + File.separator + "etc"
+ + File.separator + "security" + File.separator
+ + "cacerts.bks";
+ setTruststorePath(path);
+ }
+ }
+
+ /**
+ *
+ * @param serviceName
+ * @param timeout
+ * @throws XMPPException
+ */
+ private void AndroidInit(String serviceName, int timeout) throws XMPPException {
+ AndroidInit();
+ class DnsSrvLookupRunnable implements Runnable {
+ String serviceName;
+ List<HostAddress> addresses;
+
+ public DnsSrvLookupRunnable(String serviceName) {
+ this.serviceName = serviceName;
+ }
+
+ @Override
+ public void run() {
+ addresses = DNSUtil.resolveXMPPDomain(serviceName);
+ }
+
+ public List<HostAddress> getHostAddresses() {
+ return addresses;
+ }
+ }
+
+ DnsSrvLookupRunnable dnsSrv = new DnsSrvLookupRunnable(serviceName);
+ Thread t = new Thread(dnsSrv, "dns-srv-lookup");
+ t.start();
+ try {
+ t.join(timeout);
+ } catch (InterruptedException e) {
+ throw new XMPPException("DNS lookup timeout after " + timeout + "ms", e);
+ }
+
+ hostAddresses = dnsSrv.getHostAddresses();
+ if (hostAddresses == null) {
+ throw new XMPPException("DNS lookup failure");
+ }
+
+ ProxyInfo proxy = ProxyInfo.forDefaultProxy();
+
+ init(serviceName, proxy);
+ }
+}
diff --git a/asmack-master/static-src/custom/org/jivesoftware/smack/SmackAndroid.java b/asmack-master/static-src/custom/org/jivesoftware/smack/SmackAndroid.java
new file mode 100644
index 0000000..a18d675
--- /dev/null
+++ b/asmack-master/static-src/custom/org/jivesoftware/smack/SmackAndroid.java
@@ -0,0 +1,59 @@
+package org.jivesoftware.smack;
+
+import org.jivesoftware.smack.util.DNSUtil;
+import org.jivesoftware.smack.util.dns.DNSJavaResolver;
+import org.jivesoftware.smackx.ConfigureProviderManager;
+import org.jivesoftware.smackx.InitStaticCode;
+import org.xbill.DNS.ResolverConfig;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+public class SmackAndroid {
+ private static SmackAndroid sSmackAndroid = null;
+
+ private BroadcastReceiver mConnectivityChangedReceiver;
+ private Context mCtx;
+
+ private SmackAndroid(Context ctx) {
+ mCtx = ctx;
+ DNSUtil.setDNSResolver(DNSJavaResolver.getInstance());
+ InitStaticCode.initStaticCode(ctx);
+ ConfigureProviderManager.configureProviderManager();
+ maybeRegisterReceiver();
+ }
+
+ public static SmackAndroid init(Context ctx) {
+ if (sSmackAndroid == null) {
+ sSmackAndroid = new SmackAndroid(ctx);
+ } else {
+ sSmackAndroid.maybeRegisterReceiver();
+ }
+ return sSmackAndroid;
+ }
+
+ public void onDestroy() {
+ if (mConnectivityChangedReceiver != null) {
+ mCtx.unregisterReceiver(mConnectivityChangedReceiver);
+ mConnectivityChangedReceiver = null;
+ }
+ }
+
+ private void maybeRegisterReceiver() {
+ if (mConnectivityChangedReceiver == null) {
+ mConnectivityChangedReceiver = new ConnectivtyChangedReceiver();
+ mCtx.registerReceiver(mConnectivityChangedReceiver, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));
+ }
+ }
+
+ class ConnectivtyChangedReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ ResolverConfig.refresh();
+ }
+
+ }
+}
diff --git a/asmack-master/static-src/custom/org/jivesoftware/smackx/ConfigureProviderManager.java b/asmack-master/static-src/custom/org/jivesoftware/smackx/ConfigureProviderManager.java
new file mode 100644
index 0000000..7c0cdf2
--- /dev/null
+++ b/asmack-master/static-src/custom/org/jivesoftware/smackx/ConfigureProviderManager.java
@@ -0,0 +1,207 @@
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx;
+
+import org.jivesoftware.smack.provider.PrivacyProvider;
+import org.jivesoftware.smack.provider.ProviderManager;
+import org.jivesoftware.smackx.GroupChatInvitation;
+import org.jivesoftware.smackx.PrivateDataManager;
+import org.jivesoftware.smackx.bytestreams.ibb.provider.CloseIQProvider;
+import org.jivesoftware.smackx.bytestreams.ibb.provider.DataPacketProvider;
+import org.jivesoftware.smackx.bytestreams.ibb.provider.OpenIQProvider;
+import org.jivesoftware.smackx.bytestreams.socks5.provider.BytestreamsProvider;
+import org.jivesoftware.smackx.carbons.Carbon;
+import org.jivesoftware.smackx.entitycaps.provider.CapsExtensionProvider;
+import org.jivesoftware.smackx.forward.Forwarded;
+import org.jivesoftware.smackx.packet.AttentionExtension;
+import org.jivesoftware.smackx.packet.ChatStateExtension;
+import org.jivesoftware.smackx.packet.LastActivity;
+import org.jivesoftware.smackx.packet.Nick;
+import org.jivesoftware.smackx.packet.OfflineMessageInfo;
+import org.jivesoftware.smackx.packet.OfflineMessageRequest;
+import org.jivesoftware.smackx.packet.SharedGroupsInfo;
+import org.jivesoftware.smackx.ping.provider.PingProvider;
+import org.jivesoftware.smackx.provider.DataFormProvider;
+import org.jivesoftware.smackx.provider.DelayInformationProvider;
+import org.jivesoftware.smackx.provider.DiscoverInfoProvider;
+import org.jivesoftware.smackx.provider.DiscoverItemsProvider;
+import org.jivesoftware.smackx.provider.HeadersProvider;
+import org.jivesoftware.smackx.provider.HeaderProvider;
+import org.jivesoftware.smackx.provider.MUCAdminProvider;
+import org.jivesoftware.smackx.provider.MUCOwnerProvider;
+import org.jivesoftware.smackx.provider.MUCUserProvider;
+import org.jivesoftware.smackx.provider.MessageEventProvider;
+import org.jivesoftware.smackx.provider.MultipleAddressesProvider;
+import org.jivesoftware.smackx.provider.RosterExchangeProvider;
+import org.jivesoftware.smackx.provider.StreamInitiationProvider;
+import org.jivesoftware.smackx.provider.VCardProvider;
+import org.jivesoftware.smackx.provider.XHTMLExtensionProvider;
+import org.jivesoftware.smackx.pubsub.provider.AffiliationProvider;
+import org.jivesoftware.smackx.pubsub.provider.AffiliationsProvider;
+import org.jivesoftware.smackx.pubsub.provider.ConfigEventProvider;
+import org.jivesoftware.smackx.pubsub.provider.EventProvider;
+import org.jivesoftware.smackx.pubsub.provider.FormNodeProvider;
+import org.jivesoftware.smackx.pubsub.provider.ItemProvider;
+import org.jivesoftware.smackx.pubsub.provider.ItemsProvider;
+import org.jivesoftware.smackx.pubsub.provider.PubSubProvider;
+import org.jivesoftware.smackx.pubsub.provider.RetractEventProvider;
+import org.jivesoftware.smackx.pubsub.provider.SimpleNodeProvider;
+import org.jivesoftware.smackx.pubsub.provider.SubscriptionProvider;
+import org.jivesoftware.smackx.pubsub.provider.SubscriptionsProvider;
+import org.jivesoftware.smackx.receipts.DeliveryReceipt;
+import org.jivesoftware.smackx.search.UserSearch;
+
+/**
+ * Since dalvik on Android does not allow the loading of META-INF files from the
+ * filesystem, you have to register every provider manually.
+ *
+ * The full list of providers is at:
+ * http://fisheye.igniterealtime.org/browse/smack/trunk/build/resources/META-INF/smack.providers?hb=true
+ *
+ * @author Florian Schmaus fschmaus@gmail.com
+ *
+ */
+public class ConfigureProviderManager {
+
+ public static void configureProviderManager() {
+ ProviderManager pm = ProviderManager.getInstance();
+
+ // The order is the same as in the smack.providers file
+
+ // Private Data Storage
+ pm.addIQProvider("query","jabber:iq:private", new PrivateDataManager.PrivateDataIQProvider());
+ // Time
+ try {
+ pm.addIQProvider("query","jabber:iq:time", Class.forName("org.jivesoftware.smackx.packet.Time"));
+ } catch (ClassNotFoundException e) {
+ System.err.println("Can't load class for org.jivesoftware.smackx.packet.Time");
+ }
+
+ // Roster Exchange
+ pm.addExtensionProvider("x","jabber:x:roster", new RosterExchangeProvider());
+ // Message Events
+ pm.addExtensionProvider("x","jabber:x:event", new MessageEventProvider());
+ // Chat State
+ pm.addExtensionProvider("active","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
+ pm.addExtensionProvider("composing","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
+ pm.addExtensionProvider("paused","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
+ pm.addExtensionProvider("inactive","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
+ pm.addExtensionProvider("gone","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
+
+ // XHTML
+ pm.addExtensionProvider("html","http://jabber.org/protocol/xhtml-im", new XHTMLExtensionProvider());
+
+ // Group Chat Invitations
+ pm.addExtensionProvider("x","jabber:x:conference", new GroupChatInvitation.Provider());
+ // Service Discovery # Items
+ pm.addIQProvider("query","http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
+ // Service Discovery # Info
+ pm.addIQProvider("query","http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());
+ // Data Forms
+ pm.addExtensionProvider("x","jabber:x:data", new DataFormProvider());
+ // MUC User
+ pm.addExtensionProvider("x","http://jabber.org/protocol/muc#user", new MUCUserProvider());
+ // MUC Admin
+ pm.addIQProvider("query","http://jabber.org/protocol/muc#admin", new MUCAdminProvider());
+ // MUC Owner
+ pm.addIQProvider("query","http://jabber.org/protocol/muc#owner", new MUCOwnerProvider());
+ // Delayed Delivery
+ pm.addExtensionProvider("x","jabber:x:delay", new DelayInformationProvider());
+ pm.addExtensionProvider("delay", "urn:xmpp:delay", new DelayInformationProvider());
+ // Version
+ try {
+ pm.addIQProvider("query","jabber:iq:version", Class.forName("org.jivesoftware.smackx.packet.Version"));
+ } catch (ClassNotFoundException e) {
+ System.err.println("Can't load class for org.jivesoftware.smackx.packet.Version");
+ }
+ // VCard
+ pm.addIQProvider("vCard","vcard-temp", new VCardProvider());
+ // Offline Message Requests
+ pm.addIQProvider("offline","http://jabber.org/protocol/offline", new OfflineMessageRequest.Provider());
+ // Offline Message Indicator
+ pm.addExtensionProvider("offline","http://jabber.org/protocol/offline", new OfflineMessageInfo.Provider());
+ // Last Activity
+ pm.addIQProvider("query","jabber:iq:last", new LastActivity.Provider());
+ // User Search
+ pm.addIQProvider("query","jabber:iq:search", new UserSearch.Provider());
+ // SharedGroupsInfo
+ pm.addIQProvider("sharedgroup","http://www.jivesoftware.org/protocol/sharedgroup", new SharedGroupsInfo.Provider());
+
+ // JEP-33: Extended Stanza Addressing
+ pm.addExtensionProvider("addresses","http://jabber.org/protocol/address", new MultipleAddressesProvider());
+
+ // FileTransfer
+ pm.addIQProvider("si","http://jabber.org/protocol/si", new StreamInitiationProvider());
+ pm.addIQProvider("query","http://jabber.org/protocol/bytestreams", new BytestreamsProvider());
+ pm.addIQProvider("open","http://jabber.org/protocol/ibb", new OpenIQProvider());
+ pm.addIQProvider("data","http://jabber.org/protocol/ibb", new DataPacketProvider());
+ pm.addIQProvider("close","http://jabber.org/protocol/ibb", new CloseIQProvider());
+ pm.addExtensionProvider("data","http://jabber.org/protocol/ibb", new DataPacketProvider());
+
+ // Privacy
+ pm.addIQProvider("query","jabber:iq:privacy", new PrivacyProvider());
+
+ // SHIM
+ pm.addExtensionProvider("headers", "http://jabber.org/protocol/shim", new HeadersProvider());
+ pm.addExtensionProvider("header", "http://jabber.org/protocol/shim", new HeaderProvider());
+
+ // PubSub
+ pm.addIQProvider("pubsub", "http://jabber.org/protocol/pubsub", new PubSubProvider());
+ pm.addExtensionProvider("create", "http://jabber.org/protocol/pubsub", new SimpleNodeProvider());
+ pm.addExtensionProvider("items", "http://jabber.org/protocol/pubsub", new ItemsProvider());
+ pm.addExtensionProvider("item", "http://jabber.org/protocol/pubsub", new ItemProvider());
+ pm.addExtensionProvider("subscriptions", "http://jabber.org/protocol/pubsub", new SubscriptionsProvider());
+ pm.addExtensionProvider("subscription", "http://jabber.org/protocol/pubsub", new SubscriptionProvider());
+ pm.addExtensionProvider("affiliations", "http://jabber.org/protocol/pubsub", new AffiliationsProvider());
+ pm.addExtensionProvider("affiliation", "http://jabber.org/protocol/pubsub", new AffiliationProvider());
+ pm.addExtensionProvider("options", "http://jabber.org/protocol/pubsub", new FormNodeProvider());
+ // PubSub owner
+ pm.addIQProvider("pubsub", "http://jabber.org/protocol/pubsub#owner", new PubSubProvider());
+ pm.addExtensionProvider("configure", "http://jabber.org/protocol/pubsub#owner", new FormNodeProvider());
+ pm.addExtensionProvider("default", "http://jabber.org/protocol/pubsub#owner", new FormNodeProvider());
+ // PubSub event
+ pm.addExtensionProvider("event", "http://jabber.org/protocol/pubsub#event", new EventProvider());
+ pm.addExtensionProvider("configuration", "http://jabber.org/protocol/pubsub#event", new ConfigEventProvider());
+ pm.addExtensionProvider("delete", "http://jabber.org/protocol/pubsub#event", new SimpleNodeProvider());
+ pm.addExtensionProvider("options", "http://jabber.org/protocol/pubsub#event", new FormNodeProvider());
+ pm.addExtensionProvider("items", "http://jabber.org/protocol/pubsub#event", new ItemsProvider());
+ pm.addExtensionProvider("item", "http://jabber.org/protocol/pubsub#event", new ItemProvider());
+ pm.addExtensionProvider("retract", "http://jabber.org/protocol/pubsub#event", new RetractEventProvider());
+ pm.addExtensionProvider("purge", "http://jabber.org/protocol/pubsub#event", new SimpleNodeProvider());
+
+ // Nick Exchange
+ pm.addExtensionProvider("nick", "http://jabber.org/protocol/nick", new Nick.Provider());
+
+ // Attention
+ pm.addExtensionProvider("attention", "urn:xmpp:attention:0", new AttentionExtension.Provider());
+
+ // XEP-0297 Stanza Forwarding
+ pm.addExtensionProvider("forwarded", "urn:xmpp:forward:0", new Forwarded.Provider());
+
+ // XEP-0280 Message Carbons
+ pm.addExtensionProvider("sent", "urn:xmpp:carbons:2", new Carbon.Provider());
+ pm.addExtensionProvider("received", "urn:xmpp:carbons:2", new Carbon.Provider());
+
+ // XEP-0199 XMPP Ping
+ pm.addIQProvider("ping", "urn:xmpp:ping", new PingProvider());
+
+ // XEP-184 Message Delivery Receipts
+ pm.addExtensionProvider("received", "urn:xmpp:receipts", new DeliveryReceipt.Provider());
+ pm.addExtensionProvider("request", "urn:xmpp:receipts", new DeliveryReceipt.Provider());
+
+ // XEP-0115 Entity Capabilities
+ pm.addExtensionProvider("c", "http://jabber.org/protocol/caps", new CapsExtensionProvider());
+ }
+}
diff --git a/asmack-master/static-src/custom/org/jivesoftware/smackx/InitStaticCode.java b/asmack-master/static-src/custom/org/jivesoftware/smackx/InitStaticCode.java
new file mode 100644
index 0000000..12de5af
--- /dev/null
+++ b/asmack-master/static-src/custom/org/jivesoftware/smackx/InitStaticCode.java
@@ -0,0 +1,51 @@
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jivesoftware.smackx;
+
+import android.content.Context;
+
+/**
+ * Since dalvik on Android does not allow the loading of META-INF files from the
+ * filesystem, the static blocks of some classes have to be inited manually.
+ *
+ * The full list can be found here:
+ * http://fisheye.igniterealtime.org/browse/smack/trunk/build/resources/META-INF/smack-config.xml?hb=true
+ *
+ * @author Florian Schmaus fschmaus@gmail.com
+ *
+ */
+public class InitStaticCode {
+
+ public static void initStaticCode(Context ctx) {
+ // This has the be the application class loader,
+ // *not* the system class loader
+ ClassLoader appClassLoader = ctx.getClassLoader();
+
+ try {
+ Class.forName(org.jivesoftware.smackx.ServiceDiscoveryManager.class.getName(), true, appClassLoader);
+ Class.forName(org.jivesoftware.smack.PrivacyListManager.class.getName(), true, appClassLoader);
+ Class.forName(org.jivesoftware.smackx.XHTMLManager.class.getName(), true, appClassLoader);
+ Class.forName(org.jivesoftware.smackx.muc.MultiUserChat.class.getName(), true, appClassLoader);
+ Class.forName(org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager.class.getName(), true, appClassLoader);
+ Class.forName(org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager.class.getName(), true, appClassLoader);
+ Class.forName(org.jivesoftware.smackx.filetransfer.FileTransferManager.class.getName(), true, appClassLoader);
+ Class.forName(org.jivesoftware.smackx.LastActivityManager.class.getName(), true, appClassLoader);
+ Class.forName(org.jivesoftware.smack.ReconnectionManager.class.getName(), true, appClassLoader);
+ Class.forName(org.jivesoftware.smackx.commands.AdHocCommandManager.class.getName(), true, appClassLoader);
+ } catch (ClassNotFoundException e) {
+ throw new IllegalStateException("Could not init static class blocks", e);
+ }
+ }
+}
diff --git a/asmack-master/static-src/custom/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java b/asmack-master/static-src/custom/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java
new file mode 100644
index 0000000..a6b8694
--- /dev/null
+++ b/asmack-master/static-src/custom/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java
@@ -0,0 +1,92 @@
+/**
+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jivesoftware.smackx.pubsub.provider;
+
+import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.provider.PacketExtensionProvider;
+import org.jivesoftware.smack.provider.ProviderManager;
+import org.jivesoftware.smack.util.PacketParserUtils;
+import org.jivesoftware.smackx.pubsub.Item;
+import org.jivesoftware.smackx.pubsub.PayloadItem;
+import org.jivesoftware.smackx.pubsub.SimplePayload;
+import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Parses an <b>item</b> element as is defined in both the {@link PubSubNamespace#BASIC} and {@link PubSubNamespace#EVENT}
+ * namespaces. To parse the item contents, it will use whatever {@link PacketExtensionProvider} is registered in
+ * <b>smack.providers</b> for its element name and namespace. If no provider is registered, it will return a {@link SimplePayload}.
+ *
+ * @author Robin Collier
+ */
+public class ItemProvider implements PacketExtensionProvider {
+ public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
+ String id = parser.getAttributeValue(null, "id");
+ String node = parser.getAttributeValue(null, "node");
+ String elem = parser.getName();
+
+ int tag = parser.next();
+
+ if (tag == XmlPullParser.END_TAG) {
+ return new Item(id, node);
+ } else {
+ String payloadElemName = parser.getName();
+ String payloadNS = parser.getNamespace();
+
+ if (ProviderManager.getInstance().getExtensionProvider(payloadElemName, payloadNS) == null) {
+ StringBuilder payloadText = new StringBuilder();
+ boolean done = false;
+ boolean isEmptyElement = false;
+
+ // Parse custom payload
+ while (!done) {
+ if (tag == XmlPullParser.END_TAG && parser.getName().equals(elem)) {
+ done = true;
+ } else if (parser.getEventType() == XmlPullParser.START_TAG) {
+ payloadText.append("<").append(parser.getName());
+ if (parser.getName().equals(payloadElemName) && (!"".equals(payloadNS))) {
+ payloadText.append(" xmlns=\"").append(payloadNS).append("\"");
+ }
+ int n = parser.getAttributeCount();
+ for (int i = 0; i < n; i++) {
+ payloadText.append(" ").append(parser.getAttributeName(i)).append("=\"")
+ .append(parser.getAttributeValue(i)).append("\"");
+ }
+ if (parser.isEmptyElementTag()) {
+ payloadText.append("/>");
+ isEmptyElement = true;
+ } else {
+ payloadText.append(">");
+ }
+ } else if (parser.getEventType() == XmlPullParser.END_TAG) {
+ if (isEmptyElement) {
+ isEmptyElement = false;
+ } else {
+ payloadText.append("</").append(parser.getName()).append(">");
+ }
+ } else if (parser.getEventType() == XmlPullParser.TEXT) {
+ payloadText.append(parser.getText());
+ }
+
+ tag = parser.next();
+ }
+ return new PayloadItem<SimplePayload>(id, node, new SimplePayload(payloadElemName, payloadNS,
+ payloadText.toString()));
+ } else {
+ return new PayloadItem<PacketExtension>(id, node, PacketParserUtils.parsePacketExtension(
+ payloadElemName, payloadNS, parser));
+ }
+ }
+ }
+}
diff --git a/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/DigestChallenge.java b/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/DigestChallenge.java
new file mode 100644
index 0000000..90e6247
--- /dev/null
+++ b/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/DigestChallenge.java
@@ -0,0 +1,393 @@
+/* **************************************************************************
+ * $OpenLDAP: /com/novell/sasl/client/DigestChallenge.java,v 1.3 2005/01/17 15:00:54 sunilk Exp $
+ *
+ * Copyright (C) 2003 Novell, Inc. All Rights Reserved.
+ *
+ * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
+ * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
+ * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
+ * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
+ * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
+ * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
+ * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
+ * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
+ ******************************************************************************/
+package com.novell.sasl.client;
+
+import java.util.*;
+import org.apache.harmony.javax.security.sasl.*;
+
+/**
+ * Implements the DigestChallenge class which will be used by the
+ * DigestMD5SaslClient class
+ */
+class DigestChallenge extends Object
+{
+ public static final int QOP_AUTH = 0x01;
+ public static final int QOP_AUTH_INT = 0x02;
+ public static final int QOP_AUTH_CONF = 0x04;
+ public static final int QOP_UNRECOGNIZED = 0x08;
+
+ private static final int CIPHER_3DES = 0x01;
+ private static final int CIPHER_DES = 0x02;
+ private static final int CIPHER_RC4_40 = 0x04;
+ private static final int CIPHER_RC4 = 0x08;
+ private static final int CIPHER_RC4_56 = 0x10;
+ private static final int CIPHER_UNRECOGNIZED = 0x20;
+ private static final int CIPHER_RECOGNIZED_MASK =
+ CIPHER_3DES | CIPHER_DES | CIPHER_RC4_40 | CIPHER_RC4 | CIPHER_RC4_56;
+
+ private ArrayList m_realms;
+ private String m_nonce;
+ private int m_qop;
+ private boolean m_staleFlag;
+ private int m_maxBuf;
+ private String m_characterSet;
+ private String m_algorithm;
+ private int m_cipherOptions;
+
+ DigestChallenge(
+ byte[] challenge)
+ throws SaslException
+ {
+ m_realms = new ArrayList(5);
+ m_nonce = null;
+ m_qop = 0;
+ m_staleFlag = false;
+ m_maxBuf = -1;
+ m_characterSet = null;
+ m_algorithm = null;
+ m_cipherOptions = 0;
+
+ DirectiveList dirList = new DirectiveList(challenge);
+ try
+ {
+ dirList.parseDirectives();
+ checkSemantics(dirList);
+ }
+ catch (SaslException e)
+ {
+ }
+ }
+
+ /**
+ * Checks the semantics of the directives in the directive list as parsed
+ * from the digest challenge byte array.
+ *
+ * @param dirList the list of directives parsed from the digest challenge
+ *
+ * @exception SaslException If a semantic error occurs
+ */
+ void checkSemantics(
+ DirectiveList dirList) throws SaslException
+ {
+ Iterator directives = dirList.getIterator();
+ ParsedDirective directive;
+ String name;
+
+ while (directives.hasNext())
+ {
+ directive = (ParsedDirective)directives.next();
+ name = directive.getName();
+ if (name.equals("realm"))
+ handleRealm(directive);
+ else if (name.equals("nonce"))
+ handleNonce(directive);
+ else if (name.equals("qop"))
+ handleQop(directive);
+ else if (name.equals("maxbuf"))
+ handleMaxbuf(directive);
+ else if (name.equals("charset"))
+ handleCharset(directive);
+ else if (name.equals("algorithm"))
+ handleAlgorithm(directive);
+ else if (name.equals("cipher"))
+ handleCipher(directive);
+ else if (name.equals("stale"))
+ handleStale(directive);
+ }
+
+ /* post semantic check */
+ if (-1 == m_maxBuf)
+ m_maxBuf = 65536;
+
+ if (m_qop == 0)
+ m_qop = QOP_AUTH;
+ else if ( (m_qop & QOP_AUTH) != QOP_AUTH )
+ throw new SaslException("Only qop-auth is supported by client");
+ else if ( ((m_qop & QOP_AUTH_CONF) == QOP_AUTH_CONF) &&
+ (0 == (m_cipherOptions & CIPHER_RECOGNIZED_MASK)) )
+ throw new SaslException("Invalid cipher options");
+ else if (null == m_nonce)
+ throw new SaslException("Missing nonce directive");
+ else if (m_staleFlag)
+ throw new SaslException("Unexpected stale flag");
+ else if ( null == m_algorithm )
+ throw new SaslException("Missing algorithm directive");
+ }
+
+ /**
+ * This function implements the semenatics of the nonce directive.
+ *
+ * @param pd ParsedDirective
+ *
+ * @exception SaslException If an error occurs due to too many nonce
+ * values
+ */
+ void handleNonce(
+ ParsedDirective pd) throws SaslException
+ {
+ if (null != m_nonce)
+ throw new SaslException("Too many nonce values.");
+
+ m_nonce = pd.getValue();
+ }
+
+ /**
+ * This function implements the semenatics of the realm directive.
+ *
+ * @param pd ParsedDirective
+ */
+ void handleRealm(
+ ParsedDirective pd)
+ {
+ m_realms.add(pd.getValue());
+ }
+
+ /**
+ * This function implements the semenatics of the qop (quality of protection)
+ * directive. The value of the qop directive is as defined below:
+ * qop-options = "qop" "=" <"> qop-list <">
+ * qop-list = 1#qop-value
+ * qop-value = "auth" | "auth-int" | "auth-conf" | token
+ *
+ * @param pd ParsedDirective
+ *
+ * @exception SaslException If an error occurs due to too many qop
+ * directives
+ */
+ void handleQop(
+ ParsedDirective pd) throws SaslException
+ {
+ String token;
+ TokenParser parser;
+
+ if (m_qop != 0)
+ throw new SaslException("Too many qop directives.");
+
+ parser = new TokenParser(pd.getValue());
+ for (token = parser.parseToken();
+ token != null;
+ token = parser.parseToken())
+ {
+ if (token.equals("auth"))
+ m_qop |= QOP_AUTH;
+ else if (token.equals("auth-int"))
+ m_qop |= QOP_AUTH_INT;
+ else if (token.equals("auth-conf"))
+ m_qop |= QOP_AUTH_CONF;
+ else
+ m_qop |= QOP_UNRECOGNIZED;
+ }
+ }
+
+ /**
+ * This function implements the semenatics of the Maxbuf directive.
+ * the value is defined as: 1*DIGIT
+ *
+ * @param pd ParsedDirective
+ *
+ * @exception SaslException If an error occur
+ */
+ void handleMaxbuf(
+ ParsedDirective pd) throws SaslException
+ {
+ if (-1 != m_maxBuf) /*it's initialized to -1 */
+ throw new SaslException("Too many maxBuf directives.");
+
+ m_maxBuf = Integer.parseInt(pd.getValue());
+
+ if (0 == m_maxBuf)
+ throw new SaslException("Max buf value must be greater than zero.");
+ }
+
+ /**
+ * This function implements the semenatics of the charset directive.
+ * the value is defined as: 1*DIGIT
+ *
+ * @param pd ParsedDirective
+ *
+ * @exception SaslException If an error occurs dur to too many charset
+ * directives or Invalid character encoding
+ * directive
+ */
+ void handleCharset(
+ ParsedDirective pd) throws SaslException
+ {
+ if (null != m_characterSet)
+ throw new SaslException("Too many charset directives.");
+
+ m_characterSet = pd.getValue();
+
+ if (!m_characterSet.equals("utf-8"))
+ throw new SaslException("Invalid character encoding directive");
+ }
+
+ /**
+ * This function implements the semenatics of the charset directive.
+ * the value is defined as: 1*DIGIT
+ *
+ * @param pd ParsedDirective
+ *
+ * @exception SaslException If an error occurs due to too many algorith
+ * directive or Invalid algorithm directive
+ * value
+ */
+ void handleAlgorithm(
+ ParsedDirective pd) throws SaslException
+ {
+ if (null != m_algorithm)
+ throw new SaslException("Too many algorithm directives.");
+
+ m_algorithm = pd.getValue();
+
+ if (!"md5-sess".equals(m_algorithm))
+ throw new SaslException("Invalid algorithm directive value: " +
+ m_algorithm);
+ }
+
+ /**
+ * This function implements the semenatics of the cipher-opts directive
+ * directive. The value of the qop directive is as defined below:
+ * qop-options = "qop" "=" <"> qop-list <">
+ * qop-list = 1#qop-value
+ * qop-value = "auth" | "auth-int" | "auth-conf" | token
+ *
+ * @param pd ParsedDirective
+ *
+ * @exception SaslException If an error occurs due to Too many cipher
+ * directives
+ */
+ void handleCipher(
+ ParsedDirective pd) throws SaslException
+ {
+ String token;
+ TokenParser parser;
+
+ if (0 != m_cipherOptions)
+ throw new SaslException("Too many cipher directives.");
+
+ parser = new TokenParser(pd.getValue());
+ token = parser.parseToken();
+ for (token = parser.parseToken();
+ token != null;
+ token = parser.parseToken())
+ {
+ if ("3des".equals(token))
+ m_cipherOptions |= CIPHER_3DES;
+ else if ("des".equals(token))
+ m_cipherOptions |= CIPHER_DES;
+ else if ("rc4-40".equals(token))
+ m_cipherOptions |= CIPHER_RC4_40;
+ else if ("rc4".equals(token))
+ m_cipherOptions |= CIPHER_RC4;
+ else if ("rc4-56".equals(token))
+ m_cipherOptions |= CIPHER_RC4_56;
+ else
+ m_cipherOptions |= CIPHER_UNRECOGNIZED;
+ }
+
+ if (m_cipherOptions == 0)
+ m_cipherOptions = CIPHER_UNRECOGNIZED;
+ }
+
+ /**
+ * This function implements the semenatics of the stale directive.
+ *
+ * @param pd ParsedDirective
+ *
+ * @exception SaslException If an error occurs due to Too many stale
+ * directives or Invalid stale directive value
+ */
+ void handleStale(
+ ParsedDirective pd) throws SaslException
+ {
+ if (false != m_staleFlag)
+ throw new SaslException("Too many stale directives.");
+
+ if ("true".equals(pd.getValue()))
+ m_staleFlag = true;
+ else
+ throw new SaslException("Invalid stale directive value: " +
+ pd.getValue());
+ }
+
+ /**
+ * Return the list of the All the Realms
+ *
+ * @return List of all the realms
+ */
+ public ArrayList getRealms()
+ {
+ return m_realms;
+ }
+
+ /**
+ * @return Returns the Nonce
+ */
+ public String getNonce()
+ {
+ return m_nonce;
+ }
+
+ /**
+ * Return the quality-of-protection
+ *
+ * @return The quality-of-protection
+ */
+ public int getQop()
+ {
+ return m_qop;
+ }
+
+ /**
+ * @return The state of the Staleflag
+ */
+ public boolean getStaleFlag()
+ {
+ return m_staleFlag;
+ }
+
+ /**
+ * @return The Maximum Buffer value
+ */
+ public int getMaxBuf()
+ {
+ return m_maxBuf;
+ }
+
+ /**
+ * @return character set values as string
+ */
+ public String getCharacterSet()
+ {
+ return m_characterSet;
+ }
+
+ /**
+ * @return The String value of the algorithm
+ */
+ public String getAlgorithm()
+ {
+ return m_algorithm;
+ }
+
+ /**
+ * @return The cipher options
+ */
+ public int getCipherOptions()
+ {
+ return m_cipherOptions;
+ }
+}
+
diff --git a/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/DigestMD5SaslClient.java b/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/DigestMD5SaslClient.java
new file mode 100644
index 0000000..eb488fe
--- /dev/null
+++ b/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/DigestMD5SaslClient.java
@@ -0,0 +1,820 @@
+/* **************************************************************************
+ * $OpenLDAP: /com/novell/sasl/client/DigestMD5SaslClient.java,v 1.4 2005/01/17 15:00:54 sunilk Exp $
+ *
+ * Copyright (C) 2003 Novell, Inc. All Rights Reserved.
+ *
+ * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
+ * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
+ * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
+ * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
+ * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
+ * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
+ * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
+ * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
+ ******************************************************************************/
+package com.novell.sasl.client;
+
+import org.apache.harmony.javax.security.sasl.*;
+import org.apache.harmony.javax.security.auth.callback.*;
+import java.security.SecureRandom;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.io.UnsupportedEncodingException;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Implements the Client portion of DigestMD5 Sasl mechanism.
+ */
+public class DigestMD5SaslClient implements SaslClient
+{
+ private String m_authorizationId = "";
+ private String m_protocol = "";
+ private String m_serverName = "";
+ private Map m_props;
+ private CallbackHandler m_cbh;
+ private int m_state;
+ private String m_qopValue = "";
+ private char[] m_HA1 = null;
+ private String m_digestURI;
+ private DigestChallenge m_dc;
+ private String m_clientNonce = "";
+ private String m_realm = "";
+ private String m_name = "";
+
+ private static final int STATE_INITIAL = 0;
+ private static final int STATE_DIGEST_RESPONSE_SENT = 1;
+ private static final int STATE_VALID_SERVER_RESPONSE = 2;
+ private static final int STATE_INVALID_SERVER_RESPONSE = 3;
+ private static final int STATE_DISPOSED = 4;
+
+ private static final int NONCE_BYTE_COUNT = 32;
+ private static final int NONCE_HEX_COUNT = 2*NONCE_BYTE_COUNT;
+
+ private static final String DIGEST_METHOD = "AUTHENTICATE";
+
+ /**
+ * Creates an DigestMD5SaslClient object using the parameters supplied.
+ * Assumes that the QOP, STRENGTH, and SERVER_AUTH properties are
+ * contained in props
+ *
+ * @param authorizationId The possibly null protocol-dependent
+ * identification to be used for authorization. If
+ * null or empty, the server derives an authorization
+ * ID from the client's authentication credentials.
+ * When the SASL authentication completes
+ * successfully, the specified entity is granted
+ * access.
+ *
+ * @param protocol The non-null string name of the protocol for which
+ * the authentication is being performed (e.g. "ldap")
+ *
+ * @param serverName The non-null fully qualified host name of the server
+ * to authenticate to
+ *
+ * @param props The possibly null set of properties used to select
+ * the SASL mechanism and to configure the
+ * authentication exchange of the selected mechanism.
+ * See the Sasl class for a list of standard properties.
+ * Other, possibly mechanism-specific, properties can
+ * be included. Properties not relevant to the selected
+ * mechanism are ignored.
+ *
+ * @param cbh The possibly null callback handler to used by the
+ * SASL mechanisms to get further information from the
+ * application/library to complete the authentication.
+ * For example, a SASL mechanism might require the
+ * authentication ID, password and realm from the
+ * caller. The authentication ID is requested by using
+ * a NameCallback. The password is requested by using
+ * a PasswordCallback. The realm is requested by using
+ * a RealmChoiceCallback if there is a list of realms
+ * to choose from, and by using a RealmCallback if the
+ * realm must be entered.
+ *
+ * @return A possibly null SaslClient created using the
+ * parameters supplied. If null, this factory cannot
+ * produce a SaslClient using the parameters supplied.
+ *
+ * @exception SaslException If a SaslClient instance cannot be created
+ * because of an error
+ */
+ public static SaslClient getClient(
+ String authorizationId,
+ String protocol,
+ String serverName,
+ Map props,
+ CallbackHandler cbh)
+ {
+ String desiredQOP = (String)props.get(Sasl.QOP);
+ String desiredStrength = (String)props.get(Sasl.STRENGTH);
+ String serverAuth = (String)props.get(Sasl.SERVER_AUTH);
+
+ //only support qop equal to auth
+ if ((desiredQOP != null) && !"auth".equals(desiredQOP))
+ return null;
+
+ //doesn't support server authentication
+ if ((serverAuth != null) && !"false".equals(serverAuth))
+ return null;
+
+ //need a callback handler to get the password
+ if (cbh == null)
+ return null;
+
+ return new DigestMD5SaslClient(authorizationId, protocol,
+ serverName, props, cbh);
+ }
+
+ /**
+ * Creates an DigestMD5SaslClient object using the parameters supplied.
+ * Assumes that the QOP, STRENGTH, and SERVER_AUTH properties are
+ * contained in props
+ *
+ * @param authorizationId The possibly null protocol-dependent
+ * identification to be used for authorization. If
+ * null or empty, the server derives an authorization
+ * ID from the client's authentication credentials.
+ * When the SASL authentication completes
+ * successfully, the specified entity is granted
+ * access.
+ *
+ * @param protocol The non-null string name of the protocol for which
+ * the authentication is being performed (e.g. "ldap")
+ *
+ * @param serverName The non-null fully qualified host name of the server
+ * to authenticate to
+ *
+ * @param props The possibly null set of properties used to select
+ * the SASL mechanism and to configure the
+ * authentication exchange of the selected mechanism.
+ * See the Sasl class for a list of standard properties.
+ * Other, possibly mechanism-specific, properties can
+ * be included. Properties not relevant to the selected
+ * mechanism are ignored.
+ *
+ * @param cbh The possibly null callback handler to used by the
+ * SASL mechanisms to get further information from the
+ * application/library to complete the authentication.
+ * For example, a SASL mechanism might require the
+ * authentication ID, password and realm from the
+ * caller. The authentication ID is requested by using
+ * a NameCallback. The password is requested by using
+ * a PasswordCallback. The realm is requested by using
+ * a RealmChoiceCallback if there is a list of realms
+ * to choose from, and by using a RealmCallback if the
+ * realm must be entered.
+ *
+ */
+ private DigestMD5SaslClient(
+ String authorizationId,
+ String protocol,
+ String serverName,
+ Map props,
+ CallbackHandler cbh)
+ {
+ m_authorizationId = authorizationId;
+ m_protocol = protocol;
+ m_serverName = serverName;
+ m_props = props;
+ m_cbh = cbh;
+
+ m_state = STATE_INITIAL;
+ }
+
+ /**
+ * Determines if this mechanism has an optional initial response. If true,
+ * caller should call evaluateChallenge() with an empty array to get the
+ * initial response.
+ *
+ * @return true if this mechanism has an initial response
+ */
+ public boolean hasInitialResponse()
+ {
+ return false;
+ }
+
+ /**
+ * Determines if the authentication exchange has completed. This method
+ * may be called at any time, but typically, it will not be called until
+ * the caller has received indication from the server (in a protocol-
+ * specific manner) that the exchange has completed.
+ *
+ * @return true if the authentication exchange has completed;
+ * false otherwise.
+ */
+ public boolean isComplete()
+ {
+ if ((m_state == STATE_VALID_SERVER_RESPONSE) ||
+ (m_state == STATE_INVALID_SERVER_RESPONSE) ||
+ (m_state == STATE_DISPOSED))
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * Unwraps a byte array received from the server. This method can be called
+ * only after the authentication exchange has completed (i.e., when
+ * isComplete() returns true) and only if the authentication exchange has
+ * negotiated integrity and/or privacy as the quality of protection;
+ * otherwise, an IllegalStateException is thrown.
+ *
+ * incoming is the contents of the SASL buffer as defined in RFC 2222
+ * without the leading four octet field that represents the length.
+ * offset and len specify the portion of incoming to use.
+ *
+ * @param incoming A non-null byte array containing the encoded bytes
+ * from the server
+ * @param offset The starting position at incoming of the bytes to use
+ *
+ * @param len The number of bytes from incoming to use
+ *
+ * @return A non-null byte array containing the decoded bytes
+ *
+ */
+ public byte[] unwrap(
+ byte[] incoming,
+ int offset,
+ int len)
+ throws SaslException
+ {
+ throw new IllegalStateException(
+ "unwrap: QOP has neither integrity nor privacy>");
+ }
+
+ /**
+ * Wraps a byte array to be sent to the server. This method can be called
+ * only after the authentication exchange has completed (i.e., when
+ * isComplete() returns true) and only if the authentication exchange has
+ * negotiated integrity and/or privacy as the quality of protection;
+ * otherwise, an IllegalStateException is thrown.
+ *
+ * The result of this method will make up the contents of the SASL buffer as
+ * defined in RFC 2222 without the leading four octet field that represents
+ * the length. offset and len specify the portion of outgoing to use.
+ *
+ * @param outgoing A non-null byte array containing the bytes to encode
+ * @param offset The starting position at outgoing of the bytes to use
+ * @param len The number of bytes from outgoing to use
+ *
+ * @return A non-null byte array containing the encoded bytes
+ *
+ * @exception SaslException if incoming cannot be successfully unwrapped.
+ *
+ * @exception IllegalStateException if the authentication exchange has
+ * not completed, or if the negotiated quality of
+ * protection has neither integrity nor privacy.
+ */
+ public byte[] wrap(
+ byte[] outgoing,
+ int offset,
+ int len)
+ throws SaslException
+ {
+ throw new IllegalStateException(
+ "wrap: QOP has neither integrity nor privacy>");
+ }
+
+ /**
+ * Retrieves the negotiated property. This method can be called only after
+ * the authentication exchange has completed (i.e., when isComplete()
+ * returns true); otherwise, an IllegalStateException is thrown.
+ *
+ * @param propName The non-null property name
+ *
+ * @return The value of the negotiated property. If null, the property was
+ * not negotiated or is not applicable to this mechanism.
+ *
+ * @exception IllegalStateException if this authentication exchange has
+ * not completed
+ */
+ public Object getNegotiatedProperty(
+ String propName)
+ {
+ if (m_state != STATE_VALID_SERVER_RESPONSE)
+ throw new IllegalStateException(
+ "getNegotiatedProperty: authentication exchange not complete.");
+
+ if (Sasl.QOP.equals(propName))
+ return "auth";
+ else
+ return null;
+ }
+
+ /**
+ * Disposes of any system resources or security-sensitive information the
+ * SaslClient might be using. Invoking this method invalidates the
+ * SaslClient instance. This method is idempotent.
+ *
+ * @exception SaslException if a problem was encountered while disposing
+ * of the resources
+ */
+ public void dispose()
+ throws SaslException
+ {
+ if (m_state != STATE_DISPOSED)
+ {
+ m_state = STATE_DISPOSED;
+ }
+ }
+
+ /**
+ * Evaluates the challenge data and generates a response. If a challenge
+ * is received from the server during the authentication process, this
+ * method is called to prepare an appropriate next response to submit to
+ * the server.
+ *
+ * @param challenge The non-null challenge sent from the server. The
+ * challenge array may have zero length.
+ *
+ * @return The possibly null reponse to send to the server. It is null
+ * if the challenge accompanied a "SUCCESS" status and the
+ * challenge only contains data for the client to update its
+ * state and no response needs to be sent to the server.
+ * The response is a zero-length byte array if the client is to
+ * send a response with no data.
+ *
+ * @exception SaslException If an error occurred while processing the
+ * challenge or generating a response.
+ */
+ public byte[] evaluateChallenge(
+ byte[] challenge)
+ throws SaslException
+ {
+ byte[] response = null;
+
+ //printState();
+ switch (m_state)
+ {
+ case STATE_INITIAL:
+ if (challenge.length == 0)
+ throw new SaslException("response = byte[0]");
+ else
+ try
+ {
+ response = createDigestResponse(challenge).
+ getBytes("UTF-8");
+ m_state = STATE_DIGEST_RESPONSE_SENT;
+ }
+ catch (java.io.UnsupportedEncodingException e)
+ {
+ throw new SaslException(
+ "UTF-8 encoding not suppported by platform", e);
+ }
+ break;
+ case STATE_DIGEST_RESPONSE_SENT:
+ if (checkServerResponseAuth(challenge))
+ m_state = STATE_VALID_SERVER_RESPONSE;
+ else
+ {
+ m_state = STATE_INVALID_SERVER_RESPONSE;
+ throw new SaslException("Could not validate response-auth " +
+ "value from server");
+ }
+ break;
+ case STATE_VALID_SERVER_RESPONSE:
+ case STATE_INVALID_SERVER_RESPONSE:
+ throw new SaslException("Authentication sequence is complete");
+ case STATE_DISPOSED:
+ throw new SaslException("Client has been disposed");
+ default:
+ throw new SaslException("Unknown client state.");
+ }
+
+ return response;
+ }
+
+ /**
+ * This function takes a 16 byte binary md5-hash value and creates a 32
+ * character (plus a terminating null character) hex-digit
+ * representation of binary data.
+ *
+ * @param hash 16 byte binary md5-hash value in bytes
+ *
+ * @return 32 character (plus a terminating null character) hex-digit
+ * representation of binary data.
+ */
+ char[] convertToHex(
+ byte[] hash)
+ {
+ int i;
+ byte j;
+ byte fifteen = 15;
+ char[] hex = new char[32];
+
+ for (i = 0; i < 16; i++)
+ {
+ //convert value of top 4 bits to hex char
+ hex[i*2] = getHexChar((byte)((hash[i] & 0xf0) >> 4));
+ //convert value of bottom 4 bits to hex char
+ hex[(i*2)+1] = getHexChar((byte)(hash[i] & 0x0f));
+ }
+
+ return hex;
+ }
+
+ /**
+ * Calculates the HA1 portion of the response
+ *
+ * @param algorithm Algorith to use.
+ * @param userName User being authenticated
+ * @param realm realm information
+ * @param password password of teh user
+ * @param nonce nonce value
+ * @param clientNonce Clients Nonce value
+ *
+ * @return HA1 portion of the response in a character array
+ *
+ * @exception SaslException If an error occurs
+ */
+ char[] DigestCalcHA1(
+ String algorithm,
+ String userName,
+ String realm,
+ String password,
+ String nonce,
+ String clientNonce) throws SaslException
+ {
+ byte[] hash;
+
+ try
+ {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+
+ md.update(userName.getBytes("UTF-8"));
+ md.update(":".getBytes("UTF-8"));
+ md.update(realm.getBytes("UTF-8"));
+ md.update(":".getBytes("UTF-8"));
+ md.update(password.getBytes("UTF-8"));
+ hash = md.digest();
+
+ if ("md5-sess".equals(algorithm))
+ {
+ md.update(hash);
+ md.update(":".getBytes("UTF-8"));
+ md.update(nonce.getBytes("UTF-8"));
+ md.update(":".getBytes("UTF-8"));
+ md.update(clientNonce.getBytes("UTF-8"));
+ hash = md.digest();
+ }
+ }
+ catch(NoSuchAlgorithmException e)
+ {
+ throw new SaslException("No provider found for MD5 hash", e);
+ }
+ catch(UnsupportedEncodingException e)
+ {
+ throw new SaslException(
+ "UTF-8 encoding not supported by platform.", e);
+ }
+
+ return convertToHex(hash);
+ }
+
+
+ /**
+ * This function calculates the response-value of the response directive of
+ * the digest-response as documented in RFC 2831
+ *
+ * @param HA1 H(A1)
+ * @param serverNonce nonce from server
+ * @param nonceCount 8 hex digits
+ * @param clientNonce client nonce
+ * @param qop qop-value: "", "auth", "auth-int"
+ * @param method method from the request
+ * @param digestUri requested URL
+ * @param clientResponseFlag request-digest or response-digest
+ *
+ * @return Response-value of the response directive of the digest-response
+ *
+ * @exception SaslException If an error occurs
+ */
+ char[] DigestCalcResponse(
+ char[] HA1, /* H(A1) */
+ String serverNonce, /* nonce from server */
+ String nonceCount, /* 8 hex digits */
+ String clientNonce, /* client nonce */
+ String qop, /* qop-value: "", "auth", "auth-int" */
+ String method, /* method from the request */
+ String digestUri, /* requested URL */
+ boolean clientResponseFlag) /* request-digest or response-digest */
+ throws SaslException
+ {
+ byte[] HA2;
+ byte[] respHash;
+ char[] HA2Hex;
+
+ // calculate H(A2)
+ try
+ {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ if (clientResponseFlag)
+ md.update(method.getBytes("UTF-8"));
+ md.update(":".getBytes("UTF-8"));
+ md.update(digestUri.getBytes("UTF-8"));
+ if ("auth-int".equals(qop))
+ {
+ md.update(":".getBytes("UTF-8"));
+ md.update("00000000000000000000000000000000".getBytes("UTF-8"));
+ }
+ HA2 = md.digest();
+ HA2Hex = convertToHex(HA2);
+
+ // calculate response
+ md.update(new String(HA1).getBytes("UTF-8"));
+ md.update(":".getBytes("UTF-8"));
+ md.update(serverNonce.getBytes("UTF-8"));
+ md.update(":".getBytes("UTF-8"));
+ if (qop.length() > 0)
+ {
+ md.update(nonceCount.getBytes("UTF-8"));
+ md.update(":".getBytes("UTF-8"));
+ md.update(clientNonce.getBytes("UTF-8"));
+ md.update(":".getBytes("UTF-8"));
+ md.update(qop.getBytes("UTF-8"));
+ md.update(":".getBytes("UTF-8"));
+ }
+ md.update(new String(HA2Hex).getBytes("UTF-8"));
+ respHash = md.digest();
+ }
+ catch(NoSuchAlgorithmException e)
+ {
+ throw new SaslException("No provider found for MD5 hash", e);
+ }
+ catch(UnsupportedEncodingException e)
+ {
+ throw new SaslException(
+ "UTF-8 encoding not supported by platform.", e);
+ }
+
+ return convertToHex(respHash);
+ }
+
+
+ /**
+ * Creates the intial response to be sent to the server.
+ *
+ * @param challenge Challenge in bytes recived form the Server
+ *
+ * @return Initial response to be sent to the server
+ */
+ private String createDigestResponse(
+ byte[] challenge)
+ throws SaslException
+ {
+ char[] response;
+ StringBuffer digestResponse = new StringBuffer(512);
+ int realmSize;
+
+ m_dc = new DigestChallenge(challenge);
+
+ m_digestURI = m_protocol + "/" + m_serverName;
+
+ if ((m_dc.getQop() & DigestChallenge.QOP_AUTH)
+ == DigestChallenge.QOP_AUTH )
+ m_qopValue = "auth";
+ else
+ throw new SaslException("Client only supports qop of 'auth'");
+
+ //get call back information
+ Callback[] callbacks = new Callback[3];
+ ArrayList realms = m_dc.getRealms();
+ realmSize = realms.size();
+ if (realmSize == 0)
+ {
+ callbacks[0] = new RealmCallback("Realm");
+ }
+ else if (realmSize == 1)
+ {
+ callbacks[0] = new RealmCallback("Realm", (String)realms.get(0));
+ }
+ else
+ {
+ callbacks[0] =
+ new RealmChoiceCallback(
+ "Realm",
+ (String[])realms.toArray(new String[realmSize]),
+ 0, //the default choice index
+ false); //no multiple selections
+ }
+
+ callbacks[1] = new PasswordCallback("Password", false);
+ //false = no echo
+
+ if (m_authorizationId == null || m_authorizationId.length() == 0)
+ callbacks[2] = new NameCallback("Name");
+ else
+ callbacks[2] = new NameCallback("Name", m_authorizationId);
+
+ try
+ {
+ m_cbh.handle(callbacks);
+ }
+ catch(UnsupportedCallbackException e)
+ {
+ throw new SaslException("Handler does not support" +
+ " necessary callbacks",e);
+ }
+ catch(IOException e)
+ {
+ throw new SaslException("IO exception in CallbackHandler.", e);
+ }
+
+ if (realmSize > 1)
+ {
+ int[] selections =
+ ((RealmChoiceCallback)callbacks[0]).getSelectedIndexes();
+
+ if (selections.length > 0)
+ m_realm =
+ ((RealmChoiceCallback)callbacks[0]).getChoices()[selections[0]];
+ else
+ m_realm = ((RealmChoiceCallback)callbacks[0]).getChoices()[0];
+ }
+ else
+ m_realm = ((RealmCallback)callbacks[0]).getText();
+
+ m_clientNonce = getClientNonce();
+
+ m_name = ((NameCallback)callbacks[2]).getName();
+ if (m_name == null)
+ m_name = ((NameCallback)callbacks[2]).getDefaultName();
+ if (m_name == null)
+ throw new SaslException("No user name was specified.");
+
+ m_HA1 = DigestCalcHA1(
+ m_dc.getAlgorithm(),
+ m_name,
+ m_realm,
+ new String(((PasswordCallback)callbacks[1]).getPassword()),
+ m_dc.getNonce(),
+ m_clientNonce);
+
+ response = DigestCalcResponse(m_HA1,
+ m_dc.getNonce(),
+ "00000001",
+ m_clientNonce,
+ m_qopValue,
+ "AUTHENTICATE",
+ m_digestURI,
+ true);
+
+ digestResponse.append("username=\"");
+ digestResponse.append(m_authorizationId);
+ if (0 != m_realm.length())
+ {
+ digestResponse.append("\",realm=\"");
+ digestResponse.append(m_realm);
+ }
+ digestResponse.append("\",cnonce=\"");
+ digestResponse.append(m_clientNonce);
+ digestResponse.append("\",nc=");
+ digestResponse.append("00000001"); //nounce count
+ digestResponse.append(",qop=");
+ digestResponse.append(m_qopValue);
+ digestResponse.append(",digest-uri=\"ldap/");
+ digestResponse.append(m_serverName);
+ digestResponse.append("\",response=");
+ digestResponse.append(response);
+ digestResponse.append(",charset=utf-8,nonce=\"");
+ digestResponse.append(m_dc.getNonce());
+ digestResponse.append("\"");
+
+ return digestResponse.toString();
+ }
+
+
+ /**
+ * This function validates the server response. This step performs a
+ * modicum of mutual authentication by verifying that the server knows
+ * the user's password
+ *
+ * @param serverResponse Response recived form Server
+ *
+ * @return true if the mutual authentication succeeds;
+ * else return false
+ *
+ * @exception SaslException If an error occurs
+ */
+ boolean checkServerResponseAuth(
+ byte[] serverResponse) throws SaslException
+ {
+ char[] response;
+ ResponseAuth responseAuth = null;
+ String responseStr;
+
+ responseAuth = new ResponseAuth(serverResponse);
+
+ response = DigestCalcResponse(m_HA1,
+ m_dc.getNonce(),
+ "00000001",
+ m_clientNonce,
+ m_qopValue,
+ DIGEST_METHOD,
+ m_digestURI,
+ false);
+
+ responseStr = new String(response);
+
+ return responseStr.equals(responseAuth.getResponseValue());
+ }
+
+
+ /**
+ * This function returns hex character representing the value of the input
+ *
+ * @param value Input value in byte
+ *
+ * @return Hex value of the Input byte value
+ */
+ private static char getHexChar(
+ byte value)
+ {
+ switch (value)
+ {
+ case 0:
+ return '0';
+ case 1:
+ return '1';
+ case 2:
+ return '2';
+ case 3:
+ return '3';
+ case 4:
+ return '4';
+ case 5:
+ return '5';
+ case 6:
+ return '6';
+ case 7:
+ return '7';
+ case 8:
+ return '8';
+ case 9:
+ return '9';
+ case 10:
+ return 'a';
+ case 11:
+ return 'b';
+ case 12:
+ return 'c';
+ case 13:
+ return 'd';
+ case 14:
+ return 'e';
+ case 15:
+ return 'f';
+ default:
+ return 'Z';
+ }
+ }
+
+ /**
+ * Calculates the Nonce value of the Client
+ *
+ * @return Nonce value of the client
+ *
+ * @exception SaslException If an error Occurs
+ */
+ String getClientNonce() throws SaslException
+ {
+ byte[] nonceBytes = new byte[NONCE_BYTE_COUNT];
+ SecureRandom prng;
+ byte nonceByte;
+ char[] hexNonce = new char[NONCE_HEX_COUNT];
+
+ try
+ {
+ prng = SecureRandom.getInstance("SHA1PRNG");
+ prng.nextBytes(nonceBytes);
+ for(int i=0; i<NONCE_BYTE_COUNT; i++)
+ {
+ //low nibble
+ hexNonce[i*2] = getHexChar((byte)(nonceBytes[i] & 0x0f));
+ //high nibble
+ hexNonce[(i*2)+1] = getHexChar((byte)((nonceBytes[i] & 0xf0)
+ >> 4));
+ }
+ return new String(hexNonce);
+ }
+ catch(NoSuchAlgorithmException e)
+ {
+ throw new SaslException("No random number generator available", e);
+ }
+ }
+
+ /**
+ * Returns the IANA-registered mechanism name of this SASL client.
+ * (e.g. "CRAM-MD5", "GSSAPI")
+ *
+ * @return "DIGEST-MD5"the IANA-registered mechanism name of this SASL
+ * client.
+ */
+ public String getMechanismName()
+ {
+ return "DIGEST-MD5";
+ }
+
+} //end class DigestMD5SaslClient
+
diff --git a/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/DirectiveList.java b/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/DirectiveList.java
new file mode 100644
index 0000000..fc26a6b
--- /dev/null
+++ b/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/DirectiveList.java
@@ -0,0 +1,363 @@
+/* **************************************************************************
+ * $OpenLDAP: /com/novell/sasl/client/DirectiveList.java,v 1.4 2005/01/17 15:00:54 sunilk Exp $
+ *
+ * Copyright (C) 2002 Novell, Inc. All Rights Reserved.
+ *
+ * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
+ * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
+ * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
+ * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
+ * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
+ * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
+ * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
+ * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
+ ******************************************************************************/
+package com.novell.sasl.client;
+
+import java.util.*;
+import org.apache.harmony.javax.security.sasl.*;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Implements the DirectiveList class whihc will be used by the
+ * DigestMD5SaslClient class
+ */
+class DirectiveList extends Object
+{
+ private static final int STATE_LOOKING_FOR_FIRST_DIRECTIVE = 1;
+ private static final int STATE_LOOKING_FOR_DIRECTIVE = 2;
+ private static final int STATE_SCANNING_NAME = 3;
+ private static final int STATE_LOOKING_FOR_EQUALS = 4;
+ private static final int STATE_LOOKING_FOR_VALUE = 5;
+ private static final int STATE_LOOKING_FOR_COMMA = 6;
+ private static final int STATE_SCANNING_QUOTED_STRING_VALUE = 7;
+ private static final int STATE_SCANNING_TOKEN_VALUE = 8;
+ private static final int STATE_NO_UTF8_SUPPORT = 9;
+
+ private int m_curPos;
+ private int m_errorPos;
+ private String m_directives;
+ private int m_state;
+ private ArrayList m_directiveList;
+ private String m_curName;
+ private int m_scanStart;
+
+ /**
+ * Constructs a new DirectiveList.
+ */
+ DirectiveList(
+ byte[] directives)
+ {
+ m_curPos = 0;
+ m_state = STATE_LOOKING_FOR_FIRST_DIRECTIVE;
+ m_directiveList = new ArrayList(10);
+ m_scanStart = 0;
+ m_errorPos = -1;
+ try
+ {
+ m_directives = new String(directives, "UTF-8");
+ }
+ catch(UnsupportedEncodingException e)
+ {
+ m_state = STATE_NO_UTF8_SUPPORT;
+ }
+ }
+
+ /**
+ * This function takes a US-ASCII character string containing a list of comma
+ * separated directives, and parses the string into the individual directives
+ * and their values. A directive consists of a token specifying the directive
+ * name followed by an equal sign (=) and the directive value. The value is
+ * either a token or a quoted string
+ *
+ * @exception SaslException If an error Occurs
+ */
+ void parseDirectives() throws SaslException
+ {
+ char prevChar;
+ char currChar;
+ int rc = 0;
+ boolean haveQuotedPair = false;
+ String currentName = "<no name>";
+
+ if (m_state == STATE_NO_UTF8_SUPPORT)
+ throw new SaslException("No UTF-8 support on platform");
+
+ prevChar = 0;
+
+ while (m_curPos < m_directives.length())
+ {
+ currChar = m_directives.charAt(m_curPos);
+ switch (m_state)
+ {
+ case STATE_LOOKING_FOR_FIRST_DIRECTIVE:
+ case STATE_LOOKING_FOR_DIRECTIVE:
+ if (isWhiteSpace(currChar))
+ {
+ break;
+ }
+ else if (isValidTokenChar(currChar))
+ {
+ m_scanStart = m_curPos;
+ m_state = STATE_SCANNING_NAME;
+ }
+ else
+ {
+ m_errorPos = m_curPos;
+ throw new SaslException("Parse error: Invalid name character");
+ }
+ break;
+
+ case STATE_SCANNING_NAME:
+ if (isValidTokenChar(currChar))
+ {
+ break;
+ }
+ else if (isWhiteSpace(currChar))
+ {
+ currentName = m_directives.substring(m_scanStart, m_curPos);
+ m_state = STATE_LOOKING_FOR_EQUALS;
+ }
+ else if ('=' == currChar)
+ {
+ currentName = m_directives.substring(m_scanStart, m_curPos);
+ m_state = STATE_LOOKING_FOR_VALUE;
+ }
+ else
+ {
+ m_errorPos = m_curPos;
+ throw new SaslException("Parse error: Invalid name character");
+ }
+ break;
+
+ case STATE_LOOKING_FOR_EQUALS:
+ if (isWhiteSpace(currChar))
+ {
+ break;
+ }
+ else if ('=' == currChar)
+ {
+ m_state = STATE_LOOKING_FOR_VALUE;
+ }
+ else
+ {
+ m_errorPos = m_curPos;
+ throw new SaslException("Parse error: Expected equals sign '='.");
+ }
+ break;
+
+ case STATE_LOOKING_FOR_VALUE:
+ if (isWhiteSpace(currChar))
+ {
+ break;
+ }
+ else if ('"' == currChar)
+ {
+ m_scanStart = m_curPos+1; /* don't include the quote */
+ m_state = STATE_SCANNING_QUOTED_STRING_VALUE;
+ }
+ else if (isValidTokenChar(currChar))
+ {
+ m_scanStart = m_curPos;
+ m_state = STATE_SCANNING_TOKEN_VALUE;
+ }
+ else
+ {
+ m_errorPos = m_curPos;
+ throw new SaslException("Parse error: Unexpected character");
+ }
+ break;
+
+ case STATE_SCANNING_TOKEN_VALUE:
+ if (isValidTokenChar(currChar))
+ {
+ break;
+ }
+ else if (isWhiteSpace(currChar))
+ {
+ addDirective(currentName, false);
+ m_state = STATE_LOOKING_FOR_COMMA;
+ }
+ else if (',' == currChar)
+ {
+ addDirective(currentName, false);
+ m_state = STATE_LOOKING_FOR_DIRECTIVE;
+ }
+ else
+ {
+ m_errorPos = m_curPos;
+ throw new SaslException("Parse error: Invalid value character");
+ }
+ break;
+
+ case STATE_SCANNING_QUOTED_STRING_VALUE:
+ if ('\\' == currChar)
+ haveQuotedPair = true;
+ if ( ('"' == currChar) &&
+ ('\\' != prevChar) )
+ {
+ addDirective(currentName, haveQuotedPair);
+ haveQuotedPair = false;
+ m_state = STATE_LOOKING_FOR_COMMA;
+ }
+ break;
+
+ case STATE_LOOKING_FOR_COMMA:
+ if (isWhiteSpace(currChar))
+ break;
+ else if (currChar == ',')
+ m_state = STATE_LOOKING_FOR_DIRECTIVE;
+ else
+ {
+ m_errorPos = m_curPos;
+ throw new SaslException("Parse error: Expected a comma.");
+ }
+ break;
+ }
+ if (0 != rc)
+ break;
+ prevChar = currChar;
+ m_curPos++;
+ } /* end while loop */
+
+
+ if (rc == 0)
+ {
+ /* check the ending state */
+ switch (m_state)
+ {
+ case STATE_SCANNING_TOKEN_VALUE:
+ addDirective(currentName, false);
+ break;
+
+ case STATE_LOOKING_FOR_FIRST_DIRECTIVE:
+ case STATE_LOOKING_FOR_COMMA:
+ break;
+
+ case STATE_LOOKING_FOR_DIRECTIVE:
+ throw new SaslException("Parse error: Trailing comma.");
+
+ case STATE_SCANNING_NAME:
+ case STATE_LOOKING_FOR_EQUALS:
+ case STATE_LOOKING_FOR_VALUE:
+ throw new SaslException("Parse error: Missing value.");
+
+ case STATE_SCANNING_QUOTED_STRING_VALUE:
+ throw new SaslException("Parse error: Missing closing quote.");
+ }
+ }
+
+ }
+
+ /**
+ * This function returns TRUE if the character is a valid token character.
+ *
+ * token = 1*<any CHAR except CTLs or separators>
+ *
+ * separators = "(" | ")" | "<" | ">" | "@"
+ * | "," | ";" | ":" | "\" | <">
+ * | "/" | "[" | "]" | "?" | "="
+ * | "{" | "}" | SP | HT
+ *
+ * CTL = <any US-ASCII control character
+ * (octets 0 - 31) and DEL (127)>
+ *
+ * CHAR = <any US-ASCII character (octets 0 - 127)>
+ *
+ * @param c character to be tested
+ *
+ * @return Returns TRUE if the character is a valid token character.
+ */
+ boolean isValidTokenChar(
+ char c)
+ {
+ if ( ( (c >= '\u0000') && (c <='\u0020') ) ||
+ ( (c >= '\u003a') && (c <= '\u0040') ) ||
+ ( (c >= '\u005b') && (c <= '\u005d') ) ||
+ ('\u002c' == c) ||
+ ('\u0025' == c) ||
+ ('\u0028' == c) ||
+ ('\u0029' == c) ||
+ ('\u007b' == c) ||
+ ('\u007d' == c) ||
+ ('\u007f' == c) )
+ return false;
+
+ return true;
+ }
+
+ /**
+ * This function returns TRUE if the character is linear white space (LWS).
+ * LWS = [CRLF] 1*( SP | HT )
+ * @param c Input charcter to be tested
+ *
+ * @return Returns TRUE if the character is linear white space (LWS)
+ */
+ boolean isWhiteSpace(
+ char c)
+ {
+ if ( ('\t' == c) || // HORIZONTAL TABULATION.
+ ('\n' == c) || // LINE FEED.
+ ('\r' == c) || // CARRIAGE RETURN.
+ ('\u0020' == c) )
+ return true;
+
+ return false;
+ }
+
+ /**
+ * This function creates a directive record and adds it to the list, the
+ * value will be added later after it is parsed.
+ *
+ * @param name Name
+ * @param haveQuotedPair true if quoted pair is there else false
+ */
+ void addDirective(
+ String name,
+ boolean haveQuotedPair)
+ {
+ String value;
+ int inputIndex;
+ int valueIndex;
+ char valueChar;
+ int type;
+
+ if (!haveQuotedPair)
+ {
+ value = m_directives.substring(m_scanStart, m_curPos);
+ }
+ else
+ { //copy one character at a time skipping backslash excapes.
+ StringBuffer valueBuf = new StringBuffer(m_curPos - m_scanStart);
+ valueIndex = 0;
+ inputIndex = m_scanStart;
+ while (inputIndex < m_curPos)
+ {
+ if ('\\' == (valueChar = m_directives.charAt(inputIndex)))
+ inputIndex++;
+ valueBuf.setCharAt(valueIndex, m_directives.charAt(inputIndex));
+ valueIndex++;
+ inputIndex++;
+ }
+ value = new String(valueBuf);
+ }
+
+ if (m_state == STATE_SCANNING_QUOTED_STRING_VALUE)
+ type = ParsedDirective.QUOTED_STRING_VALUE;
+ else
+ type = ParsedDirective.TOKEN_VALUE;
+ m_directiveList.add(new ParsedDirective(name, value, type));
+ }
+
+
+ /**
+ * Returns the List iterator.
+ *
+ * @return Returns the Iterator Object for the List.
+ */
+ Iterator getIterator()
+ {
+ return m_directiveList.iterator();
+ }
+}
+
diff --git a/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/ParsedDirective.java b/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/ParsedDirective.java
new file mode 100644
index 0000000..17bf70e
--- /dev/null
+++ b/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/ParsedDirective.java
@@ -0,0 +1,56 @@
+/* **************************************************************************
+ * $OpenLDAP: /com/novell/sasl/client/ParsedDirective.java,v 1.1 2003/08/21 10:06:26 kkanil Exp $
+ *
+ * Copyright (C) 2002 Novell, Inc. All Rights Reserved.
+ *
+ * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
+ * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
+ * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
+ * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
+ * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
+ * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
+ * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
+ * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
+ ******************************************************************************/
+package com.novell.sasl.client;
+
+/**
+ * Implements the ParsedDirective class which will be used in the
+ * DigestMD5SaslClient mechanism.
+ */
+class ParsedDirective
+{
+ public static final int QUOTED_STRING_VALUE = 1;
+ public static final int TOKEN_VALUE = 2;
+
+ private int m_valueType;
+ private String m_name;
+ private String m_value;
+
+ ParsedDirective(
+ String name,
+ String value,
+ int type)
+ {
+ m_name = name;
+ m_value = value;
+ m_valueType = type;
+ }
+
+ String getValue()
+ {
+ return m_value;
+ }
+
+ String getName()
+ {
+ return m_name;
+ }
+
+ int getValueType()
+ {
+ return m_valueType;
+ }
+
+}
+
diff --git a/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/ResponseAuth.java b/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/ResponseAuth.java
new file mode 100644
index 0000000..0aef955
--- /dev/null
+++ b/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/ResponseAuth.java
@@ -0,0 +1,83 @@
+/* **************************************************************************
+ * $OpenLDAP: /com/novell/sasl/client/ResponseAuth.java,v 1.3 2005/01/17 15:00:54 sunilk Exp $
+ *
+ * Copyright (C) 2002 Novell, Inc. All Rights Reserved.
+ *
+ * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
+ * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
+ * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
+ * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
+ * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
+ * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
+ * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
+ * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
+ ******************************************************************************/
+package com.novell.sasl.client;
+
+import java.util.*;
+import org.apache.harmony.javax.security.sasl.*;
+
+/**
+ * Implements the ResponseAuth class used by the DigestMD5SaslClient mechanism
+ */
+class ResponseAuth
+{
+
+ private String m_responseValue;
+
+ ResponseAuth(
+ byte[] responseAuth)
+ throws SaslException
+ {
+ m_responseValue = null;
+
+ DirectiveList dirList = new DirectiveList(responseAuth);
+ try
+ {
+ dirList.parseDirectives();
+ checkSemantics(dirList);
+ }
+ catch (SaslException e)
+ {
+ }
+ }
+
+ /**
+ * Checks the semantics of the directives in the directive list as parsed
+ * from the digest challenge byte array.
+ *
+ * @param dirList the list of directives parsed from the digest challenge
+ *
+ * @exception SaslException If a semantic error occurs
+ */
+ void checkSemantics(
+ DirectiveList dirList) throws SaslException
+ {
+ Iterator directives = dirList.getIterator();
+ ParsedDirective directive;
+ String name;
+
+ while (directives.hasNext())
+ {
+ directive = (ParsedDirective)directives.next();
+ name = directive.getName();
+ if (name.equals("rspauth"))
+ m_responseValue = directive.getValue();
+ }
+
+ /* post semantic check */
+ if (m_responseValue == null)
+ throw new SaslException("Missing response-auth directive.");
+ }
+
+ /**
+ * returns the ResponseValue
+ *
+ * @return the ResponseValue as a String.
+ */
+ public String getResponseValue()
+ {
+ return m_responseValue;
+ }
+}
+
diff --git a/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/TokenParser.java b/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/TokenParser.java
new file mode 100644
index 0000000..3d3491d
--- /dev/null
+++ b/asmack-master/static-src/novell-openldap-jldap/com/novell/sasl/client/TokenParser.java
@@ -0,0 +1,208 @@
+/* **************************************************************************
+ * $OpenLDAP: /com/novell/sasl/client/TokenParser.java,v 1.3 2005/01/17 15:00:54 sunilk Exp $
+ *
+ * Copyright (C) 2002 Novell, Inc. All Rights Reserved.
+ *
+ * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
+ * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
+ * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
+ * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
+ * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
+ * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
+ * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
+ * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
+ ******************************************************************************/
+package com.novell.sasl.client;
+
+import org.apache.harmony.javax.security.sasl.*;
+/**
+ * The TokenParser class will parse individual tokens from a list of tokens that
+ * are a directive value for a DigestMD5 authentication.The tokens are separated
+ * commas.
+ */
+class TokenParser extends Object
+{
+ private static final int STATE_LOOKING_FOR_FIRST_TOKEN = 1;
+ private static final int STATE_LOOKING_FOR_TOKEN = 2;
+ private static final int STATE_SCANNING_TOKEN = 3;
+ private static final int STATE_LOOKING_FOR_COMMA = 4;
+ private static final int STATE_PARSING_ERROR = 5;
+ private static final int STATE_DONE = 6;
+
+ private int m_curPos;
+ private int m_scanStart;
+ private int m_state;
+ private String m_tokens;
+
+
+ TokenParser(
+ String tokens)
+ {
+ m_tokens = tokens;
+ m_curPos = 0;
+ m_scanStart = 0;
+ m_state = STATE_LOOKING_FOR_FIRST_TOKEN;
+ }
+
+ /**
+ * This function parses the next token from the tokens string and returns
+ * it as a string. If there are no more tokens a null reference is returned.
+ *
+ * @return the parsed token or a null reference if there are no more
+ * tokens
+ *
+ * @exception SASLException if an error occurs while parsing
+ */
+ String parseToken() throws SaslException
+ {
+ char currChar;
+ String token = null;
+
+
+ if (m_state == STATE_DONE)
+ return null;
+
+ while (m_curPos < m_tokens.length() && (token == null))
+ {
+ currChar = m_tokens.charAt(m_curPos);
+ switch (m_state)
+ {
+ case STATE_LOOKING_FOR_FIRST_TOKEN:
+ case STATE_LOOKING_FOR_TOKEN:
+ if (isWhiteSpace(currChar))
+ {
+ break;
+ }
+ else if (isValidTokenChar(currChar))
+ {
+ m_scanStart = m_curPos;
+ m_state = STATE_SCANNING_TOKEN;
+ }
+ else
+ {
+ m_state = STATE_PARSING_ERROR;
+ throw new SaslException("Invalid token character at position " + m_curPos);
+ }
+ break;
+
+ case STATE_SCANNING_TOKEN:
+ if (isValidTokenChar(currChar))
+ {
+ break;
+ }
+ else if (isWhiteSpace(currChar))
+ {
+ token = m_tokens.substring(m_scanStart, m_curPos);
+ m_state = STATE_LOOKING_FOR_COMMA;
+ }
+ else if (',' == currChar)
+ {
+ token = m_tokens.substring(m_scanStart, m_curPos);
+ m_state = STATE_LOOKING_FOR_TOKEN;
+ }
+ else
+ {
+ m_state = STATE_PARSING_ERROR;
+ throw new SaslException("Invalid token character at position " + m_curPos);
+ }
+ break;
+
+
+ case STATE_LOOKING_FOR_COMMA:
+ if (isWhiteSpace(currChar))
+ break;
+ else if (currChar == ',')
+ m_state = STATE_LOOKING_FOR_TOKEN;
+ else
+ {
+ m_state = STATE_PARSING_ERROR;
+ throw new SaslException("Expected a comma, found '" +
+ currChar + "' at postion " +
+ m_curPos);
+ }
+ break;
+ }
+ m_curPos++;
+ } /* end while loop */
+
+ if (token == null)
+ { /* check the ending state */
+ switch (m_state)
+ {
+ case STATE_SCANNING_TOKEN:
+ token = m_tokens.substring(m_scanStart);
+ m_state = STATE_DONE;
+ break;
+
+ case STATE_LOOKING_FOR_FIRST_TOKEN:
+ case STATE_LOOKING_FOR_COMMA:
+ break;
+
+ case STATE_LOOKING_FOR_TOKEN:
+ throw new SaslException("Trialing comma");
+ }
+ }
+
+ return token;
+ }
+
+ /**
+ * This function returns TRUE if the character is a valid token character.
+ *
+ * token = 1*<any CHAR except CTLs or separators>
+ *
+ * separators = "(" | ")" | "<" | ">" | "@"
+ * | "," | ";" | ":" | "\" | <">
+ * | "/" | "[" | "]" | "?" | "="
+ * | "{" | "}" | SP | HT
+ *
+ * CTL = <any US-ASCII control character
+ * (octets 0 - 31) and DEL (127)>
+ *
+ * CHAR = <any US-ASCII character (octets 0 - 127)>
+ *
+ * @param c character to be validated
+ *
+ * @return True if character is valid Token character else it returns
+ * false
+ */
+ boolean isValidTokenChar(
+ char c)
+ {
+ if ( ( (c >= '\u0000') && (c <='\u0020') ) ||
+ ( (c >= '\u003a') && (c <= '\u0040') ) ||
+ ( (c >= '\u005b') && (c <= '\u005d') ) ||
+ ('\u002c' == c) ||
+ ('\u0025' == c) ||
+ ('\u0028' == c) ||
+ ('\u0029' == c) ||
+ ('\u007b' == c) ||
+ ('\u007d' == c) ||
+ ('\u007f' == c) )
+ return false;
+
+ return true;
+ }
+
+ /**
+ * This function returns TRUE if the character is linear white space (LWS).
+ * LWS = [CRLF] 1*( SP | HT )
+ *
+ * @param c character to be validated
+ *
+ * @return True if character is liner whitespace else it returns false
+ */
+ boolean isWhiteSpace(
+ char c)
+ {
+ if ( ('\t' == c) || // HORIZONTAL TABULATION.
+ ('\n' == c) || // LINE FEED.
+ ('\r' == c) || // CARRIAGE RETURN.
+ ('\u0020' == c) )
+ return true;
+
+ return false;
+ }
+
+}
+