package org.openmuc.framework.driver.iec60870;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.openmuc.framework.config.ArgumentSyntaxException;
import org.openmuc.framework.data.Record;
import org.openmuc.framework.driver.iec60870.settings.ChannelAddress;
import org.openmuc.framework.driver.spi.ChannelRecordContainer;
import org.openmuc.framework.driver.spi.ConnectionException;
import org.openmuc.framework.driver.spi.RecordsReceivedListener;
import org.openmuc.j60870.ASdu;
import org.openmuc.j60870.ConnectionEventListener;
import org.openmuc.j60870.InformationObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Iec60870Listener implements ConnectionEventListener {
private static List<ChannelRecordContainer> containers;
private static RecordsReceivedListener listener;
private static List<ChannelAddress> channelAddresses;
private final static Logger logger = LoggerFactory.getLogger(Iec60870Listener.class);
public synchronized void registerOpenMucListener(List<ChannelRecordContainer> containers,
RecordsReceivedListener listener) throws ConnectionException {
Iec60870Listener.containers = containers;
Iec60870Listener.listener = listener;
Iec60870Listener.channelAddresses = new ArrayList<>();
Iterator<ChannelRecordContainer> containerIterator = containers.iterator();
while (containerIterator.hasNext()) {
ChannelRecordContainer channelRecordContainer = containerIterator.next();
try {
ChannelAddress channelAddress = new ChannelAddress(channelRecordContainer.getChannelAddress());
channelAddresses.add(channelAddress);
} catch (ArgumentSyntaxException e) {
logger.error(
"ChannelId: " + channelRecordContainer.getChannel().getId() + "; Message: " + e.getMessage());
}
}
}
public synchronized void unregisterOpenMucListener() {
containers = null;
listener = null;
channelAddresses = null;
}
@Override
public synchronized void newASdu(ASdu aSdu) {
logger.debug("Got new ASdu");
logger.trace(aSdu.toString());
if (listener != null) {
long timestamp = System.currentTimeMillis();
if (!aSdu.isTestFrame()) {
Iterator<ChannelAddress> channelAddressIterator = channelAddresses.iterator();
int i = 0;
while (channelAddressIterator.hasNext()) {
ChannelAddress channelAddress = channelAddressIterator.next();
if (aSdu.getCommonAddress() == channelAddress.commonAddress()
&& aSdu.getTypeIdentification().getId() == channelAddress.typeId()) {
processRecords(aSdu, timestamp, i, channelAddress);
}
++i;
}
}
}
else {
logger.warn("Listener object is null.");
}
}
private void processRecords(ASdu aSdu, long timestamp, int i, ChannelAddress channelAddress) {
for (InformationObject informationObject : aSdu.getInformationObjects()) {
if (informationObject.getInformationObjectAddress() == channelAddress.ioa()) {
Record record = IEC60870DataHandling.handleInformationObject(aSdu, timestamp, channelAddress,
informationObject);
newRecords(i, record);
}
}
}
@Override
public void connectionClosed(IOException e) {
logger.info("Connection was closed by server.");
}
private void newRecords(int i, Record record) {
listener.newRecords(creatNewChannelRecordContainer(containers.get(i), record));
}
private List<ChannelRecordContainer> creatNewChannelRecordContainer(ChannelRecordContainer container,
Record record) {
List<ChannelRecordContainer> channelRecordContainerList = new ArrayList<>();
container.setRecord(record);
channelRecordContainerList.add(container);
return channelRecordContainerList;
}
}