Commit b58ba7b6 by amir

first version

parent d5b8b688
Pipeline #93 skipped in 0 seconds
Showing with 14304 additions and 0 deletions
/build/
/bin/
.gradle
.settings
.idea
.lck
.project
.classpath
gradle/
group 'com.ipgallery.common'
version '1.0.0'
apply plugin: 'java'
apply plugin: 'maven-publish'
sourceCompatibility = 1.8
repositories {
mavenCentral()
maven { url "http://172.16.1.132:8081/repository/internal" }
maven { url "http://mandubian-mvn.googlecode.com/svn/trunk/mandubian-mvn/repository" }
}
dependencies {
//compile 'javax.servlet:sip-api:1.0'
testCompile group: 'junit', name: 'junit', version: '4.11'
}
publishing {
publications {
repositories.maven {
url 'http://172.16.1.132:8081/repository/internal'
credentials {
username "admin"
password "giptmgr1"
}
}
mavenJava(MavenPublication) {
//artifactId 'group-service'
from components.java
}
}
}
\ No newline at end of file
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
rootProject.name = 'rcs-core-api'
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core;
import java.util.logging.Logger;
import utils.PhoneUtils;
/**
* Core (singleton pattern)
*
* @author JM. Auffret
*/
public class Core {
/**
* Singleton instance
*/
private static Core instance = null;
/**
* Core listener
*/
private CoreListener listener;
/**
* Core status
*/
private boolean started = false;
/**
* IMS module
*/
// private ImsModule imsModule;
/**
* Sip Factory
*/
//SipFactory sipFactory = null;
/**
* Address book manager
*/
// private AddressBookManager addressBookManager;
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Returns the singleton instance
*
* @return Core instance
*/
public static Core getInstance() {
return instance;
}
/**
* Instanciate the core
*
* @param listener Listener
* @return Core instance
* @throws CoreException
*/
public synchronized static Core createCore(CoreListener listener) throws CoreException {
if (instance == null) {
instance = new Core(listener);
}
return instance;
}
/**
* Terminate the core
*/
public synchronized static void terminateCore() {
if (instance != null) {
instance.stopCore();
}
instance = null;
}
/**
* Constructor
*
* @param listener Listener
* @throws CoreException
*/
private Core(CoreListener listener) throws CoreException {
logger.info("Terminal core initialization");
// Set core event listener
this.listener = listener;
//this.sipFactory = sf;
// Get UUID
// logger.info("My device UUID is " + DeviceUtils.getDeviceUUID(AndroidFactory.getApplicationContext()));
// Initialize the phone utils
PhoneUtils.initialize(/*AndroidFactory.getApplicationContext()*/);
// Get country code
logger.info("My country code is " + PhoneUtils.getCountryCode());
// Create the address book manager
//addressBookManager = new AddressBookManager();
// Create the IMS module
// imsModule = new ImsModule(this);
logger.info("Terminal core is created with success");
}
/**
* Returns the event listener
*
* @return Listener
*/
public CoreListener getListener() {
return listener;
}
/**
* Returns the IMS module
*
* @return IMS module
*/
// public ImsModule getImsModule() {
// return imsModule;
// }
/**
* Returns the address book manager
*/
// public AddressBookManager getAddressBookManager(){
// return addressBookManager;
// }
/**
* Is core started
*
* @return Boolean
*/
public boolean isCoreStarted() {
return started;
}
/**
* Start the terminal core
*
* @throws CoreException
*/
public synchronized void startCore() throws CoreException {
if (started) {
// Already started
return;
}
// Start the IMS module
// imsModule.start();
// Start the address book monitoring
//addressBookManager.startAddressBookMonitoring();
// Notify event listener
listener.handleCoreLayerStarted();
started = true;
logger.info("RCS core service has been started with success");
}
/**
* Stop the terminal core
*/
public synchronized void stopCore() {
if (!started) {
// Already stopped
return;
}
logger.info("Stop the RCS core service");
// Stop the address book monitoring
//addressBookManager.stopAddressBookMonitoring();
try {
// Stop the IMS module
// imsModule.stop();
} catch(Exception e) {
logger.severe("Error during core shutdown: " + e);
}
// Notify event listener
listener.handleCoreLayerStopped();
started = false;
logger.info("RCS core service has been stopped with success");
}
/**
* Returns the terms service
*
* @return Terms service
*/
// public TermsConditionsService getTermsConditionsService() {
// return getImsModule().getTermsConditionsService();
// }
/**
* Returns the presence service
*
* @return Presence service
*/
// public PresenceService getPresenceService() {
// return getImsModule().getPresenceService();
// }
/**
* Returns the capabity service
*
* @return Capability service
*/
// public CapabilityService getCapabilityService() {
// return getImsModule().getCapabilityService();
// }
/**
* Returns the richcall service
*
* @return Rich call service
*/
// public RichcallService getRichcallService() {
// return getImsModule().getRichcallService();
// }
/**
* Returns the IM service
*
* @return IM service
*/
// public InstantMessagingService getImService() {
// return getImsModule().getInstantMessagingService();
// }
/**
* Returns the SIP service
*
* @return SIP service
*/
// public SipService getSipService() {
// return getImsModule().getSipService();
// }
// public SipFactory getSipFactory() {
// return sipFactory;
// }
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core;
/**
* Core module exception
*
* @author JM. Auffret
*/
public class CoreException extends java.lang.Exception {
static final long serialVersionUID = 1L;
/**
* Constructor
*
* @param error Error message
*/
public CoreException(String error) {
super(error);
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core;
/**
* Observer of core events
*
* @author JM. Auffret
*/
public interface CoreListener {
/**
* Core layer has been started
*/
public void handleCoreLayerStarted();
/**
* Core layer has been stopped
*/
public void handleCoreLayerStopped();
/**
* Registered to IMS
*/
public void handleRegistrationSuccessful();
/**
* IMS registration has failed
*
* @param error Error
*/
// public void handleRegistrationFailed(ImsError error);
/**
* Unregistered from IMS
*/
// public void handleRegistrationTerminated();
/**
* A new presence sharing notification has been received
*
* @param contact Contact
* @param status Status
* @param reason Reason
*/
public void handlePresenceSharingNotification(String contact, String status, String reason);
/**
* A new presence info notification has been received
*
* @param contact Contact
* @param presense Presence info document
*/
// public void handlePresenceInfoNotification(String contact, PidfDocument presence);
/**
* Capabilities update notification has been received
*
* @param contact Contact
* @param capabilities Capabilities
*/
//public void handleCapabilitiesNotification(String contact, Capabilities capabilities);
/**
* A new presence sharing invitation has been received
*
* @param contact Contact
*/
public void handlePresenceSharingInvitation(String contact);
/**
* A new content sharing transfer invitation has been received
*
* @param session CSh session
*/
// public void handleContentSharingTransferInvitation(ImageTransferSession session);
/**
* A new content sharing streaming invitation has been received
*
* @param session CSh session
*/
// public void handleContentSharingStreamingInvitation(VideoStreamingSession session);
/**
* A new file transfer invitation has been received
*
* @param session File transfer session
*/
// public void handleFileTransferInvitation(FileSharingSession session);
/**
* New one-to-one chat session invitation
*
* @param session Chat session
*/
//public void handleOneOneChatSessionInvitation(TerminatingOne2OneChatSession session);
/**
* New ad-hoc group chat session invitation
*
* @param session Chat session
*/
//public void handleAdhocGroupChatSessionInvitation(TerminatingAdhocGroupChatSession session);
/**
* One-to-one chat session extended to a group chat session
*
* @param groupSession Group chat session
* @param oneoneSession 1-1 chat session
*/
// public void handleOneOneChatSessionExtended(GroupChatSession groupSession, OneOneChatSession oneoneSession);
/**
* Store and Forward messages session invitation
*
* @param session Chat session
*/
// public void handleStoreAndForwardMsgSessionInvitation(TerminatingStoreAndForwardMsgSession session);
/**
* New message delivery status
*
* @param contact Contact
* @param msgId Message ID
* @param status Delivery status
*/
public void handleMessageDeliveryStatus(String contact, String msgId, String status,int handleThread);
/**
* New SIP session invitation
*
* @param session SIP session
*/
// public void handleSipSessionInvitation(TerminatingSipSession session);
/**
* User terms confirmation request
*
* @param remote Remote server
* @param id Request ID
* @param type Type of request
* @param pin PIN number requested
* @param subject Subject
* @param text Text
*/
public void handleUserConfirmationRequest(String remote, String id, String type, boolean pin, String subject, String text);
/**
* User terms confirmation acknowledge
*
* @param remote Remote server
* @param id Request ID
* @param status Status
* @param subject Subject
* @param text Text
*/
public void handleUserConfirmationAck(String remote, String id, String status, String subject, String text);
/**
* SIM has changed
*/
//public void handleSimHasChanged();
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.content;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Vector;
import core.ims.network.sip.SipUtils;
import core.ims.protocol.sdp.MediaAttribute;
import core.ims.protocol.sdp.MediaDescription;
import core.ims.protocol.sdp.SdpParser;
import platform.file.FileFactory;
import utils.MimeManager;
/**
* Multimedia content manager
*
* @author amir aharon
*/
public class ContentManager{
/**
* Generate an URL for the received content
*
* @param filename Filename
* @param mime MIME type
* @return URL
*/
public static String generateUrlForReceivedContent(String filename, String mime) {
// Generate a file path
String path;
if (mime.startsWith("image")) {
path = FileFactory.getFactory().getPhotoRootDirectory();
} else
if (mime.startsWith("video")) {
path = FileFactory.getFactory().getVideoRootDirectory();
} else {
path = FileFactory.getFactory().getFileRootDirectory();
}
// Check that the filename will not overwrite existing file
// We modify it if a file of the same name exists, by appending _1 before the extension
// For example if image.jpeg exists, next file will be image_1.jpeg, then image_2.jpeg etc
String extension = "";
if ((filename!=null) && (filename.indexOf('.')!=-1)){
// if extension is present, split it
extension = "." + filename.substring(filename.lastIndexOf('.')+1);
filename = filename.substring(0, filename.lastIndexOf('.'));
}
String destination = filename;
int i = 1;
while(FileFactory.getFactory().fileExists(path + destination + extension)){
destination = filename + '_' + i;
i++;
}
// Return free destination url
return path + destination + extension;
}
/**
* Save a content in the local directory of the device
*
* @param content Content to be saved
* @throws IOException
*/
public static void saveContent(MmContent content) throws IOException {
// Write data
OutputStream os = FileFactory.getFactory().openFileOutputStream(content.getUrl());
os.write(content.getData());
os.flush();
os.close();
// Update the media storage
FileFactory.getFactory().updateMediaStorage(content.getUrl());
}
/**
* Create a content object from URL description
*
* @param url Content URL
* @param size Content size
* @return Content instance
*/
public static MmContent createMmContentFromUrl(String url, long size) {
String ext = MimeManager.getFileExtension(url);
String mime = MimeManager.getMimeType(ext);
if (mime != null) {
if (mime.startsWith("image/")) {
return new PhotoContent(url, mime, size);
}
if (mime.startsWith("video/")) {
return new VideoContent(url, mime, size);
}
}
return new FileContent(url, size);
}
/**
* Create a content object from MIME type
*
* @param url Content URL
* @param mime MIME type
* @param size Content size
* @return Content instance
*/
public static MmContent createMmContentFromMime(String url, String mime, long size) {
if (mime.startsWith("image/")) {
// Photo content
return new PhotoContent(url, mime, size);
}
if (mime.startsWith("video/")) {
// Video content
return new VideoContent(url, mime, size);
}
if (mime.startsWith("application/")) {
// File content
return new FileContent(url, size);
}
return null;
}
/**
* Create a live video content object
*
* @param codec Codec
* @return Content instance
*/
public static LiveVideoContent createLiveVideoContent(String codec) {
return new LiveVideoContent("video/"+codec);
}
/**
* Create a generic live video content object
*
* @return Content instance
*/
public static LiveVideoContent createGenericLiveVideoContent() {
return new LiveVideoContent("video/*");
}
/**
* Create a live video content object
*
* @param sdp SDP part
* @return Content instance
*/
public static LiveVideoContent createLiveVideoContentFromSdp(byte[] sdp) {
// Parse the remote SDP part
SdpParser parser = new SdpParser(sdp);
Vector<MediaDescription> media = parser.getMediaDescriptions();
MediaDescription desc = media.elementAt(0);
String rtpmap = desc.getMediaAttribute("rtpmap").getValue();
// Extract the video encoding
String encoding = rtpmap.substring(rtpmap.indexOf(desc.payload)+desc.payload.length()+1);
String codec = encoding.toLowerCase().trim();
int index = encoding.indexOf("/");
if (index != -1) {
codec = encoding.substring(0, index);
}
return createLiveVideoContent(codec);
}
/**
* Create a content object from SDP data
*
* @param sdp SDP part
* @return Content instance
*/
public static MmContent createMmContentFromSdp(String sdp) {
// Set the content
try {
SdpParser parser = new SdpParser(sdp.getBytes());
Vector<MediaDescription> media = parser.getMediaDescriptions();
MediaDescription desc = media.elementAt(0);
MediaAttribute attr1 = desc.getMediaAttribute("file-selector");
String fileSelectorValue = attr1.getValue();
String mime = SipUtils.extractParameter(fileSelectorValue, "type:", "application/octet-stream");
long size = Long.parseLong(SipUtils.extractParameter(fileSelectorValue, "size:", "-1"));
String filename = SipUtils.extractParameter(fileSelectorValue, "name:", "");
String url = ContentManager.generateUrlForReceivedContent(filename, mime);
MmContent content = ContentManager.createMmContentFromMime(url, mime, size);
return content;
} catch(Exception e) {
return null;
}
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.content;
/**
* File content
*
* @author amir aharon
*/
public class FileContent extends MmContent {
/**
* Constructor
*
* @param url URL
* @param size Content size
*/
public FileContent(String url, long size) {
super(url, "application/octet-stream", size);
}
/**
* Constructor
*
* @param url URL
*/
public FileContent(String url) {
super(url, "application/octet-stream");
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.content;
/**
* Live photo content
*
* @author amir aharon
*/
public class LivePhotoContent extends PhotoContent {
/**
* Constructor
*
* @param url URL
* @param encoding Encoding
* @param photo Photo
*/
public LivePhotoContent(String url, String encoding, byte[] photo) {
super(url, encoding, photo.length);
setData(photo);
}
/**
* Constructor
*
* @param url URL
* @aparam encoding Encoding
* @param size Content size
*/
public LivePhotoContent(String url, String encoding, long size) {
super(url, encoding, size);
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.content;
/**
* Live video content
*
* @author amir aharon
*/
public class LiveVideoContent extends VideoContent {
/**
* Livevideo URL constant
*/
public static final String URL = "capture://video";
/**
* Constructor
*
* @param encoding Encoding
*/
public LiveVideoContent(String encoding) {
super(URL, encoding);
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.content;
/**
* Multimedia content
*
* @author amir aharon
*/
public abstract class MmContent {
/**
* Content URL
*/
private String url;
/**
* Content size in bytes
*/
private long size;
/**
* Encoding
*/
private String encoding;
/**
* Data
*/
private byte[] data = null;
/**
* Content name
*/
private String name = null;
/**
* Constructor
*
* @param url URL
* @param encoding Encoding
*/
public MmContent(String url, String encoding) {
this.url = url;
this.encoding = encoding;
this.size = -1;
}
/**
* Constructor
*
* @param url URL
* @param encoding Encoding
* @param size Content size
*/
public MmContent(String url, String encoding, long size) {
this.url = url;
this.encoding = encoding;
this.size = size;
}
/**
* Returns the URL
*
* @return String
*/
public String getUrl() {
return url;
}
/**
* Returns the content size in bytes
*
* @return Size in bytes
*/
public long getSize() {
return size;
}
/**
* Returns the content size in Kbytes
*
* @return Size in Kbytes
*/
public long getKbSize() {
return size/1024;
}
/**
* Returns the content size in Mbytes
*
* @return Size in Mbytes
*/
public long getMbSize(){
return size/(1024*1024);
}
/**
* Returns the encoding type
*
* @return Encoding type
*/
public String getEncoding() {
return encoding;
}
/**
* Set the encoding type
*
* @param encoding Encoding type
*/
public void setEncoding(String encoding) {
this.encoding = encoding;
}
/**
* Returns the codec from the encoding type
*
* @return Codec name
*/
public String getCodec() {
int index = encoding.indexOf("/");
if (index != -1) {
return encoding.substring(index+1);
} else {
return encoding;
}
}
/**
* Get the name
*
* @return Name
*/
public String getName() {
if (name == null) {
// Extract filename from URL
int index = url.lastIndexOf('/');
if (index != -1) {
return url.substring(index+1);
} else {
return url;
}
} else {
// Return the name associated to the content
return name;
}
}
/**
* Returns the string representation of a content
*
* @return String
*/
public String toString() {
return url + " (" + size + " bytes)";
}
/**
* Returns the content data
*
* @return Data
*/
public byte[] getData() {
return data;
}
/**
* Sets the content data
*
* @param Data
*/
public void setData(byte[] data) {
this.data = data;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.content;
/**
* Photo content
*
* @author amir aharon
*/
public class PhotoContent extends MmContent {
/**
* Constructor
*
* @param url URL
* @aparam encoding Encoding
* @param size Content size
*/
public PhotoContent(String url, String encoding, long size) {
super(url, encoding, size);
}
/**
* Constructor
*
* @param url URL
* @aparam encoding Encoding
*/
public PhotoContent(String url, String encoding) {
super(url, encoding);
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.content;
/**
* Video content
*
* @author amir aharon
*/
public class VideoContent extends MmContent {
/**
* Height
*/
private int height = 0;
/**
* Width
*/
private int width = 0;
/**
* Constructor
*
* @param url URL
* @aparam encoding Encoding
* @param size Content size
*/
public VideoContent(String url, String encoding, long size) {
super(url, encoding, size);
}
/**
* Constructor
*
* @param url URL
* @aparam encoding Encoding
*/
public VideoContent(String url, String encoding) {
super(url, encoding);
}
/**
* Set the width
*
* @param width width
*/
public void setWidth(int width) {
this.width = width;
}
/**
* Get the width
*
* @return width
*/
public int getWidth() {
return width;
}
/**
* Set the height
*
* @param height height
*/
public void setHeight(int height) {
this.height = height;
}
/**
* Get the height
*
* @return height
*/
public int getHeight() {
return height;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.network.sip;
/**
* Feature tags
*
* @author amir aharon
*/
public class FeatureTags {
/**
* OMA IM feature tag
*/
public final static String FEATURE_OMA_IM = "+g.oma.sip-im";
/**
* 3GPP video share feature tag
*/
public final static String FEATURE_3GPP_VIDEO_SHARE = "+g.3gpp.cs-voice";
/**
* 3GPP image share feature tag
*/
public final static String FEATURE_3GPP_IMAGE_SHARE = "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.gsma-is\"";
/**
* 3GPP image share feature tag for RCS 2.0
*/
public final static String FEATURE_3GPP_IMAGE_SHARE_RCS2 = "+g.3gpp.app_ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.gsma-is\"";
/**
* RCS-e feature tag prefix
*/
public final static String FEATURE_RCSE = "+g.3gpp.iari-ref";
/**
* RCS-e image share feature tag
*/
public final static String FEATURE_RCSE_IMAGE_SHARE = "urn%3Aurn-7%3A3gpp-application.ims.iari.gsma-is";
/**
* RCS-e chat feature tag
*/
public final static String FEATURE_RCSE_CHAT = "urn%3Aurn-7%3A3gpp-application.ims.iari.rcse.im";
/**
* RCS-e file transfer feature tag
*/
public final static String FEATURE_RCSE_FT = "urn%3Aurn-7%3A3gpp-application.ims.iari.rcse.ft";
/**
* RCS-e presence discovery feature tag
*/
public final static String FEATURE_RCSE_PRESENCE_DISCOVERY = "urn%3Aurn-7%3A3gpp-application.ims.iari.rcse.dp";
/**
* RCS-e social presence feature tag
*/
public final static String FEATURE_RCSE_SOCIAL_PRESENCE = "urn%3Aurn-7%3A3gpp-application.ims.iari.rcse.sp";
/**
* RCS-e extension feature tag prefix
*/
public final static String FEATURE_RCSE_EXTENSION = "urn%3Aurn-7%3A3gpp-application.ims.iari.rcse";
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.network.sip;
import java.util.Hashtable;
import core.ims.network.sip.SipUtils;
/**
* Multipart content for SIP message
*
* @author amir aharon
*/
public class Multipart {
/**
* Boundary delimiter
*/
public final static String BOUNDARY_DELIMITER = "--";
/**
* MIME type
*/
public static final String MIME_TYPE = "multipart/mixed";
/**
* Content type header
*/
private final static String CONTENT_TYPE_HEADER = "Content-Type";
/**
* Parts
*/
private Hashtable<String, String> parts = new Hashtable<String, String>();
/**
* Constructor
*
* @param content Content parts
* @param boundary Boundary delimiter
*/
public Multipart(String content, String boundary) {
if ((content != null) && (boundary != null)) {
if (boundary.startsWith("\""))
{
// cutting the "
int lastIndex = boundary.lastIndexOf('"');
if (lastIndex != -1)
boundary = boundary.substring(1, lastIndex - 1);
else
boundary = boundary.substring(1);
}
String token = BOUNDARY_DELIMITER + boundary;
String[] fragments = content.split(token);
for (String fragment: fragments) {
String trimmedFragment = fragment.trim();
if ((trimmedFragment.length() > 0) && !BOUNDARY_DELIMITER.equals(trimmedFragment)) {
int begin = fragment.indexOf(SipUtils.CRLF+SipUtils.CRLF);
if (begin != -1) {
try {
// Extract content type
String type = fragment.substring(0, begin).trim();
// Extract content part
String part = fragment.substring(begin).trim();
// Extract MIME type from content type
int beginType = type.indexOf(CONTENT_TYPE_HEADER);
int endType = type.indexOf(SipUtils.CRLF, beginType);
String mime;
if (endType == -1) {
mime = type.substring(beginType+CONTENT_TYPE_HEADER.length()+1).trim();
} else {
mime = type.substring(beginType+CONTENT_TYPE_HEADER.length()+1, endType).trim();
}
// Add part in lowercase
parts.put(mime.toLowerCase(), part);
} catch(Exception e) {
// Nothing to do
}
}
}
}
}
}
/**
* Is a multipart
*
* @return Boolean
*/
public boolean isMultipart() {
return (parts.size() > 0);
}
/**
* Get part from its MIME-type
*
* @param type MIME-type
* @return Part as string
*/
public String getPart(String type) {
return parts.get(type.toLowerCase());
}
/**
* Get parts
*
* @return List of parts
*/
public Hashtable<String, String> getParts() {
return parts;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.network.sip;
import java.util.*;
import java.util.Map.Entry;
import java.util.logging.Logger;
/**
* SIP utility functions
*
* @author JM. Auffret
*/
public class SipUtils {
/**
* The logger
*/
private static Logger logger = Logger.getLogger("SipUtils");
/**
* CRLF constant
*/
public final static String CRLF = "\r\n";
/**
* Header factory
*/
// public static HeaderFactory HEADER_FACTORY = null;
/**
* Address factory
*/
// public static AddressFactory ADDR_FACTORY = null;
/**
* Message factory
*/
// public static MessageFactory MSG_FACTORY = null;
/**
* Contact header
*/
public static final String HEADER_CONTACT = "Contact";
/**
* Record-Route header
*/
public static final String HEADER_RECORD_ROUTE = "Record-Route";
/**
* Accept-Contact header
*/
public static final String HEADER_ACCEPT_CONTACT = "Accept-Contact";
public static final String HEADER_ACCEPT_CONTACT_C = "a";
/**
* P-Access-Network-Info header
*/
public static final String HEADER_P_ACCESS_NETWORK_INFO = "P-Access-Network-Info";
/**
* P-Asserted-Identity header
*/
public static final String HEADER_P_ASSERTED_IDENTITY = "P-Asserted-Identity";
/**
* P-Preferred-Identity header
*/
public static final String HEADER_P_PREFERRED_IDENTITY = "P-Preferred-Identity";
/**
* P-Associated-URI header
*/
public static final String HEADER_P_ASSOCIATED_URI = "P-Associated-URI";
/**
* Expires header
*/
public static final String HEADER_EXPIRES = "Expires";
/**
* Service-Route header
*/
public static final String HEADER_SERVICE_ROUTE = "Service-Route";
/**
* Privacy header
*/
public static final String HEADER_PRIVACY = "Privacy";
/**
* Refer-Sub header
*/
public static final String HEADER_REFER_SUB = "Refer-Sub";
/**
* Referred-By header
*/
public static final String HEADER_REFERRED_BY = "Referred-By";
public static final String HEADER_REFERRED_BY_C = "b";
/**
* Content-ID header
*/
public static final String HEADER_CONTENT_ID = "Content-ID";
/**
* Content-ID header
*/
public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
/**
* Session-Expires header
*/
public static final String HEADER_SESSION_EXPIRES = "Session-Expires";
/**
* Session-Replaces header
*/
public static final String HEADER_SESSION_REPLACES = "Session-Replaces";
/**
* Min-SE header
*/
public static final String HEADER_MIN_SE = "Min-SE";
/**
* Min-Expires
*/
public static final String HEADER_MIN_EXPIRES = "Min-Expires";
/**
* Subject header
*/
public static final String HEADER_SUBJECT = "Subject";
/**
* Server header
*/
public static final String HEADER_SERVER = "Server";
/**
* Server header
*/
public static final String HEADER_USER_AGENT = "User-Agent";
/**
* Server header
*/
public static final String HEADER_SUBSCRIPTION_STATE = "Subscription-State";
/**
* Require header
*/
public static final String HEADER_REQUIRE = "Require";
/**
* Require header
*/
public static final String HEADER_REFER_TO = "Refer-To";
/**
* Extract the URI part of a SIP address
*
* @param addr SIP address
* @return URI
*/
public static String extractUriFromAddress(String addr) {
String uri = addr;
try {
int index = addr.indexOf("<");
if (index != -1) {
uri = addr.substring(index+1, addr.indexOf(">", index));
}
} catch(Exception e) {
}
return uri;
}
/**
* Construct an NTP time from a date in milliseconds
*
* @param date Date in milliseconds
* @return NTP time in string format
*/
public static String constructNTPtime(long date) {
long ntpTime = 2208988800L;
long startTime = (date / 1000) + ntpTime;
return String.valueOf(startTime);
}
/**
* Build User-Agent header
*
* @param Header
*/
// public static void buildUserAgentHeader(SipServletMessage msg) throws Exception {
// String value = "IM-client/OMA1.0"; // + TerminalInfo.getProductName() + "/" + TerminalInfo.getProductVersion();
// //Header userAgentHeader = HEADER_FACTORY.createHeader(UserAgentHeader.NAME, value);
// msg.addHeader(HEADER_USER_AGENT, value);
// }
/**
* Build Server header
*
* @return Header
* @throws Exception
*/
// public static void buildServerHeader(SipServletMessage msg) throws Exception {
// String value = "IM-client/OMA1.0"; // + TerminalInfo.getProductName() + "/" + TerminalInfo.getProductVersion();
// msg.addHeader(HEADER_SERVER, value);
// //return HEADER_FACTORY.createHeader(ServerHeader.NAME, value);
// }
/**
* Build Allow header
*
* @param msg SIP message
*/
// public static void buildAllowHeader(SipServletMessage msg) throws Exception {
//// msg.addHeader(HEADER_FACTORY.createAllowHeader(Request.INVITE));
//// msg.addHeader(HEADER_FACTORY.createAllowHeader(Request.UPDATE));
//// msg.addHeader(HEADER_FACTORY.createAllowHeader(Request.ACK));
//// msg.addHeader(HEADER_FACTORY.createAllowHeader(Request.CANCEL));
//// msg.addHeader(HEADER_FACTORY.createAllowHeader(Request.BYE));
//// msg.addHeader(HEADER_FACTORY.createAllowHeader(Request.NOTIFY));
//// msg.addHeader(HEADER_FACTORY.createAllowHeader(Request.OPTIONS));
//// msg.addHeader(HEADER_FACTORY.createAllowHeader(Request.MESSAGE));
//// msg.addHeader(HEADER_FACTORY.createAllowHeader(Request.REFER));
// }
/**
* Build Max-Forwards header
*
* @return Header
* @throws InvalidArgumentException
*/
// public static MaxForwardsHeader buildMaxForwardsHeader() throws InvalidArgumentException {
// return HEADER_FACTORY.createMaxForwardsHeader(70);
// }
/**
* Build P-Access-Network-info
*
* @param info Access info
* @return Header
* @throws Exception
*/
// public static Header buildAccessNetworkInfo(String info) throws Exception {
// Header accessInfo = HEADER_FACTORY.createHeader(SipUtils.HEADER_P_ACCESS_NETWORK_INFO, info);
// return accessInfo;
// }
/**
* Extract a parameter from an input text
*
* @param input Input text
* @param param Parameter name
* @param defaultValue Default value
* @return Returns the parameter value or a default value in case of error
*/
public static String extractParameter(String input, String param, String defaultValue) {
try {
int begin = input.indexOf(param) + param.length();
if (begin != -1) {
int end = input.indexOf(" ", begin); // The end is by default the next space encountered
if (input.charAt(begin) == '\"'){
// The exception is when the first character of the param is a "
// In this case, the end is the next " character, not the blank one
begin++; // we remove also the first quote
end = input.indexOf("\"",begin); // do not take last doubleQuote
}
if (end == -1) {
return input.substring(begin);
} else {
return input.substring(begin, end);
}
}
return defaultValue;
} catch(Exception e) {
return defaultValue;
}
}
/**
* Get Min-Expires period from message
*
* @param message SIP message
* @return Expire period in seconds or -1 in case of error
*/
// public static int getMinExpiresPeriod(SipServletMessage message) {
// String minHeader = message.getHeader(SipUtils.HEADER_MIN_EXPIRES);
// //MinExpiresHeader minHeader = (MinExpiresHeader)message.getHeader(MinExpiresHeader.NAME);
// if (minHeader != null) {
// return Integer.parseInt(minHeader);
// } else {
// return -1;
// }
// }
/**
* Get Min-SE period from message
*
* @param message SIP message
* @return Expire period in seconds or -1 in case of error
*/
// public static int getMinSessionExpirePeriod(SipServletMessage message) {
// String minSeHeader = message.getHeader(SipUtils.HEADER_MIN_SE);
// if (minSeHeader != null) {
// return Integer.parseInt(minSeHeader);
// } else {
// return -1;
// }
// }
//
// /**
// * Get asserted identity
// *
// * @param request SIP request
// * @return SIP URI
// */
// public static String getAssertedIdentity(SipServletRequest request) {
// Address assertedHeader = null;
// try
// {
// assertedHeader = request.getAddressHeader(SipUtils.HEADER_P_ASSERTED_IDENTITY);
// } catch (ServletParseException e)
// {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// if (assertedHeader != null) {
// return assertedHeader.toString();
// } else {
// return request.getFrom().toString();
// }
// }
//
// /**
// * Generate a list of route headers. The record route of the incoming message
// * is used to generate the corresponding route header.
// *
// * @param msg SIP message
// * @param invert Invert or not the route list
// * @return List of route headers as string
// * @throws Exception
// */
// public static Vector<String> routeProcessing(SipServletMessage msg, boolean invert) {
// Vector<String> result = new Vector<String>();
// ListIterator<Address> list = null;
// try
// {
// list = msg.getAddressHeaders(HEADER_RECORD_ROUTE);
// if (list == null) {
// // No route available
// return null;
// }
//
// while(list.hasNext()) {
// Address address = (Address)list.next();
// if (invert) {
// result.insertElementAt(address.toString(), 0);
// } else {
// result.addElement(address.toString());
// }
// }
// } catch (ServletParseException e)
// {
// // TODO Auto-generated catch block
// logger.severe("Got ServletParseException: " + e.toString());
// return null;
// };
//
// return result;
// }
//
// /**
// * Is a feature tag present or not in SIP message
// *
// * @param request Request
// * @param featuretag Feature tag to be checked
// * @return Boolean
// */
// public static boolean isFeatureTagPresent(SipServletRequest request, List<String> featureTags, String featuretag) {
// return featureTags.contains(featuretag);
// }
//
// /**
// * getting all the feature tags in message as a list
// * @param request
// * @return
// * @throws ServletParseException
// */
// public static List<String> getFeatureTags(SipServletRequest request) throws ServletParseException
// {
// ArrayList<String> tags = new ArrayList<String>();
//
// // Read Contact header
// Set<Entry<String,String>> paramSet = request.getAddressHeader("Contact").getParameters();
// if (paramSet != null) {
// for(Iterator i = paramSet.iterator(); i.hasNext();) {
// Entry<String,String> entry = (Entry<String, String>) i.next();
// String pname = entry.getKey();
// String value = entry.getValue();
// if ((value == null) || (value.length() == 0)) {
// tags.add(pname);
// } else {
// String[] values = value.split(",");
// for(int j=0; j < values.length; j++) {
// String tag = values[j].trim();
// if (!tags.contains(tag)){
// tags.add(tag);
// }
// }
// }
// }
// }
//
// // Read Accept-Contact header
// String acceptHeader = request.getHeader(SipUtils.HEADER_ACCEPT_CONTACT);
// if (acceptHeader == null) {
// // Check contracted form
// acceptHeader = request.getHeader(SipUtils.HEADER_ACCEPT_CONTACT_C);
// }
// if (acceptHeader != null) {
// String[] pnames = acceptHeader.split(";");
// if (pnames.length > 1) {
// // Start at index 1 to bypass the address
// for(int i=1; i < pnames.length; i++) {
// if (!tags.contains(pnames[i])){
// tags.add(pnames[i]);
// }
// }
// }
// }
// return tags;
// }
//
/**
* Set feature tags to a message
*
* @param message SIP message
* @param tags Table of tags
* @throws Exception
*/
// public static void setFeatureTags(SipMessage message, String[] tags) throws Exception {
// setFeatureTags(message.getStackMessage(), tags);
// }
/**
* Set feature tags to a message
*
* @param message SIP stack message
* @param tags Table of tags
* @throws Exception
*/
// public static void setFeatureTags(SipServletMessage message, String[] tags) throws Exception {
// List<String> list = Arrays.asList(tags);
// setFeatureTags(message, list);
// }
//
// /**
// * Set feature tags to a message
// *
// * @param message SIP stack message
// * @param tags List of tags
// * @throws Exception
// */
// public static void setFeatureTags(SipServletMessage message, List<String> tags) throws Exception {
// setContactFeatureTags(message, tags);
// setAcceptContactFeatureTags(message, tags);
// }
//
/**
* Set feature tags to Accept-Contact header
*
* @param message SIP stack message
* @param tags List of tags
* @throws Exception
*/
// public static void setAcceptContactFeatureTags(SipServletMessage message, List<String> tags) throws Exception {
// if ((tags == null) || (tags.size() == 0)) {
// return;
// }
//
// // Update Contact header
// StringBuffer acceptTags = new StringBuffer("*");
// for(int i=0; i < tags.size(); i++) {
// acceptTags.append(";" + tags.get(i));
// }
//
// // Update Accept-Contact header
// //Header header = SipUtils.HEADER_FACTORY.createHeader(SipUtils.HEADER_ACCEPT_CONTACT, acceptTags.toString());
// message.addHeader(SipUtils.HEADER_ACCEPT_CONTACT, acceptTags.toString());
// }
/**
* Set feature tags to Contact header
*
* @param message SIP stack message
* @param tags List of tags
* @throws Exception
*/
// public static void setContactFeatureTags(SipServletMessage message, List<String> tags) throws Exception {
// if ((tags == null) || (tags.size() == 0)) {
// return;
// }
//
// // CONTACT IS SYSTEM HEADER IN SIP SERVLET
//// // Update Contact header
//// ContactHeader contact = (ContactHeader)message.getHeader(ContactHeader.NAME);
//// for(int i=0; i < tags.size(); i++) {
//// if (contact != null) {
//// contact.setParameter(tags.get(i), null);
//// }
//// }
// }
//
// /**
// * Get the Referred-By header
// *
// * @param message SIP message
// * @return Strong or null if not exist
// */
// public static String getReferredByHeader(SipServletMessage message) {
// // Read Referred-By header
// String referredByHeader = message.getHeader(SipUtils.HEADER_REFERRED_BY);;
////
//// ExtensionHeader referredByHeader = (ExtensionHeader)message.getHeader(SipUtils.HEADER_REFERRED_BY);
// if (referredByHeader == null) {
// // Check contracted form
// referredByHeader = message.getHeader(SipUtils.HEADER_REFERRED_BY_C);
// }
// return referredByHeader;
//// if (referredByHeader == null) {
//// // Try to extract manually the header in the message
//// // TODO: to be removed when bug fix corrected in native NIST stack
//// String msg = message.getStackMessage().toString();
//// int index = msg.indexOf(SipUtils.CRLF + "b:");
//// if (index != -1) {
//// try {
//// int begin = index+4;
//// int end = msg.indexOf(SipUtils.CRLF, index+2);
//// return msg.substring(begin, end).trim();
//// } catch(Exception e) {
//// return null;
//// }
//// } else {
//// return null;
//// }
//// } else {
//// return referredByHeader.getValue();
//// }
//// } else {
//// return referredByHeader.getValue();
//// }
// }
//
}
package core.ims.protocol.msrp;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.logging.Logger;
/**
* Chunks receiver
*
* @author amir aharon
*/
public class ChunkReceiver extends Thread {
/**
* MSRP connection
*/
private MsrpConnection connection;
/**
* MSRP input stream
*/
private InputStream stream;
/**
* Termination flag
*/
private boolean terminated = false;
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Constructor
*
* @param connection MSRP connection
* @param stream TCP input stream
*/
public ChunkReceiver(MsrpConnection connection, InputStream stream) {
this.connection = connection;
this.stream = stream;
}
/**
* Returns the MSRP connection
*
* @return MSRP connection
*/
public MsrpConnection getConnection() {
return connection;
}
/**
* Terminate the receiver
*/
public void terminate() {
terminated = true;
try {
interrupt();
} catch(Exception e) {}
logger.info("Receiver is terminated");
}
/**
* Background processing
*/
public void run() {
try {
logger.info("Receiver is started");
// Background processing
while(!terminated) {
StringBuffer trace = new StringBuffer();
// Read first line of a new data chunk
StringBuffer line = readLine();
if (line.length() == 0) {
logger.info("End of stream");
return;
}
if (MsrpConnection.MSRP_TRACE_ENABLED) {
trace.append(line);
trace.append(MsrpConstants.NEW_LINE);
}
logger.info("Read a new chunk");
// Check the MSRP tag
String[] firstLineTags = line.toString().split(" ");
if ((firstLineTags.length < 3) || !firstLineTags[0].equals(MsrpConstants.MSRP_PROTOCOL)) {
logger.info("Not a MSRP message");
return;
}
// Get the transaction ID from the first line
String txId = firstLineTags[1];
logger.info("Transaction-ID: " + txId);
String end = MsrpConstants.END_MSRP_MSG + txId;
// Get response code or method name from the first line
int responseCode = -1;
String method = null;
try {
responseCode = Integer.parseInt(firstLineTags[2]);
logger.info("Response: " + responseCode);
} catch(NumberFormatException e) {
method = firstLineTags[2];
logger.info("Method: " + method);
}
// Data chunk
byte[] data = null;
// Read next lines
Hashtable<String, String> headers = new Hashtable<String, String>();
char continuationFlag = '\0';
long totalSize = 0;
while(continuationFlag == '\0') {
line = readLine();
if (MsrpConnection.MSRP_TRACE_ENABLED) {
trace.append(line);
trace.append(MsrpConstants.NEW_LINE);
}
// Test if there is a new line separating headers from the data
if (line.length() == 0) {
// Read data
String byteRange = headers.get(MsrpConstants.HEADER_BYTE_RANGE);
int chunkSize = 0;
if (byteRange != null) {
chunkSize = MsrpUtils.getChunkSize(byteRange);
totalSize = MsrpUtils.getTotalSize(byteRange);
}
logger.info("Read data (" + chunkSize + ")");
if (chunkSize > 0) {
// Use Byte-Range value to read directly the block of data
data = readChunkedData(chunkSize);
if (MsrpConnection.MSRP_TRACE_ENABLED) {
trace.append(new String(data));
trace.append(MsrpConstants.NEW_LINE);
}
} else {
// Read until terminating header is found
StringBuffer buffer = new StringBuffer();
StringBuffer dataline;
boolean endchunk = false;
while((!endchunk) && (buffer.length() < MsrpConstants.CHUNK_MAX_SIZE)) {
dataline = readLine();
if ((dataline.length()-1 == end.length()) && (dataline.toString().startsWith(end))) {
continuationFlag = dataline.charAt(dataline.length()-1);
logger.info("Continuous flag: " + continuationFlag);
endchunk = true;
} else {
if (buffer.length() > 0) {
buffer.append(MsrpConstants.NEW_LINE);
}
buffer.append(dataline);
}
}
data = buffer.toString().getBytes();
totalSize = data.length;
if (MsrpConnection.MSRP_TRACE_ENABLED) {
trace.append(new String(data));
trace.append(MsrpConstants.NEW_LINE);
trace.append(end);
trace.append(continuationFlag);
}
}
logger.info("Data: " + data.length);
} else
if (line.toString().startsWith(end)) {
continuationFlag = line.charAt(line.length()-1);
logger.info("Continuous flag: " + continuationFlag);
} else {
// It's an header
int index = line.indexOf(":");
String headerName = line.substring(0, index).trim();
String headerValue = line.substring(index+1).trim();
// Add the header in the list
headers.put(headerName, headerValue);
logger.info("Header: " + headerName);
}
}
// Process the received MSRP message
if (responseCode != -1) {
// Process MSRP response
if (MsrpConnection.MSRP_TRACE_ENABLED) {
System.out.println("<<< Receive MSRP response:\n" + trace);
}
connection.getSession().receiveMsrpResponse(responseCode, txId, headers);
} else {
// Process MSRP request
if (method.toString().equals(MsrpConstants.METHOD_SEND)) {
// Process a SEND request
if (MsrpConnection.MSRP_TRACE_ENABLED) {
System.out.println("<<< Receive MSRP SEND request:\n" + trace);
}
connection.getSession().receiveMsrpSend(txId, headers, continuationFlag, data, totalSize);
} else
if (method.toString().equals(MsrpConstants.METHOD_REPORT)) {
// Process a REPORT request
if (MsrpConnection.MSRP_TRACE_ENABLED) {
System.out.println("<<< Receive MSRP REPORT request:\n" + trace);
}
connection.getSession().receiveMsrpReport(txId, headers);
} else {
// Unknown request
logger.info("Unknown request received: " + method);
}
}
}
} catch(Exception e) {
if (terminated) {
logger.info("Chunk receiver thread terminated");
} else {
logger.severe("Chunk receiver has failed" + e);
// Notify the session listener that an error has occured
connection.getSession().getMsrpEventListener().msrpTransferError(e.getMessage());
}
terminated = true;
}
}
/**
* Read line
*
* @return String
* @throws IOException
*/
private StringBuffer readLine() throws IOException {
StringBuffer line = new StringBuffer();
int previous = -1;
int current = -1;
while((current = stream.read()) != -1) {
line.append((char)current);
if ((previous == MsrpConstants.CHAR_LF) && (current == MsrpConstants.CHAR_CR)) {
return line.delete(line.length()-2, line.length());
}
previous = current;
}
return line;
}
/**
* Read chunked data
*
* @param chunkSize Chunk size
* @return Data
* @throws IOException
*/
private byte[] readChunkedData(int chunkSize) throws IOException {
// Read data until chunk size is reached
byte[] result = null;
result = new byte[chunkSize];
int nbRead = 0;
int nbData = -1;
while((nbRead < chunkSize) && ((nbData = stream.read(result, nbRead, chunkSize-nbRead)) != -1)) {
nbRead += nbData;
}
stream.read(); // Read LF
stream.read(); // Read CR
return result;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.msrp;
import java.io.IOException;
import java.io.OutputStream;
import java.util.logging.Logger;
/**
* Chunks sender
*
* @author amir aharon
*/
public class ChunkSender extends Thread {
/**
* MSRP connection
*/
private MsrpConnection connection;
/**
* MSRP output stream
*/
private OutputStream stream;
/**
* Buffer of chunks
*/
private FifoBuffer buffer = new FifoBuffer();
/**
* Termination flag
*/
private boolean terminated = false;
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Constructor
*
* @param connection MSRP connection
* @param stream TCP output stream
*/
public ChunkSender(MsrpConnection connection, OutputStream stream) {
this.connection = connection;
this.stream = stream;
}
/**
* Returns the MSRP connection
*
* @return MSRP connection
*/
public MsrpConnection getConnection() {
return connection;
}
/**
* Terminate the sender
*/
public void terminate() {
terminated = true;
buffer.unblockRead();
try {
interrupt();
} catch(Exception e) {}
logger.info("Sender is terminated");
}
/**
* Background processing
*/
public void run() {
try {
logger.info("Sender is started");
// Read chunk to be sent
byte chunk[] = null;
while ((chunk = (byte[])buffer.getMessage()) != null) {
// Write chunk to the output stream
if (MsrpConnection.MSRP_TRACE_ENABLED) {
System.out.println(">>> Send MSRP message:\n" + new String(chunk));
}
writeData(chunk);
}
} catch (Exception e) {
if (terminated) {
logger.info("Chunk sender thread terminated");
} else {
logger.severe("Chunk sender has failed" + e);
// Notify the msrp session listener that an error has occured
connection.getSession().getMsrpEventListener().msrpTransferError(e.getMessage());
}
}
}
/**
* Send a chunk
*
* @param chunk New chunk
* @throws IOException
*/
public void sendChunk(byte chunk[]) throws IOException {
if (connection.getSession().isFailureReportRequested()) {
buffer.putMessage(chunk);
} else {
sendChunkImmediately(chunk);
}
}
/**
* Send a chunk immediately
*
* @param chunk New chunk
* @throws IOException
*/
public void sendChunkImmediately(byte chunk[]) throws IOException {
if (MsrpConnection.MSRP_TRACE_ENABLED) {
System.out.println(">>> Send MSRP message:\n" + new String(chunk));
}
writeData(chunk);
}
/**
* Write data to the stream
*
* @param chunk Data chunck
* @throws IOException
*/
private synchronized void writeData(byte chunk[]) throws IOException {
// stream.write(chunk);
// stream.flush();
// test
connection.writeData(chunk);
}
}
package core.ims.protocol.msrp;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.logging.Logger;
/**
* Data chunks
*
* @author amir aharon
*/
public class DataChunks {
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Current transfered size in bytes
*/
private int currentSize = 0;
/**
* Cache used to save data chunks
*/
private ByteArrayOutputStream cache = new ByteArrayOutputStream();
/**
* Constructor
*/
public DataChunks() {
}
/**
* Add a new chunk
*
* @param data Data chunk
*/
public void addChunk(byte[] data) throws IOException {
cache.write(data, 0, data.length);
currentSize += data.length;
}
/**
* Get received data
*
* @return Byte array
*/
public byte[] getReceivedData() {
byte[] result=null;
try {
result = cache.toByteArray();
} catch (OutOfMemoryError e) {
logger.severe("Not enough memory to save data" + e);
}
return result;
}
/**
* Rset the cache
*/
public void resetCache() {
cache.reset();
currentSize = 0;
}
/**
* Returns the current size of the received chunks
*
* @return Size in bytes
*/
public int getCurrentSize() {
return currentSize;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.msrp;
import java.util.Vector;
/**
* Fifo buffer
*
* @author JM. Auffret
*/
public class FifoBuffer {
/**
* Number of messages in the buffer
*/
private int numMessage = 0;
/**
* Buffer of messages
*/
private Vector<Object> fifo = new Vector<Object>();
/**
* Add a message in the buffer
*
* @param obj Message
*/
public synchronized void putMessage(Object obj) {
fifo.addElement(obj);
numMessage++;
notifyAll();
}
/**
* Read a message in the buffer. This is a blocking method until a
* message is received in the buffer.
*
* @return Message
*/
public synchronized Object getMessage() {
Object message = null;
if (numMessage == 0) {
try {
wait();
} catch (InterruptedException e) {
// Nothing to do
}
}
if (numMessage != 0) {
message = fifo.elementAt(0);
fifo.removeElementAt(0);
numMessage--;
notifyAll();
}
return message;
}
/**
* Read a message in the buffer. This is a blocking method until a timeout
* occurs or a message is received in the buffer.
*
* @param timeout Timeout
* @return Message
*/
public synchronized Object getMessage(int timeout) {
Object message = null;
if (numMessage == 0) {
try {
wait(timeout);
} catch (InterruptedException e) {
// Nothing to do
}
}
if (numMessage != 0) {
message = fifo.elementAt(0);
fifo.removeElementAt(0);
numMessage--;
notifyAll();
}
return message;
}
/**
* Unblock the reading
*/
public void unblockRead() {
synchronized (this) {
this.notifyAll();
}
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.msrp;
import java.io.IOException;
import java.util.logging.Logger;
import platform.network.NetworkFactory;
import platform.network.SocketConnection;
/**
* MSRP client connection
*
* @author amir aharon
*/
public class MsrpClientConnection extends MsrpConnection {
/**
* Remote IP address
*/
private String remoteAddress;
/**
* Remote TCP port number
*/
private int remotePort;
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Constructor
*
* @param session MSRP session
* @param remoteAddress Remote IP address
* @param remotePort Remote port number
*/
public MsrpClientConnection(MsrpSession session, String remoteAddress, int remotePort) {
super(session);
this.remoteAddress = remoteAddress;
this.remotePort = remotePort;
}
/**
* Returns the socket connection
*
* @return Socket
* @throws IOException
*/
public SocketConnection getSocketConnection() throws IOException {
logger.info("Open client socket to " + remoteAddress + ":" + remotePort);
SocketConnection socket = NetworkFactory.getFactory().createSocketClientConnection();
socket.open(remoteAddress, remotePort);
logger.info("Socket connected to " + socket.getRemoteAddress() + ":" + socket.getRemotePort());
return socket;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.msrp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Logger;
import platform.network.SocketConnection;
/**
* Abstract MSRP connection between two end points
*
* @author amir aharon
*/
public abstract class MsrpConnection {
/**
* MSRP traces enabled
*/
public static boolean MSRP_TRACE_ENABLED = false;
/**
* MSRP session
*/
private MsrpSession session;
/**
* Socket connection
*/
private SocketConnection socket = null;
/**
* Socket output stream
*/
private OutputStream outputStream = null;
/**
* Socket input stream
*/
private InputStream inputStream = null;
/**
* Chunk receiver
*/
private ChunkReceiver receiver;
/**
* Chunk sender
*/
private ChunkSender sender;
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Constructor
*
* @param session MSRP session
*/
public MsrpConnection(MsrpSession session) {
this.session = session;
}
/**
* Returns the MSRP session associated to the MSRP connection
*
* @return MSRP session
*/
public MsrpSession getSession() {
return session;
}
/**
* Open the connection
*
* @throws IOException
*/
public void open() throws IOException {
// Open socket connection
socket = getSocketConnection();
// Open I/O stream
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
// Create the chunk receiver
receiver = new ChunkReceiver(this, inputStream);
receiver.start();
// Create the chunk sender
sender = new ChunkSender(this, outputStream);
sender.start();
logger.info("Connection has been openned");
}
/**
* Open the connection
*
* @throws IOException
*/
public void setSocketConnection(SocketConnection sockConn) throws IOException {
// Open socket connection
socket = sockConn;
// Open I/O stream
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
// Create the chunk receiver
receiver = new ChunkReceiver(this, inputStream);
//receiver.start();
// Create the chunk sender
sender = new ChunkSender(this, outputStream);
//sender.start();
logger.info("Connection has been openned");
}
/**
* Open the connection with SO_TIMEOUT on the socket
*
* @param timeout Timeout value (in seconds)
* @throws IOException
*/
public void open(int timeout) throws IOException {
// Open socket connection
socket = getSocketConnection();
// Set SoTimeout
socket.setSoTimeout(timeout*1000);
// Open I/O stream
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
// Create the chunk receiver
receiver = new ChunkReceiver(this, inputStream);
receiver.start();
// Create the chunk sender
sender = new ChunkSender(this, outputStream);
sender.start();
logger.info("Connection has been openned");
}
/**
* Close the connection
*/
public void close() {
// Terminate chunk sender
if (sender != null) {
sender.terminate();
}
// Terminate chunk receiver
if (receiver != null) {
receiver.terminate();
}
// Close socket connection
try {
logger.info("Close the socket connection");
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
if (socket != null) {
socket.close();
}
} catch (Exception e) {
logger.severe("Can't close the socket correctly" + e);
}
logger.info("Connection has been closed");
}
/**
* Send a new data chunk
*
* @param chunk Data chunk
* @throws IOException
*/
public void sendChunk(byte chunk[]) throws IOException {
sender.sendChunk(chunk);
}
/**
* Send a new data chunk immediately
*
* @param chunk Data chunk
* @throws IOException
*/
public void sendChunkImmediately(byte chunk[]) throws IOException {
sender.sendChunkImmediately(chunk);
}
/**
* Returns the socket connection
*
* @return Socket
* @throws IOException
*/
public abstract SocketConnection getSocketConnection() throws IOException;
public void writeData(byte data[]) throws IOException
{
socket.write(data);
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.msrp;
/**
* MSRP contants
*
* @author amir aharon
*/
public interface MsrpConstants {
public static final String MSRP_PROTOCOL = "MSRP";
public static final String NEW_LINE = "\r\n";
public static final String END_MSRP_MSG = "-------";
public static final int FLAG_LAST_CHUNK = '$';
public static final int FLAG_MORE_CHUNK = '+';
public static final int FLAG_ABORT_CHUNK = '#';
public static final byte CHAR_SP = ' ';
public static final byte CHAR_LF = '\r';
public static final byte CHAR_CR = '\n';
public static final byte CHAR_MIN = '-';
public static final byte CHAR_DOUBLE_POINT = ':';
public static final String HEADER_BYTE_RANGE = "Byte-Range";
public static final String HEADER_STATUS = "Status";
public static final String HEADER_CONTENT_TYPE = "Content-Type";
public static final String HEADER_MESSAGE_ID = "Message-ID";
public static final String HEADER_TO_PATH = "To-Path";
public static final String HEADER_FROM_PATH = "From-Path";
public static final String HEADER_FAILURE_REPORT = "Failure-Report";
public static final String HEADER_SUCCESS_REPORT = "Success-Report";
public static final String METHOD_SEND = "SEND";
public static final String METHOD_REPORT = "REPORT";
public static final int RESPONSE_OK = 200;
public static final int CHUNK_MAX_SIZE = 10 * 1024;
public static final String COMMENT_OK = "OK";
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.msrp;
/**
* MSRP event listener
*
* @author amir aharon
*/
public interface MsrpEventListener {
/**
* Data has been transfered
*
* @param msgId Message ID
*/
public void msrpDataTransfered(String msgId);
/**
* Data has been received
*
* @param msgId Message ID
* @param data Received data
* @param mimeType Data mime-type
*/
public void msrpDataReceived(String msgId, byte[] data, String mimeType);
/**
* Data transfer in progress
*
* @param currentSize Current transfered size in bytes
* @param totalSize Total size in bytes
*/
public void msrpTransferProgress(long currentSize, long totalSize);
/**
* Data transfer has been aborted
*/
public void msrpTransferAborted();
/**
* Data transfer error
*
* @param error Error
*/
public void msrpTransferError(String error);
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.msrp;
/**
* MSRP exception
*
* @author amir aharon
*/
public class MsrpException extends Exception {
static final long serialVersionUID = 1L;
/**
* Constructor
*
* @param error Error message
*/
public MsrpException(String error) {
super(error);
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.msrp;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Logger;
import utils.IpAddressUtils;
/**
* MSRP manager
*
* @author amir aharon
*/
public class MsrpManager {
/**
* Local MSRP address
*/
private String localMsrpAddress;
/**
* Local MSRP port
*/
private int localMsrpPort;
/**
* MSRP session
*/
private MsrpSession msrpSession = null;
/**
* Session Id
*/
private long sessionId;
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Constructor
*
* @param localIpAddress Local MSRP address
* @param localMsrpPort Local MSRP port
*/
public MsrpManager(String localMsrpAddress, int localMsrpPort) {
this.localMsrpAddress = localMsrpAddress;
this.localMsrpPort = localMsrpPort;
this.sessionId = System.currentTimeMillis();
}
/**
* Returns the local MSRP port
*
* @return Port number
*/
public int getLocalMsrpPort() {
return localMsrpPort;
}
/**
* Get the local MSRP path
*
* @return MSRP path
*/
public String getLocalMsrpPath() {
if (IpAddressUtils.isIPv6(localMsrpAddress)) {
return "msrp://[" + localMsrpAddress + "]:" + localMsrpPort + "/" + sessionId + ";tcp";
} else {
return "msrp://" + localMsrpAddress + ":" + localMsrpPort + "/" + sessionId + ";tcp";
}
}
/**
* Return the MSRP session
*
* @return MSRP session
*/
public MsrpSession getMsrpSession() {
return msrpSession;
}
/**
* Open the MSRP session
*
* @throws IOException
*/
public void openMsrpSession() throws IOException {
if ((msrpSession == null) || (msrpSession.getConnection() == null)) {
throw new IOException("Session not yet created");
}
msrpSession.getConnection().open();
}
/**
* Open the connection with SO_TIMEOUT on the socket
*
* @param timeout Timeout value (in seconds)
* @throws IOException
*/
public void openMsrpSession(int timeout) throws IOException {
if ((msrpSession == null) || (msrpSession.getConnection() == null)) {
throw new IOException("Session not yet created");
}
msrpSession.getConnection().open(timeout);
}
/**
* Create a MSRP client session
*
* @param remoteHost Remote host
* @param remotePort Remote port
* @param remoteMsrpPath Remote MSRP path
* @param listener Event listener
* @return Created session
* @throws MsrpException
*/
public MsrpSession createMsrpClientSession(String remoteHost, int remotePort, String remoteMsrpPath, MsrpEventListener listener) throws MsrpException {
try {
logger.info("Create MSRP client end point at " + remoteHost + ":" + remotePort);
// Create a new MSRP session
msrpSession = new MsrpSession();
msrpSession.setFrom(getLocalMsrpPath());
msrpSession.setTo(remoteMsrpPath);
// Create a MSRP client connection
final MsrpConnection connection = new MsrpClientConnection(msrpSession, remoteHost, remotePort);
// Associate the connection to the session
msrpSession.setConnection(connection);
// Add event listener
msrpSession.addMsrpEventListener(listener);
// Return the created session
return msrpSession;
} catch(Exception e) {
logger.severe("Can't create the MSRP client session" + e);
throw new MsrpException("Create MSRP client session has failed");
}
}
/**
* Create a MSRP server session
*
* @param remoteMsrpPath Remote MSRP path
* @param listener Event listener
* @return Created session
* @throws MsrpException
*/
public MsrpSession createMsrpServerSession(String remoteMsrpPath, MsrpEventListener listener) throws MsrpException {
logger.info("Create MSRP server end point at " + localMsrpPort);
// Create a MSRP session
msrpSession = new MsrpSession();
msrpSession.setFrom(getLocalMsrpPath());
msrpSession.setTo(remoteMsrpPath);
// Create a MSRP server connection
final MsrpConnection connection = new MsrpServerConnection(msrpSession, localMsrpPort);
// Associate the connection to the session
msrpSession.setConnection(connection);
// Add event listener
msrpSession.addMsrpEventListener(listener);
// Return the created session
return msrpSession;
}
/**
* Send data chunks
*
* @param inputStream Input stream
* @param msgId Message ID
* @param contentType Content type
* @param contentSize Content size
* @throws MsrpException
*/
public void sendChunks(InputStream inputStream, String msgId, String contentType, long contentSize) throws MsrpException {
if (msrpSession == null) {
throw new MsrpException("MSRP session is null");
}
msrpSession.sendChunks(inputStream, msgId, contentType, contentSize);
}
/**
* Send an empty chunk
*
* @throws MsrpException
*/
public void sendEmptyChunk() throws MsrpException {
if (msrpSession == null) {
throw new MsrpException("MSRP session is null");
}
msrpSession.sendEmptyChunk();
}
/**
* Close the MSRP session
*/
public synchronized void closeSession() {
if (msrpSession != null) {
logger.info("Close the MSRP session");
try {
msrpSession.close();
} catch(Exception e) {
// Intentionally blank
}
msrpSession = null;
}
}
}
package core.ims.protocol.msrp;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.logging.Logger;
/**
* this class is like {@link ChatReciever } only it is not
* a thread class, it is used to parse mrsp message and
* activate the appropriate mrsp api
* @author amir
*
*/
public class MsrpParser
{
/**
* MSRP input stream
*/
private InputStream stream;
/**
* MSRP session
*/
private MsrpSession session;
/**
* The logger
*/
private static Logger logger = Logger.getLogger("MsrpParser");
/**
* Constructor
*
* @param connection MSRP connection
* @param stream TCP input stream
*/
public MsrpParser() {
}
private void reset()
{
stream = null;
session = null;
}
/**
* parse the stream and activate the adequate api's in the msrp session
* if exists,
* @param stream
* @param session
*/
public void parse(InputStream stream, MsrpSession session)
{
reset();
this.stream = stream;
this.session = session;
try
{
StringBuffer trace = new StringBuffer();
// Read first line of a new data chunk
StringBuffer line = readLine();
if (line.length() == 0) {
logger.info("End of stream");
return;
}
if (MsrpConnection.MSRP_TRACE_ENABLED) {
trace.append(line);
trace.append(MsrpConstants.NEW_LINE);
}
logger.info("Read a new chunk");
// Check the MSRP tag
String[] firstLineTags = line.toString().split(" ");
if ((firstLineTags.length < 3) || !firstLineTags[0].equals(MsrpConstants.MSRP_PROTOCOL)) {
logger.info("Not a MSRP message");
return;
}
// Get the transaction ID from the first line
String txId = firstLineTags[1];
logger.info("Transaction-ID: " + txId);
String end = MsrpConstants.END_MSRP_MSG + txId;
// Get response code or method name from the first line
int responseCode = -1;
String method = null;
try {
responseCode = Integer.parseInt(firstLineTags[2]);
logger.info("Response: " + responseCode);
} catch(NumberFormatException e) {
method = firstLineTags[2];
logger.info("Method: " + method);
}
// Data chunk
byte[] data = null;
// Read next lines
Hashtable<String, String> headers = new Hashtable<String, String>();
char continuationFlag = '\0';
long totalSize = 0;
while(continuationFlag == '\0') {
line = readLine();
if (MsrpConnection.MSRP_TRACE_ENABLED) {
trace.append(line);
trace.append(MsrpConstants.NEW_LINE);
}
// Test if there is a new line separating headers from the data
if (line.length() == 0) {
// Read data
String byteRange = headers.get(MsrpConstants.HEADER_BYTE_RANGE);
int chunkSize = 0;
if (byteRange != null) {
chunkSize = MsrpUtils.getChunkSize(byteRange);
totalSize = MsrpUtils.getTotalSize(byteRange);
}
logger.info("Read data (" + chunkSize + ")");
if (chunkSize > 0) {
// Use Byte-Range value to read directly the block of data
data = readChunkedData(chunkSize);
if (MsrpConnection.MSRP_TRACE_ENABLED) {
trace.append(new String(data));
trace.append(MsrpConstants.NEW_LINE);
}
} else {
// Read until terminating header is found
StringBuffer buffer = new StringBuffer();
StringBuffer dataline;
boolean endchunk = false;
while((!endchunk) && (buffer.length() < MsrpConstants.CHUNK_MAX_SIZE)) {
dataline = readLine();
if ((dataline.length()-1 == end.length()) && (dataline.toString().startsWith(end))) {
continuationFlag = dataline.charAt(dataline.length()-1);
logger.info("Continuous flag: " + continuationFlag);
endchunk = true;
} else {
if (buffer.length() > 0) {
buffer.append(MsrpConstants.NEW_LINE);
}
buffer.append(dataline);
}
}
data = buffer.toString().getBytes();
totalSize = data.length;
if (MsrpConnection.MSRP_TRACE_ENABLED) {
trace.append(new String(data));
trace.append(MsrpConstants.NEW_LINE);
trace.append(end);
trace.append(continuationFlag);
}
}
logger.info("Data: " + data.length);
} else
if (line.toString().startsWith(end)) {
continuationFlag = line.charAt(line.length()-1);
logger.info("Continuous flag: " + continuationFlag);
} else {
// It's an header
int index = line.indexOf(":");
String headerName = line.substring(0, index).trim();
String headerValue = line.substring(index+1).trim();
// Add the header in the list
headers.put(headerName, headerValue);
logger.info("Header: " + headerName);
}
}
// Process the received MSRP message
if (responseCode != -1) {
// Process MSRP response
if (MsrpConnection.MSRP_TRACE_ENABLED) {
System.out.println("<<< Receive MSRP response:\n" + trace);
}
if (this.session != null)
session.receiveMsrpResponse(responseCode, txId, headers);
} else {
// Process MSRP request
if (method.toString().equals(MsrpConstants.METHOD_SEND)) {
// Process a SEND request
if (MsrpConnection.MSRP_TRACE_ENABLED) {
System.out.println("<<< Receive MSRP SEND request:\n" + trace);
}
if (this.session != null)
session.receiveMsrpSend(txId, headers, continuationFlag, data, totalSize);
} else
if (method.toString().equals(MsrpConstants.METHOD_REPORT)) {
// Process a REPORT request
if (MsrpConnection.MSRP_TRACE_ENABLED) {
System.out.println("<<< Receive MSRP REPORT request:\n" + trace);
}
if (this.session != null)
session.receiveMsrpReport(txId, headers);
} else {
// Unknown request
logger.info("Unknown request received: " + method);
}
}
}
catch(Exception e)
{
logger.severe("Chunk receiver has failed" + e);
// Notify the session listener that an error has occured
if (this.session != null)
session.getMsrpEventListener().msrpTransferError(e.getMessage());
}
}
/**
* Read line
*
* @return String
* @throws IOException
*/
private StringBuffer readLine() throws IOException {
StringBuffer line = new StringBuffer();
int previous = -1;
int current = -1;
while((current = stream.read()) != -1) {
line.append((char)current);
if ((previous == MsrpConstants.CHAR_LF) && (current == MsrpConstants.CHAR_CR)) {
return line.delete(line.length()-2, line.length());
}
previous = current;
}
return line;
}
/**
* Read chunked data
*
* @param chunkSize Chunk size
* @return Data
* @throws IOException
*/
private byte[] readChunkedData(int chunkSize) throws IOException {
// Read data until chunk size is reached
byte[] result = null;
result = new byte[chunkSize];
int nbRead = 0;
int nbData = -1;
while((nbRead < chunkSize) && ((nbData = stream.read(result, nbRead, chunkSize-nbRead)) != -1)) {
nbRead += nbData;
}
stream.read(); // Read LF
stream.read(); // Read CR
return result;
}
/**
* getting the chat session id from the message
* @param stream
* @return
*/
public String getChatSessionId(InputStream stream)
{
String chatSessionId = null;
this.stream = stream;
try
{
StringBuffer sb = readLine();
while (sb != null && sb.length() > 0)
{
String line = sb.toString();
if (line.startsWith(MsrpConstants.HEADER_TO_PATH))
{
// Getting the session-id
int slashIndex = line.lastIndexOf('/');
int semiIndex = line.lastIndexOf(';');
if (slashIndex != -1 && semiIndex != -1)
{
chatSessionId = line.substring(slashIndex + 1, semiIndex);
break;
}
}
sb = readLine();
}
}
catch (Exception e)
{
logger.severe("getChatSessionId has failed: " + e);
}
return chatSessionId;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.msrp;
import java.io.IOException;
import java.util.logging.Logger;
import platform.network.NetworkFactory;
import platform.network.SocketConnection;
import platform.network.SocketServerConnection;
/**
* MSRP server connection
*
* @author amir aharon
*/
public class MsrpServerConnection extends MsrpConnection {
/**
* Local TCP port number
*/
private int localPort;
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Constructor
*
* @param session MSRP session
* @param localPort Local port number
*/
public MsrpServerConnection(MsrpSession session, int localPort) {
super(session);
this.localPort = localPort;
}
/**
* Returns the socket connection
*
* @return Socket
* @throws IOException
*/
public SocketConnection getSocketConnection() throws IOException {
logger.info("Open server socket at " + localPort);
SocketServerConnection socketServer = NetworkFactory.getFactory().createSocketServerConnection();
socketServer.open(localPort);
logger.info("Wait client connection");
SocketConnection socket = socketServer.acceptConnection();
logger.info("Socket connected to " + socket.getRemoteAddress() + ":" + socket.getRemotePort());
return socket;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.msrp;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.Random;
import java.util.logging.Logger;
/**
* MSRP session
*
* @author amir aharon
*/
public class MsrpSession {
/**
* Failure report option
*/
private boolean failureReportOption = false;
/**
* Success report option
*/
private boolean successReportOption = false;
/**
* MSRP connection
*/
private MsrpConnection connection = null;
/**
* From path
*/
private String from = null;
/**
* To path
*/
private String to = null;
/**
* Cancel transfer flag
*/
private boolean cancelTransfer = false;
/**
* Request transaction
*/
private RequestTransaction requestTransaction = null;
/**
* Received chunks
*/
private DataChunks receivedChunks = new DataChunks();
/**
* MSRP event listener
*/
private MsrpEventListener msrpEventListener = null;
/**
* Random generator
*/
private static Random random = new Random(System.currentTimeMillis());
/**
* Report transaction
*/
private ReportTransaction reportTransaction = null;
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Constructor
*/
public MsrpSession() {
}
/**
* Generate a unique ID for transaction
*
* @return ID
*/
private static synchronized String generateTransactionId() {
return Long.toHexString(random.nextLong());
}
/**
* Is failure report requested
*
* @return Boolean
*/
public boolean isFailureReportRequested() {
return failureReportOption;
}
/**
* Set the failure report option
*
* @param failureReportOption Boolean flag
*/
public void setFailureReportOption(boolean failureReportOption) {
this.failureReportOption = failureReportOption;
}
/**
* Is success report requested
*
* @return Boolean
*/
public boolean isSuccessReportRequested() {
return successReportOption;
}
/**
* Set the success report option
*
* @param successReportOption Boolean flag
*/
public void setSuccessReportOption(boolean successReportOption) {
this.successReportOption = successReportOption;
}
/**
* Set the MSRP connection
*
* @param connection MSRP connection
*/
public void setConnection(MsrpConnection connection) {
this.connection = connection;
}
/**
* Returns the MSRP connection
*
* @return MSRP connection
*/
public MsrpConnection getConnection() {
return connection;
}
/**
* Get the MSRP event listener
*
* @return Listener
*/
public MsrpEventListener getMsrpEventListener() {
return msrpEventListener;
}
/**
* Add a MSRP event listener
*
* @param listener Listener
*/
public void addMsrpEventListener(MsrpEventListener listener) {
this.msrpEventListener = listener;
}
/**
* Returns the From path
*
* @return From path
*/
public String getFrom() {
return from;
}
/**
* Set the From path
*
* @param from From path
*/
public void setFrom(String from) {
this.from = from;
}
/**
* Returns the To path
*
* @return To path
*/
public String getTo() {
return to;
}
/**
* Set the To path
*
* @param to To path
*/
public void setTo(String to) {
this.to = to;
}
/**
* Close the session
*/
public void close() {
logger.info("Close session");
// Cancel transfer
cancelTransfer = true;
// Close the connection
if (connection != null) {
connection.close();
}
// Unblock request transaction
if (requestTransaction != null) {
requestTransaction.terminate();
}
// Unblock report transaction
if (reportTransaction != null) {
reportTransaction.terminate();
}
}
/**
* Send chunks
*
* @param inputStream Input stream
* @param msgId Message ID
* @param contentType Content type to be sent
* @param totalSize Total size of content
* @throws MsrpException
*/
public void sendChunks(InputStream inputStream, String msgId, String contentType, long totalSize) throws MsrpException {
logger.info("Send content (" + contentType + ")");
if (from == null) {
throw new MsrpException("From not set");
}
if (to == null) {
throw new MsrpException("To not set");
}
if (connection == null) {
throw new MsrpException("No connection set");
}
// Send content over MSRP
try {
byte data[] = new byte[MsrpConstants.CHUNK_MAX_SIZE];
long firstByte = 1;
long lastByte = 0;
cancelTransfer = false;
if (successReportOption) {
reportTransaction = new ReportTransaction();
} else {
reportTransaction = null;
}
// Send data chunk by chunk
for (int i = inputStream.read(data); (!cancelTransfer) & (i>-1); i=inputStream.read(data)) {
// Update upper byte range
lastByte += i;
// Send a chunk
sendMsrpSendRequest(generateTransactionId(), to, from, msgId, contentType, i, data, firstByte, lastByte, totalSize);
// Update lower byte range
firstByte += i;
if (!cancelTransfer) {
// Notify event listener
msrpEventListener.msrpTransferProgress(lastByte, totalSize);
}
}
if (cancelTransfer) {
// Transfer has been aborted
return;
}
// Test if waiting report is needed
if (reportTransaction != null) {
// Wait until all data have been reported
long lastReport = reportTransaction.getReportedSize();
while(reportTransaction.getReportedSize() < totalSize) {
reportTransaction.waitReport();
if (lastReport == reportTransaction.getReportedSize()) {
// Timeout
break;
}
if (reportTransaction.getStatusCode() != 200) {
// Error
break;
}
lastReport = reportTransaction.getReportedSize();
}
// Notify event listener
if ((reportTransaction.getStatusCode() == 200) &&
(reportTransaction.getReportedSize() == totalSize)) {
msrpEventListener.msrpDataTransfered(msgId);
} else {
msrpEventListener.msrpTransferError("report timeout");
}
} else {
// Notify event listener
msrpEventListener.msrpDataTransfered(msgId);
}
} catch(Exception e) {
logger.severe("Send chunk failed" + e);
throw new MsrpException(e.getMessage());
}
}
/**
* Send empty chunk
*
* @throws MsrpException
*/
public void sendEmptyChunk() throws MsrpException {
logger.info("Send an empty chunk");
if (from == null) {
throw new MsrpException("From not set");
}
if (to == null) {
throw new MsrpException("To not set");
}
if (connection == null) {
throw new MsrpException("No connection set");
}
// Send an empty chunk
try {
sendEmptyMsrpSendRequest(generateTransactionId(), to, from, generateTransactionId());
} catch(MsrpException e) {
throw e;
} catch(Exception e) {
throw new MsrpException(e.getMessage());
}
}
/**
* Send MSRP SEND request
*
* @param transactionId Transaction ID
* @param to To header
* @param from From header
* @param msgId Message ID header
* @param contentType Content type
* @param dataSize Data chunk size
* @param data Data chunk
* @param firstByte First byte range
* @param lastByte Last byte range
* @param totalSize Total size
* @throws IOException
* @throws MsrpException
*/
private void sendMsrpSendRequest(String txId, String to, String from, String msgId, String contentType,
int dataSize, byte data[], long firstByte, long lastByte, long totalSize) throws MsrpException, IOException {
boolean isLastChunk = (lastByte == totalSize);
// Create request
ByteArrayOutputStream buffer = new ByteArrayOutputStream(4000);
buffer.reset();
buffer.write(MsrpConstants.MSRP_PROTOCOL.getBytes());
buffer.write(MsrpConstants.CHAR_SP);
buffer.write(txId.getBytes());
buffer.write((" " + MsrpConstants.METHOD_SEND).getBytes());
buffer.write(MsrpConstants.NEW_LINE.getBytes());
String toHeader = MsrpConstants.HEADER_TO_PATH + ": " + to + MsrpConstants.NEW_LINE;
buffer.write(toHeader.getBytes());
String fromHeader = MsrpConstants.HEADER_FROM_PATH + ": " + from + MsrpConstants.NEW_LINE;
buffer.write(fromHeader.getBytes());
String msgIdHeader = MsrpConstants.HEADER_MESSAGE_ID + ": " + msgId + MsrpConstants.NEW_LINE;
buffer.write(msgIdHeader.getBytes());
// Write byte range
String byteRange = MsrpConstants.HEADER_BYTE_RANGE + ": " + firstByte + "-" + lastByte + "/" + totalSize + MsrpConstants.NEW_LINE;
buffer.write(byteRange.getBytes());
// Write optional headers
if (!failureReportOption) {
String header = MsrpConstants.HEADER_FAILURE_REPORT + ": no" + MsrpConstants.NEW_LINE;
buffer.write(header.getBytes());
}
if (successReportOption) {
String header = MsrpConstants.HEADER_SUCCESS_REPORT + ": yes" + MsrpConstants.NEW_LINE;
buffer.write(header.getBytes());
}
// Write content type
if (contentType != null) {
String content = MsrpConstants.HEADER_CONTENT_TYPE + ": " + contentType + MsrpConstants.NEW_LINE;
buffer.write(content.getBytes());
}
// Write data
if (data != null) {
buffer.write(MsrpConstants.NEW_LINE.getBytes());
buffer.write(data, 0, dataSize);
buffer.write(MsrpConstants.NEW_LINE.getBytes());
}
// Write end of request
buffer.write(MsrpConstants.END_MSRP_MSG.getBytes());
buffer.write(txId.getBytes());
if (isLastChunk) {
// '$' -> last chunk
buffer.write(MsrpConstants.FLAG_LAST_CHUNK);
} else {
// '+' -> more chunk
buffer.write(MsrpConstants.FLAG_MORE_CHUNK);
}
buffer.write(MsrpConstants.NEW_LINE.getBytes());
// Send chunk
if (failureReportOption) {
requestTransaction = new RequestTransaction();
connection.sendChunk(buffer.toByteArray());
buffer.close();
requestTransaction.waitResponse();
if (!requestTransaction.isResponseReceived()) {
throw new MsrpException("timeout");
}
} else {
connection.sendChunk(buffer.toByteArray());
buffer.close();
}
}
/**
* Send an empty MSRP SEND request
*
* @param transactionId Transaction ID
* @param to To header
* @param from From header
* @param msgId Message ID header
* @throws MsrpException
* @throws IOException
*/
private void sendEmptyMsrpSendRequest(String txId, String to, String from, String msgId) throws MsrpException, IOException {
// Create request
ByteArrayOutputStream buffer = new ByteArrayOutputStream(4000);
buffer.reset();
buffer.write(MsrpConstants.MSRP_PROTOCOL.getBytes());
buffer.write(MsrpConstants.CHAR_SP);
buffer.write(txId.getBytes());
buffer.write((" " + MsrpConstants.METHOD_SEND).getBytes());
buffer.write(MsrpConstants.NEW_LINE.getBytes());
String toHeader = MsrpConstants.HEADER_TO_PATH + ": " + to + MsrpConstants.NEW_LINE;
buffer.write(toHeader.getBytes());
String fromHeader = MsrpConstants.HEADER_FROM_PATH + ": " + from + MsrpConstants.NEW_LINE;
buffer.write(fromHeader.getBytes());
String msgIdHeader = MsrpConstants.HEADER_MESSAGE_ID + ": " + msgId + MsrpConstants.NEW_LINE;
buffer.write(msgIdHeader.getBytes());
// Write end of request
buffer.write(MsrpConstants.END_MSRP_MSG.getBytes());
buffer.write(txId.getBytes());
// '$' -> last chunk
buffer.write(MsrpConstants.FLAG_LAST_CHUNK);
buffer.write(MsrpConstants.NEW_LINE.getBytes());
// Send chunk
requestTransaction = new RequestTransaction();
connection.sendChunkImmediately(buffer.toByteArray());
buffer.close();
requestTransaction.waitResponse();
if (!requestTransaction.isResponseReceived()) {
throw new MsrpException("timeout");
}
}
/**
* Send MSRP response
*
* @param code Response code
* @param txId Transaction ID
* @param headers MSRP headers
* @throws IOException
*/
private void sendMsrpResponse(String code, String txId, Hashtable<String, String> headers) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(4000);
buffer.write(MsrpConstants.MSRP_PROTOCOL .getBytes());
buffer.write(MsrpConstants.CHAR_SP);
buffer.write(txId.getBytes());
buffer.write(MsrpConstants.CHAR_SP);
buffer.write(code.getBytes());
buffer.write(MsrpConstants.NEW_LINE.getBytes());
buffer.write(MsrpConstants.HEADER_TO_PATH.getBytes());
buffer.write(MsrpConstants.CHAR_DOUBLE_POINT);
buffer.write(MsrpConstants.CHAR_SP);
buffer.write((headers.get(MsrpConstants.HEADER_FROM_PATH)).getBytes());
buffer.write(MsrpConstants.NEW_LINE.getBytes());
buffer.write(MsrpConstants.HEADER_FROM_PATH.getBytes());
buffer.write(MsrpConstants.CHAR_DOUBLE_POINT);
buffer.write(MsrpConstants.CHAR_SP);
buffer.write((headers.get(MsrpConstants.HEADER_TO_PATH)).getBytes());
buffer.write(MsrpConstants.NEW_LINE.getBytes());
// Byte-range header may not be present
if (headers.get(MsrpConstants.HEADER_BYTE_RANGE) != null) {
buffer.write(MsrpConstants.HEADER_BYTE_RANGE.getBytes());
buffer.write(MsrpConstants.CHAR_DOUBLE_POINT);
buffer.write(MsrpConstants.CHAR_SP);
buffer.write((headers.get(MsrpConstants.HEADER_BYTE_RANGE)).getBytes());
buffer.write(MsrpConstants.NEW_LINE.getBytes());
}
buffer.write(MsrpConstants.END_MSRP_MSG.getBytes());
buffer.write(txId.getBytes());
buffer.write(MsrpConstants.FLAG_LAST_CHUNK);
buffer.write(MsrpConstants.NEW_LINE.getBytes());
connection.sendChunk(buffer.toByteArray());
buffer.close();
}
/**
* Send MSRP REPORT request
*
* @param txId Transaction ID
* @param headers MSRP headers
* @throws MsrpException
* @throws IOException
*/
private void sendMsrpReportRequest(String txId, Hashtable<String, String> headers,
long lastByte, long totalSize) throws MsrpException, IOException {
// Create request
ByteArrayOutputStream buffer = new ByteArrayOutputStream(4000);
buffer.reset();
buffer.write(MsrpConstants.MSRP_PROTOCOL.getBytes());
buffer.write(MsrpConstants.CHAR_SP);
buffer.write(txId.getBytes());
buffer.write((" " + MsrpConstants.METHOD_REPORT).getBytes());
buffer.write(MsrpConstants.NEW_LINE.getBytes());
buffer.write(MsrpConstants.HEADER_TO_PATH.getBytes());
buffer.write(MsrpConstants.CHAR_DOUBLE_POINT);
buffer.write(MsrpConstants.CHAR_SP);
buffer.write((headers.get(MsrpConstants.HEADER_FROM_PATH)).getBytes());
buffer.write(MsrpConstants.NEW_LINE.getBytes());
buffer.write(MsrpConstants.HEADER_FROM_PATH.getBytes());
buffer.write(MsrpConstants.CHAR_DOUBLE_POINT);
buffer.write(MsrpConstants.CHAR_SP);
buffer.write((headers.get(MsrpConstants.HEADER_TO_PATH)).getBytes());
buffer.write(MsrpConstants.NEW_LINE.getBytes());
buffer.write(MsrpConstants.HEADER_MESSAGE_ID.getBytes());
buffer.write(MsrpConstants.CHAR_DOUBLE_POINT);
buffer.write(MsrpConstants.CHAR_SP);
buffer.write((headers.get(MsrpConstants.HEADER_MESSAGE_ID)).getBytes());
buffer.write(MsrpConstants.NEW_LINE.getBytes());
buffer.write(MsrpConstants.HEADER_BYTE_RANGE.getBytes());
buffer.write(MsrpConstants.CHAR_DOUBLE_POINT);
buffer.write(MsrpConstants.CHAR_SP);
String byteRange = "1-" + lastByte + "/" + totalSize;
buffer.write(byteRange.getBytes());
buffer.write(MsrpConstants.NEW_LINE.getBytes());
buffer.write(MsrpConstants.HEADER_STATUS.getBytes());
buffer.write(MsrpConstants.CHAR_DOUBLE_POINT);
buffer.write(MsrpConstants.CHAR_SP);
String status = "000 200 OK";
buffer.write(status.getBytes());
buffer.write(MsrpConstants.NEW_LINE.getBytes());
buffer.write(MsrpConstants.END_MSRP_MSG.getBytes());
buffer.write(txId.getBytes());
buffer.write(MsrpConstants.FLAG_LAST_CHUNK);
buffer.write(MsrpConstants.NEW_LINE.getBytes());
// Send request
requestTransaction = new RequestTransaction();
connection.sendChunk(buffer.toByteArray());
buffer.close();
}
/**
* Receive MSRP SEND request
*
* @param txId Transaction ID
* @param headers Request headers
* @param flag Continuation flag
* @param data Received data
* @param totalSize Total size of the content
* @throws IOException
*/
public void receiveMsrpSend(String txId, Hashtable<String, String> headers, int flag, byte[] data, long totalSize) throws IOException {
// Receive a SEND request
logger.info("SEND request received (flag=" + flag + ", transaction=" + txId + ")");
// Read message-ID
String msgId = headers.get(MsrpConstants.HEADER_MESSAGE_ID);
// Test if a failure report is needed
boolean failureReportNeeded = true;
String failureHeader = headers.get(MsrpConstants.HEADER_FAILURE_REPORT);
if ((failureHeader != null) && failureHeader.equalsIgnoreCase("no")) {
failureReportNeeded = false;
}
// Send MSRP response if requested
if (failureReportNeeded) {
sendMsrpResponse(MsrpConstants.RESPONSE_OK + " " + MsrpConstants.COMMENT_OK, txId, headers);
}
// Test if it's an empty chunk
if (data == null) {
logger.info("Empty chunk");
return;
}
// Save received data chunk if there is some
receivedChunks.addChunk(data);
// Check the continuation flag
if (flag == MsrpConstants.FLAG_LAST_CHUNK) {
// Transfer terminated
logger.info("Transfer terminated");
// Read the received content
byte[] dataContent = receivedChunks.getReceivedData();
receivedChunks.resetCache();
// Notify event listener
String contentTypeHeader = headers.get(MsrpConstants.HEADER_CONTENT_TYPE);
msrpEventListener.msrpDataReceived(msgId, dataContent, contentTypeHeader);
// Test if a success report is needed
boolean successReportNeeded = false;
String reportHeader = headers.get(MsrpConstants.HEADER_SUCCESS_REPORT);
if ((reportHeader != null) && reportHeader.equalsIgnoreCase("yes")) {
successReportNeeded = true;
}
// Send MSRP report if requested
if (successReportNeeded) {
try {
sendMsrpReportRequest(txId, headers, dataContent.length, totalSize);
} catch(MsrpException e) {
// Report failed
logger.severe("Can't send report" + e);
// Notify event listener
msrpEventListener.msrpTransferError("report timeout");
}
}
} else
if (flag == MsrpConstants.FLAG_ABORT_CHUNK) {
// Transfer aborted
logger.info("Transfer aborted");
// Notify event listener
msrpEventListener.msrpTransferAborted();
} else
if (flag == MsrpConstants.FLAG_MORE_CHUNK) {
// Transfer in progress
logger.info("Transfer in progress...");
// Notify event listener
msrpEventListener.msrpTransferProgress(receivedChunks.getCurrentSize(), totalSize);
}
}
/**
* Receive MSRP response
*
* @param code Response code
* @param txId Transaction ID
* @param headers MSRP headers
*/
public void receiveMsrpResponse(int code, String txId, Hashtable<String, String> headers) {
logger.info("Response received (code=" + code + ", transaction=" + txId + ")");
// Notify request transaction
if (requestTransaction != null) {
requestTransaction.notifyResponse(code, headers);
}
// Notify event listener
if (code != 200) {
msrpEventListener.msrpTransferError(code + " response received");
}
}
/**
* Receive MSRP REPORT request
*
* @param txId Transaction ID
* @param headers MSRP headers
* @throws IOException
*/
public void receiveMsrpReport(String txId, Hashtable<String, String> headers) throws IOException {
logger.info("REPORT request received (transaction=" + txId + ")");
// Notify report transaction
if (reportTransaction != null) {
reportTransaction.notifyReport(headers);
}
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.msrp;
/**
* MSRP utility functions
*
* @author amir aharon
*/
public class MsrpUtils {
/**
* Get the chunk size
*
* @param header MSRP header
* @return Size in bytes
*/
public static int getChunkSize(String header) {
if (header == null) {
return -1;
}
int index1 = header.indexOf("-");
int index2 = header.indexOf("/");
if ((index1 != -1) && (index2 != -1)) {
try {
int lowByte = Integer.parseInt(header.substring(0, index1));
int highByte = Integer.parseInt(header.substring(index1+1, index2));
return (highByte - lowByte) + 1;
} catch (NumberFormatException e) {
return -1;
}
}
return -1;
}
/**
* Get the total size
*
* @param header MSRP header
* @return Size in bytes
*/
public static long getTotalSize(String header) {
if (header == null) {
return -1;
}
int index = header.indexOf("/");
if (index != -1) {
try {
return Long.parseLong(header.substring(index+1));
} catch (NumberFormatException e) {
return -1;
}
}
return -1;
}
}
\ No newline at end of file
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.msrp;
import java.util.Hashtable;
/**
* Report transaction
*
* @author amir aharon
*/
public class ReportTransaction extends Object {
/**
* MRSP report transaction timeout (in seconds)
*/
private final static int TIMEOUT = 3600; // TODO: which value ?
/**
* Reported size
*/
private long reportedSize = 0L;
/**
* Status code
*/
private int statusCode = -1;
/**
* Constructor
*/
public ReportTransaction() {
}
/**
* Notify report
*
* @param headers MSRP headers
*/
public void notifyReport(Hashtable<String, String> headers) {
synchronized(this) {
// Get status code
String status = headers.get(MsrpConstants.HEADER_STATUS);
if ((status != null) && (status.startsWith("000 "))) {
String[] parts = status.split(" ");
if (parts.length > 0) {
try {
statusCode = Integer.parseInt(parts[1]);
} catch(NumberFormatException e) {
statusCode = -1;
}
}
}
// Get reported size
String byteRange = headers.get(MsrpConstants.HEADER_BYTE_RANGE);
if (byteRange != null) {
reportedSize = MsrpUtils.getChunkSize(byteRange);
}
// Unblock semaphore
super.notify();
}
}
/**
* Wait report
*
* @return True if success else returns false
*/
public void waitReport() {
synchronized(this) {
try {
// Wait semaphore
super.wait(TIMEOUT * 1000);
} catch(InterruptedException e) {
// Nothing to do
}
}
}
/**
* Terminate transaction
*/
public void terminate() {
synchronized(this) {
// Unblock semaphore
super.notify();
}
}
/**
* Returns the reported data size
*
* @return Size in bytes
*/
public long getReportedSize() {
return reportedSize;
}
/**
* Returns the status
*
* @return Status or -1 in case of error
*/
public int getStatusCode() {
return statusCode;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.msrp;
import java.util.Hashtable;
import provider.settings.RcsSettings;
/**
* Request transaction
*
* @author amir aharon
*/
public class RequestTransaction extends Object {
/**
* MRSP request transaction timeout (in seconds)
*/
private final static int TIMEOUT = RcsSettings.getInstance().getMsrpTransactionTimeout();
/**
* Received response
*/
private int receivedResponse = -1;
/**
* Constructor
*/
public RequestTransaction() {
}
/**
* Notify response
*
* @param code Response code
* @param headers MSRP headers
*/
public void notifyResponse(int code, Hashtable<String, String> headers) {
synchronized(this) {
// Set response code
this.receivedResponse = code;
// Unblock semaphore
super.notify();
}
}
/**
* Wait response
*/
public void waitResponse() {
synchronized(this) {
try {
// Wait semaphore
super.wait(TIMEOUT * 1000);
} catch(InterruptedException e) {
// Nothing to do
}
}
}
/**
* Terminate transaction
*/
public void terminate() {
synchronized(this) {
// Unblock semaphore
super.notify();
}
}
/**
* Is response received
*
* @return Boolean
*/
public boolean isResponseReceived() {
return (receivedResponse != -1);
}
/**
* Returns received response
*
* @return Code
*/
public int getResponse() {
return receivedResponse;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.sdp;
/**
* Media attribute
*
* @author amir aharon
*/
public class MediaAttribute {
/**
* Attribute name
*/
private String name;
/**
* Attribute value
*/
private String value;
/**
* Constructor
*
* @param name Attribute name
* @param value Attribute value
*/
public MediaAttribute(String name, String value) {
this.name = name;
this.value = value;
}
/**
* Returns the attribute name
*
* @return Name
*/
public String getName() {
return name;
}
/**
* Returns the attribute value
*
* @return Value
*/
public String getValue() {
return value;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.sdp;
import java.util.Vector;
/**
* Media description
*
* @author amir aharon
*/
public class MediaDescription {
/**
* Media name
*/
public String name;
/**
* Media port
*/
public int port;
/**
* Media protocol
*/
public String protocol;
/**
* Payload type
*/
public int payloadType;
/**
* Payload
*/
public String payload;
/**
* Media title
*/
public String mediaTitle;
/**
* Connection info
*/
public String connectionInfo;
/**
* Bandwidth info
*/
public String bandwidthInfo;
/**
* Encryption key
*/
public String encryptionKey;
/**
* Media attributes
*/
public Vector<MediaAttribute> mediaAttributes = new Vector<MediaAttribute>();
/**
* Constructor
*
* @param name Media name
* @param port Media port
* @param protocol Media protocol
* @param payload Media payload
*/
public MediaDescription(String name, int port, String protocol, String payload) {
this.name = name;
this.port = port;
this.protocol = protocol;
this.payload = payload;
try {
this.payloadType = Integer.parseInt(payload);
} catch (Exception e) {
this.payloadType = -1;
}
}
public MediaAttribute getMediaAttribute(String name) {
MediaAttribute attribute = null;
if (mediaAttributes != null) {
for (int i = 0; i < mediaAttributes.size(); i++) {
MediaAttribute entry = (MediaAttribute)mediaAttributes.elementAt(i);
if (entry.getName().equals(name)) {
attribute = entry;
break;
}
}
}
return attribute;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.sdp;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Vector;
/**
* Generic parser
*
* @author amir aharon
*/
class Parser {
/**
* Buffer
*/
private Vector<Integer> buffer = new Vector<Integer>();
/**
* Unget a token
*
* @param tk Token
*/
public void ungetToken(String tk) {
byte token[] = tk.getBytes();
for (int i = 0; i < token.length; i++) {
buffer.insertElementAt(Integer.valueOf(token[token.length - i - 1]), 0);
}
}
/**
* Get a token
*
* @param input Input stream
* @param tk Token
* @return Token value
*/
public boolean getToken(ByteArrayInputStream input, String tk) {
boolean found = false;
ByteArrayOutputStream bout = new ByteArrayOutputStream();
skipWhitespace(input);
if (input.available() > 0) {
int ch = readChar(input);
while (ch != '=' && ch != '\n' && ch != '\r' && ch != -1) {
bout.write(ch);
ch = readChar(input);
}
bout.write(ch);
}
String token = new String(bout.toByteArray());
if (tk.equals(token)) {
found = true;
} else {
ungetToken(token);
}
return found;
}
/**
* Get a line
*
* @param input Input stream
* @return Line
*/
public String getLine(ByteArrayInputStream input) {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
if (input.available() > 0) {
int ch = readChar(input);
while (ch != '\n' && ch != '\r' && ch != -1) {
bout.write(ch);
ch = readChar(input);
}
}
String line = new String(bout.toByteArray());
return line;
}
/**
* Skip whitespace
*
* @param input Input stream
*/
private void skipWhitespace(ByteArrayInputStream input) {
int ch = readChar(input);
while (ch == ' ' || ch == '\n' || ch == '\r') {
ch = readChar(input);
}
buffer.insertElementAt(Integer.valueOf(ch), 0);
}
/**
* Read char
*
* @param input Input stream
*/
private int readChar(ByteArrayInputStream input) {
int ch;
if (buffer.size() > 0) {
ch = ((Integer)buffer.elementAt(0)).intValue();
buffer.removeElementAt(0);
} else {
ch = input.read();
}
return ch;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.sdp;
import java.io.ByteArrayInputStream;
import java.util.Vector;
/**
* SDP parser
*
* @author amir aharon
*/
public class SdpParser extends Parser {
/**
* Session description
*/
public SessionDescription sessionDescription = new SessionDescription();
/**
* Media description
*/
public Vector<MediaDescription> mediaDescriptions = new Vector<MediaDescription>();
/**
* Input stream
*/
private ByteArrayInputStream bin = null;
/**
* Constructor
*
* @param data Data
*/
public SdpParser(byte data[]) {
bin = new ByteArrayInputStream(data);
if (getToken(bin, "v=")) {
parseSessionDescription();
parseMediaDescriptions();
}
}
/**
* Parse session description
*/
private void parseSessionDescription() {
// Protocol version
sessionDescription.version = getLine(bin);
// Origin
if (getToken(bin, "o=")) {
sessionDescription.origin = getLine(bin);
}
// Session name
if (getToken(bin, "s=")) {
sessionDescription.sessionName = getLine(bin);
}
// Session and media Information
if (getToken(bin, "i=")) {
sessionDescription.sessionInfo = getLine(bin);
}
// URI
if (getToken(bin, "u=")) {
sessionDescription.uri = getLine(bin);
}
// E-Mail
if (getToken(bin, "e=")) {
sessionDescription.email = getLine(bin);
}
// Phone number
if (getToken(bin, "p=")) {
sessionDescription.phone = getLine(bin);
}
// Connection information
if (getToken(bin, "c=")) {
sessionDescription.connectionInfo = getLine(bin);
}
// Bandwidth information
if (getToken(bin, "b=")) {
sessionDescription.bandwidthInfo = getLine(bin);
}
// Time description
sessionDescription.timeDescriptions = new Vector<TimeDescription>();
while(getToken(bin, "t=")) {
TimeDescription timeDescription = parseTimeDescription();
this.sessionDescription.timeDescriptions.addElement(timeDescription);
}
// Time zone adjustments
if (getToken(bin, "z=")) {
sessionDescription.timezoneAdjustment = getLine(bin);
}
// Encryption key
if (getToken(bin, "k=")) {
sessionDescription.encryptionKey = getLine(bin);
}
// Session attributes
sessionDescription.sessionAttributes = new Vector<MediaAttribute>();
while(getToken(bin, "a=")) {
String sessionAttribute = getLine(bin);
int index = sessionAttribute.indexOf(':');
if (index > 0) {
String name = sessionAttribute.substring(0, index);
String value = sessionAttribute.substring(index + 1);
MediaAttribute attribute = new MediaAttribute(name, value);
sessionDescription.sessionAttributes.addElement(attribute);
}
}
}
/**
* Parse time description
*
* @return Time description
*/
private TimeDescription parseTimeDescription() {
TimeDescription td = new TimeDescription();
// Time the session is active
td.timeActive = getLine(bin);
// Repeat times
td.repeatTimes = new Vector<String>();
while(getToken(bin, "r=")) {
String repeatTime = getLine(bin);
td.repeatTimes.addElement(repeatTime);
}
return td;
}
/**
* Parse media descriptions
*/
private void parseMediaDescriptions() {
while(getToken(bin, "m=")) {
Vector<MediaDescription> descs = new Vector<MediaDescription>();
// Media name and transport address
String line = getLine(bin);
int end = line.indexOf(' ');
String name = line.substring(0, end);
int start = end + 1;
end = line.indexOf(' ', start);
int port = Integer.parseInt(line.substring(start, end));
start = end + 1;
end = line.indexOf(' ', start);
String protocol = line.substring(start, end);
String payload;
start = end + 1;
end = line.indexOf(' ', start);
while (end != -1) {
payload = line.substring(start, end);
descs.addElement(new MediaDescription(name, port, protocol, payload));
start = end + 1;
end = line.indexOf(' ', start);
}
payload = line.substring(start);
descs.addElement(new MediaDescription(name, port, protocol, payload));
// Session and media information
if (getToken(bin, "i=")) {
String mediaTitle = getLine(bin);
for (int i = 0; i < descs.size(); i++) {
descs.elementAt(i).mediaTitle = mediaTitle;
}
}
// Connection information
if (getToken(bin, "c=")) {
String connectionInfo = getLine(bin);
for (int i = 0; i < descs.size(); i++) {
descs.elementAt(i).connectionInfo = connectionInfo;
}
}
// Bandwidth information
if (getToken(bin, "b=")) {
String bandwidthInfo = getLine(bin);
for (int i = 0; i < descs.size(); i++) {
descs.elementAt(i).bandwidthInfo = bandwidthInfo;
}
}
// Encryption key
if (getToken(bin, "k=")) {
String encryptionKey = getLine(bin);
for (int i = 0; i < descs.size(); i++) {
descs.elementAt(i).encryptionKey = encryptionKey;
}
}
// Media attributes
while(getToken(bin, "a=")) {
line = getLine(bin);
int index = line.indexOf(':');
if (index > 0) {
String nameAttribute = line.substring(0, index);
String valueAttribute = line.substring(index + 1);
MediaAttribute attribute = new MediaAttribute(nameAttribute, valueAttribute);
// Dispatch for specific payload
if ((nameAttribute.equalsIgnoreCase("rtpmap")) && (valueAttribute.indexOf(' ') != -1)) {
// Add the attribute only for same payload
for (int i = 0; i < descs.size(); i++) {
if (valueAttribute.startsWith(descs.elementAt(i).payload)) {
descs.elementAt(i).mediaAttributes.addElement(attribute);
}
}
} else {
for (int i = 0; i < descs.size(); i++) {
descs.elementAt(i).mediaAttributes.addElement(attribute);
}
}
}
}
// Copy in media descriptions
for(int i = 0; i < descs.size(); i++) {
mediaDescriptions.addElement((MediaDescription)descs.elementAt(i));
}
}
}
/**
* Returns session attribute
*
* @param name Attribute name
* @return Attribute
*/
public MediaAttribute getSessionAttribute(String name) {
if (sessionDescription != null) {
return sessionDescription.getSessionAttribute(name);
} else {
return null;
}
}
/**
* Returns a media description
*
* @param name Media name
* @return Media
*/
public MediaDescription getMediaDescription(String name) {
MediaDescription description = null;
if (mediaDescriptions != null) {
for (int i = 0; i < mediaDescriptions.size(); i++) {
MediaDescription entry = (MediaDescription)mediaDescriptions.elementAt(i);
if (entry.name.equals(name)) {
description = entry;
break;
}
}
}
return description;
}
/**
* Returns media descriptions
*
* @param name Media name
* @return Medias
*/
public Vector<MediaDescription> getMediaDescriptions(String name) {
Vector<MediaDescription> result = new Vector<MediaDescription>();
if (mediaDescriptions != null) {
for (int i = 0; i < mediaDescriptions.size(); i++) {
MediaDescription entry = (MediaDescription)mediaDescriptions.elementAt(i);
if (entry.name.equals(name)) {
result.add(entry);
}
}
}
return result;
}
/**
* Returns all media descriptions
*
* @return Medias
*/
public Vector<MediaDescription> getMediaDescriptions() {
return mediaDescriptions;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.sdp;
import utils.IpAddressUtils;
/**
* SDP utility functions
*
* @author amir aharon
*/
public class SdpUtils {
/**
* Extract the remote host address from the connection info
*
* @param connectionInfo Connection info
* @return Address
*/
public static String extractRemoteHost(String connectionInfo) {
// c=IN IP4 172.20.138.145
String[] tokens = connectionInfo.split(" ");
if (tokens.length > 2) {
return tokens[2];
} else {
return null;
}
}
/**
* Format "IN IP" attribute (4 or 6)
*
* @param address IP address
* @return "IN IP4 address" or "IN IP6 address"
*/
public static String formatAddressType(String address) {
if (IpAddressUtils.isIPv6(address)) {
return "IN IP6 " + address;
} else {
return "IN IP4 " + address;
}
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.sdp;
import java.util.Vector;
/**
* Session description
*
* @author amir aharon
*/
public class SessionDescription {
public Vector<TimeDescription> timeDescriptions;
public Vector<MediaAttribute> sessionAttributes;
public boolean connectionIncluded;
public String version;
public String origin;
public String sessionName;
public String sessionInfo;
public String uri;
public String email;
public String phone;
public String connectionInfo;
public String bandwidthInfo;
public String timezoneAdjustment;
public String encryptionKey;
public MediaAttribute getSessionAttribute(String name) {
MediaAttribute attribute = null;
if (sessionAttributes != null) {
for (int i = 0; i < sessionAttributes.size(); i++) {
MediaAttribute entry = (MediaAttribute) sessionAttributes.elementAt(i);
if (entry.getName().equals(name)) {
attribute = entry;
break;
}
}
}
return attribute;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.protocol.sdp;
import java.util.Vector;
/**
* Time description
*
* @author amir aharon
*/
public class TimeDescription {
public String timeActive;
public Vector<String> repeatTimes;
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service;
/**
* IMS service error
*
* @author amir aharon
*/
public class ImsServiceError extends Error {
static final long serialVersionUID = 1L;
/**
* Unexpected exception occurs in the module (e.g. internal exception)
*/
public final static int UNEXPECTED_EXCEPTION = 1;
/**
* Session initiation has failed (e.g. 408 timeout)
*/
public final static int SESSION_INITIATION_FAILED = 2;
/**
* Session initiation has been declined (e.g. 603 Decline or 486 Busy)
*/
public final static int SESSION_INITIATION_DECLINED = 3;
/**
* Session initiation has been cancelled (e.g. 487 Session terminated)
*/
public final static int SESSION_INITIATION_CANCELLED = 4;
/**
* Error code
*/
private int code;
/**
* Constructor
*
* @param code Error code
*/
public ImsServiceError(int code) {
super();
this.code = code;
}
/**
* Constructor
*
* @param code Error code
* @param msg Detail message
*/
public ImsServiceError(int code, String msg) {
super(msg);
this.code = code;
}
/**
* Returns the error code
*
* @return Error code
*/
public int getErrorCode() {
return code;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service;
/**
* Listener of events sent during an IMS session
*
* @author JM. Auffret
*/
public interface ImsSessionListener {
/**
* Session is started
*/
public void handleSessionStarted();
/**
* Session has been aborted
*/
public void handleSessionAborted();
/**
* Session has been terminated by remote
*/
public void handleSessionTerminatedByRemote();
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service;
/**
* Session-ID generator
*
* @author amir aharon
*/
public class SessionIdGenerator {
/**
* Counter
*/
private static long current = System.currentTimeMillis();
/**
* Returns a unique integer ID
*
* @return ID
*/
public static synchronized String getNewId() {
current++;
return ""+current;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im;
import java.util.Date;
/**
* Instant message
*
* @author amir aharon
*/
public class InstantMessage{
/**
* MIME type
*/
public static final String MIME_TYPE = "text/plain";
/**
* Remote user
*/
private String remote;
/**
* Text message
*/
private String message;
/**
* Receipt date of the message
*/
private Date receiptAt;
/**
* Receipt date of the message on the server (i.e. CPIM date)
*/
private Date serverReceiptAt;
/**
* Message Id
*/
private String msgId;
/**
* Flag indicating that an IMDN "displayed" is requested for this message
*/
private boolean imdnDisplayedRequested = false;
/**
* Constructor for outgoing message
*
* @param messageId Message Id
* @param remote Remote user
* @param message Text message
* @param imdnDisplayedRequested Flag indicating that an IMDN "displayed" is requested
*/
public InstantMessage(String messageId, String remote, String message, boolean imdnDisplayedRequested) {
this.msgId = messageId;
this.remote = remote;
this.message = message;
this.imdnDisplayedRequested = imdnDisplayedRequested;
Date date = new Date();
this.receiptAt = date;
this.serverReceiptAt = date;
}
/**
* Constructor for incoming message
*
* @param messageId Message Id
* @param remote Remote user
* @param message Text message
* @param imdnDisplayedRequested Flag indicating that an IMDN "displayed" is requested
* @param serverReceiptAt Receipt date of the message on the server
*/
public InstantMessage(String messageId, String remote, String message, boolean imdnDisplayedRequested, Date serverReceiptAt) {
this.msgId = messageId;
this.remote = remote;
this.message = message;
this.imdnDisplayedRequested = imdnDisplayedRequested;
this.receiptAt = new Date();
this.serverReceiptAt = serverReceiptAt;
}
// /**
// * Constructor
// *
// * @param
// */
// public InstantMessage() {
// this.remote = source.readString();
// this.message = source.readString();
// this.msgId = source.readString();
// this.imdnDisplayedRequested = source.readInt() != 0;
// this.receiptAt = new Date(source.readLong());
// this.serverReceiptAt = new Date(source.readLong());
// }
/**
* Describe the kinds of special objects contained in this Parcelable's
* marshalled representation
*
* @return Integer
*/
public int describeContents() {
return 0;
}
// /**
// * Write parcelable object
// *
// * @param dest The Parcel in which the object should be written
// * @param flags Additional flags about how the object should be written
// */
// public void writeToParcel(Parcel dest, int flags) {
// dest.writeString(remote);
// dest.writeString(message);
// dest.writeString(msgId);
// dest.writeInt(imdnDisplayedRequested ? 1 : 0);
// dest.writeLong(receiptAt.getTime());
// dest.writeLong(serverReceiptAt.getTime());
// }
// /**
// * Parcelable creator
// */
// public static final Parcelable.Creator<InstantMessage> CREATOR
// = new Parcelable.Creator<InstantMessage>() {
// public InstantMessage createFromParcel(Parcel source) {
// return new InstantMessage(source);
// }
//
// public InstantMessage[] newArray(int size) {
// return new InstantMessage[size];
// }
// };
/**
* Returns the text message
*
* @return String
*/
public String getTextMessage() {
return message;
}
/**
* Returns the message Id
*
* @return message Id
*/
public String getMessageId(){
return msgId;
}
/**
* Returns the remote user
*
* @return Remote user
*/
public String getRemote() {
return remote;
}
/**
* Returns true if the IMDN "displayed" has been requested
*
* @return Boolean
*/
public boolean isImdnDisplayedRequested() {
return imdnDisplayedRequested;
}
/**
* Returns the receipt date of the message
*
* @return Date
*/
public Date getDate() {
return receiptAt;
}
/**
* Returns the receipt date of the message on the server
*
* @return Date
*/
public Date getServerDate() {
return serverReceiptAt;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat;
import core.ims.service.ImsServiceError;
/**
* Chat error
*
* @author amir aharon
*/
public class ChatError extends ImsServiceError {
static final long serialVersionUID = 1L;
/**
* Unexpected exception occurs in the module (e.g. internal exception)
*/
public final static int UNEXPECTED_EXCEPTION = 0x01;
/**
* IM session initiation has failed (e.g. 408 timeout)
*/
public final static int SESSION_INITIATION_FAILED = 0x02;
/**
* Session initiation has been declined (e.g. 486 Busy)
*/
public final static int SESSION_INITIATION_DECLINED = 0x03;
/**
* Session initiation has been cancelled (e.g. 487 Session terminated)
*/
public final static int SESSION_INITIATION_CANCELLED = 0x04;
/**
* Media session has failed (e.g. MSRP failure)
*/
public final static int MEDIA_SESSION_FAILED = 0x05;
/**
* Subscription to conference package has failed
*/
public final static int SUBSCRIBE_CONFERENCE_FAILED = 0x06;
/**
* Constructor
*
* @param code Error code
*/
public ChatError(int code) {
super(code);
}
/**
* Constructor
*
* @param code Error code
* @param msg Detail message
*/
public ChatError(int code, String msg) {
super(code, msg);
}
}
package core.ims.service.im.chat;
import java.io.ByteArrayInputStream;
import org.xml.sax.InputSource;
import utils.DateUtils;
import utils.IdGenerator;
import utils.PhoneUtils;
import core.ims.service.im.chat.cpim.CpimMessage;
import core.ims.service.im.chat.cpim.CpimParser;
import core.ims.service.im.chat.imdn.ImdnDocument;
import core.ims.service.im.chat.imdn.ImdnParser;
import core.ims.service.im.chat.imdn.ImdnUtils;
/**
* handling just the msgs
* @author amir
*
*/
public class ChatMsgUtils
{
/**
* CRLF constant
*/
static final String CRLF = "\r\n";
/**
* Build a delivery report
*
* @param msgId Message ID
* @param status Status
* @return XML document
*/
public static String buildDeliveryReport(String msgId, String status,long dateTime) {
String method;
if (status.equals(ImdnDocument.DELIVERY_STATUS_DISPLAYED)) {
method = "display-notification";
} else
if (status.equals(ImdnDocument.DELIVERY_STATUS_DELIVERED)) {
method = "delivery-notification";
} else {
method = "processing-notification";
}
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + ChatMsgUtils.CRLF +
"<imdn xmlns=\"urn:ietf:params:xml:ns:imdn\">" + ChatMsgUtils.CRLF +
"<message-id>" + msgId + "</message-id>" + ChatMsgUtils.CRLF +
"<datetime>" + DateUtils.encodeDate(dateTime) + "</datetime>" + ChatMsgUtils.CRLF +
"<" + method + "><status><" + status + "/></status></" + method + ">" + ChatMsgUtils.CRLF +
"</imdn>";
}
public static String buildDeliveryReport(String[] msgIdArray, String status,long dateTime) {
String method;
if (status.equals(ImdnDocument.DELIVERY_STATUS_DISPLAYED)) {
method = "display-notification";
} else
if (status.equals(ImdnDocument.DELIVERY_STATUS_DELIVERED)) {
method = "delivery-notification";
} else {
method = "processing-notification";
}
StringBuilder sb = new StringBuilder(64);
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>").append(ChatMsgUtils.CRLF);
sb.append("<imdn xmlns=\"urn:ietf:params:xml:ns:imdn\">").append(ChatMsgUtils.CRLF);
for (String msgId : msgIdArray)
{
sb.append("<message-id>").append(msgId).append("</message-id>").append(ChatMsgUtils.CRLF);
}
sb.append("<datetime>").append(DateUtils.encodeDate(dateTime)).append("</datetime>").append(ChatMsgUtils.CRLF);
sb.append("<").append(method).append("><status><").append(status).append("/></status></").append(method).append(">").append(ChatMsgUtils.CRLF);
sb.append("</imdn>");
return sb.toString();
// "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + ChatMsgUtils.CRLF +
// "<imdn xmlns=\"urn:ietf:params:xml:ns:imdn\">" + ChatMsgUtils.CRLF +
// "<message-id>" + msgId + "</message-id>" + ChatMsgUtils.CRLF +
// "<datetime>" + DateUtils.encodeDate(dateTime) + "</datetime>" + ChatMsgUtils.CRLF +
// "<" + method + "><status><" + status + "/></status></" + method + ">" + ChatMsgUtils.CRLF +
// "</imdn>";
}
/**
* Parse a delivery report
*
* @param xml XML document
* @return IMDN document
*/
public static ImdnDocument parseDeliveryReport(String xml) {
try {
InputSource input = new InputSource(new ByteArrayInputStream(xml.getBytes()));
ImdnParser parser = new ImdnParser(input);
return parser.getImdnDocument();
} catch(Exception e) {
return null;
}
}
public static String buildDeliveryReport(String msgId, String status) {
return buildDeliveryReport(msgId, status,System.currentTimeMillis());
}
/**
* Parse a CPIM delivery report
*
* @param cpim CPIM document
* @return IMDN document
*/
public static ImdnDocument parseCpimDeliveryReport(String cpim) {
ImdnDocument imdn = null;
try {
// Parse CPIM document
CpimParser cpimParser = new CpimParser(cpim);
CpimMessage cpimMsg = cpimParser.getCpimMessage();
if (cpimMsg != null) {
// Check if the content is a IMDN message
String contentType = cpimMsg.getContentType();
if ((contentType != null) && ChatUtils.isMessageImdnType(contentType)) {
// Parse the IMDN document
imdn = parseDeliveryReport(cpimMsg.getMessageContent());
}
}
} catch(Exception e) {
imdn = null;
}
return imdn;
}
public static String buildCpimDeliveryReport(String from, String to, String imdn){
return ChatMsgUtils.buildCpimDeliveryReport(from, to , imdn, System.currentTimeMillis());
}
/**
* Build a CPIM delivery report
*
* @param from From
* @param to To
* @param imdn IMDN report
* @return String
*/
public static String buildCpimDeliveryReport(String from, String to, String imdn,long dateTime) {
String cpim =
CpimMessage.HEADER_FROM + ": " + ChatMsgUtils.formatCpimSipUri(from) + ChatUtils.CRLF +
CpimMessage.HEADER_TO + ": " + ChatMsgUtils.formatCpimSipUri(to) + ChatUtils.CRLF +
CpimMessage.HEADER_NS + ": " + ImdnDocument.IMDN_NAMESPACE + ChatUtils.CRLF +
ImdnUtils.HEADER_IMDN_MSG_ID + ": " + IdGenerator.getIdentifier() + ChatUtils.CRLF +
CpimMessage.HEADER_DATETIME + ": " + DateUtils.encodeDate(dateTime) + ChatUtils.CRLF +
ChatUtils.CRLF +
CpimMessage.HEADER_CONTENT_DISPOSITION + ": " + ImdnDocument.NOTIFICATION + ChatUtils.CRLF +
CpimMessage.HEADER_CONTENT_TYPE + ": " + ImdnDocument.MIME_TYPE + ChatUtils.CRLF +
CpimMessage.HEADER_CONTENT_LENGTH + ": " + imdn.getBytes().length + ChatUtils.CRLF +
ChatUtils.CRLF +
imdn;
return cpim;
}
public static String buildCpimMessageWithImdn(String from, String to, String messageId, String content, String contentType) {
return ChatMsgUtils.buildCpimMessageWithImdn(from, to, messageId, content, contentType,System.currentTimeMillis());
}
/**
* Build a CPIM message with IMDN headers
*
* @param from From URI
* @param to To URI
* @param messageId Message ID
* @param content Content
* @param contentType Content type
* @return String
*/
public static String buildCpimMessageWithImdn(String from, String to, String messageId, String content, String contentType,long dateTime) {
String cpim =
CpimMessage.HEADER_FROM + ": " + ChatMsgUtils.formatCpimSipUri(from) + ChatUtils.CRLF +
CpimMessage.HEADER_TO + ": " + ChatMsgUtils.formatCpimSipUri(to) + ChatUtils.CRLF +
CpimMessage.HEADER_NS + ": " + ImdnDocument.IMDN_NAMESPACE + ChatUtils.CRLF +
ImdnUtils.HEADER_IMDN_MSG_ID + ": " + messageId + ChatUtils.CRLF +
CpimMessage.HEADER_DATETIME + ": " + DateUtils.encodeDate(dateTime) + ChatUtils.CRLF +
ImdnUtils.HEADER_IMDN_DISPO_NOTIF + ": " + ImdnDocument.POSITIVE_DELIVERY + ", " + ImdnDocument.DISPLAY + ChatUtils.CRLF +
ChatUtils.CRLF +
CpimMessage.HEADER_CONTENT_TYPE + ": " + contentType + "; charset=utf-8" + ChatUtils.CRLF +
CpimMessage.HEADER_CONTENT_LENGTH + ": " + content.getBytes().length + ChatUtils.CRLF +
ChatUtils.CRLF +
content;
return cpim;
}
public static String buildCpimMessage(String from, String to, String content, String contentType) {
return ChatMsgUtils.buildCpimMessage(from, to,content, contentType, System.currentTimeMillis());
}
/**
* Build a CPIM message
*
* @param from From
* @param to To
* @param content Content
* @param contentType Content type
* @return String
*/
public static String buildCpimMessage(String from, String to, String content, String contentType, long dateTime) {
String cpim =
CpimMessage.HEADER_FROM + ": " + ChatMsgUtils.formatCpimSipUri(from) + ChatUtils.CRLF +
CpimMessage.HEADER_TO + ": " + ChatMsgUtils.formatCpimSipUri(to) + ChatUtils.CRLF +
CpimMessage.HEADER_DATETIME + ": " + DateUtils.encodeDate(dateTime) + ChatUtils.CRLF +
ChatUtils.CRLF +
CpimMessage.HEADER_CONTENT_TYPE + ": " + contentType + "; charset=utf-8" + ChatUtils.CRLF +
ChatUtils.CRLF +
content;
return cpim;
}
/**
* Format to a SIP-URI for CPIM message
*
* @param input Input
* @return SIP-URI
*/
static String formatCpimSipUri(String input) {
input = input.trim();
if (input.startsWith("<")) {
// Already a SIP-URI format
return input;
}
// It's a SIP address: remove display name
if (input.startsWith("\"")) {
int index1 = input.indexOf("\"", 1);
if (index1 > 0) {
input = input.substring(index1+2);
}
return input;
}
if (input.startsWith("sip:") || input.startsWith("tel:")) {
// Just add URI delimiter
return "<" + input + ">";
} else {
// It's a number, format it
return "<" + PhoneUtils.formatNumberToSipUri(input) + ">";
}
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat;
import core.ims.service.ImsSessionListener;
import core.ims.service.im.InstantMessage;
/**
* Chat session listener
*
* @author JM. Auffret
*/
public interface ChatSessionListener extends ImsSessionListener {
/**
* New message received
*
* @param message Message
*/
public void handleReceiveMessage(InstantMessage message);
/**
* IM error
*
* @param error Error
*/
public void handleImError(ChatError error);
/**
* Is composing event
*
* @param contact Contact
* @param status Status
*/
public void handleIsComposingEvent(String contact, boolean status);
/**
* New conference event
*
* @param contact Contact
* @param contactDisplayname Contact display name
* @param state State associated to the contact
*/
public void handleConferenceEvent(String contact, String contactDisplayname, String state);
/**
* New message delivery status
*
* @param msgId Message ID
* @param status Delivery status
*/
public void handleMessageDeliveryStatus(String msgId, String status);
/**
* Request to add participant is successful
*/
public void handleAddParticipantSuccessful();
/**
* Request to add participant has failed
*
* @param reason Error reason
*/
public void handleAddParticipantFailed(String reason);
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat;
import core.ims.service.im.InstantMessage;
import core.ims.service.im.chat.cpim.CpimMessage;
import core.ims.service.im.chat.imdn.ImdnDocument;
import core.ims.service.im.chat.iscomposing.IsComposingInfo;
import utils.IdGenerator;
import utils.PhoneUtils;
import utils.StringUtils;
import java.util.List;
//import javax.servlet.sip.SipServletRequest;
/**
* Chat utility functions
*
* @author amir aharon
*/
public class ChatUtils {
/**
* Anonymous URI
*/
public final static String ANOMYNOUS_URI = "sip:anonymous@anonymous.invalid";
/**
* Contribution ID header
*/
public static final String HEADER_CONTRIBUTION_ID = "Contribution-ID";
/**
* CRLF constant
*/
static final String CRLF = "\r\n";
/**
* boundary constant
*/
public static final String BOUNDARY = "boundary=";
public static final int BOUNDARY_LEN = BOUNDARY.length();
/**
* Is a group chat session invitation
*
* @param request Request
* @return Boolean
*/
// public static boolean isGroupChatInvitation(SipServletRequest request) {
// String contactString = request.getHeader("Contact");
// StringTokenizer token = new StringTokenizer(contactString, "; =");
// while (token.hasMoreElements())
// {
// if (token.nextToken().equalsIgnoreCase("isfocus"))
// return true;
// }
// return false;
// }
/**
* Get referred identity
*
* @param request SIP request
* @return SIP URI
*/
// public static String getReferredIdentity(SipServletRequest request) {
// String referredBy = SipUtils.getReferredByHeader(request);
// if (referredBy != null) {
// // Use the Referred-By header
// return referredBy;
// } else {
// // Use the Asserted-Identity header
// return SipUtils.getAssertedIdentity(request);
// }
// }
//
/**
* Is a plain text type
*
* @param mime MIME type
* @return Boolean
*/
public static boolean isTextPlainType(String mime) {
if ((mime != null) && mime.toLowerCase().startsWith(InstantMessage.MIME_TYPE)) {
return true;
} else {
return false;
}
}
/**
* Is a composing event type
*
* @param mime MIME type
* @return Boolean
*/
public static boolean isApplicationIsComposingType(String mime) {
if ((mime != null) && mime.toLowerCase().startsWith(IsComposingInfo.MIME_TYPE)) {
return true;
} else {
return false;
}
}
/**
* Is a CPIM message type
*
* @param mime MIME type
* @return Boolean
*/
public static boolean isMessageCpimType(String mime) {
if ((mime != null) && mime.toLowerCase().startsWith(CpimMessage.MIME_TYPE)) {
return true;
} else {
return false;
}
}
/**
* Is an IMDN message type
*
* @param mime MIME type
* @return Boolean
*/
public static boolean isMessageImdnType(String mime) {
if ((mime != null) && mime.toLowerCase().startsWith(ImdnDocument.MIME_TYPE)) {
return true;
} else {
return false;
}
}
/**
* Generate a unique message ID
*
* @return Message ID
*/
public static String generateMessageId() {
return "Msg" + IdGenerator.getIdentifier().replace('_', '-');
}
/**
* Generate resource-list for a chat session
*
* @param participants List of participants
* @return XML document
*/
public static String generateChatResourceList(List<String> participants) {
StringBuffer uriList = new StringBuffer();
for(int i=0; i < participants.size(); i++) {
String contact = participants.get(i);
uriList.append(" <entry uri=\"" + PhoneUtils.formatNumberToSipUri(contact) + "\"/>" + CRLF);
}
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + CRLF +
"<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\">" +
"<list>" + CRLF +
uriList.toString() +
"</list></resource-lists>";
return xml;
}
/**
* Generate resource-list for a extended chat session
*
* @param existingParticipant Replaced participant
* @param replaceHeader Replace header
* @param newParticipants List of new participants
* @return XML document
*/
public static String generateExtendedChatResourceList(String existingParticipant, String replaceHeader, List<String> newParticipants) {
StringBuffer uriList = new StringBuffer();
for(int i=0; i < newParticipants.size(); i++) {
String contact = newParticipants.get(i);
if (contact.equals(existingParticipant)) {
uriList.append(" <entry uri=\"" + PhoneUtils.formatNumberToSipUri(existingParticipant) +
StringUtils.encodeXML(replaceHeader) + "\"/>" + CRLF);
} else {
uriList.append(" <entry uri=\"" + PhoneUtils.formatNumberToSipUri(contact) + "\"/>" + CRLF);
}
}
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + CRLF +
"<resource-lists xmlns=\"urn:ietf:params:xml:ns:resource-lists\">" +
"<list>" + CRLF +
uriList.toString() +
"</list></resource-lists>";
return xml;
}
/**
* Is IMDN service
*
* @param request Request
* @return Boolean
*/
// public static boolean isImdnService(SipServletRequest request) {
// String content = null;
// try
// {
// content = request.getContent().toString();
// } catch (UnsupportedEncodingException e)
// {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IOException e)
// {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// String contentType = request.getContentType();
// if ((content != null) && (content.contains(ImdnDocument.IMDN_NAMESPACE)) &&
// (contentType != null) && (contentType.equalsIgnoreCase(CpimMessage.MIME_TYPE))) {
// return true;
// } else {
// return false;
// }
// }
/**
* Is IMDN notification "delivered" requested
*
* @param request Request
* @return Boolean
*/
// public static boolean isImdnDeliveredRequested(SipServletRequest request) {
// boolean result = false;
// try {
// // Read ID from multipart content
// String content = request.getContent().toString();
// int index = content.indexOf(ImdnUtils.HEADER_IMDN_DISPO_NOTIF);
// if (index != -1) {
// index = index+ImdnUtils.HEADER_IMDN_DISPO_NOTIF.length()+1;
// String part = content.substring(index);
// String notif = part.substring(0, part.indexOf(CRLF));
// if (notif.indexOf(ImdnDocument.POSITIVE_DELIVERY) != -1) {
// result = true;
// }
// }
// } catch(Exception e) {
// result = false;
// }
// return result;
// }
/**
* Is IMDN notification "displayed" requested
*
* @param request Request
* @return Boolean
*/
// public static boolean isImdnDisplayedRequested(SipServletRequest request) {
// boolean result = false;
// try {
// // Read ID from multipart content
// String content = request.getContent().toString();
// int index = content.indexOf(ImdnUtils.HEADER_IMDN_DISPO_NOTIF);
// if (index != -1) {
// index = index+ImdnUtils.HEADER_IMDN_DISPO_NOTIF.length()+1;
// String part = content.substring(index);
// String notif = part.substring(0, part.indexOf(CRLF));
// if (notif.indexOf(ImdnDocument.DISPLAY) != -1) {
// result = true;
// }
// }
// } catch(Exception e) {
// result = false;;
// }
// return result;
// }
/**
* Returns the message ID from a SIP request
*
* @param request Request
* @return Message ID
*/
// public static String getMessageId(SipServletRequest request) {
// String result = null;
// try {
// // Read ID from multipart content
// String content = request.getContent().toString();
// int index = content.indexOf(ImdnUtils.HEADER_IMDN_MSG_ID);
// if (index != -1) {
// index = index+ImdnUtils.HEADER_IMDN_MSG_ID.length()+1;
// String part = content.substring(index);
// String msgId = part.substring(0, part.indexOf(CRLF));
// result = msgId.trim();
// }
// } catch(Exception e) {
// result = null;
// }
// return result;
// }
//
/**
* Create a first message
*
* @param remote Remote contact
* @param txt Text message
* @param imdn IMDN flag
* @return First message
*/
public static InstantMessage createFirstMessage(String remote, String msg, boolean imdn) {
if ((msg != null) && (msg.length() > 0)) {
String msgId = ChatUtils.generateMessageId();
return new InstantMessage(msgId,
remote,
StringUtils.encodeUTF8(msg),
imdn);
} else {
return null;
}
}
/**
* Get the first message
*
* @param invite Request
* @return First message
*/
// public static InstantMessage getFirstMessage(SipServletRequest invite) {
// InstantMessage msg = getFirstMessageFromCpim(invite);
// if (msg != null) {
// return msg;
// } else {
// return getFirstMessageFromSubject(invite);
// }
// }
/**
* Get the first message from CPIM content
*
* @param invite Request
* @return First message
*/
// private static InstantMessage getFirstMessageFromCpim(SipServletRequest invite) {
// CpimMessage cpimMsg = ChatUtils.extractCpimMessage(invite);
// if (cpimMsg != null) {
// String remote = ChatUtils.getReferredIdentity(invite);
// String msgId = ChatUtils.getMessageId(invite);
// String txt = cpimMsg.getMessageContent();
// Date date = cpimMsg.getMessageDate();
// if ((remote != null) && (msgId != null) && (txt != null)) {
// return new InstantMessage(msgId,
// remote,
// StringUtils.decodeUTF8(txt),
// ChatUtils.isImdnDisplayedRequested(invite),
// date);
// } else {
// return null;
// }
// } else {
// return null;
// }
// }
//
/**
* Get the first message from the Subject header
*
* @param invite Request
* @return First message
*/
// private static InstantMessage getFirstMessageFromSubject(SipServletRequest invite) {
// String subject = invite.getHeader(SipUtils.HEADER_SUBJECT);
// if ((subject != null) && (subject.length() > 0)) {
// String remote = ChatUtils.getReferredIdentity(invite);
// if ((remote != null) && (subject != null)) {
// return new InstantMessage(ChatUtils.generateMessageId(),
// remote,
// StringUtils.decodeUTF8(subject),
// ChatUtils.isImdnDisplayedRequested(invite),
// new Date());
// } else {
// return null;
// }
// } else {
// return null;
// }
// }
/**
* Extract CPIM message from incoming INVITE request
*
* @param request Request
* @return Boolean
*/
// public static CpimMessage extractCpimMessage(SipServletRequest request) {
// CpimMessage message = null;
// try {
// // Extract message from content/CPIM
// String content = request.getContent().toString();
// String contentType = request.getContentType();
// String boundary = null;
// if(contentType.contains(BOUNDARY))
// {
// boundary = contentType.substring(contentType.indexOf(BOUNDARY) + BOUNDARY.length());
//
// Multipart multi = new Multipart(content, boundary);
// if (multi.isMultipart()) {
// String cpimPart = multi.getPart(CpimMessage.MIME_TYPE);
// if (cpimPart != null) {
// // CPIM part
// CpimParser cpimParser = new CpimParser(cpimPart.getBytes());
// message = cpimParser.getCpimMessage();
// }
// }
// }
// } catch(Exception e) {
// message = null;
// }
// return message;
// }
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import utils.PhoneUtils;
/**
* List of participants
*
* @author amir aharon
*/
public class ListOfParticipant {
/**
* Internal list
*/
private List<String> list = new ArrayList<String>();
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Constructor
*/
public ListOfParticipant() {
}
/**
* Constructor
*
* @param list List
*/
public ListOfParticipant(List<String> list) {
this.list = list;
}
/**
* Constructor
*
* @param xml Resource-list document in XML
*/
public ListOfParticipant(String xml) {
// try {
// InputSource pidfInput = new InputSource(new ByteArrayInputStream(xml.getBytes()));
// ResourceListParser listParser = new ResourceListParser(pidfInput);
// ResourceListDocument resList = listParser.getResourceList();
// if (resList != null) {
// Vector<String> entries = resList.getEntries();
// for(int i=0; i < entries.size(); i++) {
// String entry = entries.elementAt(i);
// if (!PhoneUtils.compareNumbers(entry, ImsModule.IMS_USER_PROFILE.getPublicUri())) {
// list.add(PhoneUtils.extractNumberFromUri(entry));
// }
// }
// }
// } catch(Exception e) {
// logger.severe("Can't parse resource-list document: " + e);
// }
}
/**
* Add a participant in the list
*
* @param participant Participant
*/
public void addParticipant(String participant) {
String number = PhoneUtils.extractNumberFromUri(participant);
if (!list.contains(participant)) {
logger.info("Add participant " + number + " to the list");
list.add(number);
}
}
/**
* Remove a participant from the list
*
* @param participant Participant
*/
public void removeParticipant(String participant) {
String number = PhoneUtils.extractNumberFromUri(participant);
if (list.contains(number)) {
logger.info("Remove participant " + number + " from the list");
list.remove(number);
} else {
logger.info("Participant " + number + " does not exist");
}
}
/**
* Get list of participants
*
* @return Array list
*/
public List<String> getList() {
return list;
}
/**
* Get list of participants as a string
*
* @return String
*/
public String toString() {
StringBuffer result = new StringBuffer();
for(String contact : getList()) {
result.append(contact + ";");
}
return result.toString();
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat.cpim;
/**
* CPIM header
*
* @author amir aharon
*/
public class CpimHeader {
/***
* Header name
*/
private String name;
/**
* Header value
*/
private String value;
/**
* Constructor
*
* @param name Header name
* @param value Header value
*/
public CpimHeader(String name, String value) {
this.name = name;
this.value = value;
}
/**
* Returns header name
*
* @return String
*/
public String getName() {
return name;
}
/**
* Returns header value
*
* @return String
*/
public String getValue() {
return value;
}
/**
* Parse CPIM header
*
* @param data Input data
* @return Header
* @throws Exception
*/
public static CpimHeader parseHeader(String data) throws Exception {
int index = data.indexOf(":");
String key = data.substring(0, index);
String value = data.substring(index+1);
return new CpimHeader(key.trim(), value.trim());
}
}
\ No newline at end of file
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat.cpim;
import java.util.Date;
import java.util.Hashtable;
import utils.DateUtils;
/**
* CPIM message
*
* @author amir aharon
*/
public class CpimMessage {
/**
* MIME type
*/
public static final String MIME_TYPE = "message/cpim";
/**
* Header "Content-type"
*/
public static final String HEADER_CONTENT_TYPE = "Content-type";
public static final String HEADER_CONTENT_TYPE2 = "Content-Type";
/**
* Header "From"
*/
public static final String HEADER_FROM = "From";
/**
* Header "To"
*/
public static final String HEADER_TO = "To";
/**
* Header "cc"
*/
public static final String HEADER_CC = "cc";
/**
* Header "DateTime"
*/
public static final String HEADER_DATETIME = "DateTime";
/**
* Header "Subject"
*/
public static final String HEADER_SUBJECT = "Subject";
/**
* Header "NS"
*/
public static final String HEADER_NS = "NS";
/**
* Header "Content-length"
*/
public static final String HEADER_CONTENT_LENGTH = "Content-length";
/**
* Header "Require"
*/
public static final String HEADER_REQUIRE = "Require";
/**
* Header "Content-Disposition"
*/
public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
/**
* Message content
*/
private String msgContent = null;
/**
* MIME headers
*/
private Hashtable<String, String> headers = new Hashtable<String, String>();
/**
* MIME content headers
*/
private Hashtable<String, String> contentHeaders = new Hashtable<String, String>();
/**
* Constructor
*
* @param headers MIME headers
* @param contentHeaders MIME content headers
* @param msgContent Content
*/
public CpimMessage(Hashtable<String, String> headers, Hashtable<String, String> contentHeaders, String msgContent) {
this.headers = headers;
this.contentHeaders = contentHeaders;
this.msgContent = msgContent;
}
/**
* Returns content type
*
* @return Content type
*/
public String getContentType() {
String type = contentHeaders.get(CpimMessage.HEADER_CONTENT_TYPE);
if (type == null) {
return contentHeaders.get(CpimMessage.HEADER_CONTENT_TYPE2);
} else {
return type;
}
}
/**
* Returns MIME header
*
* @param name Header name
* @return Header value
*/
public String getHeader(String name) {
return headers.get(name);
}
public void setHeader(String name,String value) {
headers.put(name,value);
}
/**
* Returns MIME content header
*
* @param name Header name
* @return Header value
*/
public String getContentHeader(String name) {
return contentHeaders.get(name);
}
/**
* Returns message content
*
* @return Content
*/
public String getMessageContent() {
return msgContent;
}
/**
* Returns message date
*
* @return Date
*/
public Date getMessageDate() {
String header = getHeader(CpimMessage.HEADER_DATETIME);
if (header != null)
{
Date d = null;
try{
d = DateUtils.parseRFC3339Date(header);
}
catch (Exception exp)
{
d = null;
}
return d;
}
else
{
return null;
}
}
public void setMessgeDate(long date){
setHeader(CpimMessage.HEADER_DATETIME, DateUtils.encodeDate(date));
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat.cpim;
import java.util.Hashtable;
import java.util.StringTokenizer;
import utils.StringUtils;
/**
* CPIM parser (see RFC3862)
*
* @author amir aharon
*/
public class CpimParser {
/**
* CRLF constant
*/
private static final String CRLF = "\r\n";
/**
* Double CRLF constant
*/
private static final String DOUBLE_CRLF = CRLF + CRLF;
/**
* CPIM message
*/
private CpimMessage cpim = null;
/**
* Constructor
*
* @param data Input data
* @throws Exception
*/
public CpimParser(byte data[]) throws Exception {
parse(new String(data));
}
/**
* Constructor
*
* @param data Input data
* @throws Exception
*/
public CpimParser(String data) throws Exception {
parse(data);
}
/***
* Returns the CPIM message
*
* @return CPIM message
*/
public CpimMessage getCpimMessage() {
return cpim;
}
/**
* Parse message/CPIM document
*
* @param data Input data
* @throws Exception
*/
private void parse(String data) throws Exception {
/* CPIM sample:
From: MR SANDERS <im:piglet@100akerwood.com>
To: Depressed Donkey <im:eeyore@100akerwood.com>
DateTime: 2000-12-13T13:40:00-08:00
Subject: the weather will be fine today
Content-type: text/plain
Content-ID: <1234567890@foo.com>
Here is the text of my message.
*/
try {
// Read message headers
int begin = 0;
int end = data.indexOf(DOUBLE_CRLF);
//end = data.indexOf(DOUBLE_CRLF, begin);
String block2 = data.substring(begin, end);
StringTokenizer lines = new StringTokenizer(block2, CRLF);
Hashtable<String, String> headers = new Hashtable<String, String>();
while(lines.hasMoreTokens()) {
String token = lines.nextToken();
CpimHeader hd = CpimHeader.parseHeader(token);
headers.put(hd.getName(), hd.getValue());
}
// Read the MIME-encapsulated content header
begin = end+4;
end = data.indexOf(DOUBLE_CRLF, begin);
String block3 = data.substring(begin, end);
lines = new StringTokenizer(block3, CRLF);
Hashtable<String, String> contentHeaders = new Hashtable<String, String>();
while(lines.hasMoreTokens()) {
String token = lines.nextToken();
CpimHeader hd = CpimHeader.parseHeader(token);
contentHeaders.put(hd.getName(), hd.getValue());
}
// Read the message content
begin = end+4;
String content = data.substring(begin);
// Create the CPIM message
cpim = new CpimMessage(headers, contentHeaders, StringUtils.decodeUTF8(content));
} catch(Exception e) {
throw new Exception("Bad CPIM message format");
}
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat.event;
import java.util.Vector;
/**
* Conference-Info document
*
* @author amir aharon
*/
public class ConferenceInfoDocument {
public final static String STATE_PARTIAL = "partial";
public final static String STATE_FULL = "full";
public final static String STATE_DELETED = "deleted";
private String entity;
private String state;
private Vector<User> users = new Vector<User>();
public ConferenceInfoDocument(String entity, String state) {
this.entity = entity;
this.state = state;
}
public String getEntity() {
return entity;
}
public String getState() {
return state;
}
public void addUser(User user) {
users.addElement(user);
}
public Vector<User> getUsers() {
return users;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat.event;
import java.util.logging.Logger;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.DefaultHandler;
/**
* Conference-Info parser
*
* @author amir aharon
*/
public class ConferenceInfoParser extends DefaultHandler {
/* Conference-Info SAMPLE:
<?xml version="1.0" encoding="UTF-8"?>
<conference-info xmlns="urn:ietf:params:xml:ns:conference-info" entity="sips:conf233@example.com" state="full" version="1">
<!-- CONFERENCE INFO -->
<conference-description>
<subject>Agenda: This month's goals</subject>
<service-uris>
<entry>
<uri>http://sharepoint/salesgroup/</uri>
<purpose>web-page</purpose>
</entry>
</service-uris>
</conference-description>
<!-- CONFERENCE STATE -->
<conference-state>
<user-count>33</user-count>
</conference-state>
<!-- USERS -->
<users>
<!-- USER 1 -->
<user entity="sip:bob@example.com" state="full">
<display-text>Bob Hoskins</display-text>
<!-- ENDPOINTS -->
<endpoint entity="sip:bob@pc33.example.com">
<display-text>Bob's Laptop</display-text>
<status>disconnected</status>
<disconnection-method>departed</disconnection-method>
<disconnection-info>
<when>2005-03-04T20:00:00Z</when>
<reason>bad voice quality</reason>
<by>sip:mike@example.com</by>
</disconnection-info>
<!-- MEDIA -->
<media id="1">
<display-text>main audio</display-text>
<type>audio</type>
<label>34567</label>
<src-id>432424</src-id>
<status>sendrecv</status>
</media>
</endpoint>
</user>
<!-- USER 2 -->
<user entity="sip:alice@example.com" state="full">
<display-text>Alice</display-text>
<!-- ENDPOINTS -->
<endpoint entity="sip:4kfk4j392jsu@example.com;grid=433kj4j3u">
<status>connected</status>
<joining-method>dialed-out</joining-method>
<joining-info>
<when>2005-03-04T20:00:00Z</when>
<by>sip:mike@example.com</by>
</joining-info>
<!-- MEDIA -->
<media id="1">
<display-text>main audio</display-text>
<type>audio</type>
<label>34567</label>
<src-id>534232</src-id>
<status>sendrecv</status>
</media>
</endpoint>
</user>
</users>
</conference-info>
*/
private StringBuffer accumulator;
private ConferenceInfoDocument conference = null;
private User user = null;
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Constructor
*
* @param inputSource Input source
* @throws Exception
*/
public ConferenceInfoParser(InputSource inputSource) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(inputSource, this);
}
public ConferenceInfoDocument getConferenceInfo() {
return conference;
}
public void startDocument() {
logger.info("Start document");
accumulator = new StringBuffer();
}
public void characters(char buffer[], int start, int length) {
accumulator.append(buffer, start, length);
}
public void startElement(String namespaceURL, String localName, String qname, Attributes attr) {
accumulator.setLength(0);
if (localName.equals("conference-info")) {
String entity = attr.getValue("entity").trim();
String state = attr.getValue("state").trim();
conference = new ConferenceInfoDocument(entity, state);
} else
if (localName.equals("user")) {
String entity = attr.getValue("entity").trim();
String yourown = attr.getValue("yourown");
boolean me = false;
if (yourown != null) {
try {
me = Boolean.parseBoolean(yourown);
} catch(Exception e) {}
}
user = new User(entity, me);
}
}
public void endElement(String namespaceURL, String localName, String qname) {
if (localName.equals("user")) {
if (user != null) {
conference.addUser(user);
user = null;
}
} else
if (localName.equals("display-text")) {
if (user != null) {
user.setDisplayName(accumulator.toString().trim());
}
} else
if (localName.equals("status")) {
if (user != null) {
user.setState(accumulator.toString().trim());
}
} else
if (localName.equals("conference-info")) {
logger.info("Conference-Info document complete");
}
}
public void endDocument() {
logger.info("End document");
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat.event;
public class User {
public final static String STATE_UNKNOWN = "unknown";
public final static String STATE_CONNECTED = "connected";
public final static String STATE_DISCONNECTED = "disconnected";
public final static String STATE_ONHOLD = "on-hold";
public final static String STATE_MUTED = "muted-via-focus";
public final static String STATE_PENDING = "pending";
public final static String STATE_ALERTING = "alerting";
public final static String STATE_DIALING_IN = "dialing-in";
public final static String STATE_DIALING_OUT = "dialing-out";
public final static String STATE_DISCONNECTING = "disconnecting";
private String entity;
private boolean me;
private String state = STATE_UNKNOWN;
private String displayName = null;
public User(String entity, boolean me) {
this.entity = entity;
this.me = me;
}
public String getEntity() {
return entity;
}
public boolean isMe() {
return me;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat.imdn;
import java.util.List;
import java.util.LinkedList;
/**
* IMDN document
*
* @author amir aharon
*/
public class ImdnDocument {
/**
* MIME type
*/
public static final String MIME_TYPE = "message/imdn+xml";
/**
* Delivery status delivered
*/
public static final String DELIVERY_STATUS_DELIVERED = "delivered";
/**
* Msg id
*/
public static final String MESSAGE_ID = "message-id";
/**
* Delivery status displayed
*/
public static final String DELIVERY_STATUS_DISPLAYED = "displayed";
/**
* Delivery status failed
*/
public static final String DELIVERY_STATUS_FAILED = "failed";
/**
* Delivery status error
*/
public static final String DELIVERY_STATUS_ERROR = "error";
/**
* Delivery status forbidden
*/
public static final String DELIVERY_STATUS_FORBIDDEN = "forbidden";
/**
* Namespace value
*/
public static final String IMDN_NAMESPACE = "imdn <urn:ietf:params:imdn>";
/**
* Disposition notification header positive delivery value
*/
public static final String POSITIVE_DELIVERY = "positive-delivery";
/**
* Disposition notification header display value
*/
public static final String DISPLAY = "display";
/**
* Content-Disposition header notification value
*/
public static final String NOTIFICATION = "notification";
/**
*datetime value
*/
public static final String DATE_TIME = "datetime";
/**
* Message ID/s
*/
//private String msgId = null;
private List<String> msgIdList = null;
/**
* Status
*/
private String status = null;
/**
* Datetime
*/
private String datetime = null;
/**
* Constructor
*/
public ImdnDocument() {
}
/**
* Get message ID
*
* @return Message ID
*/
public String getMsgId() {
if (this.msgIdList == null)
return null;
return this.msgIdList.get(0);
}
public List<String> getMsgIdList() {
return this.msgIdList;
}
/**
* Set message ID
*
* @param msgId Message ID
*/
public void setMsgId(String msgId) {
if (this.msgIdList == null)
{
this.msgIdList = new LinkedList<String>();
}
this.msgIdList.add(msgId);
}
/**
* Get delivery status
*
* @return Status
*/
public String getStatus() {
return status;
}
/**
* Set delivery status
*
* @param status Status
*/
public void setStatus(String status) {
this.status = status;
}
/**
* Get datetime
*
* @return datetime
*/
public String getDatetime() {
return datetime;
}
/**
* Set datetime
*
* @param datetime
*/
public void setDatetime(String datetime) {
this.datetime = datetime;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat.imdn;
import java.util.logging.Logger;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/**
* IMDN parser (RFC5438)
*/
public class ImdnParser extends DefaultHandler {
/* IMDN SAMPLE:
<?xml version="1.0" encoding="UTF-8"?>
<imdn xmlns="urn:ietf:params:xml:ns:imdn">
<message-id>34jk324j</message-id>
<datetime>2008-04-04T12:16:49-05:00</datetime>
<display-notification>
<status>
<displayed/>
</status>
</display-notification>
</imdn>
*/
private StringBuffer accumulator = null;
private ImdnDocument imdn = null;
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Constructor
*
* @param inputSource Input source
* @throws Exception
*/
public ImdnParser(InputSource inputSource) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(inputSource, this);
}
public void startDocument() {
logger.info("Start document");
accumulator = new StringBuffer();
}
public void characters(char buffer[], int start, int length) {
accumulator.append(buffer, start, length);
}
public void startElement(String namespaceURL, String localName, String qname, Attributes attr) {
accumulator.setLength(0);
if (qname.equals("imdn")) {
imdn = new ImdnDocument();
}
}
public void endElement(String namespaceURL, String localName, String qname) {
if (qname.equals(ImdnDocument.MESSAGE_ID)) {
if (imdn != null) {
imdn.setMsgId(accumulator.toString());
}
} else
if (qname.equals(ImdnDocument.DELIVERY_STATUS_DELIVERED)) {
if (imdn != null) {
imdn.setStatus(ImdnDocument.DELIVERY_STATUS_DELIVERED);
}
} else
if (qname.equals(ImdnDocument.DELIVERY_STATUS_FAILED)) {
if (imdn != null) {
imdn.setStatus(ImdnDocument.DELIVERY_STATUS_FAILED);
}
} else
if (qname.equals(ImdnDocument.DELIVERY_STATUS_ERROR)) {
if (imdn != null) {
imdn.setStatus(ImdnDocument.DELIVERY_STATUS_ERROR);
}
} else
if (qname.equals(ImdnDocument.DELIVERY_STATUS_DISPLAYED)) {
if (imdn != null) {
imdn.setStatus(ImdnDocument.DELIVERY_STATUS_DISPLAYED);
}
} else
if (qname.equals(ImdnDocument.DATE_TIME)) {
if (imdn != null) {
imdn.setDatetime(accumulator.toString());
}
} else
if (qname.equals("imdn")) {
logger.info("IMDN document is complete");
}
}
public void endDocument() {
logger.info("End document");
}
public void warning(SAXParseException exception) {
logger.severe("Warning: line " + exception.getLineNumber() + ": "
+ exception.getMessage());
}
public void error(SAXParseException exception) {
logger.severe("Error: line " + exception.getLineNumber() + ": "
+ exception.getMessage());
}
public void fatalError(SAXParseException exception) throws SAXException {
logger.severe("Fatal: line " + exception.getLineNumber() + ": "
+ exception.getMessage());
throw exception;
}
public ImdnDocument getImdnDocument() {
return imdn;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat.imdn;
/**
* IMDN utility functions
*/
public class ImdnUtils {
/**
* IMDN notification disposition header
*/
public static final String HEADER_IMDN_DISPO_NOTIF = "imdn.Disposition-Notification";
/**
* IMDN message ID header
*/
public static final String HEADER_IMDN_MSG_ID = "imdn.Message-ID";
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat.iscomposing;
import core.ims.service.im.InstantMessage;
import utils.DateUtils;
/**
* Is composing info document (see RFC3994)
*/
public class IsComposingInfo {
/**
* MIME type
*/
public static String MIME_TYPE = "application/im-iscomposing+xml";
/**
* CRLF constant
*/
private static final String CRLF = "\r\n";
/**
* State
*/
private boolean state = false;
/**
* Last active state in seconds
*/
private long lastActiveDate = 0L;
/**
* Refresh time in seconds
*/
private long refreshTime = 0L;
/**
* Content type
*/
private String contentType = "";
/**
* Constructor
*/
public IsComposingInfo() {
}
public void setState(String state) {
if (state.equalsIgnoreCase("active")){
this.state = true;
} else {
this.state = false;
}
}
public void setLastActiveDate(String lastActiveTimeStamp){
this.lastActiveDate = DateUtils.decodeDate(lastActiveTimeStamp)/1000;
}
public void setRefreshTime(String refreshTime){
this.refreshTime = Long.parseLong(refreshTime);
}
public void setContentType(String contentType){
this.contentType = contentType;
}
public boolean isStateActive(){
return state;
}
public long getLastActiveDate(){
return lastActiveDate;
}
public long getRefreshTime(){
return refreshTime;
}
public String getContentType(){
return contentType;
}
/**
* Build is composing document
*
* @param status Status
* @return XML document
*/
public static String buildIsComposingInfo(boolean status) {
String state = "idle";
if (status) {
state = "active";
}
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + CRLF +
"<isComposing xmlns=\"urn:ietf:params:xml:ns:im-iscomposing\"" + CRLF +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + CRLF +
"xsi:schemaLocation=\"urn:ietf:params:xml:ns:im-composing iscomposing.xsd\">" + CRLF +
"<state>" + state + "</state>" + CRLF +
"<contenttype>" + InstantMessage.MIME_TYPE + "</contenttype>" + CRLF +
"<lastactive>" + DateUtils.encodeDate(System.currentTimeMillis()) + "</lastactive>" + CRLF +
"<refresh>60</refresh>" + CRLF +
"</isComposing>";
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat.iscomposing;
import java.util.logging.Logger;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/**
* Is composing event parser (RFC3994)
*/
public class IsComposingParser extends DefaultHandler {
/* IsComposing SAMPLE:
<?xml version="1.0" encoding="UTF-8"?>
<isComposing xmlns="urn:ietf:params:xml:ns:im-iscomposing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:ietf:params:xml:ns:im-composing iscomposing.xsd">
<state>idle</state>
<lastactive>2003-01-27T10:43:00Z</lastactive>
<contenttype>audio</contenttype>
</isComposing>
*/
private StringBuffer accumulator = null;
private IsComposingInfo isComposingInfo = null;
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Constructor
*
* @param inputSource Input source
* @throws Exception
*/
public IsComposingParser(InputSource inputSource) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(inputSource, this);
}
public void startDocument() {
logger.info("Start document");
accumulator = new StringBuffer();
}
public void characters(char buffer[], int start, int length) {
accumulator.append(buffer, start, length);
}
public void startElement(String namespaceURL, String localName, String qname, Attributes attr) {
accumulator.setLength(0);
if (localName.equals("isComposing")) {
isComposingInfo = new IsComposingInfo();
}
}
public void endElement(String namespaceURL, String localName, String qname) {
if (localName.equals("state")) {
if (isComposingInfo != null) {
isComposingInfo.setState(accumulator.toString());
}
} else
if (localName.equals("lastactive")) {
if (isComposingInfo != null) {
isComposingInfo.setLastActiveDate(accumulator.toString());
}
} else
if (localName.equals("contenttype")) {
if (isComposingInfo != null) {
isComposingInfo.setContentType(accumulator.toString());
}
} else
if (localName.equals("refresh")) {
if (isComposingInfo != null) {
isComposingInfo.setRefreshTime(accumulator.toString());
}
} else
if (localName.equals("isComposing")) {
logger.info("Watcher document is complete");
}
}
public void endDocument() {
logger.info("End document");
}
public void warning(SAXParseException exception) {
logger.severe("Warning: line " + exception.getLineNumber() + ": "
+ exception.getMessage());
}
public void error(SAXParseException exception) {
logger.severe("Error: line " + exception.getLineNumber() + ": "
+ exception.getMessage());
}
public void fatalError(SAXParseException exception) throws SAXException {
logger.severe("Fatal: line " + exception.getLineNumber() + ": "
+ exception.getMessage());
throw exception;
}
public IsComposingInfo getIsComposingInfo() {
return isComposingInfo;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat.resourcelist;
import java.util.Vector;
/**
* Resource-list document
*
* @author amir aharon
*/
public class ResourceListDocument {
private Vector<String> entries = new Vector<String>();
public ResourceListDocument() {
}
public void addEntry(String uri) {
entries.addElement(uri);
}
public Vector<String> getEntries() {
return entries;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.chat.resourcelist;
import java.util.logging.Logger;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.DefaultHandler;
/**
* Resource list parser
*
* @author amir aharon
*/
public class ResourceListParser extends DefaultHandler {
/* Resource-List SAMPLE:
<?xml version="1.0" encoding="UTF-8"?>
<resource-lists xmlns="urn:ietf:params:xml:ns:resource-lists"
xmlns:cp="urn:ietf:params:xml:ns:copycontrol">
<list>
<entry uri="sip:bill@example.com" cp:copyControl="to" />
<entry uri="sip:joe@example.org" cp:copyControl="cc" />
<entry uri="sip:ted@example.net" cp:copyControl="bcc" />
</list>
</resource-lists>
*/
private StringBuffer accumulator;
private ResourceListDocument list = null;
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Constructor
*
* @param inputSource Input source
* @throws Exception
*/
public ResourceListParser(InputSource inputSource) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(inputSource, this);
}
public ResourceListDocument getResourceList() {
return list;
}
public void startDocument() {
logger.info("Start document");
accumulator = new StringBuffer();
}
public void characters(char buffer[], int start, int length) {
accumulator.append(buffer, start, length);
}
public void startElement(String namespaceURL, String localName, String qname, Attributes attr) {
accumulator.setLength(0);
if (localName.equals("resource-lists")) {
list = new ResourceListDocument();
} else
if (localName.equals("entry")) {
String uri = attr.getValue("uri").trim();
list.addEntry(uri);
}
}
public void endElement(String namespaceURL, String localName, String qname) {
if (localName.equals("resource-lists")) {
logger.info("Resource-list document complete");
}
}
public void endDocument() {
logger.info("End document");
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.filetransfer;
import core.ims.service.ImsServiceError;
/**
* File transfer error
*
* @author amir aharon
*/
public class FileSharingError extends ImsServiceError {
static final long serialVersionUID = 1L;
/**
* Unexpected exception occurs in the module (e.g. internal exception)
*/
public final static int UNEXPECTED_EXCEPTION = 0x01;
/**
* Session initiation has failed (e.g. 408 timeout)
*/
public final static int SESSION_INITIATION_FAILED = 0x02;
/**
* Session initiation has been declined (e.g. 603 Decline)
*/
public final static int SESSION_INITIATION_DECLINED = 0x03;
/**
* Session initiation has been cancelled (e.g. 487 Session terminated)
*/
public final static int SESSION_INITIATION_CANCELLED = 0x04;
/**
* Media transfer has failed (e.g. MSRP failure)
*/
public final static int MEDIA_TRANSFER_FAILED = 0x05;
/**
* Unsupported media type (e.g. codec not supported)
*/
public final static int UNSUPPORTED_MEDIA_TYPE = 0x06;
/**
* Media saving has failed (e.g. sdcard is not correctly mounted)
*/
public final static int MEDIA_SAVING_FAILED = 0x07;
/**
* Constructor
*
* @param code Error code
*/
public FileSharingError(int code) {
super(code);
}
/**
* Constructor
*
* @param code Error code
* @param msg Detail message
*/
public FileSharingError(int code, String msg) {
super(code, msg);
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.service.im.filetransfer;
import core.ims.service.ImsSessionListener;
/**
* File transfer session listener
*
* @author amir aharon
*/
public interface FileSharingSessionListener extends ImsSessionListener {
/**
* File transfer progress
*
* @param currentSize Data size transfered
* @param totalSize Total size to be transfered
*/
public void handleTransferProgress(long currentSize, long totalSize);
/**
* File transfer error
*
* @param error Error
*/
public void handleTransferError(FileSharingError error);
/**
* File has been transfered
*
* @param filename Filename associated to the received file
*/
public void handleFileTransfered(String filename);
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 core.ims.userprofile;
import java.util.ListIterator;
import java.util.Vector;
/**
* User profile
*
* @author JM. Auffret
*/
public class UserProfile {
/**
* User name
*/
private String username;
/**
* User private ID
*/
private String privateID;
/**
* User password
*/
private String password;
/**
* Home domain
*/
private String homeDomain;
/**
* XDM server address
*/
private String xdmServerAddr;
/**
* XDM server login
*/
private String xdmServerLogin;
/**
* XDM server password
*/
private String xdmServerPassword;
/**
* IM conference URI
*/
private String imConferenceUri;
/**
* Associated URIs
*/
private Vector<String> associatedUriList = new Vector<String>();
/**
* Preferred URI
*/
private String preferredUri = null;
/**
* Constructor
*
* @param username Username
* @param privateID Private id
* @param password Password
* @param homeDomain Home domain
* @param xdmServerAddr XDM server address
* @param xdmServerLogin Outbound proxy address
* @param xdmServerPassword Outbound proxy address
* @param imConferenceUri IM conference factory URI
*/
public UserProfile(String username,
String privateID,
String password,
String homeDomain,
String xdmServerAddr,
String xdmServerLogin,
String xdmServerPassword,
String imConferenceUri) {
this.username = username;
this.privateID = privateID;
this.password = password;
this.homeDomain = homeDomain;
this.xdmServerAddr = xdmServerAddr;
this.xdmServerLogin = xdmServerLogin;
this.xdmServerPassword = xdmServerPassword;
this.imConferenceUri = imConferenceUri;
this.preferredUri = "sip:" + username + "@" + homeDomain;
}
/**
* Get the user name
*
* @return Username
*/
public String getUsername() {
return username;
}
/**
* Set the user name
*
* @param username Username
*/
public void setUsername(String username) {
this.username = username;
}
/**
* Get the user preferred URI
*
* @return Preferred URI
*/
public String getPreferredUri() {
return preferredUri;
}
/**
* Get the user public URI
*
* @return Public URI
*/
public String getPublicUri() {
if (preferredUri == null) {
return "sip:" + username + "@" + homeDomain;
} else {
return preferredUri;
}
}
/**
* Set the user associated URIs
*
* @param uris List of URIs
*/
public void setAssociatedUri(ListIterator<String> uris) {
if (uris == null) {
return;
}
String sipUri = null;
String telUri = null;
while(uris.hasNext()) {
String header = uris.next();
String value = header; //.getValue();
associatedUriList.addElement(value);
if (value.startsWith("<sip:")) {
sipUri = value;
} else
if (value.startsWith("<tel:")) {
telUri = value;
}
}
if ((sipUri != null) && (telUri != null)) {
preferredUri = telUri;
} else
if (telUri != null) {
preferredUri = telUri;
} else
if (sipUri != null) {
preferredUri = sipUri;
}
}
/**
* Get the user private ID
*
* @return Private ID
*/
public String getPrivateID() {
return privateID;
}
/**
* Returns the user password
*
* @return Password
*/
public String getPassword() {
return password;
}
/**
* Returns the home domain
*
* @return Home domain
*/
public String getHomeDomain() {
return homeDomain;
}
/**
* Set the home domain
*
* @param domain Home domain
*/
public void setHomeDomain(String domain) {
this.homeDomain = domain;
}
/**
* Set the XDM server address
*
* @param addr Server address
*/
public void setXdmServerAddr(String addr) {
this.xdmServerAddr = addr;
}
/**
* Returns the XDM server address
*
* @return Server address
*/
public String getXdmServerAddr() {
return xdmServerAddr;
}
/**
* Set the XDM server login
*
* @param login Login
*/
public void setXdmServerLogin(String login) {
this.xdmServerLogin = login;
}
/**
* Returns the XDM server login
*
* @return Login
*/
public String getXdmServerLogin() {
return xdmServerLogin;
}
/**
* Set the XDM server password
*
* @param pwd Password
*/
public void setXdmServerPassword(String pwd) {
this.xdmServerPassword = pwd;
}
/**
* Returns the XDM server password
*
* @return Password
*/
public String getXdmServerPassword() {
return xdmServerPassword;
}
/**
* Set the IM conference URI
*
* @param uri URI
*/
public void setImConferenceUri(String uri) {
this.imConferenceUri = uri;
}
/**
* Returns the IM conference URI
*
* @return URI
*/
public String getImConferenceUri() {
return imConferenceUri;
}
/**
* Returns the profile value as string
*
* @return String
*/
public String toString() {
String result = "IMS username=" + username + ", "
+ "IMS private ID=" + privateID + ", "
+ "IMS password=" + password + ", "
+ "IMS home domain=" + homeDomain + ", "
+ "XDM server=" + xdmServerAddr + ", "
+ "XDM login=" + xdmServerLogin + ", "
+ "XDM password=" + xdmServerPassword + ", "
+ "IM Conference URI=" + imConferenceUri;
return result;
}
}
package defs;
/**
* this interface holds all the constants for the RCS core
* @author amir
*
*/
public class Constants
{
public static final String C_CHAT_SESSION = "ChatSession";
public static final String C_CHAT_SESSION_ID = "ChatSessionId";
public static final String C_SUB_ID = "C_SUB_ID";
public static final String C_CHAT_ROOM_ID = "chatRoomId";
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 platform;
/**
* Factory exception
*
* @author JM. Auffret
*/
public class FactoryException extends java.lang.Exception {
static final long serialVersionUID = 1L;
/**
* Constructor
*
* @param error Error message
*/
public FactoryException(String error) {
super(error);
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 platform.file;
/**
* File description
*
* @author amir aharon
*/
public class FileDescription {
/**
* Name
*/
private String name;
/**
* Size
*/
private long size = -1;
/**
* Directory
*/
private boolean directory = false;
/**
* Constructor
*/
public FileDescription(String name, long size) {
this.name = name;
this.size = size;
}
/**
* Constructor
*/
public FileDescription(String name, long size, boolean directory) {
this.name = name;
this.size = size;
this.directory = directory;
}
/**
* Returns the size of the file
*
* @return File size
*/
public long getSize() {
return size;
}
/**
* Returns the name of the file
*
* @return File name
*/
public String getName() {
return name;
}
/**
* Is a directory
*
* @return Boolean
*/
public boolean isDirectory() {
return directory;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 platform.file;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import platform.FactoryException;
/**
* File factory
*
* @author amir aharon
*/
public abstract class FileFactory {
/**
* Current platform factory
*/
private static FileFactory factory = null;
/**
* Load the factory
*
* @param classname Factory classname
* @throws Exception
*/
public static void loadFactory(String classname) throws FactoryException {
if (factory != null) {
return;
}
try {
factory = (FileFactory)Class.forName(classname).newInstance();
} catch(Exception e) {
throw new FactoryException("Can't load the factory " + classname);
}
}
/**
* Returns the current factory
*
* @return Factory
*/
public static FileFactory getFactory() {
return factory;
}
/**
* Open a file input stream
*
* @param url URL
* @return Input stream
* @throws IOException
*/
public abstract InputStream openFileInputStream(String url) throws IOException;
/**
* Open a file output stream
*
* @param url URL
* @return Output stream
* @throws IOException
*/
public abstract OutputStream openFileOutputStream(String url) throws IOException;
/**
* Returns the description of a file
*
* @param url URL of the file
* @return File description
* @throws IOException
*/
public abstract FileDescription getFileDescription(String url) throws IOException;
/**
* Returns the root directory for photos
*
* @return Directory path
*/
public abstract String getPhotoRootDirectory();
/**
* Returns the root directory for videos
*
* @return Directory path
*/
public abstract String getVideoRootDirectory();
/**
* Returns the root directory for files
*
* @return Directory path
*/
public abstract String getFileRootDirectory();
/**
* Update the media storage
*
* @param url New URL to be added
*/
public abstract void updateMediaStorage(String url);
/**
* Returns whether a file exists or not
*
* @param url Url of the file to check
* @return File existence
*/
public abstract boolean fileExists(String url);
/**
* Create a directory if not already exist
*
* @param path Directory path
* @return true if the directory exists or is created
*/
public static boolean createDirectory(String path) {
File dir = new File(path);
if (!dir.exists()) {
if (!dir.mkdirs()) {
return false;
}
}
return true;
}
}
package platform.network;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.SocketChannel;
/**
* nio implementation of socket connection
* @author amir
*
*/
public class NIOSocketClientConnection implements SocketConnection
{
private String mRemoteAddr = null;
private int mRemotePort = 0;
private SocketChannel sockChannel = null;
public NIOSocketClientConnection(SocketChannel sockChannel)
{
this.sockChannel = sockChannel;
InetAddress remoteAddress = sockChannel.socket().getInetAddress();
if (remoteAddress != null)
{
mRemoteAddr = remoteAddress.getHostAddress();
mRemotePort = sockChannel.socket().getPort();
}
}
public NIOSocketClientConnection()
{
}
@Override
public void open(String remoteAddr, int remotePort) throws IOException
{
mRemoteAddr = remoteAddr;
mRemotePort = remotePort;
sockChannel = SocketChannel.open();
//sockChannel.configureBlocking(false); // non-blocking
sockChannel.connect(new InetSocketAddress(remoteAddr, remotePort));
}
@Override
public void close() throws IOException
{
if (sockChannel != null)
{
sockChannel.close();
sockChannel = null;
}
}
@Override
public InputStream getInputStream() throws IOException
{
if (sockChannel != null && sockChannel.isConnected())
{
//return sockChannel.socket().getInputStream();
return Channels.newInputStream(sockChannel);
}
return null;
}
@Override
public OutputStream getOutputStream() throws IOException
{
if (sockChannel != null && sockChannel.isConnected())
{
return Channels.newOutputStream(sockChannel);
//return sockChannel.socket().getOutputStream();
}
return null;
}
@Override
public String getRemoteAddress() throws IOException
{
return mRemoteAddr;
}
@Override
public int getRemotePort() throws IOException
{
return mRemotePort;
}
@Override
public String getLocalAddress() throws IOException
{
if (sockChannel != null && sockChannel.isOpen() )
return sockChannel.socket().getLocalAddress().getHostAddress();
return InetAddress.getLocalHost().getHostAddress();
}
@Override
public int getLocalPort() throws IOException
{
if (sockChannel != null)
sockChannel.socket().getLocalPort();
return 0;
}
@Override
public int getSoTimeout() throws IOException
{
if (sockChannel != null)
sockChannel.socket().getSoTimeout();
return 0;
}
@Override
public void setSoTimeout(int timeout) throws IOException
{
if (sockChannel != null)
sockChannel.socket().setSoTimeout(timeout);
}
public SocketChannel getSocketChannel()
{
return this.sockChannel;
}
@Override
public void write(byte[] data) throws IOException
{
sockChannel.write(ByteBuffer.wrap(data));
}
}
package platform.network;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class NIOSocketServerConnection implements SocketServerConnection
{
ServerSocketChannel mServerChannel = null;
@Override
public void open(int port) throws IOException
{
mServerChannel = ServerSocketChannel.open();
//InetSocketAddress isa = new InetSocketAddress(InetAddress.getLocalHost(), port);
InetSocketAddress isa = new InetSocketAddress(port);
mServerChannel.socket().bind(isa);
}
@Override
public void close() throws IOException
{
mServerChannel.close();
}
@Override
public SocketConnection acceptConnection() throws IOException
{
SocketChannel sc = mServerChannel.accept();
String str = sc.socket().getInetAddress().toString();
return new NIOSocketClientConnection(sc);
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 platform.network;
import platform.FactoryException;
/**
* Network factory
*
* @author amir aharon
*/
public abstract class NetworkFactory {
/**
* Current platform factory
*/
private static NetworkFactory factory = null;
/**
* Load the factory
*
* @param classname Factory classname
* @throws Exception
*/
public static synchronized void loadFactory(String classname) throws FactoryException {
if (factory != null) {
return;
}
factory = new RCSNetworkFactory();
/*try {
Class cFactory = Class.forName(classname);
factory = (NetworkFactory)cFactory.newInstance();
} catch(Exception e) {
throw new FactoryException("Can't load the factory " + classname);
}*/
}
/**
* Returns the current factory
*
* @return Factory
*/
public static NetworkFactory getFactory() {
return factory;
}
/**
* Returns the local IP address
*
* @return Address
*/
public abstract String getLocalIpAddress();
/**
* Create a datagram connection
*
* @return Datagram connection
*/
// public abstract DatagramConnection createDatagramConnection();
/**
* Create a socket client connection
*
* @return Socket connection
*/
public abstract SocketConnection createSocketClientConnection();
/**
* Create a socket server connection
*
* @return Socket server connection
*/
public abstract SocketServerConnection createSocketServerConnection();
/**
* Create an HTTP connection
*
* @return HTTP connection
*/
// public abstract HttpConnection createHttpConnection();
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 platform.network;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import utils.IpAddressUtils;
/**
* Android network factory
*
* @author amir aharon
*/
public class RCSNetworkFactory extends NetworkFactory {
/**
* Returns the local IP address
*
* @return IP address
*/
public String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); (en != null) && en.hasMoreElements();) {
NetworkInterface intf = (NetworkInterface)en.nextElement();
for (Enumeration<InetAddress> addr = intf.getInetAddresses(); addr.hasMoreElements();) {
InetAddress inetAddress = (InetAddress)addr.nextElement();
if (!inetAddress.isLoopbackAddress() && !inetAddress.isLinkLocalAddress()) {
return IpAddressUtils.extractHostAddress(inetAddress.getHostAddress());
}
}
}
return null;
} catch(Exception e) {
return null;
}
}
/**
* Create a datagram connection
*
* @return Datagram connection
*/
// public DatagramConnection createDatagramConnection() {
// return new AndroidDatagramConnection();
// }
/**
* Create a socket client connection
*
* @return Socket connection
*/
public SocketConnection createSocketClientConnection() {
return new NIOSocketClientConnection(); //SocketClientConnection();
}
/**
* Create a socket server connection
*
* @return Socket server connection
*/
public SocketServerConnection createSocketServerConnection() {
return new NIOSocketServerConnection();
}
/**
* Create an HTTP connection
*
* @return HTTP connection
*/
// public HttpConnection createHttpConnection() {
// return new AndroidHttpConnection();
// }
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 platform.network;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Logger;
/**
* Android socket connection
*
* @author amir aharon
*/
public class RCSSocketServerConnection implements SocketServerConnection {
/**
* Socket server connection
*/
private ServerSocket acceptSocket = null;
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Constructor
*/
public RCSSocketServerConnection() {
}
/**
* Open the socket
*
* @param port Local port
* @throws IOException
*/
public void open(int port) throws IOException {
acceptSocket = new ServerSocket(port);
}
/**
* Close the socket
*
* @throws IOException
*/
public void close() throws IOException {
if (acceptSocket != null) {
acceptSocket.close();
acceptSocket = null;
}
}
/**
* Accept connection
*
* @return Socket connection
* @throws IOException
*/
public SocketConnection acceptConnection() throws IOException {
if (acceptSocket != null) {
logger.info("Socket serverSocket is waiting for incoming connection");
Socket socket = acceptSocket.accept();
return new SocketClientConnection(socket);
} else {
throw new IOException("Connection not openned");
}
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 platform.network;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* Android socket connection
*
* @author amir aharon
*/
public class SocketClientConnection implements SocketConnection {
/**
* Socket connection
*/
private Socket socket = null;
/**
* Constructor
*/
public SocketClientConnection() {
}
/**
* Constructor
*
* @param socket Socket
*/
public SocketClientConnection(Socket socket) {
this.socket = socket;
}
/**
* Open the socket
*
* @param remoteAddr Remote address
* @param remotePort Remote port
* @throws IOException
*/
public void open(String remoteAddr, int remotePort) throws IOException {
socket = new Socket(remoteAddr, remotePort);
}
/**
* Close the socket
*
* @throws IOException
*/
public void close() throws IOException {
if (socket != null) {
socket.close();
socket = null;
}
}
/**
* Returns the socket input stream
*
* @return Input stream
* @throws IOException
*/
public InputStream getInputStream() throws IOException {
if (socket != null) {
return socket.getInputStream();
} else {
throw new IOException("Connection not openned");
}
}
/**
* Returns the socket output stream
*
* @return Output stream
* @throws IOException
*/
public OutputStream getOutputStream() throws IOException {
if (socket != null) {
return socket.getOutputStream();
} else {
throw new IOException("Connection not openned");
}
}
/**
* Returns the remote address of the connection
*
* @return Address
* @throws IOException
*/
public String getRemoteAddress() throws IOException {
if (socket != null) {
return socket.getInetAddress().getHostAddress();
} else {
throw new IOException("Connection not openned");
}
}
/**
* Returns the remote port of the connection
*
* @return Port
* @throws IOException
*/
public int getRemotePort() throws IOException {
if (socket != null) {
return socket.getPort();
} else {
throw new IOException("Connection not openned");
}
}
/**
* Returns the local address of the connection
*
* @return Address
* @throws IOException
*/
public String getLocalAddress() throws IOException {
if (socket != null) {
return socket.getLocalAddress().getHostAddress();
} else {
throw new IOException("Connection not openned");
}
}
/**
* Returns the local port of the connection
*
* @return Port
* @throws IOException
*/
public int getLocalPort() throws IOException {
if (socket != null) {
return socket.getLocalPort();
} else {
throw new IOException("Connection not openned");
}
}
/**
* Get the timeout for this socket during which a reading
* operation shall block while waiting for data
*
* @return Timeout in milliseconds
* @throws IOException
*/
public int getSoTimeout() throws IOException {
if (socket != null) {
return socket.getSoTimeout();
} else {
throw new IOException("Connection not openned");
}
}
/**
* Set the timeout for this socket during which a reading
* operation shall block while waiting for data
*
* @param timeout Timeout in milliseconds
* @throws IOException
*/
public void setSoTimeout(int timeout) throws IOException {
if (socket != null) {
socket.setSoTimeout(timeout);
} else {
throw new IOException("Connection not openned");
}
}
@Override
public void write(byte[] data) throws IOException
{
socket.getOutputStream().write(data);
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 platform.network;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Socket client connection
*
* @author amir aharon
*/
public interface SocketConnection {
/**
* Open the socket
*
* @param remoteAddr Remote address
* @param remotePort Remote port
* @throws IOException
*/
public void open(String remoteAddr, int remotePort) throws IOException;
/**
* Close the socket
*
* @throws IOException
*/
public void close() throws IOException;
/**
* Returns the socket input stream
*
* @return Input stream
* @throws IOException
*/
public InputStream getInputStream() throws IOException;
/**
* Returns the socket output stream
*
* @return Output stream
* @throws IOException
*/
public OutputStream getOutputStream() throws IOException;
public void write(byte[] data) throws IOException;
/**
* Returns the remote address of the connection
*
* @return Address
* @throws IOException
*/
public String getRemoteAddress() throws IOException;
/**
* Returns the remote port of the connection
*
* @return Port
* @throws IOException
*/
public int getRemotePort() throws IOException;
/**
* Returns the local address of the connection
*
* @return Address
* @throws IOException
*/
public String getLocalAddress() throws IOException;
/**
* Returns the local port of the connection
*
* @return Port
* @throws IOException
*/
public int getLocalPort() throws IOException;
/**
* Get the timeout for this socket during which a reading
* operation shall block while waiting for data
*
* @return Milliseconds
* @throws IOException
*/
public int getSoTimeout() throws IOException;
/**
* Set the timeout for this socket during which a reading
* operation shall block while waiting for data
*
* @param timeout Timeout in milliseconds
* @throws IOException
*/
public void setSoTimeout(int timeout) throws IOException;
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 platform.network;
import java.io.IOException;
/**
* Socket server connection
*
* @author amir aharon
*/
public interface SocketServerConnection {
/**
* Open the socket
*
* @param port Local port
* @throws IOException
*/
public void open(int port) throws IOException;
/**
* Close the socket
*
* @throws IOException
*/
public void close() throws IOException;
/**
* Accept connection
*
* @return Socket connection
* @throws IOException
*/
public SocketConnection acceptConnection() throws IOException;
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 provider.messaging;
/**
* Rich messaging history data constants
*
* @author mhsm6403
*/
public class RichMessagingData {
// Database URI
//public static final Uri CONTENT_URI = Uri.parse("content://com.orangelabs.rcs.messaging/messaging");
// Fields for chat
public static final String KEY_ID = "_id";
public static final String KEY_TYPE = "type";
public static final String KEY_CHAT_SESSION_ID = "chat_session_id";
public static final String KEY_TIMESTAMP = "_date";
public static final String KEY_CONTACT = "contact";
public static final String KEY_STATUS = "status";
public static final String KEY_DATA = "_data";
public static final String KEY_MESSAGE_ID = "message_id";
public static final String KEY_IS_SPAM = "is_spam";
public static final String KEY_CHAT_ID = "chat_id";
// Fields for file transfer
public static final String KEY_MIME_TYPE = "mime_type";
public static final String KEY_NAME = "name";
public static final String KEY_SIZE = "size";
public static final String KEY_TOTAL_SIZE = "total_size";
public static final String KEY_NUMBER_MESSAGES ="number_of_messages";
}
package provider.settings;
import java.util.HashMap;
import java.util.Map;
/**
* RCS settings
*
* @author amir
*/
public class RcsSettings {
/**
* Current instance
*/
private static RcsSettings instance = null;
private Map<String,String> mParamsMap = null;
/**
* Create instance
*
* @param ctx Context
*/
public static synchronized void createInstance() {
if (instance == null) {
instance = new RcsSettings();
}
}
/**
* Returns instance
*
* @return Instance
*/
public static RcsSettings getInstance() {
return instance;
}
/**
* Constructor
*
* @param ctx Application context
*/
private RcsSettings() {
mParamsMap = new HashMap<String, String>();
}
/**
* Read a parameter
*
* @param key Key
* @return Value
*/
public String readParameter(String key,String defaultValue) {
if (key == null) {
return null;
}
String result = mParamsMap.get(key);
if (result == null)
result = defaultValue;
return result;
}
/**
* Write a parameter
*
* @param key Key
* @param value Value
*/
public void writeParameter(String key, String value) {
if ((key == null) || (value == null)) {
return;
}
mParamsMap.put(key, value);
}
/**
* Insert a parameter
*
* @param key Key
* @param value Value
*/
public void insertParameter(String key, String value) {
if ((key == null) || (value == null)) {
return;
}
mParamsMap.put(RcsSettingsData.KEY_KEY, key);
mParamsMap.put(RcsSettingsData.KEY_VALUE, value);
}
/**
* Is RCS service activated
*
* @return Boolean
*/
public boolean isServiceActivated() {
boolean result = false;
if (instance != null) {
result = Boolean.parseBoolean(readParameter(RcsSettingsData.SERVICE_ACTIVATED,String.valueOf(result)));
}
return result;
}
/**
* Set the RCS service activation state
*
* @param state State
*/
public void setServiceActivationState(boolean state) {
if (instance != null) {
writeParameter(RcsSettingsData.SERVICE_ACTIVATED, Boolean.toString(state));
}
}
// /**
// * Is RCS service authorized in roaming
// *
// * @return Boolean
// */
// public boolean isRoamingAuthorized() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.ROAMING_AUTHORIZED,String.valueOf(result)));
// }
// return result;
// }
//
// /**
// * Set the roaming authorization state
// *
// * @param state State
// */
// public void setRoamingAuthorizationState(boolean state) {
// if (instance != null) {
// writeParameter(RcsSettingsData.ROAMING_AUTHORIZED, Boolean.toString(state));
// }
// }
//
// /**
// * Get the ringtone for presence invitation
// *
// * @return Ringtone URI or null if there is no ringtone
// */
// public String getPresenceInvitationRingtone() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.PRESENCE_INVITATION_RINGTONE,result);
// }
// return result;
// }
//
// /**
// * Set the presence invitation ringtone
// *
// * @param uri Ringtone URI
// */
// public void setPresenceInvitationRingtone(String uri) {
// if (instance != null) {
// writeParameter(RcsSettingsData.PRESENCE_INVITATION_RINGTONE, uri);
// }
// }
//
// /**
// * Is phone vibrate for presence invitation
// *
// * @return Boolean
// */
// public boolean isPhoneVibrateForPresenceInvitation() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.PRESENCE_INVITATION_VIBRATE,String.valueOf(result)));
// }
// return result;
// }
//
// /**
// * Set phone vibrate for presence invitation
// *
// * @param vibrate Vibrate state
// */
// public void setPhoneVibrateForPresenceInvitation(boolean vibrate) {
// if (instance != null) {
// writeParameter(RcsSettingsData.PRESENCE_INVITATION_VIBRATE, Boolean.toString(vibrate));
// }
// }
//
// /**
// * Get the ringtone for CSh invitation
// *
// * @return Ringtone URI or null if there is no ringtone
// */
// public String getCShInvitationRingtone() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.CSH_INVITATION_RINGTONE,result);
// }
// return result;
// }
//
// /**
// * Set the CSh invitation ringtone
// *
// * @param uri Ringtone URI
// */
// public void setCShInvitationRingtone(String uri) {
// if (instance != null) {
// writeParameter(RcsSettingsData.CSH_INVITATION_RINGTONE, uri);
// }
// }
//
// /**
// * Is phone vibrate for CSh invitation
// *
// * @return Boolean
// */
// public boolean isPhoneVibrateForCShInvitation() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.CSH_INVITATION_VIBRATE,String.valueOf(result)));
// }
// return result;
// }
//
// /**
// * Set phone vibrate for CSh invitation
// *
// * @param vibrate Vibrate state
// */
// public void setPhoneVibrateForCShInvitation(boolean vibrate) {
// if (instance != null) {
// writeParameter(RcsSettingsData.CSH_INVITATION_VIBRATE, Boolean.toString(vibrate));
// }
// }
//
// /**
// * Is phone beep if the CSh available
// *
// * @return Boolean
// */
// public boolean isPhoneBeepIfCShAvailable() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.CSH_AVAILABLE_BEEP,String.valueOf(result)));
// }
// return result;
// }
//
// /**
// * Set phone beep if CSh available
// *
// * @param beep Beep state
// */
// public void setPhoneBeepIfCShAvailable(boolean beep) {
// if (instance != null) {
// writeParameter(RcsSettingsData.CSH_AVAILABLE_BEEP, Boolean.toString(beep));
// }
// }
//
// /**
// * Get the CSh video format
// *
// * @return Video format as string
// */
// public String getCShVideoFormat() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.CSH_VIDEO_FORMAT,result);
// }
// return result;
// }
//
// /**
// * Set the CSh video format
// *
// * @param fmt Video format
// */
// public void setCShVideoFormat(String fmt) {
// if (instance != null) {
// writeParameter(RcsSettingsData.CSH_VIDEO_FORMAT, fmt);
// }
// }
//
// /**
// * Get the CSh video size
// *
// * @return Size (e.g. QCIF, QVGA)
// */
// public String getCShVideoSize() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.CSH_VIDEO_SIZE,result);
// }
// return result;
// }
//
// /**
// * Set the CSh video size
// *
// * @param size Video size
// */
// public void setCShVideoSize(String size) {
// if (instance != null) {
// writeParameter(RcsSettingsData.CSH_VIDEO_SIZE, size);
// }
// }
//
// /**
// * Get the ringtone for file transfer invitation
// *
// * @return Ringtone URI or null if there is no ringtone
// */
// public String getFileTransferInvitationRingtone() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.FILETRANSFER_INVITATION_RINGTONE,result);
// }
// return result;
// }
//
// /**
// * Set the file transfer invitation ringtone
// *
// * @param uri Ringtone URI
// */
// public void setFileTransferInvitationRingtone(String uri) {
// if (instance != null) {
// writeParameter(RcsSettingsData.FILETRANSFER_INVITATION_RINGTONE, uri);
// }
// }
//
// /**
// * Is phone vibrate for file transfer invitation
// *
// * @return Boolean
// */
// public boolean isPhoneVibrateForFileTransferInvitation() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.FILETRANSFER_INVITATION_VIBRATE,String.valueOf(result)));
// }
// return result;
// }
//
// /**
// * Set phone vibrate for file transfer invitation
// *
// * @param vibrate Vibrate state
// */
// public void setPhoneVibrateForFileTransferInvitation(boolean vibrate) {
// if (instance != null) {
// writeParameter(RcsSettingsData.FILETRANSFER_INVITATION_VIBRATE, Boolean.toString(vibrate));
// }
// }
//
// /**
// * Get the ringtone for chat invitation
// *
// * @return Ringtone URI or null if there is no ringtone
// */
// public String getChatInvitationRingtone() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.CHAT_INVITATION_RINGTONE,result);
// }
// return result;
// }
//
// /**
// * Set the chat invitation ringtone
// *
// * @param uri Ringtone URI
// */
// public void setChatInvitationRingtone(String uri) {
// if (instance != null) {
// writeParameter(RcsSettingsData.CHAT_INVITATION_RINGTONE, uri);
// }
// }
//
// /**
// * Is phone vibrate for chat invitation
// *
// * @return Boolean
// */
// public boolean isPhoneVibrateForChatInvitation() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.CHAT_INVITATION_VIBRATE,String.valueOf(result)));
// }
// return result;
// }
//
// /**
// * Set phone vibrate for chat invitation
// *
// * @param vibrate Vibrate state
// */
// public void setPhoneVibrateForChatInvitation(boolean vibrate) {
// if (instance != null) {
// writeParameter(RcsSettingsData.CHAT_INVITATION_VIBRATE, Boolean.toString(vibrate));
// }
// }
//
// /**
// * Get the pre-defined freetext 1
// *
// * @return String
// */
// public String getPredefinedFreetext1() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.FREETEXT1,result);
// }
// return result;
// }
//
// /**
// * Set the pre-defined freetext 1
// *
// * @param txt Text
// */
// public void setPredefinedFreetext1(String txt) {
// if (instance != null) {
// writeParameter(RcsSettingsData.FREETEXT1, txt);
// }
// }
//
// /**
// * Get the pre-defined freetext 2
// *
// * @return String
// */
// public String getPredefinedFreetext2() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.FREETEXT2,result);
// }
// return result;
// }
//
// /**
// * Set the pre-defined freetext 2
// *
// * @param txt Text
// */
// public void setPredefinedFreetext2(String txt) {
// if (instance != null) {
// writeParameter(RcsSettingsData.FREETEXT2, txt);
// }
// }
//
// /**
// * Get the pre-defined freetext 3
// *
// * @return String
// */
// public String getPredefinedFreetext3() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.FREETEXT3,result);
// }
// return result;
// }
//
// /**
// * Set the pre-defined freetext 3
// *
// * @param txt Text
// */
// public void setPredefinedFreetext3(String txt) {
// if (instance != null) {
// writeParameter(RcsSettingsData.FREETEXT3, txt);
// }
// }
//
// /**
// * Get the pre-defined freetext 4
// *
// * @return String
// */
// public String getPredefinedFreetext4() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.FREETEXT4);
// }
// return result;
// }
//
// /**
// * Set the pre-defined freetext 4
// *
// * @param txt Text
// */
// public void setPredefinedFreetext4(String txt) {
// if (instance != null) {
// writeParameter(RcsSettingsData.FREETEXT4, txt);
// }
// }
//
// /**
// * Get user profile username (i.e. username part of the IMPU)
// *
// * @return Username part of SIP-URI
// */
// public String getUserProfileImsUserName() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.USERPROFILE_IMS_USERNAME,result);
// }
// return result;
// }
//
// /**
// * Set user profile IMS username (i.e. username part of the IMPU)
// *
// * @param value Value
// */
// public void setUserProfileImsUserName(String value) {
// if (instance != null) {
// writeParameter(RcsSettingsData.USERPROFILE_IMS_USERNAME, value);
// }
// }
//
/**
* Get user profile IMS display name associated to IMPU
*
* @return String
*/
public String getUserProfileImsDisplayName() {
String result = null;
if (instance != null) {
result = readParameter(RcsSettingsData.USERPROFILE_IMS_DISPLAY_NAME,result);
}
return result;
}
/**
* Set user profile IMS display name associated to IMPU
*
* @param value Value
*/
public void setUserProfileImsDisplayName(String value) {
if (instance != null) {
writeParameter(RcsSettingsData.USERPROFILE_IMS_DISPLAY_NAME, value);
}
}
//
// /**
// * Get user profile IMS private Id (i.e. IMPI)
// *
// * @return SIP-URI
// */
// public String getUserProfileImsPrivateId() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.USERPROFILE_IMS_PRIVATE_ID,result);
// }
// return result;
// }
//
// /**
// * Set user profile IMS private Id (i.e. IMPI)
// *
// * @param uri SIP-URI
// */
// public void setUserProfileImsPrivateId(String uri) {
// if (instance != null) {
// writeParameter(RcsSettingsData.USERPROFILE_IMS_PRIVATE_ID, uri);
// }
// }
//
// /**
// * Get user profile IMS password
// *
// * @return String
// */
// public String getUserProfileImsPassword() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.USERPROFILE_IMS_PASSWORD,result);
// }
// return result;
// }
//
// /**
// * Set user profile IMS password
// *
// * @param pwd Password
// */
// public void setUserProfileImsPassword(String pwd) {
// if (instance != null) {
// writeParameter(RcsSettingsData.USERPROFILE_IMS_PASSWORD, pwd);
// }
// }
//
/**
* Get user profile IMS home domain
*
* @return Domain
*/
public String getUserProfileImsDomain() {
String result = null;
if (instance != null) {
result = readParameter(RcsSettingsData.USERPROFILE_IMS_HOME_DOMAIN,result);
}
return result;
}
/**
* Set user profile IMS home domain
*
* @param domain Domain
*/
public void setUserProfileImsDomain(String domain) {
if (instance != null) {
writeParameter(RcsSettingsData.USERPROFILE_IMS_HOME_DOMAIN, domain);
}
}
// /**
// * Get IMS proxy address for mobile access
// *
// * @return Address
// */
// public String getImsProxyAddrForMobile() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.IMS_PROXY_ADDR_MOBILE,result);
// }
// return result;
// }
//
// /**
// * Set IMS proxy address for mobile access
// *
// * @param addr Address
// */
// public void setImsProxyAddrForMobile(String addr) {
// if (instance != null) {
// writeParameter(RcsSettingsData.IMS_PROXY_ADDR_MOBILE, addr);
// }
// }
//
// /**
// * Get IMS proxy port for mobile access
// *
// * @return Port
// */
// public int getImsProxyPortForMobile() {
// int result = 5060;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.IMS_PROXY_PORT_MOBILE,String.valueOf(result)));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Set IMS proxy port for mobile access
// *
// * @param port Port number
// */
// public void setImsProxyPortForMobile(int port) {
// if (instance != null) {
// writeParameter(RcsSettingsData.IMS_PROXY_PORT_MOBILE, "" + port);
// }
// }
//
// /**
// * Get IMS proxy address for Wi-Fi access
// *
// * @return Address
// */
// public String getImsProxyAddrForWifi() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.IMS_PROXY_ADDR_WIFI,result);
// }
// return result;
// }
//
// /**
// * Set IMS proxy address for Wi-Fi access
// *
// * @param addr Address
// */
// public void setImsProxyAddrForWifi(String addr) {
// if (instance != null) {
// writeParameter(RcsSettingsData.IMS_PROXY_ADDR_WIFI, addr);
// }
// }
//
// /**
// * Get IMS proxy port for Wi-Fi access
// *
// * @return Port
// */
// public int getImsProxyPortForWifi() {
// int result = 5060;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.IMS_PROXY_PORT_WIFI,String.valueOf(result)));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Set IMS proxy port for Wi-Fi access
// *
// * @param port Port number
// */
// public void setImsProxyPortForWifi(int port) {
// if (instance != null) {
// writeParameter(RcsSettingsData.IMS_PROXY_PORT_WIFI, "" + port);
// }
// }
//
// /**
// * Get XDM server address
// *
// * @return Address as <host>:<port>/<root>
// */
// public String getXdmServer() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.XDM_SERVER,result);
// }
// return result;
// }
//
// /**
// * Set XDM server address
// *
// * @param addr Address as <host>:<port>/<root>
// */
// public void setXdmServer(String addr) {
// if (instance != null) {
// writeParameter(RcsSettingsData.XDM_SERVER, addr);
// }
// }
//
// /**
// * Get XDM server login
// *
// * @return String value
// */
// public String getXdmLogin() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.XDM_LOGIN,result);
// }
// return result;
// }
//
// /**
// * Set XDM server login
// *
// * @param value Value
// */
// public void setXdmLogin(String value) {
// if (instance != null) {
// writeParameter(RcsSettingsData.XDM_LOGIN, value);
// }
// }
//
// /**
// * Get XDM server password
// *
// * @return String value
// */
// public String getXdmPassword() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.XDM_PASSWORD,result);
// }
// return result;
// }
//
// /**
// * Set XDM server password
// *
// * @param value Value
// */
// public void setXdmPassword(String value) {
// if (instance != null) {
// writeParameter(RcsSettingsData.XDM_PASSWORD, value);
// }
// }
//
// /**
// * Get IM conference URI
// *
// * @return SIP-URI
// */
// public String getImConferenceUri() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.IM_CONF_URI,result);
// }
// return result;
// }
//
// /**
// * Set IM conference URI
// *
// * @param uri SIP-URI
// */
// public void setImConferenceUri(String uri) {
// if (instance != null) {
// writeParameter(RcsSettingsData.IM_CONF_URI, uri);
// }
// }
//
// /**
// * Get end user confirmation request URI
// *
// * @return SIP-URI
// */
// public String getEndUserConfirmationRequestUri() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.ENDUSER_CONFIRMATION_URI,result);
// }
// return result;
// }
//
// /**
// * Set end user confirmation request
// *
// * @param uri SIP-URI
// */
// public void setEndUserConfirmationRequestUri(String uri) {
// if (instance != null) {
// writeParameter(RcsSettingsData.ENDUSER_CONFIRMATION_URI, uri);
// }
// }
//
/**
* Get country code
*
* @return Country code
*/
public String getCountryCode() {
String result = null;
if (instance != null) {
result = readParameter(RcsSettingsData.COUNTRY_CODE,result);
}
return result;
}
/**
* Set country code
*
* @param code Country code
*/
public void setCountryCode(String code) {
if (instance != null) {
writeParameter(RcsSettingsData.COUNTRY_CODE, code);
}
}
/**
* Get country area code
*
* @return Area code
*/
public String getCountryAreaCode() {
String result = null;
if (instance != null) {
result = readParameter(RcsSettingsData.COUNTRY_AREA_CODE,result);
}
return result;
}
/**
* Set country area code
*
* @param code Area code
*/
public void setCountryAreaCode(String code) {
if (instance != null) {
writeParameter(RcsSettingsData.COUNTRY_AREA_CODE, code);
}
}
// /**
// * Get my capabilities
// *
// * @return capability
// */
// public Capabilities getMyCapabilities(){
// Capabilities capabilities = new Capabilities();
//
// // Add default capabilities
// capabilities.setCsVideoSupport(isCsVideoSupported());
// capabilities.setFileTransferSupport(isFileTransferSupported());
// capabilities.setImageSharingSupport(isImageSharingSupported());
// capabilities.setImSessionSupport(isImSessionSupported());
// capabilities.setPresenceDiscoverySupport(isPresenceDiscoverySupported());
// capabilities.setSocialPresenceSupport(isSocialPresenceSupported());
// capabilities.setVideoSharingSupport(isVideoSharingSupported());
// capabilities.setTimestamp(System.currentTimeMillis());
//
// // Add extensions
// String exts = getSupportedRcsExtensions();
// if ((exts != null) && (exts.length() > 0)) {
// String[] ext = exts.split(",");
// for(int i=0; i < ext.length; i++) {
// capabilities.addSupportedExtension(ext[i]);
// }
// }
//
// return capabilities;
// }
//
// /**
// * Get max photo-icon size
// *
// * @return Size in kilobytes
// */
// public int getMaxPhotoIconSize() {
// int result = 256;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.MAX_PHOTO_ICON_SIZE,String.valueOf(result)));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get max freetext length
// *
// * @return Number of char
// */
// public int getMaxFreetextLength() {
// int result = 100;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.MAX_FREETXT_LENGTH,String.valueOf(result)));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get max number of participants in a group chat
// *
// * @return Number of participants
// */
// public int getMaxChatParticipants() {
// int result = 5;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.MAX_CHAT_PARTICIPANTS,String.valueOf(result)));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get max length of a chat message
// *
// * @return Number of char
// */
// public int getMaxChatMessageLength() {
// int result = 100;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.MAX_CHAT_MSG_LENGTH,String.valueOf(result)));
// } catch(Exception e) {}
// }
// return result;
// }
//
/**
* Get idle duration of a chat session
*
* @return Duration in seconds
*/
public int getChatIdleDuration() {
int result = 120;
if (instance != null) {
try {
result = Integer.parseInt(readParameter(RcsSettingsData.CHAT_IDLE_DURATION,String.valueOf(result)));
} catch(Exception e) {}
}
return result;
}
/**
* Get max file transfer size
*
* @return Size in kilobytes
*/
public int getMaxFileTransferSize() {
int result = 2048;
if (instance != null) {
try {
result = Integer.parseInt(readParameter(RcsSettingsData.MAX_FILE_TRANSFER_SIZE,String.valueOf(result)));
} catch(Exception e) {}
}
return result;
}
//
// /**
// * Get warning threshold for max file transfer size
// *
// * @return Size in kilobytes
// */
// public int getWarningMaxFileTransferSize() {
// int result = 2048;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.WARN_FILE_TRANSFER_SIZE,String.valueOf(result)));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get max image share size
// *
// * @return Size in kilobytes
// */
// public int getMaxImageSharingSize() {
// int result = 2048;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.MAX_IMAGE_SHARE_SIZE,String.valueOf(result)));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get max duration of a video share
// *
// * @return Duration in seconds
// */
// public int getMaxVideoShareDuration() {
// int result = 600;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.MAX_VIDEO_SHARE_DURATION.String.valueOf(result)));
// } catch(Exception e) {}
// }
// return result;
// }
//
public void setMaxChatSessions(int value) {
if (instance != null) {
writeParameter(RcsSettingsData.MAX_CHAT_SESSIONS, String.valueOf(value));
}
}
/**
* Get max number of simultaneous chat sessions
*
* @return Number of sessions
*/
public int getMaxChatSessions() {
int result = 1;
if (instance != null) {
try {
result = Integer.parseInt(readParameter(RcsSettingsData.MAX_CHAT_SESSIONS,String.valueOf(result)));
} catch(Exception e) {}
}
return result;
}
public void setMaxFileTransfer(int value) {
if (instance != null) {
writeParameter(RcsSettingsData.MAX_FILE_TRANSFER_SESSIONS, String.valueOf(value));
}
}
/**
* Get max number of simultaneous file transfer sessions
*
* @return Number of sessions
*/
public int getMaxFileTransferSessions() {
int result = 1;
if (instance != null) {
try {
result = Integer.parseInt(readParameter(RcsSettingsData.MAX_FILE_TRANSFER_SESSIONS,String.valueOf(result)));
} catch(Exception e) {}
}
return result;
}
// /**
// * Is SMS fallback service activated
// *
// * @return Boolean
// */
// public boolean isSmsFallbackServiceActivated() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.SMS_FALLBACK_SERVICE,String.valueOf(result)));
// }
// return result;
// }
//
// /**
// * Is chat invitation auto accepted
// *
// * @return Boolean
// */
// public boolean isChatAutoAccepted(){
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.AUTO_ACCEPT_CHAT,String.valueOf(result)));
// }
// return result;
// }
//
/**
* Is file transfer invitation auto accepted
*
* @return Boolean
*/
public boolean isFileTransferAutoAccepted() {
boolean result = false;
if (instance != null) {
result = Boolean.parseBoolean(readParameter(RcsSettingsData.AUTO_ACCEPT_FILE_TRANSFER,String.valueOf(result)));
}
return result;
}
//
// /**
// * Is Store & Forward service warning activated
// *
// * @return Boolean
// */
// public boolean isStoreForwardWarningActivated() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.WARN_SF_SERVICE,String.valueOf(result)));
// }
// return result;
// }
//
// /**
// * Get IM session start mode
// *
// * @return Integer (1: The 200 OK is sent when the receiver starts to type a message back
// * in the chat window. 2: The 200 OK is sent when the receiver sends a message)
// */
// public int getImSessionStartMode() {
// int result = 1;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.IM_SESSION_START,String.valueOf(result)));
// } catch(Exception e) {}
// }
// return result;
// }
//
/**
* Get max number of entries per contact in the chat log
*
* @return Number
*/
public int getMaxChatLogEntriesPerContact() {
int result = 200;
if (instance != null) {
try {
result = Integer.parseInt(readParameter(RcsSettingsData.MAX_CHAT_LOG_ENTRIES,String.valueOf(result)));
} catch(Exception e) {}
}
return result;
}
//
// /**
// * Get max number of entries per contact in the richcall log
// *
// * @return Number
// */
// public int getMaxRichcallLogEntriesPerContact() {
// int result = 200;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.MAX_RICHCALL_LOG_ENTRIES,String.valueOf(result)));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get polling period used before each IMS service check (e.g. test subscription state for presence service)
// *
// * @return Period in seconds
// */
// public int getImsServicePollingPeriod(){
// int result = 300;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.IMS_SERVICE_POLLING_PERIOD));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get default SIP listening port
// *
// * @return Port
// */
// public int getSipListeningPort() {
// int result = 5060;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.SIP_DEFAULT_PORT));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get default SIP protocol for mobile
// *
// * @return Protocol (udp | tcp | tls)
// */
// public String getSipDefaultProtocolForMobile() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.SIP_DEFAULT_PROTOCOL_FOR_MOBILE);
// }
// return result;
// }
//
// /**
// * Get default SIP protocol for wifi
// *
// * @return Protocol (udp | tcp | tls)
// */
// public String getSipDefaultProtocolForWifi() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.SIP_DEFAULT_PROTOCOL_FOR_WIFI);
// }
// return result;
// }
//
// /**
// * Get TLS Certificate root
// *
// * @return Path of the certificate
// */
// public String getTlsCertificateRoot() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.TLS_CERTIFICATE_ROOT);
// }
// return result;
// }
//
// /**
// * Get TLS Certificate intermediate
// *
// * @return Path of the certificate
// */
// public String getTlsCertificateIntermediate() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.TLS_CERTIFICATE_INTERMEDIATE);
// }
// return result;
// }
//
// /**
// * Get SIP transaction timeout used to wait SIP response
// *
// * @return Timeout in seconds
// */
// public int getSipTransactionTimeout() {
// int result = 30;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.SIP_TRANSACTION_TIMEOUT));
// } catch(Exception e) {}
// }
// return result;
// }
//
/**
* Get default MSRP port
*
* @return Port
*/
public int getDefaultMsrpPort() {
int result = 20000;
if (instance != null) {
try {
result = Integer.parseInt(readParameter(RcsSettingsData.MSRP_DEFAULT_PORT,String.valueOf(result)));
} catch(Exception e) {}
}
return result;
}
//
// /**
// * Get default RTP port
// *
// * @return Port
// */
// public int getDefaultRtpPort() {
// int result = 10000;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.RTP_DEFAULT_PORT));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get MSRP transaction timeout used to wait MSRP response
// *
// * @return Timeout in seconds
// */
public int getMsrpTransactionTimeout() {
int result = 5;
if (instance != null) {
try {
result = Integer.parseInt(readParameter(RcsSettingsData.MSRP_TRANSACTION_TIMEOUT,String.valueOf(result)));
} catch(Exception e) {}
}
return result;
}
//
// /**
// * Get default expire period for REGISTER
// *
// * @return Period in seconds
// */
// public int getRegisterExpirePeriod() {
// int result = 3600;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.REGISTER_EXPIRE_PERIOD));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get registration retry base time
// *
// * @return Time in seconds
// */
// public int getRegisterRetryBaseTime() {
// int result = 30;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.REGISTER_RETRY_BASE_TIME));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get registration retry max time
// *
// * @return Time in seconds
// */
// public int getRegisterRetryMaxTime() {
// int result = 1800;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.REGISTER_RETRY_MAX_TIME));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get default expire period for PUBLISH
// *
// * @return Period in seconds
// */
// public int getPublishExpirePeriod() {
// int result = 3600;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.PUBLISH_EXPIRE_PERIOD));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get revoke timeout before to unrevoke a revoked contact
// *
// * @return Timeout in seconds
// */
// public int getRevokeTimeout() {
// int result = 300;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.REVOKE_TIMEOUT));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get IMS authentication procedure for mobile access
// *
// * @return Authentication procedure
// */
// public String getImsAuhtenticationProcedureForMobile() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.IMS_AUTHENT_PROCEDURE_MOBILE);
// }
// return result;
// }
//
// /**
// * Get IMS authentication procedure for Wi-Fi access
// *
// * @return Authentication procedure
// */
// public String getImsAuhtenticationProcedureForWifi() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.IMS_AUTHENT_PROCEDURE_WIFI);
// }
// return result;
// }
//
/**
* Is Tel-URI format used
*
* @return Boolean
*/
public boolean isTelUriFormatUsed() {
boolean result = false;
if (instance != null) {
result = Boolean.parseBoolean(readParameter(RcsSettingsData.TEL_URI_FORMAT,String.valueOf(result)));
}
return result;
}
/**
* Get ringing period
*
* @return Period in seconds
*/
public int getRingingPeriod() {
int result = 120;
if (instance != null) {
try {
result = Integer.parseInt(readParameter(RcsSettingsData.RINGING_SESSION_PERIOD,String.valueOf(result)));
} catch(Exception e) {}
}
return result;
}
/**
* Get default expire period for SUBSCRIBE
*
* @return Period in seconds
*/
public int getSubscribeExpirePeriod() {
int result = 3600;
if (instance != null) {
try {
result = Integer.parseInt(readParameter(RcsSettingsData.SUBSCRIBE_EXPIRE_PERIOD,String.valueOf(result)));
} catch(Exception e) {}
}
return result;
}
//
// /**
// * Get "Is-composing" timeout for chat service
// *
// * @return Timer in seconds
// */
// public int getIsComposingTimeout() {
// int result = 15;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.IS_COMPOSING_TIMEOUT));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get default expire period for INVITE (session refresh)
// *
// * @return Period in seconds
// */
public int getSessionRefreshExpirePeriod() {
int result = 3600;
if (instance != null) {
try {
result = Integer.parseInt(readParameter(RcsSettingsData.SESSION_REFRESH_EXPIRE_PERIOD,String.valueOf(result)));
} catch(Exception e) {}
}
return result;
}
//
// /**
// * Is permanente state mode activated
// *
// * @return Boolean
// */
// public boolean isPermanentStateModeActivated() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.PERMANENT_STATE_MODE));
// }
// return result;
// }
//
// /**
// * Is trace activated
// *
// * @return Boolean
// */
// public boolean isTraceActivated() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.TRACE_ACTIVATED));
// }
// return result;
// }
//
// /**
// * Get trace level
// *
// * @return trace level
// */
// public String getTraceLevel() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.TRACE_LEVEL);
// }
// return result;
// }
//
// /**
// * Is media trace activated
// *
// * @return Boolean
// */
// public boolean isSipTraceActivated() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.SIP_TRACE_ACTIVATED));
// }
// return result;
// }
//
// /**
// * Get SIP trace file
// *
// * @return SIP trace file
// */
// public String getSipTraceFile() {
// String result = "/sdcard/sip.txt";
// if (instance != null) {
// try {
// result = readParameter(RcsSettingsData.SIP_TRACE_FILE);
// } catch(Exception e) {}
// }
// return result;
// }
//
/**
* Is media trace activated
*
* @return Boolean
*/
public boolean isMediaTraceActivated() {
boolean result = false;
if (instance != null) {
result = Boolean.parseBoolean(readParameter(RcsSettingsData.MEDIA_TRACE_ACTIVATED,String.valueOf(result)));
}
return result;
}
//
// /**
// * Get capability refresh timeout used to avoid too many requests in a short time
// *
// * @return Timeout in seconds
// */
// public int getCapabilityRefreshTimeout() {
// int result = 1;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.CAPABILITY_REFRESH_TIMEOUT));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get capability expiry timeout used to decide when to refresh contact capabilities
// *
// * @return Timeout in seconds
// */
// public int getCapabilityExpiryTimeout() {
// int result = 3600;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.CAPABILITY_EXPIRY_TIMEOUT));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get capability polling period used to refresh contacts capabilities
// *
// * @return Timeout in seconds
// */
// public int getCapabilityPollingPeriod() {
// int result = 3600;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.CAPABILITY_POLLING_PERIOD));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Is CS video supported
// *
// * @return Boolean
// */
// public boolean isCsVideoSupported() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.CAPABILITY_CS_VIDEO));
// }
// return result;
// }
//
/**
* Is file transfer supported
*
* @return Boolean
*/
public boolean isFileTransferSupported() {
boolean result = false;
if (instance != null) {
result = Boolean.parseBoolean(readParameter(RcsSettingsData.CAPABILITY_FILE_TRANSFER,String.valueOf(result)));
}
return result;
}
/**
* Is IM session supported
*
* @return Boolean
*/
public boolean isImSessionSupported() {
boolean result = true;
if (instance != null) {
result = Boolean.parseBoolean(readParameter(RcsSettingsData.CAPABILITY_IM_SESSION,String.valueOf(result)));
}
return result;
}
/**
* Is image sharing supported
*
* @return Boolean
*/
public boolean isImageSharingSupported() {
boolean result = false;
if (instance != null) {
result = Boolean.parseBoolean(readParameter(RcsSettingsData.CAPABILITY_IMAGE_SHARING,String.valueOf(result)));
}
return result;
}
/**
* Is video sharing supported
*
* @return Boolean
*/
public boolean isVideoSharingSupported() {
boolean result = false;
if (instance != null) {
result = Boolean.parseBoolean(readParameter(RcsSettingsData.CAPABILITY_VIDEO_SHARING,String.valueOf(result)));
}
return result;
}
//
// /**
// * Is presence discovery supported
// *
// * @return Boolean
// */
// public boolean isPresenceDiscoverySupported() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.CAPABILITY_PRESENCE_DISCOVERY));
// }
// return result;
// }
//
// /**
// * Is social presence supported
// *
// * @return Boolean
// */
// public boolean isSocialPresenceSupported() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.CAPABILITY_SOCIAL_PRESENCE));
// }
// return result;
// }
//
// /**
// * Get supported RCS extensions
// *
// * @return List of extensions (semicolon separated)
// */
// public String getSupportedRcsExtensions() {
// String result = null;
// if (instance != null) {
// return readParameter(RcsSettingsData.CAPABILITY_RCS_EXTENSIONS);
// }
// return result;
// }
//
// /**
// * Set supported RCS extensions
// *
// * @param extensions List of extensions (semicolon separated)
// */
// public void setSupportedRcsExtensions(String extensions) {
// if (instance != null) {
// writeParameter(RcsSettingsData.CAPABILITY_RCS_EXTENSIONS, extensions);
// }
// }
//
// /**
// * Is IM always-on thanks to the Store & Forward functionality
// *
// * @return Boolean
// */
// public boolean isImAlwaysOn() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.IM_CAPABILITY_ALWAYS_ON));
// }
// return result;
// }
//
/**
* Is IM reports activated
*
* @return Boolean
*/
public boolean isImReportsActivated() {
boolean result = false;
if (instance != null) {
result = Boolean.parseBoolean(readParameter(RcsSettingsData.IM_USE_REPORTS,String.valueOf(result)));
}
return result;
}
//
// /**
// * Get network access
// *
// * @return Network type
// */
// public int getNetworkAccess() {
// int result = RcsSettingsData.ANY_ACCESS;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.NETWORK_ACCESS));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get SIP timer T1
// *
// * @return Timer in milliseconds
// */
// public int getSipTimerT1() {
// int result = 2000;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.SIP_TIMER_T1));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get SIP timer T2
// *
// * @return Timer in milliseconds
// */
// public int getSipTimerT2() {
// int result = 16000;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.SIP_TIMER_T2));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get SIP timer T4
// *
// * @return Timer in milliseconds
// */
// public int getSipTimerT4() {
// int result = 17000;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.SIP_TIMER_T4));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Is SIP keep-alive enabled
// *
// * @return Boolean
// */
// public boolean isSipKeepAliveEnabled() {
// boolean result = true;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.SIP_KEEP_ALIVE));
// }
// return result;
// }
//
// /**
// * Get SIP keep-alive period
// *
// * @return Period in seconds
// */
// public int getSipKeepAlivePeriod() {
// int result = 60;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.SIP_KEEP_ALIVE_PERIOD));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Get APN used to connect to RCS platform
// *
// * @return APN (null means any APN may be used to connect to RCS)
// */
// public String getNetworkApn() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.RCS_APN);
// }
// return result;
// }
//
// /**
// * Get operator authorized to connect to RCS platform
// *
// * @return SIM operator name (null means any SIM operator is authorized to connect to RCS)
// */
// public String getNetworkOperator() {
// String result = null;
// if (instance != null) {
// result = readParameter(RcsSettingsData.RCS_OPERATOR);
// }
// return result;
// }
//
// /**
// * Is GRUU supported
// *
// * @return Boolean
// */
// public boolean isGruuSupported() {
// boolean result = true;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.GRUU));
// }
// return result;
// }
//
// /**
// * Is CPU Always_on activated
// *
// * @return Boolean
// */
// public boolean isCpuAlwaysOn() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.CPU_ALWAYS_ON));
// }
// return result;
// }
//
// /**
// * Get auto configuration mode
// *
// * @return Mode
// */
// public int getAutoConfigMode() {
// int result = RcsSettingsData.NO_AUTO_CONFIG;
// if (instance != null) {
// try {
// result = Integer.parseInt(readParameter(RcsSettingsData.AUTO_CONFIG_MODE));
// } catch(Exception e) {}
// }
// return result;
// }
//
// /**
// * Is Terms and conditions via provisioning is accepted
// *
// * @return Boolean
// */
// public boolean isProvisioningTermsAccepted() {
// boolean result = false;
// if (instance != null) {
// result = Boolean.parseBoolean(readParameter(RcsSettingsData.PROVISIONING_TERMS_ACCEPTED));
// }
// return result;
// }
//
// /**
// * Get provisioning version
// *
// * @return Version
// */
// public String getProvisioningVersion() {
// String result = "0";
// if (instance != null) {
// result = readParameter(RcsSettingsData.PROVISIONING_VERSION);
// }
// return result;
// }
//
// /**
// * Set provisioning version
// *
// * @param version Version
// */
// public void setProvisioningVersion(String version) {
// if (instance != null) {
// writeParameter(RcsSettingsData.PROVISIONING_VERSION, version);
// }
// }
//
// /**
// * Set Terms and conditions via provisioning accepted
// *
// * @param state State
// */
// public void setProvisioningTermsAccepted(boolean state) {
// if (instance != null) {
// writeParameter(RcsSettingsData.PROVISIONING_TERMS_ACCEPTED,
// Boolean.toString(state));
// }
// }
//
// /**
// * Reset user profile settings
// */
// public void resetUserProfile() {
// setUserProfileImsUserName("");
// setUserProfileImsDomain("");
// setUserProfileImsPassword("");
// setImsProxyAddrForMobile("");
// setImsProxyAddrForWifi("");
// setUserProfileImsDisplayName("");
// setUserProfileImsPrivateId("");
// setXdmLogin("");
// setXdmPassword("");
// setXdmServer("");
// setProvisioningVersion("0");
// }
//
// /**
// * Is user profile configured
// *
// * @return Returns true if the configuration is valid
// */
// public boolean isUserProfileConfigured() {
// // Check platform settings
// if (TextUtils.isEmpty(getImsProxyAddrForMobile())) {
// return false;
// }
//
// // Check user profile settings
// if (TextUtils.isEmpty(getUserProfileImsDomain())) {
// return false;
// }
// String mode = RcsSettings.getInstance().getImsAuhtenticationProcedureForMobile();
// if (mode.equals(RcsSettingsData.DIGEST_AUTHENT)) {
// if (TextUtils.isEmpty(getUserProfileImsUserName())) {
// return false;
// }
// if (TextUtils.isEmpty(getUserProfileImsPassword())) {
// return false;
// }
// if (TextUtils.isEmpty(this.getUserProfileImsPrivateId())) {
// return false;
// }
// }
//
// return true;
// }
//
// /**
// * Is group chat activated
// *
// * @return Boolean
// */
// public boolean isGroupChatActivated() {
// boolean result = false;
// if (instance != null) {
// String value = getImConferenceUri();
// if ((value != null) && (value.length() > 0) && !value.equals("sip:foo@bar")) {
// result = true;
// }
// }
// return result;
// }
//
// /**
// * Backup account settings
// *
// * @param account Account
// */
// public void backupAccountSettings(String account) {
// try {
// String packageName = "com.orangelabs.rcs";
// String dbFile = Environment.getDataDirectory() + "/data/" + packageName + "/databases/" + RcsSettingsProvider.DATABASE_NAME;
// String backupFile = Environment.getDataDirectory() + "/data/" + packageName + "/databases/" + account + ".db";
//
// OutputStream outStream = new FileOutputStream(backupFile);
// InputStream inStream = new FileInputStream(dbFile);
// byte[] buffer = new byte[1024];
// int length;
// while ((length = inStream.read(buffer))>0) {
// outStream.write(buffer, 0, length);
// }
// outStream.flush();
// outStream.close();
// inStream.close();
// } catch(Exception e) {
// e.printStackTrace();
// }
// }
//
// /**
// * Restore account settings
// *
// * @param account Account
// */
// public void restoreAccountSettings(String account) {
// try {
// String packageName = "com.orangelabs.rcs";
// String dbFile = Environment.getDataDirectory() + "/data/" + packageName + "/databases/" + RcsSettingsProvider.DATABASE_NAME;
// String restoreFile = Environment.getDataDirectory() + "/data/" + packageName + "/databases/" + account + ".db";
//
// File file = new File(restoreFile);
// if (!file.exists()) {
// return;
// }
//
// OutputStream outStream = new FileOutputStream(dbFile);
// InputStream inStream = new FileInputStream(file);
// byte[] buffer = new byte[1024];
// int length;
// while ((length = inStream.read(buffer))>0) {
// outStream.write(buffer, 0, length);
// }
// outStream.flush();
// outStream.close();
// inStream.close();
// } catch(Exception e) {
// e.printStackTrace();
// }
// }
public void setLocalIpAddress(String localIpAddress) {
if (instance != null) {
writeParameter(RcsSettingsData.LOCAL_IP_ADDRESS, localIpAddress);
}
}
public String getLocalIpAddress() {
String result = "127.0.0.1";
if (instance != null) {
try {
result = readParameter(RcsSettingsData.LOCAL_IP_ADDRESS,result);
} catch(Exception e) {}
}
return result;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 provider.settings;
/**
* RCS settings data constants
*
* @author amir aharon
*/
public class RcsSettingsData {
/**
* Database URI
*/
// static final Uri CONTENT_URI = Uri.parse("content://com.orangelabs.rcs.settings/settings");
/**
* Column name
*/
static final String KEY_ID = "_id";
/**
* Column name
*/
static final String KEY_KEY = "key";
/**
* Column name
*/
static final String KEY_VALUE = "value";
// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------
/**
* Boolean value "true"
*/
public static final String TRUE = Boolean.toString(true);
/**
* Boolean value "false"
*/
public static final String FALSE = Boolean.toString(false);
/**
* GIBA authentication
*/
public static final String GIBA_AUTHENT = "GIBA";
/**
* HTTP Digest authentication
*/
public static final String DIGEST_AUTHENT = "DIGEST";
/**
* Any access
*/
public static final int ANY_ACCESS = -1;
/**
* Mobile access
*/
// public static final int MOBILE_ACCESS = ConnectivityManager.TYPE_MOBILE;
/**
* Wi-Fi access
*/
// public static final int WIFI_ACCESS = ConnectivityManager.TYPE_WIFI;
/**
* Folder path for certificate
*/
public static final String CERTIFICATE_FOLDER_PATH = "/sdcard/";
/**
* File type for certificate
*/
public static final String CERTIFICATE_FILE_TYPE = ".crt";
/**
* No auto config mode
*/
public static final int NO_AUTO_CONFIG = 0;
/**
* HTTPS auto config mode
*/
public static final int HTTPS_AUTO_CONFIG = 1;
// ---------------------------------------------------------------------------
// UI settings
// ---------------------------------------------------------------------------
/**
* Activate or not the RCS service
*/
public static final String SERVICE_ACTIVATED = "ServiceActivated";
/**
* Roaming authorization parameter which indicates if the RCS service may be used or not in roaming
*/
public static final String ROAMING_AUTHORIZED = "RoamingAuthorized";
/**
* Ringtone which is played when a social presence sharing invitation is received
*/
public static final String PRESENCE_INVITATION_RINGTONE = "PresenceInvitationRingtone";
/**
* Vibrate or not when a social presence sharing invitation is received
*/
public static final String PRESENCE_INVITATION_VIBRATE = "PresenceInvitationVibrate";
/**
* Ringtone which is played when a content sharing invitation is received
*/
public static final String CSH_INVITATION_RINGTONE = "CShInvitationRingtone";
/**
* Vibrate or not when a content sharing invitation is received
*/
public static final String CSH_INVITATION_VIBRATE = "CShInvitationVibrate";
/**
* Make a beep or not when content sharing is available during a call
*/
public static final String CSH_AVAILABLE_BEEP = "CShAvailableBeep";
/**
* Video format for video share
*/
public static final String CSH_VIDEO_FORMAT = "CShVideoFormat";
/**
* Video size for video share
*/
public static final String CSH_VIDEO_SIZE = "CShVideoSize";
/**
* Ringtone which is played when a file transfer invitation is received
*/
public static final String FILETRANSFER_INVITATION_RINGTONE = "FileTransferInvitationRingtone";
/**
* Vibrate or not when a file transfer invitation is received
*/
public static final String FILETRANSFER_INVITATION_VIBRATE = "FileTransferInvitationVibrate";
/**
* Ringtone which is played when a chat invitation is received
*/
public static final String CHAT_INVITATION_RINGTONE = "ChatInvitationRingtone";
/**
* Vibrate or not when a chat invitation is received
*/
public static final String CHAT_INVITATION_VIBRATE = "ChatInvitationVibrate";
/**
* Predefined freetext
*/
public static final String FREETEXT1 = "Freetext1";
/**
* Predefined freetext
*/
public static final String FREETEXT2 = "Freetext2";
/**
* Predefined freetext
*/
public static final String FREETEXT3 = "Freetext3";
/**
* Predefined freetext
*/
public static final String FREETEXT4 = "Freetext4";
// ---------------------------------------------------------------------------
// Service settings
// ---------------------------------------------------------------------------
/**
* Max photo-icon size
*/
public static final String MAX_PHOTO_ICON_SIZE = "MaxPhotoIconSize";
/**
* Max length of the freetext
*/
public static final String MAX_FREETXT_LENGTH = "MaxFreetextLength";
/**
* Max number of participants in a group chat
*/
public static final String MAX_CHAT_PARTICIPANTS = "MaxChatParticipants";
/**
* Max length of a chat message
*/
public static final String MAX_CHAT_MSG_LENGTH = "MaxChatMessageLength";
/**
* Idle duration of a chat session
*/
public static final String CHAT_IDLE_DURATION = "ChatIdleDuration";
/**
* Max size of a file transfer
*/
public static final String MAX_FILE_TRANSFER_SIZE = "MaxFileTransferSize";
/**
* Warning threshold for file transfer size
*/
public static final String WARN_FILE_TRANSFER_SIZE = "WarnFileTransferSize";
/**
* Max size of an image share
*/
public static final String MAX_IMAGE_SHARE_SIZE = "MaxImageShareSize";
/**
* Max duration of a video share
*/
public static final String MAX_VIDEO_SHARE_DURATION = "MaxVideoShareDuration";
/**
* Max number of simultaneous chat sessions
*/
public static final String MAX_CHAT_SESSIONS = "MaxChatSessions";
/**
* Max number of simultaneous file transfer sessions
*/
public static final String MAX_FILE_TRANSFER_SESSIONS = "MaxFileTransferSessions";
/**
* Activate or not SMS fallback service
*/
public static final String SMS_FALLBACK_SERVICE = "SmsFallbackService";
/**
* Auto accept file transfer invitation
*/
public static final String AUTO_ACCEPT_FILE_TRANSFER = "AutoAcceptFileTransfer";
/**
* Auto accept chat invitation
*/
public static final String AUTO_ACCEPT_CHAT = "AutoAcceptChat";
/**
* Display a warning if Store & Forward service is activated
*/
public static final String WARN_SF_SERVICE = "StoreForwardServiceWarning";
/**
* Define when the chat receiver sends the 200 OK back to the sender
*/
public static final String IM_SESSION_START = "ImSessionStart";
/**
* Max entries for chat log
*/
public static final String MAX_CHAT_LOG_ENTRIES = "MaxChatLogEntries";
/**
* Max entries for richcall log
*/
public static final String MAX_RICHCALL_LOG_ENTRIES = "MaxRichcallLogEntries";
// ---------------------------------------------------------------------------
// User profile settings
// ---------------------------------------------------------------------------
/**
* IMS username or username part of the IMPU (for HTTP Digest only)
*/
public static final String USERPROFILE_IMS_USERNAME = "ImsUsername";
/**
* IMS display name
*/
public static final String USERPROFILE_IMS_DISPLAY_NAME = "ImsDisplayName";
/**
* IMS private URI or IMPI (for HTTP Digest only)
*/
public static final String USERPROFILE_IMS_PRIVATE_ID = "ImsPrivateId";
/**
* IMS password (for HTTP Digest only)
*/
public static final String USERPROFILE_IMS_PASSWORD = "ImsPassword";
/**
* IMS home domain (for HTTP Digest only)
*/
public static final String USERPROFILE_IMS_HOME_DOMAIN = "ImsHomeDomain";
/**
* P-CSCF or outbound proxy address for mobile access
*/
public static final String IMS_PROXY_ADDR_MOBILE = "ImsOutboundProxyAddrForMobile";
/**
* P-CSCF or outbound proxy port for mobile access
*/
public static final String IMS_PROXY_PORT_MOBILE = "ImsOutboundProxyPortForMobile";
/**
* P-CSCF or outbound proxy address for Wi-Fi access
*/
public static final String IMS_PROXY_ADDR_WIFI = "ImsOutboundProxyAddrForWifi";
/**
* P-CSCF or outbound proxy port for Wi-Fi access
*/
public static final String IMS_PROXY_PORT_WIFI = "ImsOutboundProxyPortForWifi";
/**
* XDM server address & port
*/
public static final String XDM_SERVER = "XdmServerAddr";
/**
* XDM server login (for HTTP Digest only)
*/
public static final String XDM_LOGIN= "XdmServerLogin";
/**
* XDM server password (for HTTP Digest only)
*/
public static final String XDM_PASSWORD = "XdmServerPassword";
/**
* IM conference URI for group chat session
*/
public static final String IM_CONF_URI = "ImConferenceUri";
/**
* End user confirmation request URI for terms and conditions
*/
public static final String ENDUSER_CONFIRMATION_URI = "EndUserConfReqUri";
/**
* Country code
*/
public static final String COUNTRY_CODE = "CountryCode";
/**
* Country area code
*/
public static final String COUNTRY_AREA_CODE = "CountryAreaCode";
// ---------------------------------------------------------------------------
// Stack settings
// ---------------------------------------------------------------------------
/**
* Polling period used before each IMS service check (e.g. test subscription state for presence service)
*/
public static final String IMS_SERVICE_POLLING_PERIOD = "ImsServicePollingPeriod";
/**
* Default SIP port
*/
public static final String SIP_DEFAULT_PORT = "SipListeningPort";
/**
* Default SIP protocol
*/
public static final String SIP_DEFAULT_PROTOCOL_FOR_MOBILE = "SipDefaultProtocolForMobile";
/**
* Default SIP protocol
*/
public static final String SIP_DEFAULT_PROTOCOL_FOR_WIFI = "SipDefaultProtocolForWifi";
/**
* TLS Certifcate root
*/
public static final String TLS_CERTIFICATE_ROOT = "TlsCertificateRoot";
/**
* TLS Certifcate intermediate
*/
public static final String TLS_CERTIFICATE_INTERMEDIATE = "TlsCertificateIntermediate";
/**
* SIP transaction timeout used to wait a SIP response
*/
public static final String SIP_TRANSACTION_TIMEOUT = "SipTransactionTimeout";
/**
* Default TCP port for MSRP session
*/
public static final String MSRP_DEFAULT_PORT = "DefaultMsrpPort";
/**
* Default UDP port for RTP session
*/
public static final String RTP_DEFAULT_PORT = "DefaultRtpPort";
/**
* MSRP transaction timeout used to wait MSRP response
*/
public static final String MSRP_TRANSACTION_TIMEOUT = "MsrpTransactionTimeout";
/**
* Registration expire period
*/
public static final String REGISTER_EXPIRE_PERIOD = "RegisterExpirePeriod";
/**
* Registration retry base time
*/
public static final String REGISTER_RETRY_BASE_TIME = "RegisterRetryBaseTime";
/**
* Registration retry max time
*/
public static final String REGISTER_RETRY_MAX_TIME = "RegisterRetryMaxTime";
/**
* Publish expire period
*/
public static final String PUBLISH_EXPIRE_PERIOD = "PublishExpirePeriod";
/**
* Revoke timeout
*/
public static final String REVOKE_TIMEOUT = "RevokeTimeout";
/**
* IMS authentication procedure for mobile access
*/
public static final String IMS_AUTHENT_PROCEDURE_MOBILE = "ImsAuhtenticationProcedureForMobile";
/**
* IMS authentication procedure for Wi-Fi access
*/
public static final String IMS_AUTHENT_PROCEDURE_WIFI = "ImsAuhtenticationProcedureForWifi";
/**
* Activate or not Tel-URI format
*/
public static final String TEL_URI_FORMAT = "TelUriFormat";
/**
* Ringing session period. At the end of the period the session is cancelled
*/
public static final String RINGING_SESSION_PERIOD = "RingingPeriod";
/**
* Subscribe expiration timeout
*/
public static final String SUBSCRIBE_EXPIRE_PERIOD = "SubscribeExpirePeriod";
/**
* "Is-composing" timeout for chat service
*/
public static final String IS_COMPOSING_TIMEOUT = "IsComposingTimeout";
/**
* SIP session refresh expire period
*/
public static final String SESSION_REFRESH_EXPIRE_PERIOD = "SessionRefreshExpirePeriod";
/**
* Activate or not permanent state mode
*/
public static final String PERMANENT_STATE_MODE = "PermanentState";
/**
* Activate or not the traces
*/
public static final String TRACE_ACTIVATED = "TraceActivated";
/**
* Logger trace level
*/
public static final String TRACE_LEVEL = "TraceLevel";
/**
* Activate or not the SIP trace
*/
public static final String SIP_TRACE_ACTIVATED = "SipTraceActivated";
/**
* SIP trace file
*/
public static final String SIP_TRACE_FILE = "SipTraceFile";
/**
* Activate or not the media trace
*/
public static final String MEDIA_TRACE_ACTIVATED = "MediaTraceActivated";
/**
* Capability refresh timeout used to avoid too many requests in a short time
*/
public static final String CAPABILITY_REFRESH_TIMEOUT = "CapabilityRefreshTimeout";
/**
* Capability refresh timeout used to decide when to refresh contact capabilities
*/
public static final String CAPABILITY_EXPIRY_TIMEOUT = "CapabilityExpiryTimeout";
/**
* Polling period used to decide when to refresh contacts capabilities
*/
public static final String CAPABILITY_POLLING_PERIOD = "CapabilityPollingPeriod";
/**
* CS video capability
*/
public static final String CAPABILITY_CS_VIDEO = "CapabilityCsVideo";
/**
* Image sharing capability
*/
public static final String CAPABILITY_IMAGE_SHARING = "CapabilityImageShare";
/**
* Video sharing capability
*/
public static final String CAPABILITY_VIDEO_SHARING = "CapabilityVideoShare";
/**
* Instant Messaging session capability
*/
public static final String CAPABILITY_IM_SESSION = "CapabilityImSession";
/**
* File transfer capability
*/
public static final String CAPABILITY_FILE_TRANSFER = "CapabilityFileTransfer";
/**
* Presence discovery capability
*/
public static final String CAPABILITY_PRESENCE_DISCOVERY = "CapabilityPresenceDiscovery";
/**
* Social presence capability
*/
public static final String CAPABILITY_SOCIAL_PRESENCE = "CapabilitySocialPresence";
/**
* RCS extensions capability
*/
public static final String CAPABILITY_RCS_EXTENSIONS = "CapabilityRcsExtensions";
/**
* Instant messaging is always on (Store & Forward server)
*/
public static final String IM_CAPABILITY_ALWAYS_ON = "ImAlwaysOn";
/**
* Instant messaging use report
*/
public static final String IM_USE_REPORTS = "ImUseReports";
/**
* Network access authorized
*/
public static final String NETWORK_ACCESS = "NetworkAccess";
/**
* SIP stack timer T1
*/
public static final String SIP_TIMER_T1 = "SipTimerT1";
/**
* SIP stack timer T2
*/
public static final String SIP_TIMER_T2 = "SipTimerT2";
/**
* SIP stack timer T4
*/
public static final String SIP_TIMER_T4 = "SipTimerT4";
/**
* Enable SIP keep alive
*/
public static final String SIP_KEEP_ALIVE = "SipKeepAlive";
/**
* SIP keep alive period
*/
public static final String SIP_KEEP_ALIVE_PERIOD = "SipKeepAlivePeriod";
/**
* RCS APN
*/
public static final String RCS_APN = "RcsApn";
/**
* RCS operator
*/
public static final String RCS_OPERATOR = "RcsOperator";
/**
* GRUU support
*/
public static final String GRUU = "GRUU";
/**
* CPU always_on support
*/
public static final String CPU_ALWAYS_ON = "CpuAlwaysOn";
/**
* Auto configuration mode
*/
public static final String AUTO_CONFIG_MODE = "Autoconfig";
/**
* Provisioning terms accepted
*/
public static final String PROVISIONING_TERMS_ACCEPTED = "ProvisioningTermsAccepted";
/**
* Provisioning version
*/
public static final String PROVISIONING_VERSION = "ProvisioningVersion";
/**
* LOCAL_IP_ADDRESS
*/
public static final String LOCAL_IP_ADDRESS = "LocalIpAddress";
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
/**
* Date utility functions
*
* @author amir aharon
*/
public class DateUtils {
/**
* UTC time zone
*/
private static TimeZone UTC = TimeZone.getTimeZone("UTC");
// private static threadLocal<SimpleDateFormat> rfc3339 = new threadLocal<SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ")>;
private static ThreadLocal<SimpleDateFormat> rfc3339Fractional = new ThreadLocal<SimpleDateFormat>(){
@Override
protected SimpleDateFormat initialValue()
{
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");//spec for RFC3339 (with fractional seconds)
}
};
/**
* Encode a long date to string value in Z format (see RFC 3339)
*
* @param date Date in milliseconds
* @return String
*/
public static String encodeDate(long date) {
Date d = new Date(date);
return rfc3339Fractional.get().format(d).replaceAll("(\\d\\d)(\\d\\d)$", "$1:$2");
}
/**
* Decode a string date to long value (see RFC 3339)
*
* @param date Date as string
* @return Milliseconds
* @throws ParseException
*/
public static long decodeDate(String date) {
//SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ss.SZ");
Date d;
long result = 0;
try
{
d = parseRFC3339Date(date);
result = d.getTime();
} catch (ParseException e)
{
}
return result;
}
public static Date parseRFC3339Date(String datestring) throws java.text.ParseException, IndexOutOfBoundsException{
Date d = new Date();
//if there is no time zone, we don't need to do any special parsing.
if(datestring.endsWith("Z")){
try{
d = rfc3339Fractional.get().parse(datestring);
}
catch(java.text.ParseException pe)
{//try again with optional decimals
rfc3339Fractional.get().setLenient(true);
d = rfc3339Fractional.get().parse(datestring);
}
return d;
}
// //step one, split off the timezone.
// String firstpart = datestring.substring(0,datestring.lastIndexOf('-'));
// String secondpart = datestring.substring(datestring.lastIndexOf('-'));
//
// //step two, remove the colon from the timezone offset
// secondpart = secondpart.substring(0,secondpart.indexOf(':')) + secondpart.substring(secondpart.indexOf(':')+1);
// datestring = firstpart + secondpart;
try{
d = rfc3339Fractional.get().parse(datestring);
}
catch(java.text.ParseException pe){//try again with optional decimals
rfc3339Fractional.get().setLenient(true);
d = rfc3339Fractional.get().parse(datestring);
}
return d;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 utils;
import java.util.Vector;
/**
* FIFO buffer
*
* @author JM. Auffret
*/
public class FifoBuffer {
/**
* Number of objects in the buffer
*/
private int nbObjects = 0;
/**
* Buffer of objects
*/
private Vector<Object> fifo = new Vector<Object>();
/**
* Add an object in the buffer
*
* @param obj Message
*/
public synchronized void addObject(Object obj) {
fifo.addElement(obj);
nbObjects++;
notifyAll();
}
/**
* Read an object in the buffer. This is a blocking method until an object is read.
*
* @return Object
*/
public synchronized Object getObject() {
Object obj = null;
if (nbObjects == 0) {
try {
wait();
} catch (InterruptedException e) {
// Nothing to do
}
}
if (nbObjects != 0) {
obj = fifo.elementAt(0);
fifo.removeElementAt(0);
nbObjects--;
notifyAll();
}
return obj;
}
/**
* Read an object in the buffer. This is a blocking method until a timeout
* occurs or an object is read.
*
* @param timeout Timeout
* @return Message
*/
public synchronized Object getObject(int timeout) {
Object obj = null;
if (nbObjects == 0) {
try {
wait(timeout);
} catch (InterruptedException e) {
// Nothing to do
}
}
if (nbObjects != 0) {
obj = fifo.elementAt(0);
fifo.removeElementAt(0);
nbObjects--;
notifyAll();
}
return obj;
}
/**
* Close the buffer
*/
public synchronized void close() {
// Free the semaphore
this.notifyAll();
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 utils;
/**
* Unique identifier generator
*
* @author JF. Jestin
*/
public class IdGenerator {
/**
* Every 6 bit are coded using this table (see base64 encoding standard,
* except '/' which was replaced by '_')
*/
private final static char[] CODE_TABLE =
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '_'
};
/**
* The counter which get a new value for each subsequent call of increment()
*/
private static int cyclicCounter = 0;
/**
* How much digits are used for coding the counter, 3 means 3*6 bits,
* that are 18 bits resulting in a max. value of 262144 for the counter which
* seems to be enough.
*/
private final static int N_COUNTERS_CHARS = 3;
/**
* The number of generated characters for the uniq identifier<p>
* System.currentTimeMillis() returns long, but only 42 bit are taken, which
* seems to be enough for more than 100 years after 1970, these 42 bits need
* 7 chars for their coding, the number of chars for the counter is added:
* <pre>maxDigit = 7 + N_COUNTERS_CHARS;</pre>
*/
private final static int MAX_DIGIT = 7 + N_COUNTERS_CHARS;
/**
* The central method to increment the cyclic counter, synchronized to achieve
* a unique value for each subsequent call<p>
* there is no problem if the counter reaches the maximum counter value,
* defined by N_COUNTERS_CHARS, only the right number of bits are taken into
* account for generating the output
*
* @return The new counter value
*/
private static synchronized int increment() {
return cyclicCounter++;
}
/**
* Encode twoumbers into a textual representation using a base64 like coding
* table.
* @param time This should be System.currentTimeMillis
* @param counter The counter value, it is coded into N_COUNTERS_CHARS chars, ie for
* 3 chars we have 18 bit and a max. range of 262144
* @result The converted String containing (7 + N_COUNTERS_CHARS) characters
*/
private static String encode64(long time, int counter) {
char[] result = new char[MAX_DIGIT];
int i, idx;
for (i = 0; i < 7; i++) {
idx = (int) time & 63;
time >>= 6;
result[i] = CODE_TABLE[idx];
}
for (; i < MAX_DIGIT; i++) {
idx = counter & 63;
counter >>= 6;
result[i] = CODE_TABLE[idx];
}
return new String(result);
}
/**
* Get a unique local identifier for each subsequent call
*
* @return Unique identifier
*/
public static synchronized String getIdentifier() {
long time = System.currentTimeMillis();
int counter = -1;
if (N_COUNTERS_CHARS > 0)
counter = increment();
return encode64(time, counter);
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 utils;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* IP address utility functions
*
* @author B. JOGUET
*/
public class IpAddressUtils {
/**
* Extract host address (see RFC4007 and RFC2373)
*
* @param host Host address
* @return Address
*/
public static String extractHostAddress(String host) {
if (host == null) {
return null;
}
// Remove prefix from address
int index = host.indexOf("/");
if (index != -1) {
host = host.substring(0, index);
}
// Remove zone id from address
/*
* RFC4007:
* <address>%<zone_id> where:
* <address> is a literal IPv6 address,
* <zone_id> is a string identifying the zone of the address,
* and `%' is a delimiter character to distinguish between <address> and <zone_id>.
*/
index = host.indexOf("%");
if (index != -1) {
host = host.substring(0, index);
}
return host;
}
/**
* is IPv6 Address
*
* @param ipAddress address
* @return true if IPv6
*/
public static boolean isIPv6(String ipAddress) {
InetAddress addr;
boolean isIPv6 = false;
try {
addr = InetAddress.getByName(ipAddress);
isIPv6 = addr instanceof Inet6Address;
} catch (UnknownHostException e) {
return false;
}
return isIPv6;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 utils;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
/**
* MIME manager
*
* @author amir aharon
*/
public class MimeManager {
/**
* List of supported MIME type per extension
*/
private static Hashtable<String, String> mimeTable = new Hashtable<String, String>();
static {
// Image type
mimeTable.put("jpg", "image/jpeg");
mimeTable.put("jpeg", "image/jpeg");
mimeTable.put("png", "image/png");
mimeTable.put("bmp", "image/bmp");
// Video type
mimeTable.put("3gp", "video/3gpp");
mimeTable.put("mp4", "video/mp4");
mimeTable.put("mp4a", "video/mp4");
mimeTable.put("mpeg4", "video/mp4");
mimeTable.put("mpeg", "video/mpeg");
mimeTable.put("mpg", "video/mpeg");
}
/**
* Is MIME type supported
*
* @param mime MIME-Type
* @return Boolean
*/
public static boolean isMimeTypeSupported(String mime) {
return mimeTable.containsValue(mime);
}
/**
* Returns the supported MIME types
*
* @return List
*/
public static Vector<String> getSupportedMimeTypes() {
Vector<String> result = new Vector<String>();
for (Enumeration<String> e = mimeTable.elements() ; e.hasMoreElements() ;) {
String mime = e.nextElement();
result.addElement(mime);
}
return result;
}
/**
* Returns the supported image MIME types
*
* @return List
*/
public static Vector<String> getSupportedImageMimeTypes() {
Vector<String> result = new Vector<String>();
for (Enumeration<String> e = mimeTable.elements() ; e.hasMoreElements() ;) {
String mime = e.nextElement();
if (mime.startsWith("image") && (!result.contains(mime))) {
result.addElement(mime);
}
}
return result;
}
/**
* Returns the MIME type associated to a given file extension
*
* @param ext File extension
* @return MIME type
*/
public static String getMimeType(String ext) {
return mimeTable.get(ext.toLowerCase());
}
/**
* Returns URL extension
*
* @param url URL
* @return Extension
*/
public static String getFileExtension(String url) {
if ((url != null) && (url.indexOf('.')!=-1)) {
return url.substring(url.lastIndexOf('.')+1);
}
return "";
}
/**
* Returns MIME type extension
*
* @param mime MIME type
* @return Extension
*/
public static String getMimeExtension(String mime) {
if ((mime != null) && (mime.indexOf('/')!=-1)) {
return mime.substring(mime.indexOf('/')+1);
}
return "";
}
/**
* Is a image type
*
* @param mime MIME type
* @return Boolean
*/
public static boolean isImageType(String mime ){
if (mime.toLowerCase().startsWith("image/")){
return true;
} else {
return false;
}
}
/**
* Is a video type
*
* @param mime MIME type
* @return Boolean
*/
public static boolean isVideoType(String mime) {
if (mime.toLowerCase().startsWith("video/")){
return true;
} else {
return false;
}
}
/**
* Is an audio type
*
* @param mime MIME type
* @return Boolean
*/
public static boolean isAudioType(String mime) {
if (mime.toLowerCase().startsWith("audio/")) {
return true;
} else {
return false;
}
}
/**
* Is a text type
*
* @param mime MIME type
* @return Boolean
*/
public static boolean isTextType(String mime) {
if (mime.toLowerCase().startsWith("text/")) {
return true;
} else {
return false;
}
}
/**
* Is an application type
*
* @param mime MIME type
* @return Boolean
*/
public static boolean isApplicationType(String mime) {
if (mime.toLowerCase().startsWith("application/")) {
return true;
} else {
return false;
}
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 utils;
import java.io.IOException;
import platform.network.NetworkFactory;
import platform.network.SocketServerConnection;
import provider.settings.RcsSettings;
/**
* Network ressource manager
*
* @author amir aharon
*/
public class NetworkRessourceManager {
/**
* Default SIP port base
*/
// public static final int DEFAULT_LOCAL_SIP_PORT_BASE = RcsSettings.getInstance().getSipListeningPort();
/**
* Default RTP port base
*/
// public static final int DEFAULT_LOCAL_RTP_PORT_BASE = RcsSettings.getInstance().getDefaultRtpPort();
/**
* Default MSRP port base
*/
public static final int DEFAULT_LOCAL_MSRP_PORT_BASE = RcsSettings.getInstance().getDefaultMsrpPort();
/**
* Generate a default free SIP port number
*
* @return Local SIP port
*/
// public static synchronized int generateLocalSipPort() {
// return generateLocalUdpPort(DEFAULT_LOCAL_SIP_PORT_BASE);
// }
/**
* Generate a default free RTP port number
*
* @return Local RTP port
*/
// public static synchronized int generateLocalRtpPort() {
// return generateLocalUdpPort(DEFAULT_LOCAL_RTP_PORT_BASE);
// }
/**
* Generate a default free MSRP port number
*
* @return Local MSRP port
*/
public static synchronized int generateLocalMsrpPort() {
return generateLocalTcpPort(DEFAULT_LOCAL_MSRP_PORT_BASE);
}
/**
* Generate a free UDP port number from a specific port base
*
* @param portBase UDP port base
* @return Local UDP port
*/
// private static int generateLocalUdpPort(int portBase) {
// int resp = -1;
// int port = portBase;
// while((resp == -1) && (port < Integer.MAX_VALUE)) {
// if (isLocalUdpPortFree(port)) {
// // Free UDP port found
// resp = port;
// } else {
// // +2 needed for RTCP port
// port += 2;
// }
// }
// return resp;
// }
/**
* Test if the given local UDP port is really free (not used by
* other applications)
*
* @param port Port to check
* @return Boolean
*/
// private static boolean isLocalUdpPortFree(int port) {
// boolean res = false;
// try {
// DatagramConnection conn = NetworkFactory.getFactory().createDatagramConnection();
// conn.open(port);
// conn.close();
// res = true;
// } catch(IOException e) {
// res = false;
// }
// return res;
// }
/**
* Generate a free TCP port number
*
* @param portBase TCP port base
* @return Local TCP port
*/
private static int generateLocalTcpPort(int portBase) {
int resp = -1;
int port = portBase;
while(resp == -1) {
if (isLocalTcpPortFree(port)) {
// Free TCP port found
resp = port;
} else {
port++;
}
}
return resp;
}
/**
* Test if the given local TCP port is really free (not used by
* other applications)
*
* @param port Port to check
* @return Boolean
*/
private static boolean isLocalTcpPortFree(int port) {
boolean res = false;
try {
SocketServerConnection conn = NetworkFactory.getFactory().createSocketServerConnection();
conn.open(port);
conn.close();
res = true;
} catch(IOException e) {
res = false;
}
return res;
}
/**
* Is a valid IP address
*
* @param ipAddress IP address
* @return Boolean
*/
public static boolean isValidIpAddress(String ipAddress) {
boolean result = false;
if ((ipAddress != null) &&
(!ipAddress.equals("127.0.0.1")) &&
(!ipAddress.equals("localhost"))) {
result = true;
}
return result;
}
/**
* Convert an IP address to its integer representation
*
* @param addr IP address
* @return Integer
*/
public static int ipToInt(String addr) {
String[] addrArray = addr.split("\\.");
int num = 0;
for (int i=0; i<addrArray.length; i++) {
int power = 3-i;
num += ((Integer.parseInt(addrArray[i])%256 * Math.pow(256,power)));
}
return num;
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 utils;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Logger;
/**
* Periodic refresher
*
* @author JM. Auffret
*/
public abstract class PeriodicRefresher {
/**
* Keep alive manager
*/
private KeepAlive alarmReceiver = new KeepAlive();
// /**
// * Alarm intent
// */
// private PendingIntent alarmIntent;
Timer refreshTimer = new Timer();
/**
* Action
*/
private String action;
/**
* Timer state
*/
private boolean timerStarted = false;
/**
* Polling period
*/
private int pollingPeriod;
/**
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* Constructor
*/
public PeriodicRefresher() {
// Create a unique pending intent
this.action = this.toString(); // Unique action ID
// this.alarmIntent = PendingIntent.getBroadcast(
// AndroidFactory.getApplicationContext(),
// 0,
// new Intent(action),
// 0);
}
/**
* Periodic processing
*/
public abstract void periodicProcessing();
/**
* Start the timer
*
* @param expirePeriod Expiration period in seconds
*/
public void startTimer(int expirePeriod) {
startTimer(expirePeriod, 1.0);
}
/**
* Start the timer
*
* @param expirePeriod Expiration period in seconds
* @param delta Delta to apply on the expire period in percentage
*/
public synchronized void startTimer(int expirePeriod, double delta) {
// Check expire period
if (expirePeriod <= 0) {
// Expire period is null
logger.info("Timer is deactivated");
return;
}
// Calculate the effective refresh period
pollingPeriod = (int)(expirePeriod * delta);
logger.info("Start timer at period=" + pollingPeriod + "s (expiration=" + expirePeriod + "s)");
refreshTimer.schedule(alarmReceiver, pollingPeriod * 1000);
// // Register the alarm receiver
// AndroidFactory.getApplicationContext().registerReceiver(alarmReceiver, new IntentFilter(action));
//
// // Start alarm from now to the expire value
// AlarmManager am = (AlarmManager)AndroidFactory.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
// am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+pollingPeriod*1000, alarmIntent);
// The timer is started
timerStarted = true;
}
/**
* Stop the timer
*/
public synchronized void stopTimer() {
if (!timerStarted) {
// Already stopped
return;
}
logger.info("Stop timer");
// The timer is stopped
timerStarted = false;
refreshTimer.cancel();
// // Cancel alarm
// AlarmManager am = (AlarmManager)AndroidFactory.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
// am.cancel(alarmIntent);
//
// // Unregister the alarm receiver
// AndroidFactory.getApplicationContext().unregisterReceiver(alarmReceiver);
}
/**
* Keep alive manager
*/
private class KeepAlive extends TimerTask {
@Override
public void run()
{
periodicProcessing();
}
}
// private class KeepAlive extends BroadcastReceiver {
// public void onReceive(Context context, Intent intent) {
// Thread t = new Thread() {
// public void run() {
// // Processing
// periodicProcessing();
// }
// };
// t.start();
// }
// }
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 utils;
import provider.settings.RcsSettings;
/**
* Phone utility functions
*
* @author amir aharon
*/
public class PhoneUtils {
/**
* Tel-URI format
*/
private static boolean TEL_URI_SUPPORTED = true;
/**
* Country code
*/
private static String COUNTRY_CODE = "+33";
/**
* Country area code
*/
private static String COUNTRY_AREA_CODE = "0";
/**
* Set the country code
*
* @param context Context
*/
public static synchronized void initialize(/*Context context*/) {
RcsSettings.createInstance(/*context*/);
TEL_URI_SUPPORTED = RcsSettings.getInstance().isTelUriFormatUsed();
COUNTRY_CODE = RcsSettings.getInstance().getCountryCode();
COUNTRY_AREA_CODE = RcsSettings.getInstance().getCountryAreaCode();
}
/**
* Returns the country code
*
* @return Country code
*/
public static String getCountryCode() {
return COUNTRY_CODE;
}
/**
* Format a phone number to international format
*
* @param number Phone number
* @return International number
*/
public static String formatNumberToInternational(String number) {
if (number == null) {
return null;
}
// Remove spaces
number = number.trim();
// Strip all non digits
String phoneNumber = number.replaceAll("#-*+", " ").trim(); // PhoneNumberUtils.stripSeparators(number);
// Format into international
if (phoneNumber.startsWith("00" + COUNTRY_CODE.substring(1))) {
// International format
phoneNumber = COUNTRY_CODE + phoneNumber.substring(4);
} else
if ((COUNTRY_AREA_CODE.length() > 0) && phoneNumber.startsWith(COUNTRY_AREA_CODE)) {
// National number with area code
phoneNumber = COUNTRY_CODE + phoneNumber.substring(COUNTRY_AREA_CODE.length());
} else
if (!phoneNumber.startsWith("+")) {
// National number
phoneNumber = COUNTRY_CODE + phoneNumber;
}
return phoneNumber;
}
/**
* Format a phone number to a SIP URI
*
* @param number Phone number
* @return SIP URI
*/
public static String formatNumberToSipUri(String number) {
if (number == null) {
return null;
}
// Remove spaces
number = number.trim();
// Extract username part
if (number.startsWith("tel:")) {
number = number.substring(4);
} else
if (number.startsWith("sip:")) {
number = number.substring(4, number.indexOf("@"));
}
if (TEL_URI_SUPPORTED) {
// Tel-URI format
return "tel:" + formatNumberToInternational(number);
} else {
// SIP-URI format
return "sip:" + formatNumberToInternational(number) + "@" +
RcsSettings.getInstance().getUserProfileImsDomain() + ";user=phone";
}
}
/**
* Format a phone number to a SIP address
*
* @param number Phone number
* @return SIP address
*/
public static String formatNumberToSipAddress(String number) {
String addr = formatNumberToSipUri(number);
String displayName = RcsSettings.getInstance().getUserProfileImsDisplayName();
if ((displayName != null) && (displayName.length() > 0)) {
addr = "\"" + displayName + "\" <" + addr + ">";
}
return addr;
}
/**
* Extract user part phone number from a SIP-URI or Tel-URI or SIP address
*
* @param uri SIP or Tel URI
* @return Number or null in case of error
*/
public static String extractNumberFromUri(String uri) {
if (uri == null) {
return null;
}
try {
// Extract URI from address
int index0 = uri.indexOf("<");
if (index0 != -1) {
uri = uri.substring(index0+1, uri.indexOf(">", index0));
}
// Extract a Tel-URI
int index1 = uri.indexOf("tel:");
if (index1 != -1) {
uri = uri.substring(index1+4);
}
// Extract a SIP-URI
index1 = uri.indexOf("sip:");
if (index1 != -1) {
int index2 = uri.indexOf("@", index1);
uri = uri.substring(index1+4, index2);
}
// Remove URI parameters
int index2 = uri.indexOf(";");
if (index2 != -1) {
uri = uri.substring(0, index2);
}
// Format the extracted number (username part of the URI)
return formatNumberToInternational(uri);
} catch(Exception e) {
return null;
}
}
/**
* Extract display name from URI
*
* @param uri URI
* @return Display name or null
*/
public static String extractDisplayNameFromUri(String uri) {
if (uri == null) {
return null;
}
try {
int index0 = uri.indexOf("\"");
if (index0 != -1) {
int index1 = uri.indexOf("\"", index0+1);
if (index1 > 0) {
return uri.substring(index0+1, index1);
}
}
return null;
} catch(Exception e) {
return null;
}
}
/**
* Compare phone number between two contacts
*
* @param contact1 First contact
* @param contact2 Second contact
* @return Returns true if numbers are equals
*/
public static boolean compareNumbers(String contact1, String contact2) {
String number1 = PhoneUtils.extractNumberFromUri(contact1);
String number2 = PhoneUtils.extractNumberFromUri(contact2);
if ((number1 == null) || (number2 == null)) {
return false;
}
return number1.equals(number2);
}
}
/*******************************************************************************
* Software Name : RCS IMS Stack
*
* Copyright (C) 2010 France Telecom S.A.
*
* 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 utils;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
/**
* String utility functions
*/
public class StringUtils {
/**
* UTF-8 charset
*/
private final static String CHARSET_UTF8 = "UTF-8";
/**
* Truncate a string to a max length
*
* @param text String to truncate
* @param truncatedLength Max length
* @return Truncated string
*/
public static String truncate(String text, int truncatedLength) {
if (text == null) {
return null;
}
if ((truncatedLength < 0) || (truncatedLength > text.length())) {
return text;
}
return text.substring(0, truncatedLength);
}
/**
* Encode string into UTF-8 string
*
* @param str Input string
* @return Encoded string
*/
public static String encodeUTF8(String str) {
if (str == null) {
return null;
}
try {
return new String(str.getBytes(), CHARSET_UTF8);
} catch (Exception e){
return null;
}
}
/**
* Encode UTF-8 bytes to a string
*
* @param b Input bytes
* @return Decoded string
*/
public static String encodeUTF8(byte[] b) {
if (b == null) {
return null;
}
try {
return new String(b, CHARSET_UTF8);
} catch (Exception e){
return null;
}
}
/**
* Decode UTF-8 bytes to string
*
* @param b Input bytes
* @return Decoded string
*/
public static String decodeUTF8(byte[] b) {
if (b == null) {
return null;
}
try {
return new String(b, CHARSET_UTF8);
} catch(Exception e) {
return null;
}
}
/**
* Decode UTF-8 string to a string
*
* @param str Input string
* @return Decoded string
*/
public static String decodeUTF8(String str) {
if (str == null) {
return null;
}
return decodeUTF8(str.getBytes());
}
/**
* Escape characters for text appearing as XML data, between tags.
*
* The following characters are replaced :
* <br> <
* <br> >
* <br> &
* <br> "
* <br> '
*
* @param text Input text
* @return Encoded string
*/
public static String encodeXML(String text) {
if (text == null) {
return null;
}
final StringBuilder result = new StringBuilder();
final StringCharacterIterator iterator = new StringCharacterIterator(text);
char character = iterator.current();
while (character != CharacterIterator.DONE ){
if (character == '<') {
result.append("&lt;");
}
else if (character == '>') {
result.append("&gt;");
}
else if (character == '\"') {
result.append("&quot;");
}
else if (character == '\'') {
result.append("&#039;");
}
else if (character == '&') {
result.append("&amp;");
}
else {
//the char is not a special one
//add it to the result as is
result.append(character);
}
character = iterator.next();
}
return result.toString();
}
/**
* Decode XML string
*
* @param text Input text
* @return Decoded string
*/
public static String decodeXML(String text) {
if (text == null) {
return null;
}
text = text.replaceAll("&lt;", "<");
text = text.replaceAll("&gt;", ">");
text = text.replaceAll("&quot;", "\"");
text = text.replaceAll("&#039;", "\'");
text = text.replaceAll("&amp;", "&");
return text;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment