//=================================================================
//
//        Port.h
//
//        Port test class
//
//=================================================================
//####COPYRIGHTBEGIN####
//
// -------------------------------------------
// The contents of this file are subject to the Cygnus eCos Public License
// Version 1.0 (the "License"); you may not use this file except in
// compliance with the License.  You may obtain a copy of the License at
// http://sourceware.cygnus.com/ecos
// 
// Software distributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the
// License for the specific language governing rights and limitations under
// the License.
// 
// The Original Code is eCos - Embedded Cygnus Operating System, released
// September 30, 1998.
// 
// The Initial Developer of the Original Code is Cygnus.  Portions created
// by Cygnus are Copyright (C) 1998, 1999 Cygnus Solutions.
// All Rights Reserved.
// -------------------------------------------
//
//####COPYRIGHTEND####
//=================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):     sdf
// Contributors:  sdf
// Date:          1999-04-01
// Description:   This class abstracts download ports for use in the testing infrastructure
// Usage:
//
//####DESCRIPTIONEND####

#ifndef _PORT_H
#define _PORT_H
#include "stdafx.h"
#include "eCosTest.h"
#include "eCosTestSerial.h"

// Class representing permission to run a test.  Instances of this class correspond
// either to physically attached communications ports or to simulator processes.
// GetPort acquires (locks) such a resource - Release() relinquishes it.
class CPort {
	friend class GarbageCollector;
public:
	// Declare the availability of a port to execute tests of type target.
	// Two versions exist - one to give permission to execute a test in the current thread in a simulator and another
	// on attached hardware.

	// Simulator
	CPort(CeCosTest::TargetType target);
	// Hardware with reset
	CPort(
		CeCosTest::TargetType target, 
		// Physical port characteristics.  If pszPort is null, simulator run is meant (in which case nBaud is ignored)
		const char *pszPort, int nBaud,
		// Associated X10 characteristics: pszPort may be a remote server (host:port) or a local port
		const char *pszResetHostPort, char cControl1, char cControl2, const char *pszAuxPort=0,
        int nDelay=1000
		);
	// Hardware without reset
	CPort(CeCosTest::TargetType target, const char * pszDownloadPort, int nBaud);
	virtual ~CPort();

	// Count of ports (free or not) capable of executing this kind of test:
	static int Count (const CeCosTest::ExecutionParameters &e);
	static void DeleteAllInstances();

	// For report purposes:
	const char * Name() const { return m_strPort; }					// Name [of serial port]
	const CeCosTest::TargetType Target() const { return m_Target; }	// Supported target
	
	// Acquire a port for exclusive use by the current process and thread.
	// [block current thread until such a port becomes available]
	// This function is thread-safe.
	static CPort *GetPort(const CeCosTest::ExecutionParameters &e);
	void Release();

	// Reset the hardware attached to this port
    bool Reset(int &nErr, CeCosTestUtils::String &str);

    bool IsLocked() const { return m_bLocked; }
    bool Lock (const CeCosTest::ExecutionParameters &e);
    
    int Baud() const { return m_nBaud; }							// Baud rate
    char Control1()  const { return m_cControl1; }
    char Control2()  const { return m_cControl2; }
    const char *ResetHost() const { return m_strResetHost; }
    int ResetPort() const { return m_nResetPort; }


protected:
    int m_nDelay;
    CeCosTestSerial m_Serial;
    bool OpenSerial ();
    bool CloseSerial();

    bool m_bLocked;
    void Chain();
	// Can this port deal with the given test?
    bool Matches (const CeCosTest::ExecutionParameters &e) const { 
        return m_Target==e.Target() 
            ; }

	// House code and device code for X10 reset:
	char m_cControl1;
	char m_cControl2;
	// X10 daemon, host and tcp/ip port:
	CeCosTestUtils::String m_strResetHost;
	int m_nResetPort;

	// Download host and serial port:
	int m_nPort;
	CeCosTestUtils::String m_strPort,m_strAuxPort;

	int m_nBaud;						// Baud rate

	CeCosTest::TargetType m_Target;		// Target type
	bool m_bSim;						// Whether a simulator "port"

	bool m_bInUse;						// Whether being used

	// Chaining to support DeleteAllInstances:
	static CPort *pFirstInstance;
	CPort *m_pPrevInstance;
	CPort *m_pNextInstance;

	class GarbageCollector {
	public:
		GarbageCollector();
		~GarbageCollector();
		static GarbageCollector gc;
	};
};
#endif
