Package org.bigbluebutton.voiceconf.sip

Source Code of org.bigbluebutton.voiceconf.sip.SipPeer

/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.voiceconf.sip;

import java.util.Collection;
import java.util.Iterator;
import org.zoolu.sip.provider.*;
import org.zoolu.net.SocketAddress;
import org.slf4j.Logger;
import org.bigbluebutton.voiceconf.messaging.IMessagingService;
import org.bigbluebutton.voiceconf.red5.CallStreamFactory;
import org.bigbluebutton.voiceconf.red5.ClientConnectionManager;
import org.red5.logging.Red5LoggerFactory;
import org.red5.server.api.scope.IScope;
import org.red5.server.api.stream.IBroadcastStream;

/**
* Class that is a peer to the sip server. This class will maintain
* all calls to it's peer server.
* @author Richard Alam
*
*/
public class SipPeer implements SipRegisterAgentListener {
    private static Logger log = Red5LoggerFactory.getLogger(SipPeer.class, "sip");

    private ClientConnectionManager clientConnManager;
    private CallStreamFactory callStreamFactory;
   
    private CallManager callManager = new CallManager();
    private IMessagingService messagingService;
    private SipProvider sipProvider;
    private String clientRtpIp;
    private SipRegisterAgent registerAgent;
    private final String id;
    private final AudioConferenceProvider audioconfProvider;
   
    private boolean registered = false;
    private SipPeerProfile registeredProfile;
   
    public SipPeer(String id, String sipClientRtpIp, String host, int sipPort,
        int startAudioPort, int stopAudioPort, IMessagingService messagingService) {
     
        this.id = id;
        this.clientRtpIp = sipClientRtpIp;
        this.messagingService = messagingService;
        audioconfProvider = new AudioConferenceProvider(host, sipPort, startAudioPort, stopAudioPort);
        initSipProvider(host, sipPort);
    }
   
    private void initSipProvider(String host, int sipPort) {
        sipProvider = new SipProvider(host, sipPort);   
        sipProvider.setOutboundProxy(new SocketAddress(host));
        sipProvider.addSipProviderListener(new OptionMethodListener());     
    }
   
    public void register(String username, String password) {
      log.debug( "SIPUser register" );
        createRegisterUserProfile(username, password);
        if (sipProvider != null) {
          registerAgent = new SipRegisterAgent(sipProvider, registeredProfile.fromUrl,
              registeredProfile.contactUrl, registeredProfile.username,
              registeredProfile.realm, registeredProfile.passwd);
          registerAgent.addListener(this);
          registerAgent.register(registeredProfile.expires, registeredProfile.expires/2, registeredProfile.keepaliveTime);
        }                             
    }
   
    private void createRegisterUserProfile(String username, String password) {           
      registeredProfile = new SipPeerProfile();
      registeredProfile.audioPort = audioconfProvider.getStartAudioPort();
             
        String fromURL = "\"" + username + "\" <sip:" + username + "@" + audioconfProvider.getHost() + ">";
        registeredProfile.username = username;
        registeredProfile.passwd = password;
        registeredProfile.realm = audioconfProvider.getHost();
        registeredProfile.fromUrl = fromURL;
        registeredProfile.contactUrl = "sip:" + username + "@" + sipProvider.getViaAddress();
        if (sipProvider.getPort() != SipStack.default_port) {
          registeredProfile.contactUrl += ":" + sipProvider.getPort();
        }   
        registeredProfile.keepaliveTime=8000;
        registeredProfile.acceptTime=0;
        registeredProfile.hangupTime=20;  
       
        log.debug( "SIPUser register : {}", fromURL );
        log.debug( "SIPUser register : {}", registeredProfile.contactUrl );
    }

