package bssoft.stack.sip; import java.util.StringTokenizer; public class SDPMedia { public int mediaType = SIPStack.SIP_MEDIATYPE_NONE; public String mediaIp = null; public int mediaPort = 0; public int flowIndicator = SIPStack.SIP_MEDIAFLOW_NONE; public StringBuffer rtpmapBuffer = null; public StringBuffer fmtpBuffer = null; public String flow = "sendrecv"; public StringBuffer codecS = null; public int commonCodec = -1; public boolean flag = false; public String mediaString = null; public SDPMedia(int mediatype) { if (!SIPStack.bStackLicensed) { System.out.println("라이슨스키를 설정하세요."); //System.exit(0); } this.mediaType = mediatype; this.mediaIp = null; this.mediaPort = 0; this.rtpmapBuffer = new StringBuffer(); this.fmtpBuffer = new StringBuffer(); this.flow = "sendrecv"; this.codecS = new StringBuffer(); this.commonCodec = -1; this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDRECV; this.flag = true; } public SDPMedia(String mediadescribe, String platformIp) { this.mediaType = SIPStack.SIP_MEDIATYPE_NONE; this.mediaIp = platformIp; this.mediaPort = 0; this.rtpmapBuffer = new StringBuffer(); this.fmtpBuffer = new StringBuffer(); this.flow = "sendrecv"; this.codecS = new StringBuffer(); this.commonCodec = -1; this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDRECV; boolean bContinueParse = true; if (mediadescribe != null && mediadescribe.length() > 0) { int iS = 0; int iE = 0; String header = null; if (mediadescribe.startsWith("m=audio ")) { this.mediaType = SIPStack.SIP_MEDIATYPE_AUDIO; } else if (mediadescribe.startsWith("m=video ")) { this.mediaType = SIPStack.SIP_MEDIATYPE_VIDEO; } else { bContinueParse = false; } if (bContinueParse) { iE = mediadescribe.indexOf(SIPStack.SIP_LINE_END); if (iE > 0) { header = mediadescribe.substring(0, iE); StringTokenizer st = new StringTokenizer(header, " ", true); int fieldCount = 0; while (st.hasMoreTokens()) { String str = st.nextToken().trim(); if (str.length() > 0 && str.compareTo(" ") != 0) { if (fieldCount == 0) { if (str.compareTo("m=audio") != 0) { bContinueParse = false; break; } } else if (fieldCount == 1) { this.mediaPort = Integer.parseInt(str); } else if (fieldCount == 2) { if (str.compareTo("RTP/AVP") != 0) { bContinueParse = false; break; } } else if (fieldCount > 2) { if (this.codecS.length() > 0) { this.codecS.append(" " + str); } else { this.codecS.append(str); } } fieldCount++; } } } else { bContinueParse = false; } } if (bContinueParse) { StringTokenizer st = new StringTokenizer(mediadescribe, "\n", true); while (st.hasMoreTokens()) { String str = st.nextToken().trim(); if (str.length() > 0 && str.startsWith("a=")) { if (str.startsWith("a=rtpmap:")) { this.rtpmapBuffer.append(String.valueOf(str) + "\n"); continue; } if (str.startsWith("a=fmtp:")) { this.fmtpBuffer.append(String.valueOf(str) + "\n"); continue; } if (str.startsWith("a=sendrecv")) { this.flow = "sendrecv"; this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDRECV; continue; } if (str.startsWith("a=sendonly")) { this.flow = "sendonly"; this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDONLY; continue; } if (str.startsWith("a=recvonly")) { this.flow = "recvonly"; this.flowIndicator = SIPStack.SIP_MEDIAFLOW_RECVONLY; } } } } if (bContinueParse && mediadescribe.indexOf("\nc=IN IP4 ") > 0) { iS = 0; iE = 0; iS = mediadescribe.indexOf("c="); if (iS >= 0) { iE = mediadescribe.indexOf(SIPStack.SIP_LINE_END, iS); header = ""; if (iS >= 0 && iE > iS) { header = mediadescribe.substring(iS, iE + 2); iE = header.indexOf(SIPStack.SIP_LINE_END); this.mediaIp = header.substring("c=IN IP4 ".length(), iE); } } } } if (!bContinueParse) resetMedia(); this.flag = true; } public void resetMedia() { this.mediaType = SIPStack.SIP_MEDIATYPE_NONE; this.mediaIp = null; this.mediaPort = 0; this.rtpmapBuffer = null; this.fmtpBuffer = null; this.flow = "sendrecv"; this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDRECV; this.codecS = null; this.commonCodec = -1; this.flag = false; this.mediaString = null; } public String getMediaString() { if (!this.flag) return null; String mString = ""; String aString = ""; String fmtpString = ""; String flowString = "a=" + this.flow + SIPStack.SIP_LINE_END; if (this.mediaType == SIPStack.SIP_MEDIATYPE_AUDIO) { mString = "m=audio " + this.mediaPort + " RTP/AVP " + this.codecS.toString() + SIPStack.SIP_LINE_END; } else if (this.mediaType != SIPStack.SIP_MEDIATYPE_VIDEO) { return null; } if (this.rtpmapBuffer.length() > 0) aString = this.rtpmapBuffer.toString(); if (this.fmtpBuffer.length() > 0) fmtpString = this.fmtpBuffer.toString(); this.mediaString = String.valueOf(mString) + aString + fmtpString + flowString; return this.mediaString; } public String getFinalMediaString() { if (!this.flag) return null; if (this.commonCodec < 0) return null; String mString = ""; String aString = ""; String flowString = "a=" + this.flow + SIPStack.SIP_LINE_END; if (this.mediaType == SIPStack.SIP_MEDIATYPE_AUDIO) { mString = "m=audio " + this.mediaPort + " RTP/AVP " + this.commonCodec + SIPStack.SIP_LINE_END; } else if (this.mediaType != SIPStack.SIP_MEDIATYPE_VIDEO) { return null; } if (this.commonCodec == 0) { aString = "a=rtpmap:0 PCMU/8000" + SIPStack.SIP_LINE_END; } else if (this.commonCodec == 8) { aString = "a=rtpmap:8 PCMA/8000" + SIPStack.SIP_LINE_END; } else if (this.commonCodec == 18) { aString = "a=rtpmap:18 G729/8000" + SIPStack.SIP_LINE_END; } this.mediaString = String.valueOf(mString) + aString + flowString; return this.mediaString; } public boolean setMediaAddress(String ip, int port) { if (!this.flag) return false; if (port < 0 || port > 65556) return false; this.mediaIp = ip; this.mediaPort = port; return true; } public boolean setCodec(int codec) { if (!this.flag) return false; if (this.codecS.length() > 0) { this.codecS.append(" " + codec); } else { this.codecS.append(codec); } return true; } public boolean setCodec(int codec, String describe) { if (!this.flag) return false; setCodec(codec); this.rtpmapBuffer.append("a=rtpmap:" + codec + " " + describe + SIPStack.SIP_LINE_END); return true; } public boolean setFmtpDescribe(int codec, String describe) { if (!this.flag) return false; this.fmtpBuffer.append("a=fmtp:" + codec + " " + describe + SIPStack.SIP_LINE_END); return true; } public boolean setCommonCodec(int codec) { if (!this.flag) return false; this.commonCodec = codec; return true; } public boolean setFlow(String flow) { if (flow == null) return false; if (!this.flag) return false; this.flow = flow; if (flow.compareTo("sendrecv") == 0) { this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDRECV; } else if (flow.compareTo("sendonly") == 0) { this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDONLY; } else if (flow.compareTo("recvonly") == 0) { this.flowIndicator = SIPStack.SIP_MEDIAFLOW_RECVONLY; } else { this.flowIndicator = SIPStack.SIP_MEDIAFLOW_NONE; } return true; } public int negotiateAudioCodec(String sideCodecs) { if (this.codecS == null || this.codecS.length() <= 0) return -1; String myCodecs = this.codecS.toString(); myCodecs.trim(); if (myCodecs == null || myCodecs.length() <= 0) return -1; sideCodecs.trim(); if (sideCodecs == null || sideCodecs.length() <= 0) return -1; StringTokenizer my_st = new StringTokenizer(myCodecs, " ", true); String str = null; int codec = -1; while (my_st.hasMoreTokens()) { str = my_st.nextToken().trim(); if (str == null || str.length() == 0) continue; codec = Integer.parseInt(str); if (codec >= 0 && codec < 100) { StringTokenizer side_st = new StringTokenizer(sideCodecs, " ", true); int sidecodec = -1; boolean bDecided = false; while (side_st.hasMoreTokens()) { str = side_st.nextToken().trim(); if (str == null || str.length() == 0) continue; sidecodec = Integer.parseInt(str); if (str.length() > 0 && sidecodec >= 0 && codec < 100) if (sidecodec == codec) { bDecided = true; this.commonCodec = codec; break; } } if (bDecided) return this.commonCodec; } } return -1; } }