package art.servers.pvvserver.controller; import art.library.interop.InteropParameters; import art.library.interop.serialization.Serialization; import art.library.interop.serialization.SerializationException; import art.library.model.devices.DeviceAction; import art.library.model.devices.DeviceActionResult; import art.library.model.devices.DeviceCommands; import art.library.model.devices.vms.pvv.Pvv; import art.library.model.devices.vms.pvv.PvvCommands; import art.library.model.devices.vms.pvv.PvvStatus; import art.library.utils.synchro.Mutex; import art.servers.ServerException; import art.servers.Shared; import art.servers.pvvserver.protocols.dgt.clv.ClvDgtConstants; import art.servers.pvvserver.protocols.dgt.clv.ClvDgtPDU; import art.servers.pvvserver.protocols.dgt.clv.ClvDgtProtocolAnalyser; import art.servers.pvvserver.protocols.dgt.clv.ClvDgtProtocolConstructor; import java.util.List; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.net.SocketTimeoutException; import java.util.ArrayList; public class ControllerClvDGTTcp extends ControllerPvv { private String name = null; private boolean firstTime = true; private final Mutex mutex = new Mutex(); private Socket socket = null; private InputStream is = null; private OutputStream os = null; private boolean connected = false; public ControllerClvDGTTcp(Pvv pvv) { super(pvv); this.device = pvv; this.name = Shared.getMessage("Controller pvv dgt tcp") + " " + pvv.toString(); this.setName(name); if (device.getDeviceStatus() == null) { device.status = new PvvStatus(); } } public void run() { Shared.traceInformation(name, "Starting"); while ((isInterrupted() == false) && (exit == false)) { long startTimestamp = System.currentTimeMillis(); try { if (art.servers.Shared.isServerEnabled() == true) { connect(); update(); } } catch (Exception e) { } long timetowait = (device.getDeviceInformation().polling * 1000) - (System.currentTimeMillis() - startTimestamp); timetowait = Math.min(timetowait, (device.getDeviceInformation().polling * 1000)); if (timetowait > 0) { try { sleep(timetowait); } catch (Exception e) { } } else { try { sleep(50); } catch (Exception e) { } } if (Shared.model.existsDevice(device.getIdentifier()) == false) { exit = true; } } Shared.traceInformation(name, "Finishing"); } // private void update() throws Exception { mutex.lockWrite(); Pvv deviceclone = (Pvv) Serialization.clone(device); try { deviceclone.getDeviceAlarms().clear(); readAlarms(deviceclone); if (deviceclone.getAlarm("alarm_offline") > 0) { offline(deviceclone); return; } readConfiguration(deviceclone); readStatus(deviceclone); online(deviceclone); } catch (Exception e) { offline(deviceclone); } finally { try { Shared.model.updateDevice(device, deviceclone); } finally { mutex.releaseWrite(); } } } private void offline(Pvv deviceclone) throws Exception { if ((device.alarms.alarm_offline <= 0) || (firstTime == true)) { firstTime = false; String message = art.servers.Shared.getMessage("Asf offline"); art.servers.Shared.println(name, message); } deviceclone.setAlarm("alarm_offline", System.currentTimeMillis()); Shared.model.updateDevice(device, deviceclone); } private void online(Pvv deviceclone) throws Exception { if ((device.alarms.alarm_offline > 0) || (firstTime == true)) { firstTime = false; String message = art.servers.Shared.getMessage("Asf online"); Shared.println(this.name, message); } deviceclone.setAlarm("alarm_offline", false); deviceclone.setAlarm("alarm_invalid", false); Shared.model.updateDevice(device, deviceclone); } private void readAlarms(Pvv deviceclone) throws Exception { try { byte[] command = ClvDgtProtocolConstructor.readAlarms(deviceclone.getDeviceInformation().connectionTcp.logicalAddress); ClvDgtPDU response = read(command); if ((response.function == ClvDgtConstants.STR_ICLV_ALR) && (response.address == deviceclone.getDeviceInformation().connectionTcp.logicalAddress)) { ClvDgtProtocolAnalyser.analyseResponseEyA(deviceclone, response.information); } } catch (Exception e) { throw e; } } private void readConfiguration(Pvv deviceclone) throws Exception { try { byte[] command = ClvDgtProtocolConstructor.readConfiguration(deviceclone.getDeviceInformation().connectionTcp.logicalAddress); ClvDgtPDU response = read(command); if ((response.function == ClvDgtConstants.STR_ICLV_PP) && (response.address == deviceclone.getDeviceInformation().connectionTcp.logicalAddress)) { ClvDgtProtocolAnalyser.analyseResponsePP(deviceclone, response.information); } } catch (Exception e) { throw e; } } private void readStatus(Pvv deviceclone) throws Exception { try { byte[] command = ClvDgtProtocolConstructor.readMessage(deviceclone.getDeviceInformation().connectionTcp.logicalAddress); ClvDgtPDU response = read(command); if ((response.function == ClvDgtConstants.STR_ICLV_PP) && (response.address == deviceclone.getDeviceInformation().connectionTcp.logicalAddress)) { ClvDgtProtocolAnalyser.analyseResponseEP(deviceclone, response.information); } } catch (Exception e) { e.printStackTrace(); throw e; } } // // public DeviceAction[] sendCommands(InteropParameters parameters) throws ServerException, SerializationException, Exception { try { List result = new ArrayList<>(); PvvCommands pvvCommands = (PvvCommands) parameters.getBodyContentValue(PvvCommands.class); Pvv clone = (Pvv) Serialization.clone(device); if (pvvCommands.liberate == DeviceCommands.CONDITION_YES) { PvvCommands command = new PvvCommands(); command.liberate = pvvCommands.liberate; result.add(liberate(parameters, command, clone)); } if (pvvCommands.message != null) { PvvCommands command = new PvvCommands(); command.message = pvvCommands.message; command.priority = pvvCommands.priority; result.add(mep(parameters, command, clone)); } if (pvvCommands.reset == PvvCommands.CONDITION_YES) { PvvCommands command = new PvvCommands(); command.reset = pvvCommands.reset; result.add(reset(parameters, command, clone)); } mutex.lockWrite(); { Shared.model.updateDevice(device, clone); } mutex.releaseWrite(); return result.toArray(new DeviceAction[result.size()]); } catch (Exception exception) { return (art.servers.pvvserver.Shared.responseError(device, parameters, exception)); } } /* private DeviceAction mpp(InteropParameters parameters, PvvCommands command, Pvv deviceclone) { String language = (String) parameters.getParameterValue("language"); DeviceAction action = new DeviceAction(device, parameters, command); action.actionName = command.getActionName(); try { int currentPriority = this.device.getDeviceStatus().priority; if ((command.priority >= 0) && (command.priority < currentPriority)) { DeviceActionResult actionResult = new DeviceActionResult(DeviceActionResult.RESULT_ERROR, Shared.getMessage("Insufficient priority")); action.setResult(actionResult); Shared.model.addAction(action); return action; } else { byte[] commandByte = ClvDgtProtocolConstructor.mpp(deviceclone.getDeviceInformation().connectionTcp.logicalAddress, command, deviceclone); ClvDgtPDU response = read(commandByte); if ((response.function == ClvDgtConstants.STR_OCLV_MPP) && (response.address == deviceclone.getDeviceInformation().connectionTcp.logicalAddress)) { ClvDgtProtocolAnalyser.analyseResponseMPP(deviceclone, response.information); } deviceclone.getDeviceStatus().priority = command.priority; deviceclone.getDeviceStatus().timestampOrder = System.currentTimeMillis(); DeviceActionResult actionResult = new DeviceActionResult(DeviceActionResult.RESULT_CORRECT); action.setResult(actionResult); Shared.model.addAction(action); return action; } } catch (Exception exception) { DeviceActionResult actionResult = new DeviceActionResult(DeviceActionResult.RESULT_ERROR, exception.getMessage()); action.setResult(actionResult); Shared.model.addAction(action); return action; } } */ private DeviceAction reset(InteropParameters parameters, PvvCommands command, Pvv deviceclone) { String language = (String) parameters.getParameterValue("language"); DeviceAction action = new DeviceAction(device, parameters, command); action.actionName = command.getActionName(); try { int currentPriority = this.device.getDeviceStatus().priority; if ((command.priority >= 0) && (command.priority < currentPriority)) { DeviceActionResult actionResult = new DeviceActionResult(DeviceActionResult.RESULT_ERROR, Shared.getMessage("Insufficient priority")); action.setResult(actionResult); Shared.model.addAction(action); return action; } else { byte[] commandByte = ClvDgtProtocolConstructor.reset(deviceclone.getDeviceInformation().connectionTcp.logicalAddress); ClvDgtPDU response = read(commandByte); if ((response.function == ClvDgtConstants.STR_OCLV_RES) && (response.address == deviceclone.getDeviceInformation().connectionTcp.logicalAddress)) { ClvDgtProtocolAnalyser.analyseResponseReset(response.information); } deviceclone.getDeviceStatus().priority = command.priority; deviceclone.getDeviceStatus().timestampOrder = System.currentTimeMillis(); DeviceActionResult actionResult = new DeviceActionResult(DeviceActionResult.RESULT_CORRECT); action.setResult(actionResult); Shared.model.addAction(action); return action; } } catch (Exception exception) { DeviceActionResult actionResult = new DeviceActionResult(DeviceActionResult.RESULT_ERROR, exception.getMessage()); action.setResult(actionResult); Shared.model.addAction(action); return action; } } /* private DeviceAction timeout(InteropParameters parameters, PvvCommands command, Pvv deviceclone) { String language = (String) parameters.getParameterValue("language"); DeviceAction action = new DeviceAction(device, parameters, command); action.actionName = command.getActionName(); try { int currentPriority = this.device.getDeviceStatus().priority; if ((command.priority >= 0) && (command.priority < currentPriority)) { DeviceActionResult actionResult = new DeviceActionResult(DeviceActionResult.RESULT_ERROR, Shared.getMessage("Insufficient priority")); action.setResult(actionResult); Shared.model.addAction(action); return action; } else { byte[] commandByte = ClvDgtProtocolConstructor.timeout(deviceclone.getDeviceInformation().connectionTcp.logicalAddress, command, deviceclone); ClvDgtPDU response = read(commandByte); if ((response.function == ClvDgtConstants.STR_OCLV_MPP) && (response.address == deviceclone.getDeviceInformation().connectionTcp.logicalAddress)) { ClvDgtProtocolAnalyser.analyseResponseTimeout(response.information); } deviceclone.getDeviceStatus().priority = command.priority; deviceclone.getDeviceStatus().timestampOrder = System.currentTimeMillis(); DeviceActionResult actionResult = new DeviceActionResult(DeviceActionResult.RESULT_CORRECT); action.setResult(actionResult); Shared.model.addAction(action); return action; } } catch (Exception exception) { DeviceActionResult actionResult = new DeviceActionResult(DeviceActionResult.RESULT_ERROR, exception.getMessage()); action.setResult(actionResult); Shared.model.addAction(action); return action; } } */ private DeviceAction liberate(InteropParameters parameters, PvvCommands command, Pvv deviceclone) { String language = (String) parameters.getParameterValue("language"); DeviceAction action = new DeviceAction(device, parameters, command); action.actionName = command.getActionName(); try { deviceclone.getDeviceStatus().priority = -1; DeviceActionResult actionResult = new DeviceActionResult(DeviceActionResult.RESULT_CORRECT); action.setResult(actionResult); Shared.model.addAction(action); return action; } catch (Exception exception) { DeviceActionResult actionResult = new DeviceActionResult(DeviceActionResult.RESULT_ERROR, exception.getMessage()); action.setResult(actionResult); Shared.model.addAction(action); return action; } } private DeviceAction mep(InteropParameters parameters, PvvCommands command, Pvv deviceclone) { String language = (String) parameters.getParameterValue("language"); String username = (String) parameters.getParameterValue("username"); DeviceAction action = new DeviceAction(device, parameters, command); action.actionName = command.getActionName(); try { int currentPriority = this.device.getDeviceStatus().priority; if ((command.priority >= 0) && (command.priority < currentPriority)) { DeviceActionResult actionResult = new DeviceActionResult(DeviceActionResult.RESULT_ERROR, Shared.getMessage("Insufficient priority")); action.setResult(actionResult); Shared.model.addAction(action); return action; } else { byte[] commandByte = ClvDgtProtocolConstructor.mep(deviceclone.getDeviceInformation().connectionTcp.logicalAddress, command, deviceclone); ClvDgtPDU response = read(commandByte); if ((response.function == ClvDgtConstants.STR_OCLV_MEP) && (response.address == deviceclone.getDeviceInformation().connectionTcp.logicalAddress)) { ClvDgtProtocolAnalyser.analyseResponseMEP(deviceclone, response.information); } deviceclone.getDeviceStatus().priority = command.priority; deviceclone.getDeviceStatus().timestampOrder = System.currentTimeMillis(); DeviceActionResult actionResult = new DeviceActionResult(DeviceActionResult.RESULT_CORRECT); action.setResult(actionResult); Shared.model.addAction(action); return action; } } catch (Exception exception) { DeviceActionResult actionResult = new DeviceActionResult(DeviceActionResult.RESULT_ERROR, exception.getMessage()); action.setResult(actionResult); Shared.model.addAction(action); return action; } } // // private void connect() { try { if (socket != null) { if (this.connected == true) { return; } } disconnect(); InetAddress inetAddress = InetAddress.getByName(device.getDeviceInformation().connectionTcp.address); SocketAddress sockaddress = new InetSocketAddress(inetAddress, device.getDeviceInformation().connectionTcp.port); socket = new Socket(); socket.connect(sockaddress, 2000); socket.setSoLinger(true, 1); socket.setSoTimeout(device.getDeviceInformation().connectionTcp.timeout); is = socket.getInputStream(); os = socket.getOutputStream(); this.connected = true; } catch (Exception e) { try { disconnect(); } catch (Exception ex) { }; } } public void disconnect() throws Exception { try { is.close(); } catch (Exception e) { } try { os.close(); } catch (Exception e) { } try { socket.close(); } catch (Exception e) { } is = null; os = null; socket = null; this.connected = false; } private ClvDgtPDU read(byte[] command) throws Exception { try { mutex.lockWrite(); send(command); return (listen()); } catch (Exception e) { disconnect(); throw e; } finally { mutex.releaseWrite(); } } private void send(byte[] command) throws Exception { connect(); if (is != null) { is.skip(0); } os.write(command); os.flush(); } private ClvDgtPDU listen() throws Exception { try { connect(); ClvDgtPDU pdu = new ClvDgtPDU(); pdu.stx = readByte(); if (pdu.stx == ClvDgtConstants.CLV_ACK) { pdu.ack = true; return (pdu); } else if (pdu.stx != ClvDgtConstants.CLV_STX) { while ((pdu.stx != ClvDgtConstants.CLV_STX) && (pdu.stx != ClvDgtConstants.CLV_ETX) && (pdu.stx != 0xFF) && (pdu.stx != ClvDgtConstants.CLV_ACK)) { pdu.stx = readByte(); } if (pdu.stx == ClvDgtConstants.CLV_ACK) { pdu.ack = true; return (pdu); } if (pdu.stx != ClvDgtConstants.CLV_STX) { if (pdu.stx == ClvDgtConstants.CLV_ETX) { pdu.stx = readByte(); } if (pdu.stx != ClvDgtConstants.CLV_STX) { throw new Exception("Message not start with STX: " + pdu.stx + " - " + readByte()); } } } // Message starts with STX pdu.address = readByte(); pdu.function = readByte(); ArrayList list = new ArrayList(); list.add(new Integer(pdu.stx)); list.add(new Integer(pdu.address)); list.add(new Integer(pdu.function)); // Read until the reading of ETX byte int value = readByte(); while (value != ClvDgtConstants.CLV_ETX) { list.add(new Integer(value)); value = readByte(); } list.add(new Integer(value)); pdu.etx = value; int[] message = new int[list.size()]; for (int i = 0; i < message.length; i++) { message[i] = ((Integer) list.get(i)).intValue(); } message = pdu.removeStuffing(message); pdu.information = new int[message.length - 6]; System.arraycopy(message, 3, pdu.information, 0, pdu.information.length); return pdu; } catch (SocketTimeoutException e) { throw e; } catch (Exception e) { int value = readByte(); try { while ((value != ClvDgtConstants.CLV_ETX) && (value != 0xFF)) { value = readByte(); } } catch (Exception ex) { } throw e; } } /** * TCP Socket reading functions */ public int readByte() throws Exception { int value = is.read(); if (value < 0) { value += 256; } return (value); } public int readShort() throws Exception { return ((readByte() << 8) + readByte()); } public int[] readBytes(int len) throws Exception { byte[] data = new byte[len]; is.read(data); int[] result = new int[data.length]; for (int i = 0; i < result.length; i++) { result[i] = (int) data[i]; if (result[i] < 0) { result[i] += 256; } } return (result); } // }