/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
*
* 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 net.java.sip.communicator.impl.protocol.jabber.extensions.jingle;
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.colibri.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.jitsimeet.*;
import net.java.sip.communicator.service.protocol.jabber.*;
import org.jivesoftware.smack.provider.*;
import org.xmlpull.v1.*;
/**
* An implementation of a Jingle IQ provider that parses incoming Jingle IQs.
*
* @author Emil Ivov
*/
public class JingleIQProvider implements IQProvider
{
/**
* Creates a new instance of the <tt>JingleIQProvider</tt> and register all
* jingle related extension providers. It is the responsibility of the
* application to register the <tt>JingleIQProvider</tt> itself.
*/
public JingleIQProvider()
{
AbstractSmackInteroperabilityLayer smackInteroperabilityLayer =
AbstractSmackInteroperabilityLayer.getInstance();
//<description/> provider
smackInteroperabilityLayer.addExtensionProvider(
RtpDescriptionPacketExtension.ELEMENT_NAME,
RtpDescriptionPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
<RtpDescriptionPacketExtension>(
RtpDescriptionPacketExtension.class));
//<payload-type/> provider
smackInteroperabilityLayer.addExtensionProvider(
PayloadTypePacketExtension.ELEMENT_NAME,
RtpDescriptionPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
<PayloadTypePacketExtension>(
PayloadTypePacketExtension.class));
//<parameter/> provider
smackInteroperabilityLayer.addExtensionProvider(
ParameterPacketExtension.ELEMENT_NAME,
RtpDescriptionPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
<ParameterPacketExtension>
(ParameterPacketExtension.class));
//<rtp-hdrext/> provider
smackInteroperabilityLayer.addExtensionProvider(
RTPHdrExtPacketExtension.ELEMENT_NAME,
RTPHdrExtPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
<RTPHdrExtPacketExtension>
(RTPHdrExtPacketExtension.class));
// <sctpmap/> provider
smackInteroperabilityLayer.addExtensionProvider(
SctpMapExtension.ELEMENT_NAME,
SctpMapExtension.NAMESPACE,
new SctpMapExtensionProvider());
//<encryption/> provider
smackInteroperabilityLayer.addExtensionProvider(
EncryptionPacketExtension.ELEMENT_NAME,
RtpDescriptionPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
<EncryptionPacketExtension>
(EncryptionPacketExtension.class));
//<zrtp-hash/> provider
smackInteroperabilityLayer.addExtensionProvider(
ZrtpHashPacketExtension.ELEMENT_NAME,
ZrtpHashPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
<ZrtpHashPacketExtension>
(ZrtpHashPacketExtension.class));
//<crypto/> provider
smackInteroperabilityLayer.addExtensionProvider(
CryptoPacketExtension.ELEMENT_NAME,
RtpDescriptionPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
<CryptoPacketExtension>
(CryptoPacketExtension.class));
// <bundle/> provider
smackInteroperabilityLayer.addExtensionProvider(
BundlePacketExtension.ELEMENT_NAME,
BundlePacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
<BundlePacketExtension>
(BundlePacketExtension.class));
// <group/> provider
smackInteroperabilityLayer.addExtensionProvider(
GroupPacketExtension.ELEMENT_NAME,
GroupPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
<GroupPacketExtension>(GroupPacketExtension.class));
//ice-udp transport
smackInteroperabilityLayer.addExtensionProvider(
IceUdpTransportPacketExtension.ELEMENT_NAME,
IceUdpTransportPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
<IceUdpTransportPacketExtension>(
IceUdpTransportPacketExtension.class));
//<raw-udp/> provider
smackInteroperabilityLayer.addExtensionProvider(
RawUdpTransportPacketExtension.ELEMENT_NAME,
RawUdpTransportPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
<RawUdpTransportPacketExtension>(
RawUdpTransportPacketExtension.class));
//ice-udp <candidate/> provider
smackInteroperabilityLayer.addExtensionProvider(
CandidatePacketExtension.ELEMENT_NAME,
IceUdpTransportPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
<CandidatePacketExtension>(
CandidatePacketExtension.class));
//raw-udp <candidate/> provider
smackInteroperabilityLayer.addExtensionProvider(
CandidatePacketExtension.ELEMENT_NAME,
RawUdpTransportPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
<CandidatePacketExtension>(
CandidatePacketExtension.class));
//ice-udp <remote-candidate/> provider
smackInteroperabilityLayer.addExtensionProvider(
RemoteCandidatePacketExtension.ELEMENT_NAME,
IceUdpTransportPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
<RemoteCandidatePacketExtension>(
RemoteCandidatePacketExtension.class));
//inputevt <inputevt/> provider
smackInteroperabilityLayer.addExtensionProvider(
InputEvtPacketExtension.ELEMENT_NAME,
InputEvtPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<InputEvtPacketExtension>(
InputEvtPacketExtension.class));
//coin <conference-info/> provider
smackInteroperabilityLayer.addExtensionProvider(
CoinPacketExtension.ELEMENT_NAME,
CoinPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<CoinPacketExtension>(
CoinPacketExtension.class));
// DTLS-SRTP
smackInteroperabilityLayer.addExtensionProvider(
DtlsFingerprintPacketExtension.ELEMENT_NAME,
DtlsFingerprintPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider
<DtlsFingerprintPacketExtension>(
DtlsFingerprintPacketExtension.class));
/*
* XEP-0251: Jingle Session Transfer <transfer/> and <transferred>
* providers
*/
smackInteroperabilityLayer.addExtensionProvider(
TransferPacketExtension.ELEMENT_NAME,
TransferPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<TransferPacketExtension>(
TransferPacketExtension.class));
smackInteroperabilityLayer.addExtensionProvider(
TransferredPacketExtension.ELEMENT_NAME,
TransferredPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<TransferredPacketExtension>(
TransferredPacketExtension.class));
//conference description <callid/> provider
smackInteroperabilityLayer.addExtensionProvider(
ConferenceDescriptionPacketExtension.CALLID_ELEM_NAME,
ConferenceDescriptionPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<CallIdPacketExtension>(
CallIdPacketExtension.class));
//rtcp-fb
smackInteroperabilityLayer.addExtensionProvider(
RtcpFbPacketExtension.ELEMENT_NAME,
RtcpFbPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<RtcpFbPacketExtension>(
RtcpFbPacketExtension.class));
//rtcp-mux
smackInteroperabilityLayer.addExtensionProvider(
RtcpmuxPacketExtension.ELEMENT_NAME,
IceUdpTransportPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<RtcpmuxPacketExtension>(
RtcpmuxPacketExtension.class));
//web-socket
smackInteroperabilityLayer.addExtensionProvider(
WebSocketPacketExtension.ELEMENT_NAME,
WebSocketPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<>(
WebSocketPacketExtension.class));
//ssrcInfo
smackInteroperabilityLayer.addExtensionProvider(
SSRCInfoPacketExtension.ELEMENT_NAME,
SSRCInfoPacketExtension.NAMESPACE,
new DefaultPacketExtensionProvider<SSRCInfoPacketExtension>(
SSRCInfoPacketExtension.class));
}
/**
* Parses a Jingle IQ sub-document and returns a {@link JingleIQ} instance.
*
* @param parser an XML parser.
*
* @return a new {@link JingleIQ} instance.
*
* @throws Exception if an error occurs parsing the XML.
*/
public JingleIQ parseIQ(XmlPullParser parser)
throws Exception
{
JingleIQ jingleIQ = new JingleIQ();
//let's first handle the "jingle" element params.
JingleAction action = JingleAction.parseString(parser
.getAttributeValue("", JingleIQ.ACTION_ATTR_NAME));
String initiator = parser
.getAttributeValue("", JingleIQ.INITIATOR_ATTR_NAME);
String responder = parser
.getAttributeValue("", JingleIQ.RESPONDER_ATTR_NAME);
String sid = parser
.getAttributeValue("", JingleIQ.SID_ATTR_NAME);
jingleIQ.setAction(action);
jingleIQ.setInitiator(initiator);
jingleIQ.setResponder(responder);
jingleIQ.setSID(sid);
boolean done = false;
// Sub-elements providers
DefaultPacketExtensionProvider<ContentPacketExtension> contentProvider
= new DefaultPacketExtensionProvider<ContentPacketExtension>(
ContentPacketExtension.class);
ReasonProvider reasonProvider = new ReasonProvider();
DefaultPacketExtensionProvider<TransferPacketExtension> transferProvider
= new DefaultPacketExtensionProvider<TransferPacketExtension>(
TransferPacketExtension.class);
DefaultPacketExtensionProvider<CoinPacketExtension> coinProvider
= new DefaultPacketExtensionProvider<CoinPacketExtension>(
CoinPacketExtension.class);
DefaultPacketExtensionProvider<CallIdPacketExtension> callidProvider
= new DefaultPacketExtensionProvider<CallIdPacketExtension>(
CallIdPacketExtension.class);
// Now go on and parse the jingle element's content.
int eventType;
String elementName;
String namespace;
while (!done)
{
eventType = parser.next();
elementName = parser.getName();
namespace = parser.getNamespace();
if (eventType == XmlPullParser.START_TAG)
{
// <content/>
if (elementName.equals(ContentPacketExtension.ELEMENT_NAME))
{
ContentPacketExtension content
= contentProvider.parseExtension(parser);
jingleIQ.addContent(content);
}
// <reason/>
else if(elementName.equals(ReasonPacketExtension.ELEMENT_NAME))
{
ReasonPacketExtension reason
= reasonProvider.parseExtension(parser);
jingleIQ.setReason(reason);
}
// <transfer/>
else if (elementName.equals(
TransferPacketExtension.ELEMENT_NAME)
&& namespace.equals(TransferPacketExtension.NAMESPACE))
{
jingleIQ.addExtension(
transferProvider.parseExtension(parser));
}
else if(elementName.equals(CoinPacketExtension.ELEMENT_NAME))
{
jingleIQ.addExtension(coinProvider.parseExtension(parser));
}
else if (elementName.equals(
ConferenceDescriptionPacketExtension.CALLID_ELEM_NAME))
{
jingleIQ.addExtension(callidProvider.parseExtension(parser));
}
//<mute/> <active/> and other session-info elements
if (namespace.equals( SessionInfoPacketExtension.NAMESPACE))
{
SessionInfoType type = SessionInfoType.valueOf(elementName);
//<mute/>
if( type == SessionInfoType.mute
|| type == SessionInfoType.unmute)
{
String name = parser.getAttributeValue("",
MuteSessionInfoPacketExtension.NAME_ATTR_VALUE);
jingleIQ.setSessionInfo(
new MuteSessionInfoPacketExtension(
type == SessionInfoType.mute, name));
}
//<hold/>, <unhold/>, <active/>, etc.
else
{
jingleIQ.setSessionInfo(
new SessionInfoPacketExtension(type));
}
}
}
if ((eventType == XmlPullParser.END_TAG)
&& parser.getName().equals(JingleIQ.ELEMENT_NAME))
{
done = true;
}
}
return jingleIQ;
}
}