Add SDP constructor
change to builder.
Change-Id: I950cff410f746a433f1c96da738ca888ec1f6575
diff --git a/src/android/net/sip/SdpSessionDescription.java b/src/android/net/sip/SdpSessionDescription.java
index 281a3b8..d5bef4d 100644
--- a/src/android/net/sip/SdpSessionDescription.java
+++ b/src/android/net/sip/SdpSessionDescription.java
@@ -16,24 +16,132 @@
package android.net.sip;
+import gov.nist.javax.sdp.*;
+import gov.nist.javax.sdp.fields.*;
import gov.nist.javax.sdp.parser.SDPAnnounceParser;
import java.text.ParseException;
-import javax.sdp.SdpParseException;
+import java.util.Vector;
+import javax.sdp.*;
import javax.sip.SipException;
public class SdpSessionDescription implements SessionDescription {
- private String mContent;
- private javax.sdp.SessionDescription mSessionDescription;
+ private SessionDescriptionImpl mSessionDescription;
public SdpSessionDescription(String sdpString) throws SdpParseException {
- mContent = sdpString;
try {
mSessionDescription = new SDPAnnounceParser(sdpString).parse();
} catch (ParseException e) {
throw new SdpParseException(e.toString(), e);
}
}
+ public static class Builder {
+ private SdpSessionDescription mSdp = new SdpSessionDescription();
+ private SessionDescriptionImpl mSessionDescription;
+
+ public Builder(String sessionName) throws SdpParseException {
+ mSessionDescription = new SessionDescriptionImpl();
+ try {
+ ProtoVersionField proto = new ProtoVersionField();
+ proto.setVersion(0);
+ mSessionDescription.addField(proto);
+
+ TimeField time = new TimeField();
+ time.setZero();
+ mSessionDescription.addField(time);
+
+ SessionNameField session = new SessionNameField();
+ session.setValue(sessionName);
+ mSessionDescription.addField(session);
+ } catch (Exception e) {
+ throw new SdpParseException(e.toString(), e);
+ }
+ }
+
+ public Builder setConnectionInfo(String netType, String addrType,
+ String addr) throws SdpParseException {
+ try {
+ ConnectionField connection = new ConnectionField();
+ connection.setNetworkType(netType);
+ connection.setAddressType(addrType);
+ connection.setAddress(addr);
+ mSessionDescription.addField(connection);
+ } catch (Exception e) {
+ throw new SdpParseException(e.toString(), e);
+ }
+ return this;
+ }
+
+ public Builder setOrigin(SipProfile user, long sessionId,
+ long sessionVersion, String networkType, String addressType,
+ String address) throws SdpParseException {
+ try {
+ OriginField origin = new OriginField();
+ origin.setUsername(user.getUserName());
+ origin.setSessionId(sessionId);
+ origin.setSessionVersion(sessionVersion);
+ origin.setAddressType(addressType);
+ origin.setNetworkType(networkType);
+ origin.setAddress(address);
+ mSessionDescription.addField(origin);
+ } catch (Exception e) {
+ throw new SdpParseException(e.toString(), e);
+ }
+ return this;
+ }
+
+ public Builder addMedia(String media, int port, int numPorts,
+ String transport, Vector types) throws SdpParseException {
+ MediaField field = new MediaField();
+ try {
+ field.setMediaType(media);
+ field.setMediaPort(port);
+ field.setPortCount(numPorts);
+ field.setProtocol(transport);
+ field.setMediaFormats(types);
+ mSessionDescription.addField(field);
+ } catch (Exception e) {
+ throw new SdpParseException(e.toString(), e);
+ }
+ return this;
+ }
+
+ public Builder addMediaAttribute(String name, String value)
+ throws SdpParseException {
+ try {
+ if (mSessionDescription.getMediaDescriptions(false) == null) {
+ throw new SdpParseException("Should add media first!");
+ }
+ AttributeField attribute = new AttributeField();
+ attribute.setName(name);
+ attribute.setValueAllowNull(value);
+ mSessionDescription.addField(attribute);
+ } catch (Exception e) {
+ throw new SdpParseException(e.toString(), e);
+ }
+ return this;
+ }
+
+ public Builder addSessionAttribute(String name, String value)
+ throws SdpParseException {
+ try {
+ AttributeField attribute = new AttributeField();
+ attribute.setName(name);
+ attribute.setValueAllowNull(value);
+ mSessionDescription.addField(attribute);
+ } catch (Exception e) {
+ throw new SdpParseException(e.toString(), e);
+ }
+ return this;
+ }
+
+ public SdpSessionDescription build() {
+ mSdp.mSessionDescription = mSessionDescription;
+ return mSdp;
+ }
+ }
+
+ SdpSessionDescription() { }
public SdpSessionDescription(byte[] content) throws SdpParseException {
this(new String(content));
@@ -44,6 +152,6 @@
}
public byte[] getContent() {
- return mContent.getBytes();
+ return mSessionDescription.toString().getBytes();
}
}
diff --git a/src/com/android/sip/SipMain.java b/src/com/android/sip/SipMain.java
index 15b106e..308c09e 100644
--- a/src/com/android/sip/SipMain.java
+++ b/src/com/android/sip/SipMain.java
@@ -33,10 +33,13 @@
import android.view.Menu;
import android.view.MenuItem;
+import gov.nist.javax.sdp.fields.SDPKeywords;
+
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.text.ParseException;
+import java.util.Vector;
import javax.sdp.SdpParseException;
import javax.sip.SipException;
@@ -57,6 +60,7 @@
private EditTextPreference mLocalMediaPort;
private Preference mMyIp;
+ private SipProfile mLocalProfile;
private SipSessionLayer mSipSessionLayer;
private SipSession mSipSession;
private SipSession mSipCallSession;
@@ -133,10 +137,13 @@
private SipProfile createLocalSipProfile() {
try {
- return new SipProfile.Builder(getServerUri())
- .setPassword(getText(mPassword))
- .setDisplayName(getText(mDisplayName))
- .build();
+ if (mLocalProfile == null) {
+ mLocalProfile = new SipProfile.Builder(getServerUri())
+ .setPassword(getText(mPassword))
+ .setDisplayName(getText(mDisplayName))
+ .build();
+ }
+ return mLocalProfile;
} catch (ParseException e) {
throw new RuntimeException(e);
}
@@ -263,7 +270,8 @@
private void makeCall() {
try {
- mSipSession.makeCall(createPeerSipProfile(), getSdp());
+ mSipSession.makeCall(createPeerSipProfile(),
+ getSdpSampleBuilder().build());
} catch (SipException e) {
// TODO: UI feedback
Log.e(TAG, "makeCall()", e);
@@ -298,7 +306,7 @@
SipSession session = getActiveSession();
try {
if (Math.random() > 0.2) {
- session.answerCall(getSdp());
+ session.answerCall(getSdpSampleBuilder().build());
} else {
session.endCall();
}
@@ -319,33 +327,43 @@
}
}
- private SessionDescription getSdp() {
+ private SdpSessionDescription.Builder getSdpSampleBuilder() {
// TODO: integrate with SDP
String localIp = getLocalIp();
+ SdpSessionDescription.Builder sdpBuilder;
try {
- return new SdpSessionDescription("v=0\r\n"
- + "o=4855 13760799956958020 13760799956958020"
- + " IN IP4 " + localIp + "\r\n" + "s=mysession session\r\n"
- + "p=+46 8 52018010\r\n" + "c=IN IP4 " + localIp + "\r\n"
- + "t=0 0\r\n" + "m=audio 6022 RTP/AVP 0 4 18\r\n"
- + "a=rtpmap:0 PCMU/8000\r\n" +"a=rtpmap:4 G723/8000\r\n"
- + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n");
+ Vector v = new Vector();
+ v.add(0);
+ v.add(4);
+ v.add(18);
+ sdpBuilder = new SdpSessionDescription.Builder("SIP Call")
+ .setOrigin(mLocalProfile, (long)Math.random() * 10000000L,
+ (long)Math.random() * 10000000L, SDPKeywords.IN,
+ SDPKeywords.IPV4, localIp)
+ .setConnectionInfo(SDPKeywords.IN, SDPKeywords.IPV4, localIp)
+ .addMedia("audio", 6022, 1, "RTP/AVP", v)
+ .addMediaAttribute("rtpmap", "0 PCMU/8000")
+ .addMediaAttribute("rtpmap", "4 G723/8000")
+ .addMediaAttribute("rtpmap", "18 G729A/8000")
+ .addMediaAttribute("ptime", "20");
} catch (SdpParseException e) {
throw new RuntimeException(e);
}
+ return sdpBuilder;
}
private SessionDescription getHoldSdp() {
try {
- return new SdpSessionDescription(
- new String(getSdp().getContent()) + "a=sendonly\r\n");
+ SdpSessionDescription.Builder sdpBuilder = getSdpSampleBuilder();
+ sdpBuilder.addMediaAttribute("sendonly", (String)null);
+ return sdpBuilder.build();
} catch (SdpParseException e) {
throw new RuntimeException(e);
}
}
private SessionDescription getContinueSdp() {
- return getSdp();
+ return getSdpSampleBuilder().build();
}
private Preference[] allPreferences() {