@Test public void testInactiveHalfOpenTimer() throws MgcpConnectionException, InterruptedException { final int identifier = 1; final int halfOpenTimeout = 0; final int openTimeout = 4; final MgcpEventObserver observer = mock(MgcpEventObserver.class); final ArgumentCaptor<RtpTimeoutEvent> timeoutCaptor = ArgumentCaptor.forClass(RtpTimeoutEvent.class); final AudioChannel audioChannel = mock(AudioChannel.class); final MediaChannelProvider channelProvider = mock(MediaChannelProvider.class); final MgcpEventProvider eventProvider = mock(MgcpEventProvider.class); when(channelProvider.provideAudioChannel()).thenReturn(audioChannel); when(audioChannel.getFormats()).thenReturn(AVProfile.audio); when(audioChannel.getMediaType()).thenReturn(AudioChannel.MEDIA_TYPE); final MgcpRemoteConnection connection = new MgcpRemoteConnection(identifier, halfOpenTimeout, openTimeout, eventProvider, channelProvider, this.executor); connection.observe(observer); connection.halfOpen(new LocalConnectionOptions()); Thread.sleep(openTimeout * 1000); assertEquals(MgcpConnectionState.HALF_OPEN, connection.state); verify(observer, never()).onEvent(eq(connection), timeoutCaptor.capture()); }
@Override public String halfOpen(LocalConnectionOptions options) throws MgcpConnectionException { synchronized (this.stateLock) { switch (this.state) { case CLOSED: this.state = MgcpConnectionState.HALF_OPEN; String webrtcOption = options.get(LocalConnectionOptionType.WEBRTC); this.outbound = true; this.webrtc = webrtcOption != null && webrtcOption.equals("true"); this.audioChannel.open(); try { this.audioChannel.bind(false, this.webrtc); } catch (IOException e) { throw new MgcpConnectionException("Could not bind audio channel " + this.cname, e); } if (this.webrtc) { this.audioChannel.enableICE(this.externalAddress, true); this.audioChannel.enableDTLS(); } this.localSdp = SdpFactory.buildSdp(true, this.localAddress, this.externalAddress, this.audioChannel); if(log.isDebugEnabled()) { log.debug("Connection " + getHexIdentifier() + " state is " + this.state.name()); } if (this.halfOpenTimeout > 0) { expireIn(this.halfOpenTimeout); } return this.localSdp.toString(); default: throw new MgcpConnectionException("Cannot half-open connection " + this.getHexIdentifier() + " because state is " + this.state.name()); } } }
MgcpRemoteConnection extends AbstractMgcpConnection implements RtpListener { @Override public String halfOpen(LocalConnectionOptions options) throws MgcpConnectionException { synchronized (this.stateLock) { switch (this.state) { case CLOSED: this.state = MgcpConnectionState.HALF_OPEN; String webrtcOption = options.get(LocalConnectionOptionType.WEBRTC); this.outbound = true; this.webrtc = webrtcOption != null && webrtcOption.equals("true"); this.audioChannel.open(); try { this.audioChannel.bind(false, this.webrtc); } catch (IOException e) { throw new MgcpConnectionException("Could not bind audio channel " + this.cname, e); } if (this.webrtc) { this.audioChannel.enableICE(this.externalAddress, true); this.audioChannel.enableDTLS(); } this.localSdp = SdpFactory.buildSdp(true, this.localAddress, this.externalAddress, this.audioChannel); if(log.isDebugEnabled()) { log.debug("Connection " + getHexIdentifier() + " state is " + this.state.name()); } if (this.halfOpenTimeout > 0) { expireIn(this.halfOpenTimeout); } return this.localSdp.toString(); default: throw new MgcpConnectionException("Cannot half-open connection " + this.getHexIdentifier() + " because state is " + this.state.name()); } } } }
MgcpRemoteConnection extends AbstractMgcpConnection implements RtpListener { @Override public String halfOpen(LocalConnectionOptions options) throws MgcpConnectionException { synchronized (this.stateLock) { switch (this.state) { case CLOSED: this.state = MgcpConnectionState.HALF_OPEN; String webrtcOption = options.get(LocalConnectionOptionType.WEBRTC); this.outbound = true; this.webrtc = webrtcOption != null && webrtcOption.equals("true"); this.audioChannel.open(); try { this.audioChannel.bind(false, this.webrtc); } catch (IOException e) { throw new MgcpConnectionException("Could not bind audio channel " + this.cname, e); } if (this.webrtc) { this.audioChannel.enableICE(this.externalAddress, true); this.audioChannel.enableDTLS(); } this.localSdp = SdpFactory.buildSdp(true, this.localAddress, this.externalAddress, this.audioChannel); if(log.isDebugEnabled()) { log.debug("Connection " + getHexIdentifier() + " state is " + this.state.name()); } if (this.halfOpenTimeout > 0) { expireIn(this.halfOpenTimeout); } return this.localSdp.toString(); default: throw new MgcpConnectionException("Cannot half-open connection " + this.getHexIdentifier() + " because state is " + this.state.name()); } } } MgcpRemoteConnection(int identifier, int callId, int halfOpenTimeout, int openTimeout, MgcpEventProvider eventProvider, MediaChannelProvider channelProvider, ListeningScheduledExecutorService executor);  MgcpRemoteConnection(int identifier, int callId, int timeout, MgcpEventProvider eventProvider, MediaChannelProvider channelProvider, ListeningScheduledExecutorService executor);  MgcpRemoteConnection(int identifier, int callId, MgcpEventProvider eventProvider, MediaChannelProvider channelProvider, ListeningScheduledExecutorService executor); }
MgcpRemoteConnection extends AbstractMgcpConnection implements RtpListener { @Override public String halfOpen(LocalConnectionOptions options) throws MgcpConnectionException { synchronized (this.stateLock) { switch (this.state) { case CLOSED: this.state = MgcpConnectionState.HALF_OPEN; String webrtcOption = options.get(LocalConnectionOptionType.WEBRTC); this.outbound = true; this.webrtc = webrtcOption != null && webrtcOption.equals("true"); this.audioChannel.open(); try { this.audioChannel.bind(false, this.webrtc); } catch (IOException e) { throw new MgcpConnectionException("Could not bind audio channel " + this.cname, e); } if (this.webrtc) { this.audioChannel.enableICE(this.externalAddress, true); this.audioChannel.enableDTLS(); } this.localSdp = SdpFactory.buildSdp(true, this.localAddress, this.externalAddress, this.audioChannel); if(log.isDebugEnabled()) { log.debug("Connection " + getHexIdentifier() + " state is " + this.state.name()); } if (this.halfOpenTimeout > 0) { expireIn(this.halfOpenTimeout); } return this.localSdp.toString(); default: throw new MgcpConnectionException("Cannot half-open connection " + this.getHexIdentifier() + " because state is " + this.state.name()); } } } MgcpRemoteConnection(int identifier, int callId, int halfOpenTimeout, int openTimeout, MgcpEventProvider eventProvider, MediaChannelProvider channelProvider, ListeningScheduledExecutorService executor);  MgcpRemoteConnection(int identifier, int callId, int timeout, MgcpEventProvider eventProvider, MediaChannelProvider channelProvider, ListeningScheduledExecutorService executor);  MgcpRemoteConnection(int identifier, int callId, MgcpEventProvider eventProvider, MediaChannelProvider channelProvider, ListeningScheduledExecutorService executor); @Override boolean isLocal(); @Override void setMode(ConnectionMode mode); @Override String halfOpen(LocalConnectionOptions options); @Override String open(String sdp); @Override String renegotiate(String sdp); @Override void close(); @Override AudioComponent getAudioComponent(); @Override OOBComponent getOutOfBandComponent(); @Override void onRtpFailure(Throwable e); @Override void onRtpFailure(String message); @Override void onRtcpFailure(Throwable e); @Override void onRtcpFailure(String e); }
MgcpRemoteConnection extends AbstractMgcpConnection implements RtpListener { @Override public String halfOpen(LocalConnectionOptions options) throws MgcpConnectionException { synchronized (this.stateLock) { switch (this.state) { case CLOSED: this.state = MgcpConnectionState.HALF_OPEN; String webrtcOption = options.get(LocalConnectionOptionType.WEBRTC); this.outbound = true; this.webrtc = webrtcOption != null && webrtcOption.equals("true"); this.audioChannel.open(); try { this.audioChannel.bind(false, this.webrtc); } catch (IOException e) { throw new MgcpConnectionException("Could not bind audio channel " + this.cname, e); } if (this.webrtc) { this.audioChannel.enableICE(this.externalAddress, true); this.audioChannel.enableDTLS(); } this.localSdp = SdpFactory.buildSdp(true, this.localAddress, this.externalAddress, this.audioChannel); if(log.isDebugEnabled()) { log.debug("Connection " + getHexIdentifier() + " state is " + this.state.name()); } if (this.halfOpenTimeout > 0) { expireIn(this.halfOpenTimeout); } return this.localSdp.toString(); default: throw new MgcpConnectionException("Cannot half-open connection " + this.getHexIdentifier() + " because state is " + this.state.name()); } } } MgcpRemoteConnection(int identifier, int callId, int halfOpenTimeout, int openTimeout, MgcpEventProvider eventProvider, MediaChannelProvider channelProvider, ListeningScheduledExecutorService executor);  MgcpRemoteConnection(int identifier, int callId, int timeout, MgcpEventProvider eventProvider, MediaChannelProvider channelProvider, ListeningScheduledExecutorService executor);  MgcpRemoteConnection(int identifier, int callId, MgcpEventProvider eventProvider, MediaChannelProvider channelProvider, ListeningScheduledExecutorService executor); @Override boolean isLocal(); @Override void setMode(ConnectionMode mode); @Override String halfOpen(LocalConnectionOptions options); @Override String open(String sdp); @Override String renegotiate(String sdp); @Override void close(); @Override AudioComponent getAudioComponent(); @Override OOBComponent getOutOfBandComponent(); @Override void onRtpFailure(Throwable e); @Override void onRtpFailure(String message); @Override void onRtcpFailure(Throwable e); @Override void onRtcpFailure(String e);  }