org.mobicents.media.control.mgcp.command.ModifyConnectionCommand Maven / Gradle / Ivy
/*
* TeleStax, Open Source Cloud Communications
* Copyright 2011-2016, Telestax Inc and individual contributors
* by the @authors tag.
*
* This 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 2.1 of
* the License, or (at your option) any later version.
*
* This software 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 this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.mobicents.media.control.mgcp.command;
import org.apache.log4j.Logger;
import org.mobicents.media.control.mgcp.connection.MgcpConnection;
import org.mobicents.media.control.mgcp.endpoint.MgcpEndpoint;
import org.mobicents.media.control.mgcp.endpoint.MgcpEndpointManager;
import org.mobicents.media.control.mgcp.exception.MgcpConnectionException;
import org.mobicents.media.control.mgcp.message.MgcpParameterType;
import org.mobicents.media.control.mgcp.message.MgcpResponseCode;
import org.mobicents.media.control.mgcp.util.collections.Parameters;
import org.mobicents.media.server.spi.ConnectionMode;
import com.google.common.base.Optional;
/**
* This command is used to modify the characteristics of a gateway's "view" of a connection.
* This "view" of the call includes both the local connection descriptor as well as the remote connection descriptor.
*
* @author Henrique Rosa ([email protected])
*
*/
public class ModifyConnectionCommand extends AbstractMgcpCommand {
private static final Logger log = Logger.getLogger(ModifyConnectionCommand.class);
public ModifyConnectionCommand(int transactionId, Parameters parameters, MgcpEndpointManager endpointManager) {
super(transactionId, parameters, endpointManager);
}
private void validateParameters(Parameters parameters, MdcxContext context) throws MgcpCommandException, RuntimeException {
// Call ID
Optional callId = parameters.getIntegerBase16(MgcpParameterType.CALL_ID);
if (!callId.isPresent()) {
throw new MgcpCommandException(MgcpResponseCode.INCORRECT_CALL_ID);
} else {
context.callId = callId.get();
}
// Endpoint ID
Optional endpointId = parameters.getString(MgcpParameterType.ENDPOINT_ID);
if (!endpointId.isPresent()) {
throw new MgcpCommandException(MgcpResponseCode.ENDPOINT_UNKNOWN);
} else if (endpointId.get().contains(WILDCARD_ALL) || endpointId.get().contains(WILDCARD_ANY)) {
throw new MgcpCommandException(MgcpResponseCode.WILDCARD_TOO_COMPLICATED);
} else {
context.endpointId = endpointId.get();
}
// TODO Local Connection Options
// Connection ID
Optional connectionId = parameters.getIntegerBase16(MgcpParameterType.CONNECTION_ID);
if(!connectionId.isPresent()) {
throw new MgcpCommandException(MgcpResponseCode.INCORRECT_CONNECTION_ID);
} else {
context.connectionId = connectionId.get();
}
// Connection Mode (optional)
Optional mode = parameters.getString(MgcpParameterType.MODE);
if (mode.isPresent()) {
try {
ConnectionMode connectionMode = ConnectionMode.fromDescription(mode.get());
context.mode = connectionMode;
} catch (IllegalArgumentException e) {
throw new MgcpCommandException(MgcpResponseCode.INVALID_OR_UNSUPPORTED_MODE);
}
}
// Remote Description (optional)
context.remoteDescription = parameters.getString(MgcpParameterType.SDP).or("");
}
private void executeCommand(MdcxContext context) throws MgcpCommandException {
// Retrieve endpoint
String endpointId = context.endpointId;
MgcpEndpoint endpoint = this.endpointManager.getEndpoint(endpointId);
if (endpoint == null) {
throw new MgcpCommandException(MgcpResponseCode.ENDPOINT_UNKNOWN);
}
// Retrieve connection from endpoint
int callId = context.callId;
int connectionId = context.connectionId;
MgcpConnection connection = endpoint.getConnection(callId, connectionId);
if (connection == null) {
throw new MgcpCommandException(MgcpResponseCode.INCORRECT_CONNECTION_ID);
}
// Set Mode (if specified)
ConnectionMode mode = context.mode;
if (mode != null) {
connection.setMode(mode);
}
// Set Remote Description (if defined)
String remoteSdp = context.remoteDescription;
if (!remoteSdp.isEmpty()) {
try {
String localSdp = connection.open(remoteSdp);
context.localDescription = localSdp;
} catch (MgcpConnectionException e) {
throw new MgcpCommandException(MgcpResponseCode.UNSUPPORTED_SDP);
}
}
}
private MgcpCommandResult respond(MdcxContext context) {
Parameters parameters = new Parameters<>();
MgcpCommandResult result = new MgcpCommandResult(this.transactionId, context.code, context.message, parameters);
boolean successful = context.code < 300;
if(successful) {
translateContext(context, parameters);
}
return result;
}
private void translateContext(MdcxContext context, Parameters parameters) {
// Local Description (optional)
String localDescription = context.localDescription;
if(!localDescription.isEmpty()) {
parameters.put(MgcpParameterType.SDP, localDescription);
}
}
@Override
public MgcpCommandResult call() {
// Initialize empty context
MdcxContext context = new MdcxContext();
try {
// Validate Parameters
validateParameters(this.requestParameters, context);
// Execute Command
executeCommand(context);
context.code = MgcpResponseCode.TRANSACTION_WAS_EXECUTED.code();
context.message = MgcpResponseCode.TRANSACTION_WAS_EXECUTED.message();
} catch (RuntimeException e) {
log.error("Unexpected error occurred during tx=" + this.transactionId + " execution. Rolling back.");
context.code = MgcpResponseCode.PROTOCOL_ERROR.code();
context.message = MgcpResponseCode.PROTOCOL_ERROR.message();
} catch (MgcpCommandException e) {
log.error("Protocol error occurred during tx=" + this.transactionId + " execution: " + e.getMessage());
context.code = e.getCode();
context.message = e.getMessage();
}
return respond(context);
}
private class MdcxContext {
private int callId;
private String endpointId;
private int connectionId;
private ConnectionMode mode;
private String remoteDescription;
private String localDescription;
private int code;
private String message;
public MdcxContext() {
this.callId = -1;
this.endpointId = "";
this.connectionId = -1;
this.remoteDescription = "";
this.localDescription = "";
this.mode = null;
this.code = MgcpResponseCode.ABORTED.code();
this.message = MgcpResponseCode.ABORTED.message();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy