Skip to content
Snippets Groups Projects
USB2.cpp 23.4 KiB
Newer Older
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
/*----- PROTECTED REGION ID(USB2.cpp) ENABLED START -----*/
//=============================================================================
//
// file :        USB2.cpp
//
// description : C++ source for the USB2 class and its commands.
//               The class is derived from Device. It represents the
//               CORBA servant object which will be accessed from the
//               network. All commands which can be executed on the
//               USB2 are implemented in this file.
//
// project :     
//
// This file is part of Tango device class.
// 
// Tango is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// Tango is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with Tango.  If not, see <http://www.gnu.org/licenses/>.
// 
// $Author: alessio $
//
// $Revision: 1.5 $
// $Date: 2018-10-24 08:12:41 $
//
// $HeadURL:  $
//
//=============================================================================
//                This file is generated by POGO
//        (Program Obviously used to Generate tango Object)
//=============================================================================


#include <USB2.h>
#include <USB2Class.h>

/*----- PROTECTED REGION END -----*/	//	USB2.cpp

/**
 *  USB2 class description:
 *    
 */

//================================================================
//  The following table gives the correspondence
//  between command and method names.
//
//  Command name  |  Method name
//================================================================
//  Write         |  write
//  Read          |  read
//  ReadUntil     |  read_until
//================================================================

//================================================================
//  Attributes managed are:
//================================================================
//  InputLength    |  Tango::DevLong	Scalar
//  OutputLength   |  Tango::DevLong	Scalar
//  Reconnections  |  Tango::DevLong	Scalar
//================================================================

