mirror of https://github.com/sipwise/jitsi.git
parent
b95675bb3d
commit
3d232caf52
@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.protocol.jabber.extensions.gtalk;
|
||||
|
||||
import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
|
||||
|
||||
/**
|
||||
* Google Talk version of Candidate packet extension.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class GTalkCandidatePacketExtension
|
||||
extends CandidatePacketExtension
|
||||
{
|
||||
/**
|
||||
* Address attribute name.
|
||||
*/
|
||||
public static final String ADDRESS_ATTR_NAME = "address";
|
||||
|
||||
/**
|
||||
* The name of the "preference" element.
|
||||
*/
|
||||
public static final String PREFERENCE_ATTR_NAME = "preference";
|
||||
|
||||
/**
|
||||
* Name attribute name.
|
||||
*/
|
||||
public static final String NAME_ATTR_NAME = "name";
|
||||
|
||||
/**
|
||||
* Username attribute name.
|
||||
*/
|
||||
public static final String USERNAME_ATTR_NAME = "username";
|
||||
|
||||
/**
|
||||
* Password attribute name.
|
||||
*/
|
||||
public static final String PASSWORD_ATTR_NAME = "password";
|
||||
|
||||
/**
|
||||
* Name for candidate audio RTP.
|
||||
*/
|
||||
public static final String AUDIO_RTP_NAME = "rtp";
|
||||
|
||||
/**
|
||||
* Name for candidate audio RTCP.
|
||||
*/
|
||||
public static final String AUDIO_RTCP_NAME = "rtcp";
|
||||
|
||||
/**
|
||||
* Name for candidate video RTP.
|
||||
*/
|
||||
public static final String VIDEO_RTP_NAME = "video_rtp";
|
||||
|
||||
/**
|
||||
* Name for candidate video RTCP.
|
||||
*/
|
||||
public static final String VIDEO_RTCP_NAME = "video_rtcp";
|
||||
|
||||
/**
|
||||
* Constructs a new <tt>GTalkCandidatePacketExtension</tt>.
|
||||
*/
|
||||
public GTalkCandidatePacketExtension()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a Candidate Type as defined in ICE-CORE.
|
||||
*
|
||||
* @param type this candidates' type as per ICE's Google dialect.
|
||||
*/
|
||||
public void setType(String type)
|
||||
{
|
||||
super.setAttribute(TYPE_ATTR_NAME, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this candidate's name.
|
||||
*
|
||||
* @param name this candidate's name
|
||||
*/
|
||||
public void setName(String name)
|
||||
{
|
||||
super.setAttribute(NAME_ATTR_NAME, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this candidate's name.
|
||||
*
|
||||
* @return this candidate's name
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return super.getAttributeAsString(NAME_ATTR_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this candidate's preference.
|
||||
*
|
||||
* @param preference this candidate's preference
|
||||
*/
|
||||
public void setPreference(double preference)
|
||||
{
|
||||
super.setAttribute(PREFERENCE_ATTR_NAME, Double.toString((preference)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this candidate's preference.
|
||||
*
|
||||
* @return this candidate's preference
|
||||
*/
|
||||
public double getPreference()
|
||||
{
|
||||
return Float.parseFloat(
|
||||
super.getAttributeAsString(PREFERENCE_ATTR_NAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this candidate's username.
|
||||
*
|
||||
* @param username this candidate's username
|
||||
*/
|
||||
public void setUsername(String username)
|
||||
{
|
||||
super.setAttribute(USERNAME_ATTR_NAME, username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this candidate's username.
|
||||
*
|
||||
* @return this candidate's username
|
||||
*/
|
||||
public String getUsername()
|
||||
{
|
||||
return super.getAttributeAsString(USERNAME_ATTR_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this candidate's password.
|
||||
*
|
||||
* @param password this candidate's password
|
||||
*/
|
||||
public void setPassword(String password)
|
||||
{
|
||||
super.setAttribute(PASSWORD_ATTR_NAME, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this candidate's password.
|
||||
*
|
||||
* @return this candidate's password
|
||||
*/
|
||||
public String getPassword()
|
||||
{
|
||||
return super.getAttributeAsString(PASSWORD_ATTR_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this candidate's Internet Protocol (IP) address; this can be either
|
||||
* an IPv4 address or an IPv6 address.
|
||||
*
|
||||
* @param ip this candidate's IPv4 or IPv6 address.
|
||||
*/
|
||||
public void setAddress(String ip)
|
||||
{
|
||||
super.setAttribute(ADDRESS_ATTR_NAME, ip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this candidate's Internet Protocol (IP) address; this can be
|
||||
* either an IPv4 address or an IPv6 address.
|
||||
*
|
||||
* @return this candidate's IPv4 or IPv6 address.
|
||||
*/
|
||||
public String getAddress()
|
||||
{
|
||||
return super.getAttributeAsString(ADDRESS_ATTR_NAME);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,347 @@
|
||||
/*
|
||||
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.protocol.jabber.extensions.gtalk;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
|
||||
import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.CandidateType;
|
||||
|
||||
import org.ice4j.*;
|
||||
import org.ice4j.ice.*;
|
||||
import org.jivesoftware.smack.packet.*;
|
||||
|
||||
/**
|
||||
* A utility class containing methods for creating {@link SessionIQ}
|
||||
* instances for various situations.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class GTalkPacketFactory
|
||||
{
|
||||
/**
|
||||
* Creates a {@link SessionIQ} <tt>reject</tt> packet.
|
||||
*
|
||||
* @param from our JID
|
||||
* @param to the destination JID
|
||||
* @param sid the ID of the Google Talk session that this message will be
|
||||
* rejecting.
|
||||
*
|
||||
* @return a {@link SessionIQ} <tt>reject</tt> packet.
|
||||
*/
|
||||
public static SessionIQ createReject(String from, String to, String sid)
|
||||
{
|
||||
SessionIQ reject = new SessionIQ();
|
||||
|
||||
reject.setTo(to);
|
||||
reject.setFrom(from);
|
||||
reject.setType(IQ.Type.SET);
|
||||
|
||||
reject.setID(sid);
|
||||
reject.setGTalkType(GTalkType.REJECT);
|
||||
|
||||
return reject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SessionIQ} <tt>terminate</tt> packet carrying a
|
||||
* {@link Reason#BUSY} payload.
|
||||
*
|
||||
* @param from our JID
|
||||
* @param to the destination JID
|
||||
* @param sid the ID of the Google Talk session that this message will be
|
||||
* terminating.
|
||||
*
|
||||
* @return a {@link SessionIQ} <tt>terminate</tt> packet.
|
||||
*/
|
||||
public static SessionIQ createBusy(String from, String to, String sid)
|
||||
{
|
||||
return createSessionTerminate(from, to, sid, Reason.BUSY, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SessionIQ} <tt>session-terminate</tt> packet that is
|
||||
* meant to terminate an on-going, well established session (similar to a SIP
|
||||
* BYE request).
|
||||
*
|
||||
* @param from our JID
|
||||
* @param to the destination JID
|
||||
* @param sid the ID of the Google Talk session that this message will be
|
||||
* terminating.
|
||||
*
|
||||
* @return a {@link SessionIQ} <tt>terminate</tt> packet
|
||||
* .
|
||||
*/
|
||||
public static SessionIQ createBye(String from, String to, String sid)
|
||||
{
|
||||
return createSessionTerminate(from, to, sid, Reason.SUCCESS,
|
||||
"Nice talking to you!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SessionIQ} <tt>terminate</tt> packet that is
|
||||
* meant to terminate a not yet established session.
|
||||
*
|
||||
* @param from our JID
|
||||
* @param to the destination JID
|
||||
* @param sid the ID of the Google Talk session that this message will be
|
||||
* terminating.
|
||||
*
|
||||
* @return a {@link SessionIQ} <tt>terminate</tt> packet
|
||||
* .
|
||||
*/
|
||||
public static SessionIQ createCancel(String from, String to, String sid)
|
||||
{
|
||||
return createSessionTerminate(from, to, sid, Reason.CANCEL, "Oops!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SessionIQ} <tt>terminate</tt> packet with the
|
||||
* specified src, dst, sid, and reason.
|
||||
*
|
||||
* @param from our JID
|
||||
* @param to the destination JID
|
||||
* @param sid the ID of the Google Talk session that this message will be
|
||||
* terminating.
|
||||
* @param reason the reason for the termination
|
||||
* @param reasonText a human readable reason for the termination or
|
||||
* <tt>null</tt> for none.
|
||||
*
|
||||
* @return the newly constructed {@link SessionIQ} <tt>terminate</tt>
|
||||
* packet.
|
||||
* .
|
||||
*/
|
||||
public static SessionIQ createSessionTerminate(String from,
|
||||
String to,
|
||||
String sid,
|
||||
Reason reason,
|
||||
String reasonText)
|
||||
{
|
||||
SessionIQ terminate = new SessionIQ();
|
||||
|
||||
terminate.setTo(to);
|
||||
terminate.setFrom(from);
|
||||
terminate.setType(IQ.Type.SET);
|
||||
|
||||
terminate.setID(sid);
|
||||
terminate.setGTalkType(GTalkType.TERMINATE);
|
||||
|
||||
ReasonPacketExtension reasonPacketExt
|
||||
= new ReasonPacketExtension(reason, reasonText, null);
|
||||
|
||||
terminate.setReason(reasonPacketExt);
|
||||
|
||||
return terminate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SessionIQ} <tt>accept</tt> packet with the
|
||||
* specified <tt>from</tt>, <tt>to</tt>, <tt>sid</tt>, and <tt>content</tt>.
|
||||
* Given our role in a conversation, we would assume that the <tt>from</tt>
|
||||
* value should also be used for the value of the Google Talk <tt>responder</tt>.
|
||||
*
|
||||
* @param from our JID
|
||||
* @param to the destination JID
|
||||
* @param sid the ID of the Google Talk session that this message will be
|
||||
* terminating.
|
||||
* @param description description containing payload types list
|
||||
* descriptions.
|
||||
*
|
||||
* @return the newly constructed {@link SessionIQ} <tt>accept</tt>
|
||||
* packet.
|
||||
* .
|
||||
*/
|
||||
public static SessionIQ createSessionAccept(
|
||||
String from,
|
||||
String to,
|
||||
String sid,
|
||||
RtpDescriptionPacketExtension description)
|
||||
{
|
||||
SessionIQ sessionAccept = new SessionIQ();
|
||||
|
||||
sessionAccept.setTo(to);
|
||||
sessionAccept.setFrom(from);
|
||||
sessionAccept.setType(IQ.Type.SET);
|
||||
sessionAccept.setInitiator(to);
|
||||
sessionAccept.setID(sid);
|
||||
sessionAccept.setGTalkType(GTalkType.ACCEPT);
|
||||
sessionAccept.addExtension(description);
|
||||
|
||||
return sessionAccept;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link SessionIQ} with the <tt>initiate</tt> type.
|
||||
*
|
||||
* @param from our JID
|
||||
* @param to the destination JID
|
||||
* @param sid the ID of the Google Talk session that this message will be
|
||||
* terminating.
|
||||
* @param description description containing payload types list.
|
||||
*
|
||||
* @return the newly constructed {@link SessionIQ} <tt>terminate</tt>
|
||||
* packet.
|
||||
*/
|
||||
public static SessionIQ createSessionInitiate(
|
||||
String from,
|
||||
String to,
|
||||
String sid,
|
||||
RtpDescriptionPacketExtension description)
|
||||
{
|
||||
SessionIQ sessionInitiate = new SessionIQ();
|
||||
|
||||
sessionInitiate.setTo(to);
|
||||
sessionInitiate.setFrom(from);
|
||||
sessionInitiate.setInitiator(from);
|
||||
sessionInitiate.setType(IQ.Type.SET);
|
||||
|
||||
sessionInitiate.setID(sid);
|
||||
sessionInitiate.setGTalkType(GTalkType.INITIATE);
|
||||
sessionInitiate.addExtension(description);
|
||||
|
||||
return sessionInitiate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link SessionIQ} with the <tt>candidates</tt> type.
|
||||
*
|
||||
* @param from our JID
|
||||
* @param to the destination JID
|
||||
* @param sid the ID of the Google Talk session.
|
||||
* @param candidate a <tt>GTalkCandidatePacketExtension</tt>.
|
||||
*
|
||||
* @return the newly constructed {@link SessionIQ} <tt>terminate</tt>
|
||||
* packet.
|
||||
*/
|
||||
public static SessionIQ createSessionCandidates(
|
||||
String from,
|
||||
String to,
|
||||
String sid,
|
||||
GTalkCandidatePacketExtension candidate)
|
||||
{
|
||||
SessionIQ sessionInitiate = new SessionIQ();
|
||||
|
||||
sessionInitiate.setTo(to);
|
||||
sessionInitiate.setFrom(from);
|
||||
sessionInitiate.setInitiator(from);
|
||||
sessionInitiate.setType(IQ.Type.SET);
|
||||
|
||||
sessionInitiate.setID(sid);
|
||||
sessionInitiate.setGTalkType(GTalkType.CANDIDATES);
|
||||
sessionInitiate.addExtension(candidate);
|
||||
|
||||
return sessionInitiate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the ICE media <tt>stream</tt> and its local candidates into a
|
||||
* list of Google Talk candidates.
|
||||
*
|
||||
* @param name of the stream
|
||||
* @param stream the {@link IceMediaStream} that we'd like to describe in
|
||||
* XML.
|
||||
*
|
||||
* @return the list of Google Talk candidates
|
||||
*/
|
||||
public static List<GTalkCandidatePacketExtension> createCandidates(
|
||||
String name,
|
||||
IceMediaStream stream)
|
||||
{
|
||||
List<GTalkCandidatePacketExtension> exts = new
|
||||
ArrayList<GTalkCandidatePacketExtension>();
|
||||
|
||||
for(Component component : stream.getComponents())
|
||||
{
|
||||
String mediaName = null;
|
||||
if(name.equals("rtp"))
|
||||
{
|
||||
if(component.getComponentID() == 1)
|
||||
{
|
||||
mediaName = name;
|
||||
}
|
||||
else
|
||||
{
|
||||
mediaName = "rtcp";
|
||||
// Audio RTCP is never used in Google Talk and it is also
|
||||
// never transmitted by Gmail client
|
||||
}
|
||||
}
|
||||
else if(name.equals("video_rtp"))
|
||||
{
|
||||
if(component.getComponentID() == 1)
|
||||
{
|
||||
mediaName = name;
|
||||
}
|
||||
else
|
||||
{
|
||||
mediaName = "video_rtcp";
|
||||
}
|
||||
}
|
||||
|
||||
for(Candidate candidate : component.getLocalCandidates())
|
||||
{
|
||||
exts.add(createCandidate(candidate, mediaName, stream));
|
||||
}
|
||||
}
|
||||
|
||||
return exts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GTalkCandidatePacketExtension} and initializes it so
|
||||
* that it would describe the state of <tt>candidate</tt>
|
||||
*
|
||||
* @param candidate the ICE4J {@link Candidate} that we'd like to convert
|
||||
* into an Google Talk packet extension.
|
||||
* @param name name of the candidate extension
|
||||
* @param stream ICE stream
|
||||
*
|
||||
* @return a new {@link GTalkCandidatePacketExtension} corresponding to the
|
||||
* state of the <tt>candidate</tt> candidate.
|
||||
*/
|
||||
private static GTalkCandidatePacketExtension createCandidate(
|
||||
Candidate candidate, String name, IceMediaStream stream)
|
||||
{
|
||||
GTalkCandidatePacketExtension packet =
|
||||
new GTalkCandidatePacketExtension();
|
||||
|
||||
Component component = candidate.getParentComponent();
|
||||
|
||||
packet.setName(name);
|
||||
packet.setProtocol(candidate.getTransport().toString());
|
||||
packet.setGeneration(
|
||||
component.getParentStream().getParentAgent().getGeneration());
|
||||
|
||||
TransportAddress transportAddress = candidate.getTransportAddress();
|
||||
|
||||
// XXX different username/password for each candidate ?
|
||||
packet.setUsername(stream.getParentAgent().getLocalUfrag());
|
||||
packet.setPassword("");
|
||||
packet.setAddress(transportAddress.getHostAddress());
|
||||
packet.setPort(transportAddress.getPort());
|
||||
packet.setNetwork(0);
|
||||
packet.setFoundation(0);
|
||||
packet.setComponent(component.getComponentID());
|
||||
|
||||
CandidateType candType = CandidateType.valueOf(
|
||||
candidate.getType().toString());
|
||||
|
||||
if(candType == CandidateType.srflx)
|
||||
{
|
||||
candType = CandidateType.stun;
|
||||
}
|
||||
else if(candType == CandidateType.host)
|
||||
{
|
||||
candType = CandidateType.local;
|
||||
}
|
||||
|
||||
packet.setType(candType);
|
||||
packet.setPreference(candidate.getPriority() / 1000);
|
||||
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.protocol.jabber.extensions.gtalk;
|
||||
|
||||
/**
|
||||
* Enumeration of all possible type field value for Google Talk session IQ.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public enum GTalkType
|
||||
{
|
||||
/**
|
||||
* Initiate type.
|
||||
*/
|
||||
INITIATE("initiate"),
|
||||
|
||||
/**
|
||||
* Accept type.
|
||||
*/
|
||||
ACCEPT("accept"),
|
||||
|
||||
/**
|
||||
* Candidate type.
|
||||
*/
|
||||
CANDIDATES("candidates"),
|
||||
|
||||
/**
|
||||
* Reject type.
|
||||
*/
|
||||
REJECT("reject"),
|
||||
|
||||
/**
|
||||
* Terminate type.
|
||||
*/
|
||||
TERMINATE("terminate");
|
||||
|
||||
/**
|
||||
* The name of this type.
|
||||
*/
|
||||
private final String typeName;
|
||||
|
||||
/**
|
||||
* Creates a <tt>GTalkType</tt> instance with the specified name.
|
||||
*
|
||||
* @param typeName the name of the <tt>GTalkType</tt> we'd like
|
||||
* to create.
|
||||
*/
|
||||
private GTalkType(String typeName)
|
||||
{
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this <tt>GTalkType</tt> (e.g. "initiate"
|
||||
* or "accept"). The name returned by this method is meant for
|
||||
* use directly in the XMPP XML string.
|
||||
*
|
||||
* @return Returns the name of this <tt>GTalkType</tt>
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return typeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a <tt>GTalkType</tt> value corresponding to the specified
|
||||
* <tt>gtalkTypeStr</tt>.
|
||||
*
|
||||
* @param gtalkTypeStr the action <tt>String</tt> that we'd like to
|
||||
* parse.
|
||||
* @return a <tt>GTalkType</tt> value corresponding to the specified
|
||||
* <tt>GTalkTypeStr</tt>.
|
||||
*
|
||||
* @throws IllegalArgumentException in case <tt>GTalkTypeStr</tt> is
|
||||
* not a valid media direction.
|
||||
*/
|
||||
public static GTalkType parseString(String gtalkTypeStr)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
for (GTalkType value : values())
|
||||
if (value.toString().equals(gtalkTypeStr))
|
||||
return value;
|
||||
|
||||
throw new IllegalArgumentException(
|
||||
gtalkTypeStr + " is not a valid Google Talk type");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.protocol.jabber.extensions.gtalk;
|
||||
|
||||
import java.math.*;
|
||||
import java.security.*;
|
||||
|
||||
import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
|
||||
|
||||
import org.jivesoftware.smack.packet.*;
|
||||
import org.jivesoftware.smack.util.*;
|
||||
|
||||
/**
|
||||
* A straightforward extension of the IQ. A <tt>SessionIQ</tt> object is created
|
||||
* by smack via the {@link SessionIQProvider}. It contains all the information
|
||||
* extracted from a <tt>Session</tt> IQ.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class SessionIQ
|
||||
extends IQ
|
||||
{
|
||||
/**
|
||||
* The name space that session belongs to.
|
||||
*/
|
||||
public static final String NAMESPACE = "http://www.google.com/session";
|
||||
|
||||
/**
|
||||
* The name of the element that contains the session data.
|
||||
*/
|
||||
public static final String ELEMENT_NAME = "session";
|
||||
|
||||
/**
|
||||
* The name of the argument that contains the session type value.
|
||||
*/
|
||||
public static final String TYPE_ATTR_NAME = "type";
|
||||
|
||||
/**
|
||||
* The name of the argument that contains the "initiator" jid.
|
||||
*/
|
||||
public static final String INITIATOR_ATTR_NAME = "initiator";
|
||||
|
||||
/**
|
||||
* The name of the argument that contains the session id.
|
||||
*/
|
||||
public static final String ID_ATTR_NAME = "id";
|
||||
|
||||
/**
|
||||
* The <tt>GTalkType</tt> that describes the purpose of this
|
||||
* <tt>session</tt> element.
|
||||
*/
|
||||
private GTalkType gtalkType;
|
||||
|
||||
/**
|
||||
* The full JID of the entity that has initiated the session flow.
|
||||
*/
|
||||
private String initiator = null;
|
||||
|
||||
/**
|
||||
* The ID of the GTalk session that this IQ belongs to.
|
||||
*/
|
||||
private String id = null;
|
||||
|
||||
/**
|
||||
* The <tt>reason</tt> extension in a <tt>session</tt> IQ providers machine
|
||||
* and possibly human-readable information about the reason for the action.
|
||||
*/
|
||||
private ReasonPacketExtension reason = null;
|
||||
|
||||
/**
|
||||
* Sets this element's session ID value.
|
||||
*
|
||||
* @param id the session ID to set
|
||||
*/
|
||||
public void setID(String id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this element's session ID value.
|
||||
*
|
||||
* @return this element's session ID.
|
||||
*/
|
||||
public String getID()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random <tt>String</tt> usable as a session ID.
|
||||
*
|
||||
* @return a newly generated random sid <tt>String</tt>
|
||||
*/
|
||||
public static String generateSID()
|
||||
{
|
||||
return new BigInteger(64, new SecureRandom()).toString(32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the full JID of the entity that has initiated the session flow. Only
|
||||
* present when the <tt>GTalkType</tt> is <tt>accept</tt>.
|
||||
*
|
||||
* @param initiator the full JID of the initiator.
|
||||
*/
|
||||
public void setInitiator(String initiator)
|
||||
{
|
||||
this.initiator = initiator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full JID of the entity that has initiated the session flow.
|
||||
* Only present when the <tt>GTalkType</tt> is <tt>session-accept</tt>.
|
||||
*
|
||||
* @return the full JID of the initiator.
|
||||
*/
|
||||
public String getInitiator()
|
||||
{
|
||||
return initiator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this element's <tt>action</tt> attribute. The value of
|
||||
* the 'action' attribute MUST be one of the values enumerated here. If an
|
||||
* entity receives a value not defined here, it MUST ignore the attribute
|
||||
* and MUST return a <tt>bad-request</tt> error to the sender. There is no
|
||||
* default value for the 'action' attribute.
|
||||
*
|
||||
* @param gtalkType the value of the <tt>action</tt> attribute.
|
||||
*/
|
||||
public void setGTalkType(GTalkType gtalkType)
|
||||
{
|
||||
this.gtalkType = gtalkType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this element's <tt>action</tt> attribute. The value
|
||||
* of the 'action' attribute MUST be one of the values enumerated here. If
|
||||
* an entity receives a value not defined here, it MUST ignore the attribute
|
||||
* and MUST return a <tt>bad-request</tt> error to the sender. There is no
|
||||
* default value for the 'action' attribute.
|
||||
*
|
||||
* @return the value of the <tt>action</tt> attribute.
|
||||
*/
|
||||
public GTalkType getGTalkType()
|
||||
{
|
||||
return gtalkType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies this IQ's <tt>reason</tt> extension. The <tt>reason</tt>
|
||||
* extension in a <tt>session</tt> IQ provides machine and possibly human
|
||||
* -readable information about the reason for the action.
|
||||
*
|
||||
* @param reason this IQ's <tt>reason</tt> extension.
|
||||
*/
|
||||
public void setReason(ReasonPacketExtension reason)
|
||||
{
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this IQ's <tt>reason</tt> extension. The <tt>reason</tt>
|
||||
* extension in a <tt>session</tt> IQ provides machine and possibly human
|
||||
* -readable information about the reason for the action.
|
||||
*
|
||||
* @return this IQ's <tt>reason</tt> extension.
|
||||
*/
|
||||
public ReasonPacketExtension getReason()
|
||||
{
|
||||
return reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML string of this GTalk session IQ's "section" sub-element.
|
||||
*
|
||||
* Extensions of this class must override this method.
|
||||
*
|
||||
* @return the child element section of the IQ XML.
|
||||
*/
|
||||
@Override
|
||||
public String getChildElementXML()
|
||||
{
|
||||
StringBuilder bldr = new StringBuilder("<" + ELEMENT_NAME);
|
||||
|
||||
bldr.append(" xmlns='" + NAMESPACE + "'");
|
||||
|
||||
bldr.append(" " + TYPE_ATTR_NAME + "='" + getGTalkType() + "'");
|
||||
|
||||
if( initiator != null)
|
||||
bldr.append(" " + INITIATOR_ATTR_NAME
|
||||
+ "='" + getInitiator() + "'");
|
||||
|
||||
bldr.append(" " + ID_ATTR_NAME
|
||||
+ "='" + getID() + "'");
|
||||
|
||||
String extensionsXML = getExtensionsXML();
|
||||
|
||||
if ((extensionsXML == null) || (extensionsXML.length() == 0) &&
|
||||
reason == null)
|
||||
{
|
||||
bldr.append("/>");
|
||||
}
|
||||
else
|
||||
{
|
||||
bldr.append(">");//it is possible to have empty session elements
|
||||
|
||||
//reason
|
||||
if (reason != null)
|
||||
bldr.append(reason.toXML());
|
||||
|
||||
// extensions
|
||||
if ((extensionsXML != null) && (extensionsXML.length() != 0))
|
||||
bldr.append(extensionsXML);
|
||||
|
||||
bldr.append("</" + ELEMENT_NAME + ">");
|
||||
}
|
||||
|
||||
return bldr.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.protocol.jabber.extensions.gtalk;
|
||||
|
||||
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
|
||||
import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
|
||||
|
||||
import org.jivesoftware.smack.packet.*;
|
||||
import org.jivesoftware.smack.provider.*;
|
||||
import org.xmlpull.v1.*;
|
||||
|
||||
/**
|
||||
* An implementation of a GTalk session IQ provider that parses incoming session IQs.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class SessionIQProvider
|
||||
implements IQProvider
|
||||
{
|
||||
/**
|
||||
* Namespace for "audio" description.
|
||||
*/
|
||||
public static final String GTALK_AUDIO_NAMESPACE =
|
||||
"http://www.google.com/session/phone";
|
||||
|
||||
/**
|
||||
* Namespace for "video" description.
|
||||
*/
|
||||
public static final String GTALK_VIDEO_NAMESPACE =
|
||||
"http://www.google.com/session/video";
|
||||
|
||||
/**
|
||||
* Creates a new instance of the <tt>SessionIQProvider</tt> and register all
|
||||
* GTalk related extension providers. It is the responsibility of the
|
||||
* application to register the <tt>SessionIQProvider</tt> itself.
|
||||
*/
|
||||
public SessionIQProvider()
|
||||
{
|
||||
ProviderManager providerManager = ProviderManager.getInstance();
|
||||
|
||||
providerManager.addExtensionProvider(
|
||||
RtpDescriptionPacketExtension.ELEMENT_NAME,
|
||||
GTALK_AUDIO_NAMESPACE,
|
||||
new DefaultPacketExtensionProvider
|
||||
<RtpDescriptionPacketExtension>(
|
||||
RtpDescriptionPacketExtension.class));
|
||||
providerManager.addExtensionProvider(
|
||||
RtpDescriptionPacketExtension.ELEMENT_NAME,
|
||||
GTALK_VIDEO_NAMESPACE,
|
||||
new DefaultPacketExtensionProvider
|
||||
<RtpDescriptionPacketExtension>(
|
||||
RtpDescriptionPacketExtension.class));
|
||||
|
||||
providerManager.addExtensionProvider(
|
||||
PayloadTypePacketExtension.ELEMENT_NAME,
|
||||
GTALK_AUDIO_NAMESPACE,
|
||||
new DefaultPacketExtensionProvider
|
||||
<PayloadTypePacketExtension>(
|
||||
PayloadTypePacketExtension.class));
|
||||
|
||||
providerManager.addExtensionProvider(
|
||||
PayloadTypePacketExtension.ELEMENT_NAME,
|
||||
GTALK_VIDEO_NAMESPACE,
|
||||
new DefaultPacketExtensionProvider
|
||||
<PayloadTypePacketExtension>(
|
||||
PayloadTypePacketExtension.class));
|
||||
|
||||
providerManager.addExtensionProvider(
|
||||
EncryptionPacketExtension.ELEMENT_NAME,
|
||||
null,
|
||||
new DefaultPacketExtensionProvider<EncryptionPacketExtension>(
|
||||
EncryptionPacketExtension.class));
|
||||
|
||||
providerManager.addExtensionProvider(
|
||||
SrcIdPacketExtension.ELEMENT_NAME,
|
||||
GTALK_AUDIO_NAMESPACE,
|
||||
new SrcIdProvider());
|
||||
|
||||
providerManager.addExtensionProvider(
|
||||
SrcIdPacketExtension.ELEMENT_NAME,
|
||||
GTALK_VIDEO_NAMESPACE,
|
||||
new SrcIdProvider());
|
||||
|
||||
providerManager.addExtensionProvider(
|
||||
UsagePacketExtension.ELEMENT_NAME,
|
||||
null,
|
||||
new DefaultPacketExtensionProvider<UsagePacketExtension>(
|
||||
UsagePacketExtension.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a GTalk session IQ sub-document and returns a {@link SessionIQ}
|
||||
* instance.
|
||||
*
|
||||
* @param parser an XML parser.
|
||||
*
|
||||
* @return a new {@link SessionIQ} instance.
|
||||
*
|
||||
* @throws Exception if an error occurs parsing the XML.
|
||||
*/
|
||||
@Override
|
||||
public IQ parseIQ(XmlPullParser parser) throws Exception
|
||||
{
|
||||
SessionIQ sessionIQ = new SessionIQ();
|
||||
boolean done = false;
|
||||
|
||||
//let's first handle the "session" element params.
|
||||
GTalkType type = GTalkType.parseString(parser
|
||||
.getAttributeValue("", SessionIQ.TYPE_ATTR_NAME));
|
||||
String initiator = parser
|
||||
.getAttributeValue("", SessionIQ.INITIATOR_ATTR_NAME);
|
||||
String id = parser
|
||||
.getAttributeValue("", SessionIQ.ID_ATTR_NAME);
|
||||
|
||||
sessionIQ.setGTalkType(type);
|
||||
sessionIQ.setInitiator(initiator);
|
||||
sessionIQ.setID(id);
|
||||
|
||||
// Sub-elements providers
|
||||
DefaultPacketExtensionProvider<GTalkCandidatePacketExtension>
|
||||
candidateProvider
|
||||
= new DefaultPacketExtensionProvider<
|
||||
GTalkCandidatePacketExtension>(
|
||||
GTalkCandidatePacketExtension.class);
|
||||
|
||||
DefaultPacketExtensionProvider<RtpDescriptionPacketExtension>
|
||||
descriptionProvider
|
||||
= new
|
||||
DefaultPacketExtensionProvider<RtpDescriptionPacketExtension>(
|
||||
RtpDescriptionPacketExtension.class);
|
||||
|
||||
ReasonProvider reasonProvider = new ReasonProvider();
|
||||
|
||||
//int nbTab = 0;
|
||||
|
||||
// Now go on and parse the session element's content.
|
||||
while (!done)
|
||||
{
|
||||
int eventType = parser.next();
|
||||
String elementName = parser.getName();
|
||||
|
||||
if (eventType == XmlPullParser.START_TAG)
|
||||
{
|
||||
/*
|
||||
String namespace = parser.getNamespace();;
|
||||
String tab = "";
|
||||
nbTab++;
|
||||
|
||||
for(int ii = 0 ; ii < nbTab ; ii++)
|
||||
tab += "\t";
|
||||
|
||||
System.out.println(tab + parser.getName() + " " +
|
||||
parser.getNamespace());
|
||||
|
||||
for(int i = 0 ; i < parser.getAttributeCount() ; i++)
|
||||
{
|
||||
|
||||
System.out.print(tab + "\t");
|
||||
System.out.println(parser.getAttributeName(i) + "=" +
|
||||
parser.getAttributeValue(i));
|
||||
}
|
||||
*/
|
||||
if(elementName.equals(CandidatePacketExtension.ELEMENT_NAME))
|
||||
{
|
||||
sessionIQ.addExtension(
|
||||
candidateProvider.parseExtension(parser));
|
||||
}
|
||||
else if(elementName.equals(
|
||||
RtpDescriptionPacketExtension.ELEMENT_NAME))
|
||||
{
|
||||
RtpDescriptionPacketExtension ext =
|
||||
descriptionProvider.parseExtension(parser);
|
||||
sessionIQ.addExtension(ext);
|
||||
}
|
||||
else if(elementName.equals(ReasonPacketExtension.ELEMENT_NAME))
|
||||
{
|
||||
ReasonPacketExtension reason
|
||||
= reasonProvider.parseExtension(parser);
|
||||
sessionIQ.setReason(reason);
|
||||
}
|
||||
}
|
||||
if (eventType == XmlPullParser.END_TAG)
|
||||
{
|
||||
//nbTab--;
|
||||
if (parser.getName().equals(SessionIQ.ELEMENT_NAME))
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sessionIQ;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.protocol.jabber.extensions.gtalk;
|
||||
|
||||
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
|
||||
|
||||
/**
|
||||
* SRC-ID packet extension.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class SrcIdPacketExtension
|
||||
extends AbstractPacketExtension
|
||||
{
|
||||
/**
|
||||
* The namespace that URIs belongs to.
|
||||
*/
|
||||
public static final String NAMESPACE = "";
|
||||
|
||||
/**
|
||||
* The name of the element that contains the URIs data.
|
||||
*/
|
||||
public static final String ELEMENT_NAME = "src-id";
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param namespace namespace
|
||||
*/
|
||||
public SrcIdPacketExtension(String namespace)
|
||||
{
|
||||
super(namespace, ELEMENT_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set source ID.
|
||||
*
|
||||
* @param srcId source ID
|
||||
*/
|
||||
public void setSrcId(String srcId)
|
||||
{
|
||||
this.setText(srcId);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.protocol.jabber.extensions.gtalk;
|
||||
|
||||
import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
|
||||
|
||||
import org.jivesoftware.smack.packet.*;
|
||||
import org.jivesoftware.smack.provider.*;
|
||||
import org.xmlpull.v1.*;
|
||||
|
||||
/**
|
||||
* Parser for src-id packet extension.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class SrcIdProvider
|
||||
implements PacketExtensionProvider
|
||||
{
|
||||
/**
|
||||
* Parses a reason extension sub-packet and creates a {@link
|
||||
* ReasonPacketExtension} instance. At the beginning of the method call,
|
||||
* the xml parser will be positioned on the opening element of the packet
|
||||
* extension. As required by the smack API, at the end of the method call,
|
||||
* the parser will be positioned on the closing element of the packet
|
||||
* extension.
|
||||
*
|
||||
* @param parser an XML parser positioned at the opening <tt>reason</tt>
|
||||
* element.
|
||||
*
|
||||
* @return a new {@link ReasonPacketExtension} instance.
|
||||
* @throws java.lang.Exception if an error occurs parsing the XML.
|
||||
*/
|
||||
public PacketExtension parseExtension(XmlPullParser parser)
|
||||
throws Exception
|
||||
{
|
||||
boolean done = false;
|
||||
int eventType;
|
||||
String ns = parser.getNamespace();
|
||||
|
||||
SrcIdPacketExtension ext
|
||||
= new SrcIdPacketExtension(ns);
|
||||
|
||||
while (!done)
|
||||
{
|
||||
eventType = parser.next();
|
||||
|
||||
if (eventType == XmlPullParser.TEXT)
|
||||
{
|
||||
ext.setText(parser.getText());
|
||||
}
|
||||
else if (eventType == XmlPullParser.END_TAG)
|
||||
{
|
||||
if (parser.getName().equals(
|
||||
SrcIdPacketExtension.ELEMENT_NAME))
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ext;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.protocol.jabber.extensions.gtalk;
|
||||
|
||||
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
|
||||
|
||||
/**
|
||||
* URIs packet extension.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class UsagePacketExtension
|
||||
extends AbstractPacketExtension
|
||||
{
|
||||
/**
|
||||
* The namespace that URIs belongs to.
|
||||
*/
|
||||
public static final String NAMESPACE = "";
|
||||
|
||||
/**
|
||||
* The name of the element that contains the URIs data.
|
||||
*/
|
||||
public static final String ELEMENT_NAME = "usage";
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public UsagePacketExtension()
|
||||
{
|
||||
super(NAMESPACE, ELEMENT_NAME);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue