<commit_before>/**
 * Copyright (c) 2010-2014, openHAB.org and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.openhab.binding.benqprojector.internal.transport;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Implement the network based transport for simple TCP/IP to 
 * RS232/Serial port adapters
 * @author <NAME> (cyclingengineer)
 * @since 1.6.0
 */
public class BenqProjectorNetworkTransport implements BenqProjectorTransport {

	private static final Logger logger = 
			LoggerFactory.getLogger(BenqProjectorNetworkTransport.class);
	
	/**
	 * Network host to use
	 */
	private String networkHost = "";
	
	/**
	 * Network port to use
	 */
	private int networkPort = 0;
	
	private Socket projectorSocket = null;
	private PrintWriter projectorWriter = null;
	private BufferedReader projectorReader = null;
	
	/**
	 * Set socket timeout time in milliseconds
	 */
	private final int SOCKET_TIMEOUT_MS = 5000;
	
	@Override
	public boolean setupConnection(String connectionParams) {
		boolean setupOK = false;
		if (this.projectorSocket == null)
		{
			/* parse connection paramters in the format host:port */
			String[] deviceIdParts = connectionParams.split(":");
			if (deviceIdParts.length == 2)
			{
				this.networkHost = deviceIdParts[0];
				this.networkPort = Integer.parseInt(deviceIdParts[1]);
			}
			else
			{
				return false;
			}
			
			logger.debug("Running connection setup");
			try
			{
				logger.debug("Setting up socket connection to "+this.networkHost+":"+this.networkPort);
				this.projectorSocket = new Socket(this.networkHost, this.networkPort);
				this.projectorSocket.setSoTimeout(SOCKET_TIMEOUT_MS);
				logger.debug("Setup reader/writer");
				this.projectorReader = new BufferedReader(new InputStreamReader(this.projectorSocket.getInputStream()));
				this.projectorWriter = new PrintWriter( this.projectorSocket.getOutputStream(), true );
				setupOK = true;
			}
			catch (UnknownHostException e)
			{
				logger.error("Unable to find host: "+this.networkHost);
			} catch (IOException e) {
				logger.error("IO Exception: "+e.getMessage());
			}
			logger.debug("Network connection setup successfully!");
		}
		else 
		{
			logger.debug("Socket is already setup");
		}
		return setupOK;
	}

	@Override
	public void closeConnection() {
		try {
			this.projectorReader.close();
			this.projectorReader = null;		
			this.projectorWriter.close();
			this.projectorReader = null;
			this.projectorSocket.close();
		} catch (IOException e) {
			logger.error("Trying close socket, reader or writer resulted in IO exception: "+e.getMessage());
		}
		this.projectorSocket = null;
	}
	
