package org.red5.server.webapp.sip; import java.text.MessageFormat; import java.util.List; import java.util.Set; import org.slf4j.Logger; import org.red5.app.sip.ConnectionClientMethodInvoker; import org.red5.app.sip.SipUserManager; import org.red5.logging.Red5LoggerFactory; import org.red5.server.adapter.MultiThreadedApplicationAdapter; import org.red5.server.api.IClient; import org.red5.server.api.IConnection; import org.red5.server.api.Red5; import org.red5.server.api.scope.IScope; import org.red5.server.api.service.IServiceCapableConnection; import org.red5.server.api.stream.IBroadcastStream; public class VoiceConferenceApplication extends MultiThreadedApplicationAdapter { private static Logger log = Red5LoggerFactory.getLogger(VoiceConferenceApplication.class, "sip"); private SipUserManager sipManager; private String asteriskHost; private int startSIPPort = 5070; private int stopSIPPort = 5099; private int sipPort; private int startRTPPort = 3000; private int stopRTPPort = 3029; private int rtpPort; private String password = "secret"; private MessageFormat callExtensionPattern = new MessageFormat("{0}"); @Override public boolean appStart(IScope scope) { log.debug("VoiceConferenceApplication appStart[" + scope.getName() + "]"); sipPort = startSIPPort; rtpPort = startRTPPort; return true; } @Override public void appStop(IScope scope) { log.debug("VoiceConferenceApplication appStop[" + scope.getName() + "]"); sipManager.destroyAllSessions(); } @Override public boolean appConnect(IConnection conn, Object[] params) { IServiceCapableConnection service = (IServiceCapableConnection) conn; log.debug("VoiceConferenceApplication appConnect[" + conn.getClient().getId() + "," + service + "]"); return true; } @Override public boolean appJoin(IClient client, IScope scope) { log.debug("VoiceConferenceApplication appJoin[" + client.getId() + "]"); return true; } @Override public void appLeave(IClient client, IScope scope) { log.debug("VoiceConferenceApplication appLeave[" + client.getId() + "]"); String userid = getSipUserId(); log.debug( "Red5SIP Client closing client " +userid ); sipManager.close(userid); } @Override public void streamPublishStart(IBroadcastStream stream) { log.debug("streamPublishStart: {}; {}", stream, stream.getPublishedName()); System.out.println("streamPublishStart: " + stream.getPublishedName()); super.streamPublishStart(stream); String userid = getSipUserId(); sipManager.startTalkStream(userid, stream, Red5.getConnectionLocal().getScope()); } @Override public void streamBroadcastClose(IBroadcastStream stream) { System.out.println("streamBroadcastClose: " + stream.getPublishedName()); String userid = getSipUserId(); sipManager.stopTalkStream(userid, stream, Red5.getConnectionLocal().getScope()); super.streamBroadcastClose(stream); } public Set<String> getStreams() { IConnection conn = Red5.getConnectionLocal(); return getBroadcastStreamNames( conn.getScope() ); } public void onPing() { log.debug( "Red5SIP Ping" ); } /******************************************************************/ public void open(String obproxy,String uid, String phone, String username, String password, String realm, String proxy) { System.out.println("Red5SIP open"); login(obproxy, uid, phone, username, password, realm, proxy); register(uid); } public void login(String obproxy, String uid, String phone, String username, String password, String realm, String proxy) { System.out.println("Red5SIP login " + uid); int rport = getRtpPort(); int sport = getSipPort(); login(proxy, uid, new Integer(rtpPort).toString(), username, password, realm, proxy, sport, rport); } /******************************************************************/ private synchronized int getRtpPort() { int rtpport = rtpPort; rtpPort++; if (rtpPort > stopRTPPort) rtpPort = startRTPPort; return rtpport; } private synchronized int getSipPort() { int sipport = sipPort; sipPort++; if (sipPort > stopSIPPort) sipPort = startSIPPort; return sipport; } public void open(String uid, String username) { log.debug("Red5SIP open"); login(uid, username); register(uid); } public void login(String userid, String username) { log.debug("Red5SIP login " + userid); /* * Let's tie this users account to the RTPPort. This allows us to dynamically * register a user when he/she joins the conference. */ String realm = asteriskHost; //asteriskHost; "192.168.0.120"; String proxy = realm; int rport = getRtpPort(); int sport = getSipPort(); log.debug("Logging in as [" + rport + "," + sport + "]"); //SipUser will connect to "outbound-proxy", just pass-in the proxy for it. login(proxy, userid, new Integer(rport).toString(), username, password, realm, proxy, sport, rport); } private void login(String obproxy, String uid, String phone, String username, String password, String realm, String proxy, int sipport, int rtpport) { System.out.println("Red5SIP login " + uid); IConnection conn = Red5.getConnectionLocal(); IServiceCapableConnection service = (IServiceCapableConnection) conn; ConnectionClientMethodInvoker rtmpConnection = new ConnectionClientMethodInvoker(service, conn.getScope()); String userid = getSipUserId(); sipManager.createSipUser(userid, rtmpConnection, sipport, rtpport); sipManager.login(userid, obproxy, phone, username, password, realm, proxy); } public void register(String uid) { log.debug("Red5SIP register"); String userid = getSipUserId(); sipManager.registerSipUser(userid); } public void call(String uid, String destination) { //destination = "600"; log.debug("Red5SIP Call " + destination); System.out.println("Red5SIP Call " + destination); String userid = getSipUserId(); String extension = callExtensionPattern.format(new String[] { destination }); sipManager.call(userid, extension); } public void dtmf(String uid, String digits) { log.debug("Red5SIP DTMF " + digits); String userid = getSipUserId(); sipManager.passDtmf(userid, digits); } public void accept(String uid) { log.debug("Red5SIP Accept"); String userid = getSipUserId(); sipManager.accept(userid); } public void unregister(String uid) { log.debug("Red5SIP unregister"); String userid = getSipUserId(); sipManager.unregister(userid); } public void hangup(String uid) { log.debug("Red5SIP Hangup"); String userid = getSipUserId(); sipManager.hangup(userid); } /* public void streamStatus(String uid, String status) { log.debug("Red5SIP streamStatus"); String userid = getSipUserId(); sipManager.streamStatus(userid, status); } */ public void close(String uid) { log.debug("Red5SIP endRegister"); String userid = getSipUserId(); sipManager.close(userid); } private String getSipUserId() { IConnection conn = Red5.getConnectionLocal(); return conn.getClient().getId(); } public void setAsteriskHost(String h) { asteriskHost = h; } public void setStartSIPPort(int startSIPPort) { this.startSIPPort = startSIPPort; } public void setStopSIPPort(int stopSIPPort) { this.stopSIPPort = stopSIPPort; } public void setStartRTPPort(int startRTPPort) { this.startRTPPort = startRTPPort; } public void setStopRTPPort(int stopRTPPort) { this.stopRTPPort = stopRTPPort; } public void setCallExtensionPattern(String callExtensionPattern) { this.callExtensionPattern = new MessageFormat(callExtensionPattern); } public void setSipUserManager(SipUserManager sum) { sipManager = sum; } }