import crcmod, copy, struct, sys, os, fcntl
from datetime import datetime
from serial import *
import socket
import debug

class PortgwSerial(object):
	def __init__(self, _serial_port, _baudrate, _bytesize=8,
			_parity='N', _stopbits=1):
		self.serial_port = _serial_port
		self.baudrate = _baudrate
		self.bytesize = _bytesize
		self.parity = _parity
		self.stopbits = _stopbits
		self.serial_resume()
		self.name = "UART"

	def serial_pause(self):
		if self.serial != None:
			self.serial.close()
		self.serial = None

	def serial_resume(self):
		self.serial = serial_for_url(self.serial_port, self.baudrate, bytesize=self.bytesize, 
			parity=self.parity, stopbits=self.stopbits, rtscts=False, xonxoff=False, timeout=0.12)
		return self.serial != None

	def open(self):
		if self.serial == None:
			return self.serial_resume()
		else:
			return True

	def close(self):
		self.serial_pause()

	def read(self, nbytes, timeout = 1):
		data = ''
		self.serial.timeout = timeout
		while len(data) < nbytes:
			ret = self.serial.read(nbytes)
			if len(ret) == 0:
				break
			data += ret
		return data

	def write(self, data):
		self.serial.flushInput()
		self.serial.flushOutput()
		ret = self.serial.write(data)
		# self.serial.flush()
		return ret


class PortgwTcp(object):
	def __init__(self, _ip, _port):
		self.ip = _ip
		self.port = _port
		self.name = "TCP"

	def open(self):
		self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		try:
			self.sock.connect((self.ip, self.port))
			# fcntl.fcntl(self.sock, fcntl.F_SETFL, os.O_NONBLOCK)
		except socket.error, e:
			print "\r\nConnection to %s:%s failed. Exit" %(self.ip, self.port)
			return False
		time.sleep(0.1)
		return True

	def close(self):
		self.sock.close()

	def read(self, nbytes, timeout = 1):
		data = ''
		self.sock.settimeout(timeout)
		while len(data) < nbytes:
			try:
				ret = self.sock.recv(nbytes)
			except socket.error, e:
				err = e.args[0]
				if err == 'timed out':
					break
			data += ret
		return data

	def write(self, data):
		sent = self.sock.send(data)
		if sent == 0:
			raise RuntimeError("socket connection broken")
		return sent