	@Override
	public String sendCommandExpectResponse(String cmd)
	{	
		String respStr="";
		String tmp;
		if (this.projectorWriter != null)
		{
			this.projectorWriter.printf("%s", cmd);
			logger.debug("Sent command '"+cmd.replace("\r", "")+"'");
			try {
				tmp = this.projectorReader.readLine();		
				while (tmp != null)
				{					
					if (tmp.startsWith("*")==true && tmp.endsWith("#"))
					{						
						/* got response */
						logger.debug("Response: '"+tmp+"'");
						respStr = tmp;
						break;
					}
					tmp = this.projectorReader.readLine();
				}
			} catch (SocketTimeoutException e) {
				logger.warn("Timed out reading response from projector");
			} catch (IOException e) {
				logger.error("IO Exception while reading response from projector: "+e.getMessage());
			}
			
		} else {
			logger.debug("Not sending command to projector as connection is not configured yet.");<commit_msg>Add reconnect attempt if a message fails due to IOException.<commit_after>/**
 * Copyright (c) 2010-2014, openHAB.org and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.openhab.binding.benqprojector.internal.transport;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Implement the network based transport for simple TCP/IP to 
 * RS232/Serial port adapters
 * @author <NAME> (cyclingengineer)
 * @since 1.6.0
 */
public class BenqProjectorNetworkTransport implements BenqProjectorTransport {

	private static final Logger logger = 
			LoggerFactory.getLogger(BenqProjectorNetworkTransport.class);
	
	/**
	 * Network host to use
	 */
	private String networkHost = "";
	
	/**
	 * Network port to use
	 */
	private int networkPort = 0;
	
	private Socket projectorSocket = null;
	private PrintWriter projectorWriter = null;
	private BufferedReader projectorReader = null;
	private boolean retryAttempt = false;
	
	/**
	 * Set socket timeout time in milliseconds
	 */
	private final int SOCKET_TIMEOUT_MS = 5000;
	
	private boolean networkConnect()
	{
		logger.debug("Running connection setup");
		try
		{
			logger.debug("Setting up socket connection to "+this.networkHost+":"+this.networkPort);
			this.projectorSocket = new Socket(this.networkHost, this.networkPort);
			this.projectorSocket.setSoTimeout(SOCKET_TIMEOUT_MS);
			logger.debug("Setup reader/writer");
			this.projectorReader = new BufferedReader(new InputStreamReader(this.projectorSocket.getInputStream()));
			this.projectorWriter = new PrintWriter( this.projectorSocket.getOutputStream(), true );
			logger.debug("Network connection setup successfully!");
			return true;
		}
		catch (UnknownHostException e)
		{
			logger.error("Unable to find host: "+this.networkHost);
		} catch (IOException e) {
			logger.error("IO Exception: "+e.getMessage());
		}
		return false;
	}
	
	@Override
	public boolean setupConnection(String connectionParams) {
		boolean setupOK = false;
		if (this.projectorSocket == null)
		{
			/* parse connection paramters in the format host:port */
			String[] deviceIdParts = connectionParams.split(":");
			if (deviceIdParts.length == 2)
			{
				this.networkHost = deviceIdParts[0];
				this.networkPort = Integer.parseInt(deviceIdParts[1]);
			}
			else
			{
				return false;
			}
			
			setupOK = this.networkConnect();
		}
		else 
		{
			logger.debug("Socket is already setup");
		}
		return setupOK;
	}

	@Override
	public void closeConnection() {
		try {
			this.projectorReader.close();
			this.projectorReader = null;		
			this.projectorWriter.close();
			this.projectorReader = null;
			this.projectorSocket.close();
		} catch (IOException e) {
			logger.error("Trying close socket, reader or writer resulted in IO exception: "+e.getMessage());
		}
		this.projectorSocket = null;
	}
	
	@Override
	public String sendCommandExpectResponse(String cmd)
	{	
		String respStr="";
		String tmp;
		if (this.projectorWriter != null)
		{
			this.projectorWriter.printf("%s", cmd);
			logger.debug("Sent command '"+cmd.replace("\r", "")+"'");
			try {
				tmp = this.projectorReader.readLine();		
				while (tmp != null)
				{					
					if (tmp.startsWith("*")==true && tmp.endsWith("#"))
					{						
						/* got response */
						logger.debug("Response: '"+tmp+"'");
						respStr = tmp;
						break;
					}
					tmp = this.projectorReader.readLine();
				}
			} catch (SocketTimeoutException e) {
				logger.warn("Timed out reading response from projector");
			} catch (IOException e) {
				if (retryAttempt == false)
				{
					this.closeConnection();
					if (this.networkConnect())
					{
						retryAttempt = true;
						sendCommandExpectResponse(cmd);
					} else {
						logger.error("Attempt to reconnect after IOException failed: "+e.getMessage());
					}
				} else {
					logger.error("IO Exception while reading response from projector: "+e.getMessage());
				}
			}
		} else {
			logger.debug("Not sending command to projector as connection is not setup yet.");
{'fraction_non_alphanumeric': 0.11743053906435526, 'fraction_numerical': 0.006649251959154595, 'mean_word_length': 3.710850111856823, 'pattern_counts': {'":': 4, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3757683', 'n_tokens_mistral': 2934, 'n_tokens_neox': 2441, 'n_words': 641}