/* * JBoss, Home of Professional Open Source * Copyright 2011, Red Hat, Inc. and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * 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.restcomm.media.control.mgcp.tx.cmd; import java.io.IOException; import java.util.Collection; import org.apache.log4j.Logger; import org.restcomm.media.control.mgcp.MgcpEvent; import org.restcomm.media.control.mgcp.controller.MgcpEndpoint; import org.restcomm.media.control.mgcp.controller.UnknownEventException; import org.restcomm.media.control.mgcp.controller.UnknownPackageException; import org.restcomm.media.control.mgcp.controller.UnknownSignalException; import org.restcomm.media.control.mgcp.controller.naming.UnknownEndpointException; import org.restcomm.media.control.mgcp.message.MgcpRequest; import org.restcomm.media.control.mgcp.message.MgcpResponse; import org.restcomm.media.control.mgcp.message.MgcpResponseCode; import org.restcomm.media.control.mgcp.message.Parameter; import org.restcomm.media.control.mgcp.tx.Action; import org.restcomm.media.scheduler.PriorityQueueScheduler; import org.restcomm.media.scheduler.Scheduler; import org.restcomm.media.scheduler.Task; import org.restcomm.media.scheduler.TaskChain; import org.restcomm.media.spi.utils.Text; /** * * @author yulian oifa */ public class NotificationRequestCmd extends Action { private final static Text SUCCESS= new Text("Success"); private final static Text eventsSplit= new Text("),"); private MgcpRequest request; private MgcpEndpoint endpoint; private MgcpEndpoint[] endpoints = new MgcpEndpoint[1]; private TaskChain handler; private ErrorHandler errorHandler; //error code and message private int code; private Text message; private final static Logger logger = Logger.getLogger(NotificationRequestCmd.class); public NotificationRequestCmd(Scheduler scheduler) { handler = new TaskChain(3,scheduler); Request req = new Request(); Responder responder = new Responder(); Executor executor = new Executor(); errorHandler = new ErrorHandler(); handler.add(req); handler.add(responder); handler.add(executor); this.setActionHandler(handler); this.setRollbackHandler(errorHandler); } private class Request extends Task { public Request() { super(); } @Override public int getQueueNumber() { return PriorityQueueScheduler.MANAGEMENT_QUEUE; } @Override public long perform() { request = (MgcpRequest) getEvent().getMessage(); //getting the endpoint name Text localName = new Text(); Text domainName = new Text(); //read endpoint name from request and break into parts Text[] endpointName = new Text[]{localName, domainName}; request.getEndpoint().divide('@', endpointName); //checking the local name: if (localName.contains('*')) { throw new MgcpCommandException(MgcpResponseCode.WILDCARD_TOO_COMPLICATED, new Text("Wildcard all is not allowed here")); } try { int n = transaction().find(localName, endpoints); if (n == 0) { throw new MgcpCommandException(MgcpResponseCode.ENDPOINT_UNKNOWN, new Text("Unknown endpoint")); } } catch (UnknownEndpointException e) { throw new MgcpCommandException(MgcpResponseCode.ENDPOINT_UNKNOWN, new Text("Endpoint not available")); } endpoint = endpoints[0]; endpoint.getRequest().cancel(); Parameter reqID = request.getParameter(Parameter.REQUEST_ID); if (reqID == null) { throw new MgcpCommandException(MgcpResponseCode.PROTOCOL_ERROR, new Text("Request identifier is missing")); } Text callAgent = null; Parameter p = request.getParameter(Parameter.NOTIFIED_ENTITY); if (p != null) { callAgent = p.getValue(); } Parameter pe = request.getParameter(Parameter.REQUESTED_EVENTS); Parameter ps = request.getParameter(Parameter.REQUESTED_SIGNALS); Collection<Text> events = null; Collection<Text> signals = null; if (pe != null) { events = pe.getValue().split(eventsSplit); } if (ps != null) { signals = ps.getValue().split(eventsSplit); } if (pe != null || ps != null) { try { endpoint.getRequest().accept(reqID.getValue(), callAgent, events, signals); } catch (UnknownEventException e1) { throw new MgcpCommandException(MgcpResponseCode.CAN_NOT_DETECT_EVENT, new Text(e1.getMessage())); } catch (UnknownSignalException e2) { throw new MgcpCommandException(MgcpResponseCode.CAN_NOT_GENERATE_SIGNAL, new Text(e2.getMessage())); } catch (UnknownPackageException e) { throw new MgcpCommandException(MgcpResponseCode.CAN_NOT_DETECT_EVENT, new Text(e.getMessage())); } catch (Exception e) { e.printStackTrace(); throw new MgcpCommandException(MgcpResponseCode.TRANSIENT_ERROR, new Text(e.getMessage())); } } return 0; } } private class Responder extends Task { public Responder() { super(); } @Override public int getQueueNumber() { return PriorityQueueScheduler.MANAGEMENT_QUEUE; } @Override public long perform() { MgcpEvent evt = transaction().getProvider().createEvent(MgcpEvent.RESPONSE, getEvent().getAddress()); MgcpResponse response = (MgcpResponse) evt.getMessage(); response.setResponseCode(MgcpResponseCode.TRANSACTION_WAS_EXECUTED); response.setResponseString(SUCCESS); response.setTxID(transaction().getId()); try { transaction().getProvider().send(evt); } catch (IOException e) { logger.error(e); } finally { evt.recycle(); } return 0; } } private class Executor extends Task { public Executor() { super(); } @Override public int getQueueNumber() { return PriorityQueueScheduler.MANAGEMENT_QUEUE; } @Override public long perform() { endpoint.getRequest().execute(); return 0; } } private class ErrorHandler extends Task { public ErrorHandler() { super(); } @Override public int getQueueNumber() { return PriorityQueueScheduler.MANAGEMENT_QUEUE; } @Override public long perform() { MgcpEvent evt = null; try { code = ((MgcpCommandException) transaction().getLastError()).getCode(); message = ((MgcpCommandException) transaction().getLastError()).getErrorMessage(); evt = transaction().getProvider().createEvent(MgcpEvent.RESPONSE, getEvent().getAddress()); MgcpResponse response = (MgcpResponse) evt.getMessage(); response.setResponseCode(code); response.setResponseString(message); response.setTxID(transaction().getId()); transaction().getProvider().send(evt); } catch (IOException e) { logger.error(e); } finally { evt.recycle(); } return 0; } } }