package art.servers.colorsserver.controller; import art.library.model.devices.Device; import art.library.model.devices.colors.controller.M.M_Controller; import art.library.utils.synchro.Mutex; import art.servers.ServerException; import art.servers.colorsserver.Shared; import art.servers.colorsserver.m.protocol.M_Message; import static art.servers.colorsserver.m.protocol.M_ProtocolWriter.*; import art.servers.colorsserver.m.protocol.M_Request; import art.servers.controller.Controller; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.SocketException; import java.net.SocketTimeoutException; import java.util.ArrayList; import java.util.List; public class ControllerConnection extends Controller { private String address = null; private int port = 0; private int timeout = 0; private boolean hasCRC = false; private Socket socket = null; private InputStream is = null; private OutputStream os = null; private boolean connected = false; private Mutex mutexListRequest = new Mutex(); private List lrequest = new ArrayList(); public ControllerConnection (String address, int port, int timeout, boolean hasCRC) { this.address = address; this.port = port; this.timeout = this.timeout; this.hasCRC = hasCRC; this.setName(Shared.getMessage("Controller connection") + " " + address + ":" + port + "," + timeout + "," + hasCRC); } public void run () { while ((isInterrupted() == false) && (exit == false)) { try { connect(); long millis = System.currentTimeMillis(); clearM_Request(); if (lrequest.size() > 10) { System.out.println(Device.getDate(System.currentTimeMillis()) + " - " + address + ":" + port + " - 0.RCV: " + (System.currentTimeMillis()-millis) + " - " + lrequest.size()); } if (this.connected == true) { M_Message response = receive(); ack(); M_Request request = getM_Request(response); if (request != null) { removeM_Request(request, response); } else { // Notification } } } catch (Exception e) { } finally { try{sleep(50);} catch (Exception exception){}; } } } public void setTimeout (int timeout) { try { socket.setSoTimeout(timeout); } catch (Exception e) { } } private void clearM_Request () { try { mutexListRequest.lockWrite(); List lremove = new ArrayList(); for (M_Request request : lrequest) { if (request.finishedByTimeout == true) { lremove.add(request); } } if (lremove.size() > 0) { lrequest.removeAll(lremove); } } catch (Exception e) { } finally { mutexListRequest.releaseWrite(); } } public void addM_Request (M_Request request) { try { mutexListRequest.lockWrite(); send(request.request.toByteArray()); request.send(timeout); lrequest.add(request); } catch (Exception e) { } finally { mutexListRequest.releaseWrite(); } } private void removeM_Request (M_Request request, M_Message response) { try { mutexListRequest.lockWrite(); request.receive(response); lrequest.remove(request); } catch (Exception e) { } finally { mutexListRequest.releaseWrite(); } } private M_Request getM_Request (M_Message response) { try { mutexListRequest.lockRead(); if ((response.isAck == true) || (response.isNack == true) || (response.isTrcam == true)) return null; for (M_Request request : lrequest) { if ((request.finishedByTimeout == false) && (request.request.controller == response.controller) && (request.request.table == response.table)) { if (request.request.isCountingDetectorQuery() == true) { if (response.directive == M_CURRENT_COUNTING_DETECTORS) { return(request); } } switch(request.request.directive) { case M_RECORDABLE_PLAN_QUERY: { if ((request.request.directive == response.directive) && (request.request.controller == response.controller)) { // There is a request pending return(request); } } break; case M_CURRENT_PLAN_QUERY: { if ((request.request.directive == response.directive) && (request.request.controller == response.controller)) { // There is a request pending return(request); } } break; case M_CURRENT_TIME_QUERY: { if ((request.request.directive == response.directive) && (request.request.controller == response.controller)) { // There is a request pending return(request); } } break; case M_CURRENT_SUBCONTROLLER_STATE_QUERY: { if ((request.request.directive == response.directive) && (request.request.controller == response.controller)) { // There is a request pending return(request); } } break; case M_CURRENT_PRESENCE_DETECTORS: { if ((request.request.directive == response.directive) && (request.request.controller == response.controller)) { // There is a request pending return(request); } } break; case M_CURRENT_COUNTING_DETECTORS_DATETIME: { } break; case M_CURRENT_COUNTING_DETECTORS: { if (request.request.isCountingDetectorQuery() == true) { // There is a request pending return(request); } } break; case M_ALARMS_QUERY: { if ((request.request.directive == response.directive) && (request.request.controller == response.controller)) { // There is a request pending return(request); } } break; case M_BLOWN_LAMPS_ALARMS_QUERY: { if ((request.request.directive == response.directive) && (request.request.controller == response.controller)) { // There is a request pending return(request); } } break; case M_DAMAGED_GROUP_ALARMS_QUERY: { if ((request.request.directive == response.directive) && (request.request.controller == response.controller)) { // There is a request pending return(request); } } break; case M_INCOMPATIBILITY_ALARMS_QUERY: { if ((request.request.directive == response.directive) && (request.request.controller == response.controller)) { // There is a request pending return(request); } } break; case M_CURRENT_STATUS_GROUPS_QUERY: { if ((request.request.directive == response.directive) && (request.request.controller == response.controller)) { // There is a request pending return(request); } } break; } } } } catch (Exception e) { e.printStackTrace(); } finally { mutexListRequest.releaseRead(); } return(null); } public void connect() { try { if (socket != null) { if (this.connected == true) { return; } } socket = new Socket(address, port); socket.setSoTimeout(timeout); is = socket.getInputStream(); os = socket.getOutputStream(); this.connected = true; // System.out.println(Device.getDate(System.currentTimeMillis()) + " - " + m_controller.getIdentifier() + " - Connected"); } catch (Exception e) { try{disconnect();} catch (Exception ex){}; } } public void disconnect() throws ServerException, 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; if (this.connected == true) { // System.out.println(Device.getDate(System.currentTimeMillis()) + " - " + m_controller.getIdentifier() + " - Disconnected"); } this.connected = false; } public M_Message read(byte[] command) throws ServerException, Exception { try { send(command); return receive(); } catch (SocketException e) { System.out.println(this.getName() + " Socket.EX.read: " + e.toString()); disconnect(); throw e; } catch (Exception e) { System.out.println(this.getName() + " EX.read: " + e.toString()); e.printStackTrace(); throw e; } } public void send(byte[] command) throws ServerException, Exception { socket.getOutputStream().write(command); socket.getOutputStream().flush(); } public M_Message receive() throws ServerException, Exception { boolean salir = false; int res = 0; byte[] trama = null; int longitud = 0; try { while ((res = is.read()) == 0){sleep(10);}; if (res != -1) { if (res == 0x11) { while (res == 0x11) { res = is.read(); } } if (res == 0x06) { M_Message message = new M_Message(); message.isAck = true; int[] data = new int[1]; data[0] = res; message.setData(data); return(message); } if (res == 0x15) { M_Message message = new M_Message(); message.isNack = true; int[] data = new int[1]; data[0] = res; message.setData(data); return(message); } if ((res >= 0x30) && (res <= 0x3F)) { M_Message message = new M_Message(); message.isTrcam = true; int[] data = new int[1]; data[0] = res; message.setData(data); return(message); } if (res == 0x02) { int apuntador = 0; trama = new byte[4096]; trama[apuntador] = (byte)res; apuntador++; // Obtenemos todos los datos disponibles while (res != 0x03) { res = is.read(); trama[apuntador] = (byte)res; apuntador++; } longitud = apuntador; } } } catch (SocketTimeoutException e) { System.out.println(this.getName() + " Timeout.EX.rcv: " + e.toString()); } catch (Exception e) { System.out.println(this.getName() + " EX.rcv: " + e.toString()); e.printStackTrace(); disconnect(); throw e; } if (res == -1) throw new Exception(Shared.getMessage("Timeout Error")); // Enviamos el resultado byte[] resultado = new byte[longitud]; System.arraycopy(trama, 0, resultado, 0, longitud); M_Message message = new M_Message(); message.setData(resultado); message.fillInformation(); return(message); } public void ack() { if (this.hasCRC == true) { byte[] ack = {0x06}; try{send(ack);} catch (Exception e){}; } } }