    public void call(String clientId, String callerName, String destination) {
      if (!registered) {
        /*
         * If we failed to register with FreeSWITCH, reject all calls right away.
         * This way the user will know that there is a problem as quickly as possible.
         * If we pass the call, it take more that 30seconds for the call to timeout
         * (in case FS is offline) and the user will be kept wondering why the call
         * isn't going through.
         */
        log.warn("We are not registered to FreeSWITCH. However, we will allow {} to call {}.", callerName, destination);
//        return;
      }

      CallAgent ca = createCallAgent(clientId);

      ca.call(callerName, destination);
    }

  public void connectToGlobalStream(String clientId, String callerIdName, String destination) {
      CallAgent ca = createCallAgent(clientId);
     
      ca.connectToGlobalStream(clientId, callerIdName, destination);  
  }

    private CallAgent createCallAgent(String clientId) {
      SipPeerProfile callerProfile = SipPeerProfile.copy(registeredProfile);
      CallAgent ca = new CallAgent(this.clientRtpIp, sipProvider, callerProfile, audioconfProvider, clientId, messagingService);
      ca.setClientConnectionManager(clientConnManager);
      ca.setCallStreamFactory(callStreamFactory);
      callManager.add(ca);

      return ca;
    }

  public void close() {
    log.debug("SIPUser close1");
        try {
      unregister();
    } catch(Exception e) {
      log.error("close: Exception:>\n" + e);
    }

       log.debug("Stopping SipProvider");
       sipProvider.halt();
  }

    public void hangup(String clientId) {
        log.debug( "SIPUser hangup" );

        CallAgent ca = callManager.remove(clientId);

        if (ca != null) {
            if (ca.isListeningToGlobal()) {
                String destination = ca.getDestination();
                ListenOnlyUser lou = GlobalCall.removeUser(clientId, destination);
                if (lou != null) {
                  log.info("User has disconnected from global audio, user [{}] voiceConf {}", lou.callerIdName, lou.voiceConf);
                  messagingService.userDisconnectedFromGlobalAudio(lou.voiceConf, lou.callerIdName);
                }
                ca.hangup();

                boolean roomRemoved = GlobalCall.removeRoomIfUnused(destination);
                log.debug("Should the global connection be removed? {}", roomRemoved? "yes": "no");
                if (roomRemoved) {
                    log.debug("Hanging up the global audio call {}", destination);
                    CallAgent caGlobal = callManager.remove(destination);
                    caGlobal.hangup();
                }
            } else {
                ca.hangup();
            }
        }
    }

    public void unregister() {
      log.debug( "SIPUser unregister" );

      Collection<CallAgent> calls = callManager.getAll();
      for (Iterator<CallAgent> iter = calls.iterator(); iter.hasNext();) {
        CallAgent ca = (CallAgent) iter.next();
        ca.hangup();
      }

        if (registerAgent != null) {
            registerAgent.unregister();
            registerAgent = null;
        }
    }

    public void startTalkStream(String clientId, IBroadcastStream broadcastStream, IScope scope) {
      CallAgent ca = callManager.get(clientId);
        if (ca != null) {
           ca.startTalkStream(broadcastStream, scope);
        }
    }
   
    public void stopTalkStream(String clientId, IBroadcastStream broadcastStream, IScope scope) {
      CallAgent ca = callManager.get(clientId);
        if (ca != null) {
           ca.stopTalkStream(broadcastStream, scope);
        } else {
          log.info("Can't stop talk stream as stream may have already been stopped.");
        }
    }

  @Override
  public void onRegistrationFailure(String result) {
    log.error("Failed to register with Sip Server.");
    registered = false;
  }

  @Override
  public void onRegistrationSuccess(String result) {
    log.info("Successfully registered with Sip Server.");
    registered = true;
  }

  @Override
  public void onUnregistedSuccess() {
    log.info("Successfully unregistered with Sip Server");
    registered = false;
  }
 
  public void setCallStreamFactory(CallStreamFactory csf) {
    callStreamFactory = csf;
  }
 
  public void setClientConnectionManager(ClientConnectionManager ccm) {
    clientConnManager = ccm;
  }
}
TOP

Related Classes of org.bigbluebutton.voiceconf.sip.SipPeer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.