SDPMedia.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. package bssoft.stack.sip;
  2. import java.util.StringTokenizer;
  3. public class SDPMedia {
  4. public int mediaType = SIPStack.SIP_MEDIATYPE_NONE;
  5. public String mediaIp = null;
  6. public int mediaPort = 0;
  7. public int flowIndicator = SIPStack.SIP_MEDIAFLOW_NONE;
  8. public StringBuffer rtpmapBuffer = null;
  9. public StringBuffer fmtpBuffer = null;
  10. public String flow = "sendrecv";
  11. public StringBuffer codecS = null;
  12. public int commonCodec = -1;
  13. public boolean flag = false;
  14. public String mediaString = null;
  15. public SDPMedia(int mediatype) {
  16. if (!SIPStack.bStackLicensed) {
  17. System.out.println("라이슨스키를 설정하세요.");
  18. //System.exit(0);
  19. }
  20. this.mediaType = mediatype;
  21. this.mediaIp = null;
  22. this.mediaPort = 0;
  23. this.rtpmapBuffer = new StringBuffer();
  24. this.fmtpBuffer = new StringBuffer();
  25. this.flow = "sendrecv";
  26. this.codecS = new StringBuffer();
  27. this.commonCodec = -1;
  28. this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDRECV;
  29. this.flag = true;
  30. }
  31. public SDPMedia(String mediadescribe, String platformIp) {
  32. this.mediaType = SIPStack.SIP_MEDIATYPE_NONE;
  33. this.mediaIp = platformIp;
  34. this.mediaPort = 0;
  35. this.rtpmapBuffer = new StringBuffer();
  36. this.fmtpBuffer = new StringBuffer();
  37. this.flow = "sendrecv";
  38. this.codecS = new StringBuffer();
  39. this.commonCodec = -1;
  40. this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDRECV;
  41. boolean bContinueParse = true;
  42. if (mediadescribe != null && mediadescribe.length() > 0) {
  43. int iS = 0;
  44. int iE = 0;
  45. String header = null;
  46. if (mediadescribe.startsWith("m=audio ")) {
  47. this.mediaType = SIPStack.SIP_MEDIATYPE_AUDIO;
  48. } else if (mediadescribe.startsWith("m=video ")) {
  49. this.mediaType = SIPStack.SIP_MEDIATYPE_VIDEO;
  50. } else {
  51. bContinueParse = false;
  52. }
  53. if (bContinueParse) {
  54. iE = mediadescribe.indexOf(SIPStack.SIP_LINE_END);
  55. if (iE > 0) {
  56. header = mediadescribe.substring(0, iE);
  57. StringTokenizer st = new StringTokenizer(header, " ", true);
  58. int fieldCount = 0;
  59. while (st.hasMoreTokens()) {
  60. String str = st.nextToken().trim();
  61. if (str.length() > 0 && str.compareTo(" ") != 0) {
  62. if (fieldCount == 0) {
  63. if (str.compareTo("m=audio") != 0) {
  64. bContinueParse = false;
  65. break;
  66. }
  67. } else if (fieldCount == 1) {
  68. this.mediaPort = Integer.parseInt(str);
  69. } else if (fieldCount == 2) {
  70. if (str.compareTo("RTP/AVP") != 0) {
  71. bContinueParse = false;
  72. break;
  73. }
  74. } else if (fieldCount > 2) {
  75. if (this.codecS.length() > 0) {
  76. this.codecS.append(" " + str);
  77. } else {
  78. this.codecS.append(str);
  79. }
  80. }
  81. fieldCount++;
  82. }
  83. }
  84. } else {
  85. bContinueParse = false;
  86. }
  87. }
  88. if (bContinueParse) {
  89. StringTokenizer st = new StringTokenizer(mediadescribe, "\n", true);
  90. while (st.hasMoreTokens()) {
  91. String str = st.nextToken().trim();
  92. if (str.length() > 0 && str.startsWith("a=")) {
  93. if (str.startsWith("a=rtpmap:")) {
  94. this.rtpmapBuffer.append(String.valueOf(str) + "\n");
  95. continue;
  96. }
  97. if (str.startsWith("a=fmtp:")) {
  98. this.fmtpBuffer.append(String.valueOf(str) + "\n");
  99. continue;
  100. }
  101. if (str.startsWith("a=sendrecv")) {
  102. this.flow = "sendrecv";
  103. this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDRECV;
  104. continue;
  105. }
  106. if (str.startsWith("a=sendonly")) {
  107. this.flow = "sendonly";
  108. this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDONLY;
  109. continue;
  110. }
  111. if (str.startsWith("a=recvonly")) {
  112. this.flow = "recvonly";
  113. this.flowIndicator = SIPStack.SIP_MEDIAFLOW_RECVONLY;
  114. }
  115. }
  116. }
  117. }
  118. if (bContinueParse && mediadescribe.indexOf("\nc=IN IP4 ") > 0) {
  119. iS = 0;
  120. iE = 0;
  121. iS = mediadescribe.indexOf("c=");
  122. if (iS >= 0) {
  123. iE = mediadescribe.indexOf(SIPStack.SIP_LINE_END, iS);
  124. header = "";
  125. if (iS >= 0 && iE > iS) {
  126. header = mediadescribe.substring(iS, iE + 2);
  127. iE = header.indexOf(SIPStack.SIP_LINE_END);
  128. this.mediaIp = header.substring("c=IN IP4 ".length(), iE);
  129. }
  130. }
  131. }
  132. }
  133. if (!bContinueParse)
  134. resetMedia();
  135. this.flag = true;
  136. }
  137. public void resetMedia() {
  138. this.mediaType = SIPStack.SIP_MEDIATYPE_NONE;
  139. this.mediaIp = null;
  140. this.mediaPort = 0;
  141. this.rtpmapBuffer = null;
  142. this.fmtpBuffer = null;
  143. this.flow = "sendrecv";
  144. this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDRECV;
  145. this.codecS = null;
  146. this.commonCodec = -1;
  147. this.flag = false;
  148. this.mediaString = null;
  149. }
  150. public String getMediaString() {
  151. if (!this.flag)
  152. return null;
  153. String mString = "";
  154. String aString = "";
  155. String fmtpString = "";
  156. String flowString = "a=" + this.flow + SIPStack.SIP_LINE_END;
  157. if (this.mediaType == SIPStack.SIP_MEDIATYPE_AUDIO) {
  158. mString = "m=audio " + this.mediaPort + " RTP/AVP " + this.codecS.toString() + SIPStack.SIP_LINE_END;
  159. } else if (this.mediaType != SIPStack.SIP_MEDIATYPE_VIDEO) {
  160. return null;
  161. }
  162. if (this.rtpmapBuffer.length() > 0)
  163. aString = this.rtpmapBuffer.toString();
  164. if (this.fmtpBuffer.length() > 0)
  165. fmtpString = this.fmtpBuffer.toString();
  166. this.mediaString = String.valueOf(mString) +
  167. aString +
  168. fmtpString +
  169. flowString;
  170. return this.mediaString;
  171. }
  172. public String getFinalMediaString() {
  173. if (!this.flag)
  174. return null;
  175. if (this.commonCodec < 0)
  176. return null;
  177. String mString = "";
  178. String aString = "";
  179. String flowString = "a=" + this.flow + SIPStack.SIP_LINE_END;
  180. if (this.mediaType == SIPStack.SIP_MEDIATYPE_AUDIO) {
  181. mString = "m=audio " + this.mediaPort + " RTP/AVP " + this.commonCodec + SIPStack.SIP_LINE_END;
  182. } else if (this.mediaType != SIPStack.SIP_MEDIATYPE_VIDEO) {
  183. return null;
  184. }
  185. if (this.commonCodec == 0) {
  186. aString = "a=rtpmap:0 PCMU/8000" + SIPStack.SIP_LINE_END;
  187. } else if (this.commonCodec == 8) {
  188. aString = "a=rtpmap:8 PCMA/8000" + SIPStack.SIP_LINE_END;
  189. } else if (this.commonCodec == 18) {
  190. aString = "a=rtpmap:18 G729/8000" + SIPStack.SIP_LINE_END;
  191. }
  192. this.mediaString = String.valueOf(mString) +
  193. aString +
  194. flowString;
  195. return this.mediaString;
  196. }
  197. public boolean setMediaAddress(String ip, int port) {
  198. if (!this.flag)
  199. return false;
  200. if (port < 0 || port > 65556)
  201. return false;
  202. this.mediaIp = ip;
  203. this.mediaPort = port;
  204. return true;
  205. }
  206. public boolean setCodec(int codec) {
  207. if (!this.flag)
  208. return false;
  209. if (this.codecS.length() > 0) {
  210. this.codecS.append(" " + codec);
  211. } else {
  212. this.codecS.append(codec);
  213. }
  214. return true;
  215. }
  216. public boolean setCodec(int codec, String describe) {
  217. if (!this.flag)
  218. return false;
  219. setCodec(codec);
  220. this.rtpmapBuffer.append("a=rtpmap:" + codec + " " + describe + SIPStack.SIP_LINE_END);
  221. return true;
  222. }
  223. public boolean setFmtpDescribe(int codec, String describe) {
  224. if (!this.flag)
  225. return false;
  226. this.fmtpBuffer.append("a=fmtp:" + codec + " " + describe + SIPStack.SIP_LINE_END);
  227. return true;
  228. }
  229. public boolean setCommonCodec(int codec) {
  230. if (!this.flag)
  231. return false;
  232. this.commonCodec = codec;
  233. return true;
  234. }
  235. public boolean setFlow(String flow) {
  236. if (flow == null)
  237. return false;
  238. if (!this.flag)
  239. return false;
  240. this.flow = flow;
  241. if (flow.compareTo("sendrecv") == 0) {
  242. this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDRECV;
  243. } else if (flow.compareTo("sendonly") == 0) {
  244. this.flowIndicator = SIPStack.SIP_MEDIAFLOW_SENDONLY;
  245. } else if (flow.compareTo("recvonly") == 0) {
  246. this.flowIndicator = SIPStack.SIP_MEDIAFLOW_RECVONLY;
  247. } else {
  248. this.flowIndicator = SIPStack.SIP_MEDIAFLOW_NONE;
  249. }
  250. return true;
  251. }
  252. public int negotiateAudioCodec(String sideCodecs) {
  253. if (this.codecS == null || this.codecS.length() <= 0)
  254. return -1;
  255. String myCodecs = this.codecS.toString();
  256. myCodecs.trim();
  257. if (myCodecs == null || myCodecs.length() <= 0)
  258. return -1;
  259. sideCodecs.trim();
  260. if (sideCodecs == null || sideCodecs.length() <= 0)
  261. return -1;
  262. StringTokenizer my_st = new StringTokenizer(myCodecs, " ", true);
  263. String str = null;
  264. int codec = -1;
  265. while (my_st.hasMoreTokens()) {
  266. str = my_st.nextToken().trim();
  267. if (str == null || str.length() == 0)
  268. continue;
  269. codec = Integer.parseInt(str);
  270. if (codec >= 0 && codec < 100) {
  271. StringTokenizer side_st = new StringTokenizer(sideCodecs, " ", true);
  272. int sidecodec = -1;
  273. boolean bDecided = false;
  274. while (side_st.hasMoreTokens()) {
  275. str = side_st.nextToken().trim();
  276. if (str == null || str.length() == 0)
  277. continue;
  278. sidecodec = Integer.parseInt(str);
  279. if (str.length() > 0 && sidecodec >= 0 && codec < 100)
  280. if (sidecodec == codec) {
  281. bDecided = true;
  282. this.commonCodec = codec;
  283. break;
  284. }
  285. }
  286. if (bDecided)
  287. return this.commonCodec;
  288. }
  289. }
  290. return -1;
  291. }
  292. }