diff --git a/lib/native/windows-64/jmsofficecomm.dll b/lib/native/windows-64/jmsofficecomm.dll
index 8205f5970..af28cc97c 100755
Binary files a/lib/native/windows-64/jmsofficecomm.dll and b/lib/native/windows-64/jmsofficecomm.dll differ
diff --git a/lib/native/windows/jmsofficecomm.dll b/lib/native/windows/jmsofficecomm.dll
index 69d4f0a6e..968465a20 100755
Binary files a/lib/native/windows/jmsofficecomm.dll and b/lib/native/windows/jmsofficecomm.dll differ
diff --git a/src/native/windows/msofficecomm/Messenger.cxx b/src/native/windows/msofficecomm/Messenger.cxx
index 41f42ba71..a24eb498d 100644
--- a/src/native/windows/msofficecomm/Messenger.cxx
+++ b/src/native/windows/msofficecomm/Messenger.cxx
@@ -705,7 +705,7 @@ HRESULT Messenger::start(JNIEnv *env)
= env->GetMethodID(
clazz,
"startConversation",
- "(I[Ljava/lang/String;)V");
+ "(I[Ljava/lang/String;Ljava/lang/String;)V");
if (startConversationMethodID)
{
@@ -744,11 +744,119 @@ Messenger::StartConversation
VARIANT vConversationData,
VARIANT *pvWndHnd)
{
+ JavaVM *vm = OutOfProcessServer::getJavaVM();
+ JNIEnv *env;
+ HRESULT hr;
+
+ if (vm && !(vm->AttachCurrentThreadAsDaemon((void **) &env, NULL)))
+ {
+ jobjectArray participants;
+
+ hr = toStringArray(env, vParticipants, &participants);
+ if (SUCCEEDED(hr))
+ {
+ jstring conversationData;
+
+ hr = toString(env, vConversationData, &conversationData);
+ /*
+ * The MSDN is pretty scarce on the subject of vConversationData
+ * thus we can hardly rely on getting it right.
+ */
+ if (hr == E_INVALIDARG)
+ {
+ conversationData = NULL;
+ hr = S_OK;
+ }
+ if (SUCCEEDED(hr))
+ {
+ if (_jobject)
+ {
+ env->CallVoidMethod(
+ _jobject,
+ _jstartConversationMethodID,
+ (jint) ConversationType,
+ participants,
+ conversationData);
+ }
+ else
+ hr = E_FAIL;
+ }
+ }
+ if (env->ExceptionCheck())
+ {
+ env->ExceptionClear();
+ hr = E_FAIL;
+ }
+ }
+ else
+ hr = E_UNEXPECTED;
+ return hr;
+}
+
+STDMETHODIMP Messenger::StartVideo(VARIANT vContact, IDispatch **ppMWindow)
+ STDMETHODIMP_E_NOTIMPL_STUB
+
+STDMETHODIMP Messenger::StartVoice(VARIANT vContact, IDispatch **ppMWindow)
+ STDMETHODIMP_E_NOTIMPL_STUB
+
+HRESULT Messenger::stop(JNIEnv *env)
+{
+ jclass clazz = _jclass;
+
+ _jclass = NULL;
+ _jctorMethodID = NULL;
+ _jstartConversationMethodID = NULL;
+ if (clazz)
+ env->DeleteGlobalRef(clazz);
+
+ return S_OK;
+}
+
+HRESULT Messenger::toString(JNIEnv *env, VARIANT &v, jstring *string)
+{
+ BSTR bstr;
HRESULT hr;
- if (VT_ARRAY == (vParticipants.vt & VT_ARRAY))
+ if (VT_BSTR == v.vt)
{
- SAFEARRAY *sa = vParticipants.parray;
+ bstr = v.bstrVal;
+ hr = S_OK;
+ }
+ else if ((VT_BSTR | VT_BYREF) == v.vt)
+ {
+ bstr = *(v.pbstrVal);
+ hr = S_OK;
+ }
+ else
+ hr = E_INVALIDARG;
+
+ if (SUCCEEDED(hr))
+ {
+ if (bstr)
+ {
+ jstring _string
+ = env->NewString((const jchar *) bstr, ::SysStringLen(bstr));
+
+ if (_string)
+ *string = _string;
+ else
+ hr = E_OUTOFMEMORY;
+ }
+ else
+ *string = NULL;
+ }
+
+ return hr;
+}
+
+HRESULT
+Messenger::toStringArray(JNIEnv *env, VARIANT &v, jobjectArray *stringArray)
+{
+ HRESULT hr;
+
+ if (VT_ARRAY == (v.vt & VT_ARRAY))
+ {
+ SAFEARRAY *sa = v.parray;
if (sa
&& (1 == sa->cDims)
@@ -759,86 +867,41 @@ Messenger::StartConversation
hr = ::SafeArrayAccessData(sa, (PVOID *) &data);
if (SUCCEEDED(hr))
{
- JavaVM *vm = OutOfProcessServer::getJavaVM();
- JNIEnv *env;
+ jclass stringClass = env->FindClass("java/lang/String");
- if (vm
- && !(vm->AttachCurrentThreadAsDaemon(
- (void **) &env,
- NULL)))
+ if (stringClass)
{
- jclass stringClass = env->FindClass("java/lang/String");
+ SAFEARRAYBOUND *bound = sa->rgsabound;
+ ULONG length = bound->cElements;
+ jobjectArray _stringArray
+ = env->NewObjectArray(length, stringClass, NULL);
- if (stringClass)
+ if (_stringArray)
{
- SAFEARRAYBOUND *bound = sa->rgsabound;
- ULONG length = bound->cElements;
- jobjectArray participants
- = env->NewObjectArray(length, stringClass, NULL);
+ ULONG elemsize = sa->cbElements;
- if (participants)
+ data += bound->lLbound;
+ for (ULONG i = 0; i < length; i++, data += elemsize)
{
- ULONG elemsize = sa->cbElements;
-
- data += bound->lLbound;
- for (ULONG i = 0; i < length; i++, data += elemsize)
- {
- VARIANT *v = (VARIANT *) data;
- BSTR bstr;
-
- if (VT_BSTR == v->vt)
- bstr = v->bstrVal;
- else if ((VT_BSTR | VT_BYREF) == v->vt)
- bstr = *(v->pbstrVal);
- else
- {
- hr = E_INVALIDARG;
- break;
- }
-
- jstring participant
- = env->NewString(
- (const jchar *) bstr,
- ::SysStringLen(bstr));
-
- if (participant)
- {
- env->SetObjectArrayElement(
- participants,
- i,
- participant);
- }
- else
- {
- hr = E_OUTOFMEMORY;
- break;
- }
- }
+ jstring _string;
+ hr = toString(env, *((VARIANT *) data), &_string);
if (SUCCEEDED(hr))
{
- if (_jobject)
- {
- env->CallVoidMethod(
- _jobject,
- _jstartConversationMethodID,
- (jint) ConversationType,
- participants);
- if (env->ExceptionCheck())
- {
- env->ExceptionClear();
- hr = E_FAIL;
- }
- }
- else
- hr = E_FAIL;
+ env->SetObjectArrayElement(
+ _stringArray,
+ i,
+ _string);
}
+ else
+ break;
}
- else
- hr = E_OUTOFMEMORY;
+
+ if (SUCCEEDED(hr))
+ *stringArray = _stringArray;
}
else
- hr = E_UNEXPECTED;
+ hr = E_OUTOFMEMORY;
}
else
hr = E_UNEXPECTED;
@@ -853,24 +916,5 @@ Messenger::StartConversation
return hr;
}
-STDMETHODIMP Messenger::StartVideo(VARIANT vContact, IDispatch **ppMWindow)
- STDMETHODIMP_E_NOTIMPL_STUB
-
-STDMETHODIMP Messenger::StartVoice(VARIANT vContact, IDispatch **ppMWindow)
- STDMETHODIMP_E_NOTIMPL_STUB
-
-HRESULT Messenger::stop(JNIEnv *env)
-{
- jclass clazz = _jclass;
-
- _jclass = NULL;
- _jctorMethodID = NULL;
- _jstartConversationMethodID = NULL;
- if (clazz)
- env->DeleteGlobalRef(clazz);
-
- return S_OK;
-}
-
STDMETHODIMP Messenger::ViewProfile(VARIANT vContact)
STDMETHODIMP_E_NOTIMPL_STUB
diff --git a/src/native/windows/msofficecomm/Messenger.h b/src/native/windows/msofficecomm/Messenger.h
index 7a8051c6a..5eca3e885 100644
--- a/src/native/windows/msofficecomm/Messenger.h
+++ b/src/native/windows/msofficecomm/Messenger.h
@@ -113,6 +113,8 @@ private:
HRESULT createMessengerContact(BSTR signinName, REFIID iid, PVOID *obj);
HRESULT destructJobject();
HRESULT getMessengerContact(BSTR signinName, REFIID iid, PVOID *obj);
+ HRESULT toString(JNIEnv *env, VARIANT &v, jstring *string);
+ HRESULT toStringArray(JNIEnv *env, VARIANT &v, jobjectArray *stringArray);
DMessengerEventsConnectionPoint *_dMessengerEventsConnectionPoint;
jobject _jobject;
diff --git a/src/net/java/sip/communicator/plugin/msofficecomm/Messenger.java b/src/net/java/sip/communicator/plugin/msofficecomm/Messenger.java
index 21319d1e8..831b3724d 100644
--- a/src/net/java/sip/communicator/plugin/msofficecomm/Messenger.java
+++ b/src/net/java/sip/communicator/plugin/msofficecomm/Messenger.java
@@ -21,7 +21,9 @@
import net.java.sip.communicator.service.protocol.yahooconstants.*;
import net.java.sip.communicator.util.*;
+import org.jitsi.util.xml.*;
import org.osgi.framework.*;
+import org.w3c.dom.*;
/**
* Represents the Java counterpart of a native IMessenger
@@ -31,6 +33,12 @@
*/
public class Messenger
{
+ /**
+ * The Logger used by the Messenger class and its
+ * instances for logging output.
+ */
+ private static final Logger logger = Logger.getLogger(Messenger.class);
+
static final int CONVERSATION_TYPE_AUDIO = 8;
static final int CONVERSATION_TYPE_IM = 1;
@@ -653,10 +661,13 @@ public Messenger()
* type of the conversation to be started
* @param participants an array of String values specifying the
* other users to start a conversation with
+ * @param conversationData an XML BLOB specifying the phone numbers to be
+ * dialed in order to start the conversation
*/
public void startConversation(
final int conversationType,
- String[] participants)
+ String[] participants,
+ String conversationData)
{
/*
* Firstly, resolve the participants into Contacts which may include
@@ -670,10 +681,103 @@ public void startConversation(
case CONVERSATION_TYPE_PHONE:
case CONVERSATION_TYPE_PSTN:
opSetClass = OperationSetBasicTelephony.class;
+
+ if ((conversationData != null) && (conversationData.length() != 0))
+ {
+ if (logger.isTraceEnabled())
+ {
+ logger.trace(
+ "conversationData = \"" + conversationData + "\"");
+ }
+
+ // According to MSDN, vConversationData could be an XML BLOB.
+ if (conversationData.startsWith("<"))
+ {
+ try
+ {
+ Document document
+ = XMLUtils.createDocument(conversationData);
+ Element documentElement = document.getDocumentElement();
+
+ if ("TelURIs".equalsIgnoreCase(
+ documentElement.getTagName()))
+ {
+ NodeList childNodes
+ = documentElement.getChildNodes();
+
+ if (childNodes != null)
+ {
+ int childNodeCount = childNodes.getLength();
+ List phoneNumbers
+ = new ArrayList(childNodeCount);
+
+ for (int childNodeIndex = 0;
+ childNodeIndex < childNodeCount;
+ childNodeIndex++)
+ {
+ Node childNode
+ = childNodes.item(childNodeIndex);
+
+ if (childNode.getNodeType()
+ == Node.ELEMENT_NODE)
+ {
+ phoneNumbers.add(
+ childNode.getTextContent());
+ }
+ }
+
+ int count = participants.length;
+
+ if (phoneNumbers.size() == count)
+ {
+ for (int i = 0; i < count; i++)
+ {
+ String phoneNumber
+ = phoneNumbers.get(i);
+
+ if ((phoneNumber != null)
+ && (phoneNumber.length() != 0))
+ {
+ if (phoneNumber
+ .toLowerCase()
+ .startsWith("tel:"))
+ {
+ phoneNumber
+ = phoneNumber.substring(4);
+ }
+ participants[i] = phoneNumber;
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ logger.error(
+ "Failed to parse"
+ + " IMessengerAdvanced::StartConversation"
+ + " vConversationData: "
+ + conversationData,
+ e);
+ }
+ }
+ else
+ {
+ /*
+ * Practice/testing shows that vConversationData is the
+ * phone number in the case of a single participant.
+ */
+ if (participants.length == 1)
+ participants[0] = conversationData;
+ }
+ }
+
break;
case CONVERSATION_TYPE_IM:
opSetClass = OperationSetBasicInstantMessaging.class;
break;
+
default:
throw new UnsupportedOperationException();
}