org.mobicents.ss7.hardware.dahdi.oam.DahdiLinkset Maven / Gradle / Ivy
The newest version!
/*
* 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.mobicents.ss7.hardware.dahdi.oam;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.ConcurrentLinkedQueue;
import javolution.util.FastMap;
import javolution.xml.XMLFormat;
import javolution.xml.stream.XMLStreamException;
import org.apache.log4j.Logger;
import org.mobicents.protocols.ss7.mtp.Mtp3;
import org.mobicents.protocols.ss7.mtp.Mtp3Listener;
import org.mobicents.protocols.ss7.scheduler.Scheduler;
import org.mobicents.protocols.stream.api.SelectorKey;
import org.mobicents.protocols.stream.api.SelectorProvider;
import org.mobicents.protocols.stream.api.StreamSelector;
import org.mobicents.ss7.linkset.oam.FormatterHelp;
import org.mobicents.ss7.linkset.oam.Link;
import org.mobicents.ss7.linkset.oam.LinkMode;
import org.mobicents.ss7.linkset.oam.LinkOAMMessages;
import org.mobicents.ss7.linkset.oam.LinkState;
import org.mobicents.ss7.linkset.oam.Linkset;
import org.mobicents.ss7.linkset.oam.LinksetMode;
import org.mobicents.ss7.linkset.oam.LinksetSelector;
import org.mobicents.ss7.linkset.oam.LinksetState;
import org.mobicents.ss7.linkset.oam.LinksetStream;
/**
*
* Linkset for dahdi based hardware. dahdi boards usually have no MTP support and depends on external software
* to provide MTP2/MTP3 support.
*
*
* DahdiLinkset encapsulates the {@link Mtp3 Mtp3} and {@link Mtp2 Mtp2} protocols.
*
*
* Well known dahdi based SS7 cards are Diguim and Sangoma
*
*
* @author amit bhayani
*
*/
public class DahdiLinkset extends Linkset implements Mtp3Listener {
private static final Logger logger = Logger.getLogger(DahdiLinkset.class);
private Mtp3 mtp3 = null;
private ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();
public DahdiLinkset() {
super();
}
public DahdiLinkset(String linksetName, int opc, int dpc, int ni) {
super(linksetName, opc, dpc, ni);
}
@Override
protected void initialize() {
this.linksetStream = new LinksetStreamImpl();
}
@Override
protected void configure() throws Exception {
if (this.mode == LinksetMode.CONFIGURED) {
if (this.mtp3 == null) {
// TODO fix String to TextBuilder
this.mtp3 = new Mtp3(this.linksetName, scheduler);
}
this.mtp3.clearLinks();
try {
this.mtp3.addMtp3Listener(this);
} catch (Exception e) {
// can not be another listener , this only
}
for (FastMap.Entry e = this.links.head(), end = this.links.tail(); (e = e.getNext()) != end;) {
Link value = e.getValue();
if (value.getMode() == LinkMode.CONFIGURED) {
this.mtp3.addLink(((DahdiLink) value).getMtp2());
}
}
this.mtp3.setDpc(this.apc);
this.mtp3.setOpc(this.opc);
this.mtp3.setNetworkIndicator(this.ni);
if (this.state != LinksetState.SHUTDOWN) {
this.mtp3.start();
}
}
}
@Override
public void setScheduler(Scheduler scheduler) {
this.scheduler = scheduler;
if (this.mtp3 != null)
this.mtp3.setScheduler(scheduler);
FastMap.Entry e = this.links.head();
FastMap.Entry end = this.links.tail();
for (; (e = e.getNext()) != end;) {
Link link = e.getValue();
link.setScheduler(scheduler);
}
e = this.loadedLinks.head();
end = this.loadedLinks.tail();
for (; (e = e.getNext()) != end;) {
Link link = e.getValue();
link.setScheduler(scheduler);
}
}
/**
* Operations
*/
@Override
public void createLink(String[] options) throws Exception {
// the command looks like "linkset link create span 1 code 1 channel 1
// linkset1 link1"
if (options.length != 11) {
throw new Exception(LinkOAMMessages.INVALID_COMMAND);
}
String option = options[3];
if (option == null || option.compareTo("span") != 0) {
throw new Exception(LinkOAMMessages.INVALID_COMMAND);
}
int span = Integer.parseInt(options[4]);
option = options[5];
if (option == null || option.compareTo("code") != 0) {
throw new Exception(LinkOAMMessages.INVALID_COMMAND);
}
int code = Integer.parseInt(options[6]);
option = options[7];
if (option == null || option.compareTo("channel") != 0) {
throw new Exception(LinkOAMMessages.INVALID_COMMAND);
}
int channel = Integer.parseInt(options[8]);
option = options[10]; // Link name
if (option == null) {
throw new Exception(LinkOAMMessages.INVALID_COMMAND);
}
if (links.containsKey(option)) {
throw new Exception(LinkOAMMessages.LINK_ALREADY_EXIST);
}
DahdiLink link = new DahdiLink(option, span, channel, code);
link.setScheduler(scheduler);
link.setLinkSet(this);
this.links.put(option, link);
}
@Override
public void deleteLink(String linkName) throws Exception {
Link link = this.links.get(linkName);
if (link == null) {
throw new Exception(LinkOAMMessages.LINK_DOESNT_EXIST);
}
if (link.getState() == LinkState.AVAILABLE) {
throw new Exception(LinkOAMMessages.CANT_DELETE_LINK);
}
this.links.remove(linkName);
}
@Override
public void activate() throws Exception {
if (this.state == LinksetState.AVAILABLE) {
throw new Exception(LinkOAMMessages.LINKSET_ALREADY_ACTIVE);
}
// Check if atleast one Link is in Configured mode
for (FastMap.Entry e = this.links.head(), end = this.links.tail(); (e = e.getNext()) != end;) {
Link value = e.getValue();
if (value.getMode() == LinkMode.CONFIGURED) {
this.mode = LinksetMode.CONFIGURED;
this.configure();
this.state = LinksetState.UNAVAILABLE;
return;
}
}
// If at least 1 Link is not configured
throw new Exception(LinkOAMMessages.LINKSET_NO_LINKS_CONFIGURED);
}
@Override
public void deactivate() throws Exception {
throw new Exception(LinkOAMMessages.NOT_IMPLEMENTED);
}
@Override
public void activateLink(String linkName) throws Exception {
Link link = this.links.get(linkName);
if (link == null) {
throw new Exception(LinkOAMMessages.LINK_DOESNT_EXIST);
}
link.activate();
}
@Override
public void deactivateLink(String linkName) throws Exception {
Link link = this.links.get(linkName);
if (link == null) {
throw new Exception(LinkOAMMessages.LINK_DOESNT_EXIST);
}
link.deactivate();
}
/**
* XML Serialization/Deserialization
*/
protected static final XMLFormat DAHDI_LINKSET_XML = new XMLFormat(DahdiLinkset.class) {
@Override
public void read(javolution.xml.XMLFormat.InputElement xml, DahdiLinkset linkSet) throws XMLStreamException {
LINKSET_XML.read(xml, linkSet);
try {
linkSet.configure();
} catch (Exception e) {
logger.error("Error while initializing dahdi linkset", e);
}
}
@Override
public void write(DahdiLinkset linkSet, javolution.xml.XMLFormat.OutputElement xml) throws XMLStreamException {
LINKSET_XML.write(linkSet, xml);
}
};
// TODO : We still working with Listener model. rather change MTP3 to give
// back byte[] and caller calls .read(byte[] data) to read data
/**
* Mtp3Listener Methods
*/
public void linkDown() {
this.state = LinksetState.UNAVAILABLE;
}
public void linkUp() {
queue.clear();
this.state = LinksetState.AVAILABLE;
}
public void receive(byte[] msgBuff) {
queue.offer(msgBuff);
}
private class LinksetStreamImpl extends LinksetStream {
@Override
public boolean poll(int arg0, int arg1) {
if (mtp3 != null) {
mtp3.run();
return true;
} else {
return false;
}
}
@Override
public String getName() {
return linksetName;
}
public void close() {
// TODO Auto-generated method stub
}
public SelectorProvider provider() {
throw new UnsupportedOperationException("Not supported yet.");
}
public int read(byte[] paramArrayOfByte) throws IOException {
if (queue.isEmpty()) {
return 0;
}
byte[] data = queue.poll();
if (data != null) {
System.arraycopy(data, 0, paramArrayOfByte, 0, data.length);
}
return paramArrayOfByte == null ? 0 : data.length;
}
public SelectorKey register(StreamSelector selector) throws IOException {
return ((LinksetSelector) selector).register(this);
}
public int write(byte[] paramArrayOfByte) throws IOException {
mtp3.send(paramArrayOfByte, paramArrayOfByte.length);
return paramArrayOfByte.length;
}
public int read(ByteBuffer arg0) throws IOException {
// TODO Auto-generated method stub
return 0;
}
public int write(ByteBuffer arg0) throws IOException {
// TODO Auto-generated method stub
return 0;
}
}
@Override
public void print(StringBuffer sb, int leftPad, int descPad) {
// left pad
FormatterHelp.createPad(sb, leftPad);
// Add name
sb.append(this.linksetName);
// check if length is less than Link.NAME_SIZE, add padding
if (this.linksetName.length() < Linkset.NAME_SIZE) {
FormatterHelp.createPad(sb, Linkset.NAME_SIZE - this.linksetName.length());
}
// add desc padding
FormatterHelp.createPad(sb, descPad);
// type is dahdi
sb.append("dahdi");
// add desc padding
FormatterHelp.createPad(sb, descPad);
// add opc
sb.append(LINKSET_OPC).append(FormatterHelp.EQUAL_SIGN).append(this.opc);
// opc can be max 8 (ANSI is max 24bits) digits. Add padding if its not
int length = (Integer.toString(this.opc).length());
if (length < 8) {
FormatterHelp.createPad(sb, 8 - length);
}
// add desc padding
FormatterHelp.createPad(sb, descPad);
// add apc
sb.append(LINKSET_APC).append(FormatterHelp.EQUAL_SIGN).append(this.apc);
// opc can be max 8 (ANSI is max 24bits) digits. Add padding if its not
length = (Integer.toString(this.apc).length());
if (length < 8) {
FormatterHelp.createPad(sb, 8 - length);
}
// add desc padding
FormatterHelp.createPad(sb, descPad);
// add NI
sb.append(LINKSET_NI).append(FormatterHelp.EQUAL_SIGN).append(this.ni);
// add desc padding
FormatterHelp.createPad(sb, descPad);
// add state
sb.append(LINKSET_STATE).append(FormatterHelp.EQUAL_SIGN).append(FormatterHelp.getLinksetState(this.state));
sb.append(FormatterHelp.NEW_LINE);
for (FastMap.Entry e = this.links.head(), end = this.links.tail(); (e = e.getNext()) != end;) {
Link link = e.getValue();
link.print(sb, 4, 2);
sb.append(FormatterHelp.NEW_LINE);
}
}
}