PageRenderTime 27ms CodeModel.GetById 48ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/phono-java-audio/src/java/com/phono/rtp/RTPApplet.java

https://github.com/mastahype/PhonoSDK
Java | 327 lines | 235 code | 23 blank | 69 comment | 26 complexity | 7f533e63f67eebd8839609011dc5a019 MD5 | raw file
  1. /*
  2. * Copyright 2011 Voxeo Corp.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package com.phono.rtp;
  18. import com.phono.audio.AudioException;
  19. import com.phono.audio.Log;
  20. import com.phono.api.Codec;
  21. import com.phono.api.CodecList;
  22. import com.phono.api.Play;
  23. import com.phono.api.Share;
  24. import java.applet.Applet;
  25. import java.io.IOException;
  26. import java.io.StringReader;
  27. import java.net.DatagramSocket;
  28. import java.net.Inet4Address;
  29. import java.net.Inet6Address;
  30. import java.net.InetAddress;
  31. import java.net.NetworkInterface;
  32. import java.net.SocketException;
  33. import java.security.AccessControlException;
  34. import java.security.AccessController;
  35. import java.security.AllPermission;
  36. import java.security.Permission;
  37. import java.security.PrivilegedAction;
  38. import java.security.PrivilegedActionException;
  39. import java.security.PrivilegedExceptionAction;
  40. import java.util.Enumeration;
  41. import java.util.Hashtable;
  42. import java.util.Properties;
  43. import java.util.logging.Level;
  44. import java.util.logging.Logger;
  45. import netscape.javascript.*;
  46. public class RTPApplet extends Applet {
  47. private PhonoAudioShim _audio;
  48. final private Hashtable _endpoints = new Hashtable();
  49. private CodecList _codecList;
  50. private boolean _userClickedTrust = false;
  51. private String _deviceList;
  52. /**
  53. * Initialization method that will be called after the applet is loaded
  54. * into the browser.
  55. */
  56. @Override
  57. public void init() {
  58. Log.setLevel(Log.DEBUG);
  59. Permission all = new AllPermission();
  60. try {
  61. AccessController.checkPermission(all);
  62. _userClickedTrust = true;
  63. } catch (AccessControlException ace) {
  64. _userClickedTrust = false;
  65. Log.error("permission problem " + ace.getMessage());
  66. }
  67. printSigners(this.getClass());
  68. StringBuffer bret = new StringBuffer("{\n");
  69. PhonoAudioShim.getMixersJSON(bret);
  70. bret.append("}\n");
  71. _deviceList = bret.toString();
  72. _audio = new PhonoAudioShim();
  73. _codecList = new CodecList(_audio);
  74. // Call the callback that we have been given to say we are ready
  75. String callback = this.getParameter("callback");
  76. if (callback != null) {
  77. JSObject jso = JSObject.getWindow(this);
  78. try {
  79. jso.call(callback, new String[]{_deviceList});
  80. } catch (Throwable t){
  81. Log.error(t.getMessage());
  82. }
  83. }
  84. }
  85. @Override
  86. public void start(){
  87. if (!_userClickedTrust){
  88. Log.error("User does not trust us. Can't continue.");
  89. }
  90. }
  91. @Override
  92. public void stop(){
  93. Log.debug("Applet stopped");
  94. }
  95. @Override
  96. public void destroy(){
  97. Log.debug("Applet destroyed");
  98. // if (_audio != null){
  99. // _audio.destroy();
  100. // }
  101. }
  102. public String allocateEndpoint() {
  103. String ret = null;
  104. // strictly we supposedly want to actually allocate a socket here,
  105. // but there is _really_ no point so we make plausible something up
  106. synchronized (_endpoints) {
  107. /*
  108. if (_localAdd == null) {
  109. AccessController.doPrivileged(new PrivilegedAction<Void>() {
  110. public Void run() {
  111. findAnIPAddress();
  112. return null; // nothing to return
  113. }
  114. });
  115. }
  116. */
  117. Endpoint r = AccessController.doPrivileged(new PrivilegedAction<Endpoint>() {
  118. public Endpoint run() {
  119. Endpoint end = null;
  120. try {
  121. end = Endpoint.allocate();
  122. } catch (SocketException ex) {
  123. Log.error("Problem allocating a socket " + ex.getMessage());
  124. }
  125. return end;
  126. }
  127. });
  128. /* String u = "rtp://" + _localAdd + ":" + _portNo++;
  129. Endpoint r = new Endpoint(u);
  130. *
  131. */
  132. _endpoints.put(r.getLocalURI(), r);
  133. ret = r.getLocalURI();
  134. }
  135. return ret;
  136. }
  137. public void freeEndpoint(String uri) {
  138. synchronized (_endpoints) {
  139. Endpoint e = (Endpoint) _endpoints.get(uri);
  140. if (e != null) {
  141. e.release();
  142. }
  143. _endpoints.remove(e);
  144. }
  145. }
  146. // see http://download.oracle.com/javase/7/docs/api/java/security/AccessController.html
  147. // for doc on priv escalation
  148. public Codec[] codecs() {
  149. return _codecList.getCodecs();
  150. }
  151. public Share share(String uri, final Codec codec, boolean autoStart) {
  152. return share(uri, codec, autoStart, null, null);
  153. }
  154. /**
  155. *
  156. * @param uri rtp://localhost:port<:remotehost:remoteport>
  157. * @param autoPlay start immediatly
  158. * @param codec Selected codec.
  159. * @param srtp crypto params
  160. * @return
  161. */
  162. public Share share(String uri, final Codec codec, boolean autoStart, String srtpPropsl, String srtpPropsr) {
  163. Share ret = null;
  164. Share s = null;
  165. Properties spl = null;
  166. Properties spr = null;
  167. if ((srtpPropsl != null) && (srtpPropsl.length() > 0)) {
  168. StringReader reader = new StringReader(srtpPropsl);
  169. spl = new Properties();
  170. try {
  171. spl.load(reader);
  172. } catch (IOException ex) {
  173. Log.error("srtp Props invalid format" + ex.toString());
  174. }
  175. }
  176. if ((srtpPropsr != null) && (srtpPropsr.length() > 0)) {
  177. StringReader reader = new StringReader(srtpPropsr);
  178. spr = new Properties();
  179. try {
  180. spr.load(reader);
  181. } catch (IOException ex) {
  182. Log.error("srtp Props invalid format" + ex.toString());
  183. }
  184. }
  185. Log.verb("in share() codec = " + codec.name);
  186. Log.verb("in share() uri = " + uri);
  187. try {
  188. s = new Share(uri, _audio, codec.pt, spl, spr);
  189. AccessController.doPrivileged(new PrivilegedAction<Void>() {
  190. public Void run() {
  191. try {
  192. _audio.init(codec.iaxcn, 100);
  193. } catch (AudioException ex) {
  194. Log.error(ex.toString());
  195. }
  196. return null; // nothing to return
  197. }
  198. });
  199. String luri = s.getLocalURI();
  200. synchronized (_endpoints) {
  201. Endpoint e = (Endpoint) _endpoints.get(luri);
  202. if (e != null) {
  203. e.setShare(s);
  204. } else {
  205. e = new Endpoint(luri);
  206. e.setShare(s);
  207. Log.warn("Unexpected local endpoint used :" + luri);
  208. _endpoints.put(luri, e);
  209. }
  210. }
  211. // should check auto start here...
  212. if (autoStart) {
  213. s.start();
  214. }
  215. ret = s; // only return the share if no exceptions ....
  216. } catch (Exception ex) {
  217. if (s != null) {
  218. s.stop(); // minimal cleanup on errors.
  219. }
  220. Log.error(ex.toString()); // do something useful here....
  221. }
  222. return ret;
  223. }
  224. // TODO overwrite start(), stop() and destroy() methods
  225. /*
  226. allocateEndpoint() -> uri
  227. Allocate a local RTP endpoint uri, rtp://ipaddress:port
  228. freeEndpoint(uri)
  229. Free a given local RTP endpoint
  230. share(uri, autoPlay, codec) -> Share
  231. Start to send audio from the localUri to the remoteUri {bi-directionally? - thp}
  232. play(uri, autoPlay) -> Play
  233. Start to play audio received on the local Uri,
  234. or from a remote http Uri (used for mp3 ringtones etc).
  235. codecs() -> Codec[]
  236. Return an array of codecs supported by the plugin {JSON array of property objects thp}
  237. *
  238. */
  239. public Play play(final String uri, boolean autoStart) {
  240. Play s = null;
  241. Log.debug("in play() uri = " + uri);
  242. try {
  243. s = AccessController.doPrivileged(
  244. new PrivilegedExceptionAction<Play>() {
  245. public Play run() {
  246. Play id = new Play(uri);
  247. return id;
  248. }
  249. });
  250. if (autoStart) {
  251. s.start();
  252. }
  253. } catch (Exception ex) {
  254. Log.error(ex.toString()); // do something useful here....
  255. }
  256. return s;
  257. }
  258. public String getJSONStatus() {
  259. StringBuffer ret = new StringBuffer("{\n");
  260. ret.append("userTrust").append(" : ");
  261. ret.append(_userClickedTrust?"true":"false").append(",\n");
  262. Enumeration rat = _endpoints.elements();
  263. ret.append("endpoints").append(" : ");
  264. ret.append("[");
  265. while (rat.hasMoreElements()) {
  266. Endpoint r = (Endpoint) rat.nextElement();
  267. r.getJSONStatus(ret);
  268. ret.append(",");
  269. }
  270. ret.append("]\n");
  271. ret.append("}\n");
  272. // Log.debug("Phonefromhere.getCallStatus(): " + ret);
  273. return ret.toString();
  274. }
  275. void printSigners(Class cl) {
  276. Object[] signers = cl.getSigners();
  277. if (signers != null) {
  278. int len = signers.length;
  279. for (int i = 0; i < len; i++) {
  280. Object o = signers[i];
  281. if (o instanceof java.security.cert.X509Certificate) {
  282. java.security.cert.X509Certificate cert =
  283. (java.security.cert.X509Certificate) o;
  284. Log.debug(cl.getName() + ": signer " + i
  285. + " = " + cert.getSubjectX500Principal().getName());
  286. }
  287. }
  288. }
  289. else {
  290. Log.debug(cl.getName() + " is not signed (has no signers)");
  291. }
  292. }
  293. public String getAudioDeviceList(){
  294. return _deviceList;
  295. }
  296. public void setAudioIn(String ain){
  297. if (_audio != null){
  298. _audio.setAudioInName(ain);
  299. Log.debug("Set audio input device preference to "+ ain);
  300. }
  301. }
  302. }