namespace USB2_ns
{
/*----- PROTECTED REGION ID(USB2::namespace_starting) ENABLED START -----*/

//	static initializations

/*----- PROTECTED REGION END -----*/	//	USB2::namespace_starting

//--------------------------------------------------------
/**
 *	Method     : USB2::USB2()
 *	Description: Constructors for a Tango device
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 *                implementing the classUSB2
 */
//--------------------------------------------------------
USB2::USB2(Tango::DeviceClass *cl, std::string &s)
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 : TANGO_BASE_CLASS(cl, s.c_str())
{
	/*----- PROTECTED REGION ID(USB2::constructor_1) ENABLED START -----*/
	reconnections = -1;
	init_device();
	
	/*----- PROTECTED REGION END -----*/	//	USB2::constructor_1
}
//--------------------------------------------------------
USB2::USB2(Tango::DeviceClass *cl, const char *s)
 : TANGO_BASE_CLASS(cl, s)
{
	/*----- PROTECTED REGION ID(USB2::constructor_2) ENABLED START -----*/
	reconnections = -1;
	init_device();
	
	/*----- PROTECTED REGION END -----*/	//	USB2::constructor_2
}
//--------------------------------------------------------
USB2::USB2(Tango::DeviceClass *cl, const char *s, const char *d)
 : TANGO_BASE_CLASS(cl, s, d)
{
	/*----- PROTECTED REGION ID(USB2::constructor_3) ENABLED START -----*/
	reconnections = -1;
	init_device();
	
	/*----- PROTECTED REGION END -----*/	//	USB2::constructor_3
}
//--------------------------------------------------------
USB2::~USB2()
{
	delete_device();
}
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed

//--------------------------------------------------------
/**
 *	Method     : USB2::delete_device()
 *	Description: will be called at device destruction or at init command
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 */
//--------------------------------------------------------
void USB2::delete_device()
{
	DEBUG_STREAM << "USB2::delete_device() " << device_name << std::endl;
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
	/*----- PROTECTED REGION ID(USB2::delete_device) ENABLED START -----*/
	
	close();
	delete[] buffer;

	/*----- PROTECTED REGION END -----*/	//	USB2::delete_device
	delete[] attr_InputLength_read;
	delete[] attr_OutputLength_read;
	delete[] attr_Reconnections_read;
}

//--------------------------------------------------------
/**
 *	Method     : USB2::init_device()
 *	Description: will be called at device initialization.
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 */
//--------------------------------------------------------
void USB2::init_device()
{
	DEBUG_STREAM << "USB2::init_device() create device " << device_name << std::endl;
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
	/*----- PROTECTED REGION ID(USB2::init_device_before) ENABLED START -----*/
	
	//	Initialization before get_device_property() call
	ctx = NULL;
	dev_handle = NULL;
	buffer = NULL;
	init_error.clear();
	
	/*----- PROTECTED REGION END -----*/	//	USB2::init_device_before
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed

	//	Get the device properties from database
	get_device_property();
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
	attr_InputLength_read = new Tango::DevLong[1];
	attr_OutputLength_read = new Tango::DevLong[1];
	attr_Reconnections_read = new Tango::DevLong[1];
	//	No longer if mandatory property not set.
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
	if (mandatoryNotDefined)
		return;

	/*----- PROTECTED REGION ID(USB2::init_device) ENABLED START -----*/

	//	Initialize device
	try
	{
		buffer = new unsigned char[maxPacketSize];
		open();
	}
	catch (Tango::DevFailed &e)
	{
		init_error = "Initialization failed: " + string(e.errors[0].desc);
	}
	catch (...)
	{
		init_error = "Initialization failed: Unknown error";
	}

	/*----- PROTECTED REGION END -----*/	//	USB2::init_device
}

//--------------------------------------------------------
/**
 *	Method     : USB2::get_device_property()
 *	Description: Read database to initialize property data members.
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 */
//--------------------------------------------------------
void USB2::get_device_property()
{
	/*----- PROTECTED REGION ID(USB2::get_device_property_before) ENABLED START -----*/
	
	//	Initialize property data members
	
	/*----- PROTECTED REGION END -----*/	//	USB2::get_device_property_before

	mandatoryNotDefined = false;

	//	Read device properties from database.
	Tango::DbData	dev_prop;
	dev_prop.push_back(Tango::DbDatum("Timeout"));
	dev_prop.push_back(Tango::DbDatum("VendorID"));
	dev_prop.push_back(Tango::DbDatum("ProductID"));
	dev_prop.push_back(Tango::DbDatum("Interface"));
	dev_prop.push_back(Tango::DbDatum("EndpointUP"));
	dev_prop.push_back(Tango::DbDatum("EndpointDOWN"));
	dev_prop.push_back(Tango::DbDatum("MaxPacketSize"));

	//	is there at least one property to be read ?
	if (dev_prop.size()>0)
	{
		//	Call database and extract values
		if (Tango::Util::instance()->_UseDb==true)
			get_db_device()->get_property(dev_prop);
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
		//	get instance on USB2Class to get class property
		Tango::DbDatum	def_prop, cl_prop;
		USB2Class	*ds_class =
			(static_cast<USB2Class *>(get_device_class()));
		int	i = -1;

		//	Try to initialize Timeout from class property
		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
		if (cl_prop.is_empty()==false)	cl_prop  >>  timeout;
		else {
			//	Try to initialize Timeout from default device value
			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
			if (def_prop.is_empty()==false)	def_prop  >>  timeout;
		}
		//	And try to extract Timeout value from database
		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  timeout;
		//	Property StartDsPath is mandatory, check if has been defined in database.
		check_mandatory_property(cl_prop, dev_prop[i]);

		//	Try to initialize VendorID from class property
		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
		if (cl_prop.is_empty()==false)	cl_prop  >>  vendorID;
		else {
			//	Try to initialize VendorID from default device value
			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
			if (def_prop.is_empty()==false)	def_prop  >>  vendorID;
		}
		//	And try to extract VendorID value from database
		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  vendorID;
		//	Property StartDsPath is mandatory, check if has been defined in database.
		check_mandatory_property(cl_prop, dev_prop[i]);

		//	Try to initialize ProductID from class property
		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
		if (cl_prop.is_empty()==false)	cl_prop  >>  productID;
		else {
			//	Try to initialize ProductID from default device value
			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
			if (def_prop.is_empty()==false)	def_prop  >>  productID;
		}
		//	And try to extract ProductID value from database
		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  productID;
		//	Property StartDsPath is mandatory, check if has been defined in database.
		check_mandatory_property(cl_prop, dev_prop[i]);

		//	Try to initialize Interface from class property
		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
		if (cl_prop.is_empty()==false)	cl_prop  >>  interface;
		else {
			//	Try to initialize Interface from default device value
			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
			if (def_prop.is_empty()==false)	def_prop  >>  interface;
		}
		//	And try to extract Interface value from database
		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  interface;
		//	Property StartDsPath is mandatory, check if has been defined in database.
		check_mandatory_property(cl_prop, dev_prop[i]);

		//	Try to initialize EndpointUP from class property
		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
		if (cl_prop.is_empty()==false)	cl_prop  >>  endpointUP;
		else {
			//	Try to initialize EndpointUP from default device value
			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
			if (def_prop.is_empty()==false)	def_prop  >>  endpointUP;
		}
		//	And try to extract EndpointUP value from database
		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  endpointUP;
		//	Property StartDsPath is mandatory, check if has been defined in database.
		check_mandatory_property(cl_prop, dev_prop[i]);

		//	Try to initialize EndpointDOWN from class property
		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
		if (cl_prop.is_empty()==false)	cl_prop  >>  endpointDOWN;
		else {
			//	Try to initialize EndpointDOWN from default device value
			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
			if (def_prop.is_empty()==false)	def_prop  >>  endpointDOWN;
		}
		//	And try to extract EndpointDOWN value from database
		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  endpointDOWN;
		//	Property StartDsPath is mandatory, check if has been defined in database.
		check_mandatory_property(cl_prop, dev_prop[i]);

		//	Try to initialize MaxPacketSize from class property
		cl_prop = ds_class->get_class_property(dev_prop[++i].name);
		if (cl_prop.is_empty()==false)	cl_prop  >>  maxPacketSize;
		else {
			//	Try to initialize MaxPacketSize from default device value
			def_prop = ds_class->get_default_device_property(dev_prop[i].name);
			if (def_prop.is_empty()==false)	def_prop  >>  maxPacketSize;
		}
		//	And try to extract MaxPacketSize value from database
		if (dev_prop[i].is_empty()==false)	dev_prop[i]  >>  maxPacketSize;
		//	Property StartDsPath is mandatory, check if has been defined in database.
		check_mandatory_property(cl_prop, dev_prop[i]);

	}

	/*----- PROTECTED REGION ID(USB2::get_device_property_after) ENABLED START -----*/
	
	//	Check device property data members init
	vid = stoi(vendorID, NULL, 16);
	pid = stoi(productID, NULL, 16);

	ep_up = stoi(endpointUP, NULL, 16);
	ep_down = stoi(endpointDOWN, NULL, 16);

	/*----- PROTECTED REGION END -----*/	//	USB2::get_device_property_after
}
//--------------------------------------------------------
/**
 *	Method     : USB2::check_mandatory_property()
 *	Description: For mandatory properties check if defined in database.
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 */
//--------------------------------------------------------
void USB2::check_mandatory_property(Tango::DbDatum &class_prop, Tango::DbDatum &dev_prop)
{
	//	Check if all properties are empty
	if (class_prop.is_empty() && dev_prop.is_empty())
	{
		TangoSys_OMemStream	tms;
		tms << std::endl <<"Property \'" << dev_prop.name;
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
		if (Tango::Util::instance()->_UseDb==true)
			tms << "\' is mandatory but not defined in database";
		else
			tms << "\' is mandatory but cannot be defined without database";
		append_status(tms.str());
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
		mandatoryNotDefined = true;
		/*----- PROTECTED REGION ID(USB2::check_mandatory_property) ENABLED START -----*/
		cerr << tms.str() << " for " << device_name << endl;
		
		/*----- PROTECTED REGION END -----*/	//	USB2::check_mandatory_property
	}
}


//--------------------------------------------------------
/**
 *	Method     : USB2::always_executed_hook()
 *	Description: method always executed before any command is executed
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 */
//--------------------------------------------------------
void USB2::always_executed_hook()
{
	DEBUG_STREAM << "USB2::always_executed_hook()  " << device_name << std::endl;
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
	if (mandatoryNotDefined)
	{
		Tango::Except::throw_exception(
					(const char *)"PROPERTY_NOT_SET",
					get_status().c_str(),
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
					(const char *)"USB2::always_executed_hook()");
	}
	/*----- PROTECTED REGION ID(USB2::always_executed_hook) ENABLED START -----*/
	
	//	code always executed before all requests
	if (! init_error.empty())
	{
		set_state(Tango::FAULT);
		set_status(init_error);
		return;
	}

	try {
		if (! dev_handle) {
			open();
		}
	} catch(Tango::DevFailed &e) {
		set_state(Tango::FAULT);
		set_status(string(e.errors[0].desc));
	} catch(...) {
		set_state(Tango::FAULT);
		set_status("The device is in FAULT state for unknown reason");
	}

	/*----- PROTECTED REGION END -----*/	//	USB2::always_executed_hook
}

//--------------------------------------------------------
/**
 *	Method     : USB2::read_attr_hardware()
 *	Description: Hardware acquisition for attributes
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 */
//--------------------------------------------------------
void USB2::read_attr_hardware(TANGO_UNUSED(std::vector<long> &attr_list))
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
{
	DEBUG_STREAM << "USB2::read_attr_hardware(std::vector<long> &attr_list) entering... " << std::endl;
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
	/*----- PROTECTED REGION ID(USB2::read_attr_hardware) ENABLED START -----*/
	
	//	Add your own code
	
	/*----- PROTECTED REGION END -----*/	//	USB2::read_attr_hardware
}

//--------------------------------------------------------
/**
 *	Read attribute InputLength related method
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 *
 *	Data type:	Tango::DevLong
 *	Attr type:	Scalar
 */
//--------------------------------------------------------
void USB2::read_InputLength(Tango::Attribute &attr)
{
	DEBUG_STREAM << "USB2::read_InputLength(Tango::Attribute &attr) entering... " << std::endl;
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
	/*----- PROTECTED REGION ID(USB2::read_InputLength) ENABLED START -----*/
	//	Set the attribute value
	attr_InputLength_read[0] = input_queue_length(); 
	attr.set_value(attr_InputLength_read);
	
	/*----- PROTECTED REGION END -----*/	//	USB2::read_InputLength
}
//--------------------------------------------------------
/**
 *	Read attribute OutputLength related method
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 *
 *	Data type:	Tango::DevLong
 *	Attr type:	Scalar
 */
//--------------------------------------------------------
void USB2::read_OutputLength(Tango::Attribute &attr)
{
	DEBUG_STREAM << "USB2::read_OutputLength(Tango::Attribute &attr) entering... " << std::endl;
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
	/*----- PROTECTED REGION ID(USB2::read_OutputLength) ENABLED START -----*/
	//	Set the attribute value
	attr_OutputLength_read[0] = output_queue_length();
	attr.set_value(attr_OutputLength_read);
	
	/*----- PROTECTED REGION END -----*/	//	USB2::read_OutputLength
}
//--------------------------------------------------------
/**
 *	Read attribute Reconnections related method
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 *
 *	Data type:	Tango::DevLong
 *	Attr type:	Scalar
 */
//--------------------------------------------------------
void USB2::read_Reconnections(Tango::Attribute &attr)
{
	DEBUG_STREAM << "USB2::read_Reconnections(Tango::Attribute &attr) entering... " << std::endl;
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
	/*----- PROTECTED REGION ID(USB2::read_Reconnections) ENABLED START -----*/
	//	Set the attribute value
	attr_Reconnections_read[0] = reconnections;
	attr.set_value(attr_Reconnections_read);
	
	/*----- PROTECTED REGION END -----*/	//	USB2::read_Reconnections
}

//--------------------------------------------------------
/**
 *	Method     : USB2::add_dynamic_attributes()
 *	Description: Create the dynamic attributes if any
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 *                for specified device.
 */
//--------------------------------------------------------
void USB2::add_dynamic_attributes()
{
	/*----- PROTECTED REGION ID(USB2::add_dynamic_attributes) ENABLED START -----*/
	
	//	Add your own code to create and add dynamic attributes if any
	
	/*----- PROTECTED REGION END -----*/	//	USB2::add_dynamic_attributes
}

//--------------------------------------------------------
/**
 *	Command Write related method
 *
 *
 *	@param argin
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 */
//--------------------------------------------------------
void USB2::write(const Tango::DevVarCharArray *argin)
{
	DEBUG_STREAM << "USB2::Write()  - " << device_name << std::endl;
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
	/*----- PROTECTED REGION ID(USB2::write) ENABLED START -----*/
	
	check_init();

	if(!timeout) {
		Tango::Except::throw_exception( "",
				"Invalid timeout",
				"USB2::write()");
	}

	unsigned char *argin_data = new unsigned char[argin->length()];
	for(unsigned int i=0; i<argin->length(); ++i)
	{
		argin_data[i] = (*argin)[i];
	}

	int bytes_total = 0, bytes_to_write  = argin->length();
	while(bytes_total != bytes_to_write) {
		int bytes_written;
		int ret = libusb_bulk_transfer(dev_handle,
				ep_down, argin_data + bytes_total,
				bytes_to_write - bytes_total, &bytes_written, timeout);

		if(ret != 0 || bytes_written != bytes_to_write - bytes_total) {
			delete argin_data;

			string error_mesg = "Unable to send request to device";

			close();
			open();
			DEBUG_STREAM << error_mesg << endl;
			set_state( Tango::FAULT );
			set_status( error_mesg );

			Tango::Except::throw_exception( "",
					error_mesg,
					"USB2::write()");
		}
		bytes_total += bytes_written;
	}
	delete argin_data;

	/*----- PROTECTED REGION END -----*/	//	USB2::write
}
//--------------------------------------------------------
/**
 *	Command Read related method
 *
 *
 *	@param argin
 *	@returns
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 */
//--------------------------------------------------------
Tango::DevVarCharArray *USB2::read(Tango::DevLong argin)
{
	Tango::DevVarCharArray *argout;
	DEBUG_STREAM << "USB2::Read()  - " << device_name << std::endl;
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
	/*----- PROTECTED REGION ID(USB2::read) ENABLED START -----*/
	
	check_init();
	
	if(!timeout) {
		Tango::Except::throw_exception( "",
				"Invalid timeout",
				"USB2::write()");
	}
	
	if (argin < 0)
	{
		Tango::Except::throw_exception("",
				"Input has to be in positive range",
				"USB2::read()");
	}

	while( (size_t)argin > data.size() )
	{
		int bytes_readed;
		int ret = libusb_bulk_transfer(dev_handle, ep_up, buffer,
				maxPacketSize, &bytes_readed, timeout);
		if(ret != 0 || bytes_readed == 0) {
			string error_mesg( "No response from device" );
			DEBUG_STREAM << error_mesg << endl;
			Tango::Except::throw_exception("",
					error_mesg, "USB2::read()");
		}

		for(int i=0;i<bytes_readed;++i) {
			data.push_back(buffer[i]);
		}
	}

	argout = new Tango::DevVarCharArray();
	argout->length(argin);
	for( int i=0; i<argin; ++i )
	{
		(*argout)[i] = data[i];
	}
	data.erase( data.begin(), data.begin() + argin );

	/*----- PROTECTED REGION END -----*/	//	USB2::read
	return argout;
}
//--------------------------------------------------------
/**
 *	Command ReadUntil related method
 *
 *
 *	@param argin
 *	@returns
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 */
//--------------------------------------------------------
Tango::DevVarCharArray *USB2::read_until(const Tango::DevVarCharArray *argin)
{
	Tango::DevVarCharArray *argout;
	DEBUG_STREAM << "USB2::ReadUntil()  - " << device_name << std::endl;
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
	/*----- PROTECTED REGION ID(USB2::read_until) ENABLED START -----*/
	
	check_init();
	
	if(!timeout) {
		Tango::Except::throw_exception( "",
				"Invalid timeout",
				"USB2::write()");
	}
	
	if (argin->length() != 1)
	{
		Tango::Except::throw_exception("",
				"Delimiter has to be one byte length",
				"USB2::read_until()");
	}

	char delim = (*argin)[0];
	bool found = false;
	size_t pos;

	while( ! found )
	{
		for( pos = 0; pos < data.size(); ++pos )
		{
			if (memcmp(&data[pos], &delim, 1) == 0)
			{
				found = true;
				break;
			}
		}
		if ( ! found )
		{
			int bytes_readed;
			int ret = libusb_bulk_transfer(dev_handle, ep_up, buffer,
					maxPacketSize, &bytes_readed, timeout);
			if(ret != 0 || bytes_readed == 0) {
				string error_mesg( "No response from device" );
				DEBUG_STREAM << error_mesg << endl;
				Tango::Except::throw_exception("",
						error_mesg, "USB2::read_until()");
			}

			for(int i=0;i<bytes_readed;++i) {
				data.push_back(buffer[i]);
			}
		}
	}

	argout = new Tango::DevVarCharArray();
	argout->length( pos+1 );
	for( size_t i = 0; i < pos + 1; ++i )
	{
		(*argout)[i] = data[i];
	}
	data.erase( data.begin(), data.begin() + pos + 1 );

	/*----- PROTECTED REGION END -----*/	//	USB2::read_until
	return argout;
}
//--------------------------------------------------------
/**
 *	Method     : USB2::add_dynamic_commands()
 *	Description: Create the dynamic commands if any
Alessio Igor Bogani's avatar
Alessio Igor Bogani committed
 *                for specified device.
 */
//--------------------------------------------------------
void USB2::add_dynamic_commands()
{
	/*----- PROTECTED REGION ID(USB2::add_dynamic_commands) ENABLED START -----*/
	
	//	Add your own code to create and add dynamic commands if any
	
	/*----- PROTECTED REGION END -----*/	//	USB2::add_dynamic_commands
}

/*----- PROTECTED REGION ID(USB2::namespace_ending) ENABLED START -----*/

//	Additional Methods
void USB2::check_init()
{
	if (! init_error.empty() )
	{
		DEBUG_STREAM << init_error << endl;
		Tango::Except::throw_exception( "",
				init_error.c_str(),
				"USB2::check_init()");
	}
}

void USB2::open()
{
	DEBUG_STREAM << "Opening USB device..." << endl;

	if(libusb_init(&ctx) < 0) {
		string error_mesg = "Failed to initialize libusb";
		ERROR_STREAM << error_mesg << endl;
		assert( false);
		Tango::Except::throw_exception( "",
				error_mesg,
				"USB2::open()");
	}

#ifndef NDEBUG
	libusb_set_debug(ctx, LIBUSB_LOG_LEVEL_WARNING);
#endif

	dev_handle = libusb_open_device_with_vid_pid(ctx, vid, pid);
	if(dev_handle == NULL) {
		libusb_exit(ctx);

		string error_mesg = "Unable to open device";
		ERROR_STREAM << error_mesg << endl;
		assert( false);
		Tango::Except::throw_exception( "",
				error_mesg,
				"USB2::open()");
	}

	if(libusb_claim_interface(dev_handle, interface) < 0) {
		libusb_release_interface(dev_handle, interface);
		libusb_close(dev_handle);
		libusb_exit(ctx);

		string error_mesg = "Failed to claim interface";
		ERROR_STREAM << error_mesg << endl;
		assert( false);
		Tango::Except::throw_exception( "",
				error_mesg,
				"USB2::open()");
	}
  
	DEBUG_STREAM << "USB device opened." << endl;
	reconnections++;

	set_state(Tango::ON);
	set_status("The device in ON state");
}

void USB2::close()
{
	DEBUG_STREAM << "Closing USB device..." << endl;

	int input_len = input_queue_length();
	int output_len = output_queue_length();

	if( input_len + output_len)
	{
		WARN_STREAM << " Bytes dropped: " << input_len << " input, "
			<< output_len << " output" << endl;
	}

	if(dev_handle)
	{
		libusb_release_interface(dev_handle, interface);
		libusb_close(dev_handle);
		libusb_exit(ctx);

		dev_handle = NULL;
	}

	data.clear();

	DEBUG_STREAM << "USB device closed" << endl;
}

int USB2::input_queue_length()
{
	return data.size();
}

int USB2::output_queue_length()
{
	return 0;
}

/*----- PROTECTED REGION END -----*/	//	USB2::namespace_ending
} //	namespace