/*
                               Siemens AG
                         Mobile Radio Terminals
                             Munich,  Germany

                          COMPANY CONFIDENTIAL
                          All Rights Reserved

.AUTHOR         Jens Packeiser

.VERSION        0.9

.DATE           05.09.2003

.SHORT_DESCR    Dialog Funktion for Serial Device Driver S0

.SW_COMPONENT   

.SW_TYPE        

.STATUS         INOFFICAL

.CHANGE_CONTROL
Version |  Date  | Changed by | Reason for Change
  0.1    20.06.02 J. Packeiser  file created...
  0.2    24.06.02 J. Packeiser	Added functions for Serial Port
  0.3	 27.06.02 J. Packeiser	Added funktions for Log File
  0.4	 09.07.02 J. Packeiser	Added flow control
  0.5	 17.07.02 J. Packeiser	File is ready
  0.6	 13.08.02 J. Packeiser	some corrections on flow control
  0.7	 29.08.02 Ferry Hielscher  
  0.8	 29.08.02 S. Lackner add Ferry Hielscher and include ddserhw_ci.h  
  0.9    05.09.02 A. Bucher     changes for MOPI...\n
                                restructured OVERLAPPED operation\n 
                                adjusted stringlength in SetMessageWin\n
  1.0    25.01.05 Li Yang (PEK) Modify function RecMPMDataEventFun()  
*/  


/* ------------------------------------------------------------------ */
/* --------------------- I N C L U D E S ---------------------------- */
/* ------------------------------------------------------------------ */
#include <global.h>
#include "winrc.h"				// needed for Callback function messages
#include "winmain.h"			// needed for windows functions (DispGetWinHandle, ...)
#include <stdio.h>				// needed for sprintf(...)
#include "comdevs.h"
#include "ddserhw.h"			// needed for stSerDevStatus
#include "ddserhw_ci.h"			
#include "mopi.h"
#include "mopiext.h"

#include "avsdapi.h"            // needed for MPM connection  
#include <atlbase.h>            // needed for MPM connection 	

/* ------------------------------------------------------------------ */
/* --------------------- D E F I N E S ------------------------------ */
/* ------------------------------------------------------------------ */
#define MAXWIRECOM 20


/* ------------------------------------------------------------------ */
/* ------------------ N E W   D A T A T Y P E S --------------------- */
/* ------------------------------------------------------------------ */
typedef enum {CREATE_NEW_TRACE_FILE, WRITE_SENT_BUFFER, WRITE_RECIEVED_BUFFER, WRITE_ACT, WRITE_BUF} TYP;
typedef enum {TRACE,OPEN,CLOSE,GIP,RC, TRACEOV, TRACEAP,TRACEDIS,
		SET_DTR, CLR_DTR,
		SET_RTS, CLR_RTS,
		SET_CTS, CLR_CTS,
		SET_DSR, CLR_DSR}MSG_WIN;

typedef enum {CTS,RTS,DSR,DTR,DCD}SIGNAL;


/* ------------------------------------------------------------------ */
/* --------------------- F U N C T I O N S -------------------------- */
/* ------------------------------------------------------------------ */
// Prototypes intern
void initWindow (HWND, UINT, UINT);
BOOL CloseWIRECom(void);
BOOL InitWIRECom(unsigned int, unsigned int);
DWORD dwWatchSerComWire(void);
void ScrollWIRETextField(void);
void detectLines(void);

// Calls from ddwirepc.c
extern "C" void SetWireFlowControl(unsigned int,stSerDevStatus);
extern "C" void SetAppFlowControl(unsigned int);
extern "C" unsigned int WriteSerComWire(char*, unsigned int);
extern "C" void SetDlgTextInFC(FCMODE);
extern "C" void SetDlgTextOutFC(FCMODE);

// Calls from extern and intern
extern "C" void WriteWIRETrace(char *, unsigned char*, unsigned int, TYP, int);
extern "C" void SetSignalInWin(SIGNAL,DWORD);
extern "C" void RecFlowC(SIGNAL, int, int);
extern "C" void SetMessageWin(MSG_WIN, BOOL);
extern "C" void SetWireComSpeed(unsigned int);
extern "C" long GetActTime(void);


// Externals
extern "C" HWND DispGetWinHandle(void);		// Windows function

// Definitions in ddwirepc.c
extern "C" void WIRESerComRead(BYTE);
extern "C" void SignalEvent(SIGNAL, int, int);
extern "C" void SetBaudrateVar(unsigned int);
extern "C" void	ReqDisconnect(void);
extern "C" void InitIOHandleWire(void);
extern "C" void ChangeBufSize(char *);
extern "C" void ResetSignals(void);
extern "C" void ResetBuf(void);

// Defines and function for MPM connection use 
#define AVSD_SIGNAL_NO_RTS		0xFE
#define AVSD_SIGNAL_NO_CTS		0xFD
#define AVSD_SIGNAL_NO_DTR		0xFB
#define AVSD_SIGNAL_NO_DSR		0xF7
#define AVSD_SIGNAL_NO_RI		0xEF
#define AVSD_SIGNAL_NO_CD		0xDF

#define MPM_LOGFILE_NAME_SIZE  50     

BOOL InitMPMWire(void);                     
void CloseMPMWire(void);
unsigned int  SendFrameToMPMWire(char *pSend, int Length);
int MPMConnectState  = 0 ;
int WireSimuState    = 0 ;
unsigned int MPMWirePort  = 21;

char recvMPMLogFile[MPM_LOGFILE_NAME_SIZE] = "MPMin.txt"; 
char sendMPMLogFile[MPM_LOGFILE_NAME_SIZE] = "MPMout.txt"; 	
void CreateMPMLogfile(void);
void WriteMPMTrace(char *cFile, unsigned char *Msg, unsigned int len, unsigned int iType);

HANDLE hDataEvent,hFlowEvent; 
BOOL bStopDataEventThread;
BOOL bStopFlowEventThread;

DWORD dwRecThreadMPMDataEventId;
HANDLE hRecMPMDataEventThread;	
extern "C" DWORD WINAPI RecMPMDataEventFun(LPVOID pParam);	

DWORD dwRecThreadMPMFlowEventId;
HANDLE hRecMPMFlowEventThread;	
extern "C" DWORD WINAPI RecMPMFlowEventFun(LPVOID pParam);	
void SetVCommState(int signal);


/* ------------------------------------------------------------------ */
/* ------------------------- G L O B A L S -------------------------- */
/* ------------------------------------------------------------------ */
static HWND hWireDialog;
static BOOL bLogFileYN=FALSE, bStopThread=FALSE;
static HANDLE hCom=INVALID_HANDLE_VALUE, hReadThread=NULL;
static DWORD dwThreadID;
static OVERLAPPED stOverlapedWrite, stOverlapedRead;
bit bFlow_Control;


/* ------------------------------------------------------------------ */
/* ---------------- W I N D O W   F U N C T I O N S ----------------- */
/* ------------------------------------------------------------------ */

/* ---------------------------------------------------------- */
/* - Callback function for CreateWindow Function			- */
/* ---------------------------------------------------------- */
BOOL CALLBACK WireDialogProc (HWND hwndDlg, UINT message, WPARAM wParam, 
							 LPARAM lParam)
{
	static unsigned int uiComNr=0, uiBaudNr=3;
	static char Bufsize[]={'1','0','2','4','\0'},cBufSize1[]={'1','0','2','4','\0'};
	BOOL bHelp;
	char cFileName[256];
	char cFilter[33]={"Wire trace files (*.wtf)\0*.wtf\0\0"};
	static OPENFILENAME lpfile;

	switch (message)
	{
		case WM_INITDIALOG:
			initWindow(hwndDlg, uiComNr, uiBaudNr);
			return TRUE;
		case WM_CLOSE:
			/*Destroy*/CloseWindow(hwndDlg);
			hWireDialog = 0;
			return TRUE;

		case WM_COMMAND:
			switch(LOWORD(wParam))
			{
			case IDC_WIRE_OPEN:
				// -----  get selected Settings -----
				uiComNr=SendMessage(GetDlgItem(hwndDlg, IDC_WIRE_COM), 
					CB_GETCURSEL, 0, 0);
				uiBaudNr=SendMessage(GetDlgItem(hwndDlg, IDC_WIRE_BAUD), 
					CB_GETCURSEL, 0, 0);
				
				// Is COM Port already initialised
				if(hCom!=INVALID_HANDLE_VALUE)
				{	
					if(MessageBox( DispGetWinHandle(), "Com Port already initialised! Do you want to go on?",
						"PC-Simulator: IrDA Command Dialog",
						(MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION) | MB_TASKMODAL )
						==IDNO)
						return TRUE;
					else
						ReqDisconnect();

				}
				if(hCom!=INVALID_HANDLE_VALUE)
            {
					// -----  Close COM first -----
					CloseWIRECom();
            }
				
				// Init COM
				bHelp=InitWIRECom(uiComNr+1, uiBaudNr);

				// Init Comhandle
				InitIOHandleWire();

				// Disable COM and BAUD
				EnableWindow(GetDlgItem(hwndDlg, IDC_WIRE_COM),FALSE); 
				EnableWindow(GetDlgItem(hwndDlg, IDC_WIRE_BAUD),FALSE);
				EnableWindow(GetDlgItem(hwndDlg, IDC_WIRE_BUF),FALSE);

				// No flow control
				bFlow_Control=0;
				detectLines();

				WireSimuState   = 1 ;										//log wiresimu status 
				
				break;
			case IDC_WIRE_CLOSE:
				CloseWIRECom();
				// Close Connection
				ReqDisconnect();
				// Enable COM and BAUD
				EnableWindow(GetDlgItem(hwndDlg, IDC_WIRE_COM),TRUE); 
				EnableWindow(GetDlgItem(hwndDlg, IDC_WIRE_BAUD),TRUE);
				EnableWindow(GetDlgItem(hwndDlg, IDC_WIRE_BUF),TRUE);

				ResetSignals();
				ResetBuf();
				CheckDlgButton(hWireDialog, IDC_WIRE_FC_FDEV, BST_UNCHECKED);
				CheckDlgButton(hWireDialog, IDC_WIRE_FC_TDEV, BST_UNCHECKED);
				CheckDlgButton(hWireDialog, IDC_WIRE_FC_FAPP, BST_UNCHECKED);
				CheckDlgButton(hWireDialog, IDC_WIRE_FC_TAPP, BST_UNCHECKED);
				
				WireSimuState   = 0 ;										//log wiresimu status 
				
				break;
			case IDC_WIRE_CHLOG:
				if(bLogFileYN==TRUE)
				{
					bLogFileYN=FALSE;
					return 0;
				}
				else
					bLogFileYN=TRUE;

				/* File dialog */
				lpfile.lStructSize=sizeof(OPENFILENAME);
				lpfile.hwndOwner=hWireDialog;
				/* Filter */
				lpfile.lpstrFilter=cFilter;
				lpfile.lpstrCustomFilter=NULL;
				lpfile.nFilterIndex=0;

				lpfile.lpstrTitle="Logfile";
				lpfile.lpstrDefExt=".wtf";
				strcpy(cFileName,"");
				lpfile.lpstrFile=cFileName;
				lpfile.nMaxFile=255;
				if(GetSaveFileName(&lpfile)!=0)
				{	// File
					WriteWIRETrace(cFileName, NULLP, 0, CREATE_NEW_TRACE_FILE, 0);
				} 
				else
				{
					CheckDlgButton(hWireDialog, IDC_WIRE_CHLOG, BST_UNCHECKED);
					SetDlgItemText(hWireDialog,IDC_WIRE_CHLOG,"Logfile");
					bLogFileYN=FALSE;
				}

				break;

			case IDC_WIRE_BUF:
				GetDlgItemText(hwndDlg, IDC_WIRE_BUF, cBufSize1, 50);
				if(strcmp(cBufSize1,Bufsize)!=0)
				{
					ChangeBufSize(cBufSize1);
					strcpy(Bufsize,cBufSize1);
				}
				break;
			case IDC_WIRE_RES:
				ResetSignals();
				ResetBuf();
				if(hCom!=INVALID_HANDLE_VALUE)
				{
					EscapeCommFunction(hCom,CLRRTS);
					EscapeCommFunction(hCom,CLRDTR);
				}
				break;
			return TRUE;
			}
	}
	return FALSE;
}

/* --------------------------------------------------------------- */
/* - Init Function for the Window which is called after creation - */
/* --------------------------------------------------------------- */
void initWindow(HWND hwndDlg, UINT uiComNr, UINT uiBaudNr)
{
	int i, iBaud=2400;
	char cNames[6];

	// Init ComboBox for COM Ports
	for ( i=1; i<=MAXWIRECOM; i++)
	{
		sprintf(cNames, "COM%d", i);
		SendMessage(GetDlgItem(hwndDlg, IDC_WIRE_COM), 
			CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) cNames);
	}
	// Set Curser Selection for Com Ports
	SendMessage(GetDlgItem(hwndDlg, IDC_WIRE_COM), 
		CB_SETCURSEL, uiComNr, 0);

	// Init ComboBox for Baudrates
	for ( i=1; i<8; i++)
	{
		sprintf(cNames, "%d", iBaud);
		SendMessage(GetDlgItem(hwndDlg, IDC_WIRE_BAUD), 
			CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) cNames);
		if (iBaud==38400)
			iBaud=57600;
		else
			iBaud*=2;
	}
	SendMessage(GetDlgItem(hwndDlg, IDC_WIRE_BAUD), 
			CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "128000");
	SendMessage(GetDlgItem(hwndDlg, IDC_WIRE_BAUD), 
			CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "256000");

	// Set Curser Selection for Baudrates
	SendMessage(GetDlgItem(hwndDlg, IDC_WIRE_BAUD), 
		CB_SETCURSEL, uiBaudNr, 0);

	// Init ComboBox for Buffer Size
	SendMessage(GetDlgItem(hwndDlg, IDC_WIRE_BUF), 
			CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "10");
	SendMessage(GetDlgItem(hwndDlg, IDC_WIRE_BUF), 
			CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "1024");
	SendMessage(GetDlgItem(hwndDlg, IDC_WIRE_BUF), 
			CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "2048");
	SendMessage(GetDlgItem(hwndDlg, IDC_WIRE_BUF), 
			CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "4096");

	SendMessage(GetDlgItem(hwndDlg, IDC_WIRE_BUF), 
		CB_SETCURSEL, 1, 0);

	SetDlgItemText(hwndDlg,IDC_WIRE_REC,"Recieved Bytes: ");
	SetDlgItemText(hwndDlg,IDC_WIRE_SENT,"Sent Bytes: ");
}


/* ---------------------------------------------------------- */
/* - Function is called if Button in Command Bar is pressed	- */
/* ---------------------------------------------------------- */
void open_Wire_command_dialog(void)
{ 
	//To avoid run two wire simulation applications at same time; 
	if( MPMConnectState == 1 )            
	{
		MessageBox(DispGetWinHandle(),"MPM connection has been enabled!Please stop them first!", "Information", MB_ICONINFORMATION | MB_OK);
		return;					
	}
	

	hWireDialog = CreateDialog(MainApp::hInstance,MAKEINTRESOURCE(DLG_WIRE),
		DispGetWinHandle(),(DLGPROC)WireDialogProc);
	
	if (hWireDialog == NULL)
	{
		MessageBox( DispGetWinHandle(), 
			"Error: Could not create Wire Dialog Window",
			"PC-Simulator: Wire Command Dialog",
			(MB_OK | MB_ICONEXCLAMATION) | MB_TASKMODAL );
		return;
	}
	
	ShowWindow(hWireDialog,SW_SHOW);
}

/* -------------------------------------------------------------- */
/* - Shows what happened in the window							- */
/* -------------------------------------------------------------- */
void SetMessageWin(MSG_WIN msg, BOOL err)
{
	char cMsg[10000], cHelp[81], cHelp2[81];

	// Get Text aout of Box
	GetDlgItemText(hWireDialog, IDC_WIRE_TEXT, cMsg, 10000);
	// append new line
	if (strlen(cMsg)!=0)
	{
		sprintf(cHelp,"%c%c",0x0d, 0x0a);
		strcat(cMsg,cHelp);
	}

	// Error?
	if (err==FALSE)
		strcat(cMsg,"Error: ");

	switch (msg)
	{
	case OPEN:  strcat(cMsg,"Opened Port COM");
				sprintf(cHelp,"%d with ",SendMessage(GetDlgItem(hWireDialog, IDC_WIRE_COM), 
					CB_GETCURSEL, 0, 0)+1);
				strcat(cMsg,cHelp);
				GetDlgItemText(hWireDialog, IDC_WIRE_BAUD, cHelp2, 6);
				strcat(cMsg, cHelp2);
				break;
	case CLOSE: strcat(cMsg,"Closed Port COM");
				sprintf(cHelp,"%d",SendMessage(GetDlgItem(hWireDialog, IDC_WIRE_COM), 
					CB_GETCURSEL, 0, 0)+1);
				strcat(cMsg,cHelp);
				break;
	case TRACE: strcat(cMsg,"Creating new trace file");
				break;
	case TRACEOV:strcat(cMsg,"Creating new trace file (overwrite old file)");
				break;
	case TRACEAP:strcat(cMsg,"Appending to old trace file");
				break;
	case TRACEDIS:strcat(cMsg,"Disabled logfile");
				break;
	case GIP: strcat(cMsg,"Connected to GIPSY");
				break;
	case RC: strcat(cMsg,"Connected to RCCP");
				break;

	case SET_DTR: strcat(cMsg,"Application sets DTR");
				break;
	case CLR_DTR: strcat(cMsg,"Application resets DTR");
				break;
	case SET_RTS: strcat(cMsg,"Application sets RTS");
				break;
	case CLR_RTS: strcat(cMsg,"Application resets RTS");
				break;

	case SET_DSR: strcat(cMsg,"Detected DSR=1");
				break;
	case CLR_DSR: strcat(cMsg,"Detected DSR=0");
				break;
	case SET_CTS: strcat(cMsg,"Detected CTS=1");
				break;
	case CLR_CTS: strcat(cMsg,"Detected CTS=0");
				break;
	}

	SetDlgItemText(hWireDialog, IDC_WIRE_TEXT, cMsg);
	ScrollWIRETextField();
}

/* -------------------------------------------------------------- */
/* - Scrolls the textfield in the window						- */
/* -------------------------------------------------------------- */
void ScrollWIRETextField(void)
{
	UINT uiNum;

	uiNum=SendMessage(GetDlgItem(hWireDialog, IDC_WIRE_TEXT),
		EM_GETLINECOUNT,0,0);
	SendMessage(GetDlgItem(hWireDialog, IDC_WIRE_TEXT),
		EM_LINESCROLL,0,uiNum-3);
}

/* -------------------------------------------------------------- */
/* - Sets or resets a Signal which can be set, and shows which  - */
/* - Control Lines of the Port are set							- */
/* -------------------------------------------------------------- */
void SetSignalInWin(SIGNAL sig,DWORD dwin)
{
	char trace[26];
	int anz;

	switch (sig)
	{

	// Set from Applikation
	case RTS:
		if (dwin!=0)
		{
			/* if the CTS Signal is set by an applikation */
			/* the RTS Signal is set */
			/* Application can recieve data */
			CheckDlgButton(hWireDialog, IDC_WIRE_FC_TDEV, BST_UNCHECKED);
			CheckDlgButton(hWireDialog, IDC_WIRE_RTS, BST_CHECKED);
			if( MPMConnectState == 1){
			    SetVCommState(SETRTS);						
			}else{
			    EscapeCommFunction(hCom,SETRTS);
			}
			strcpy(trace,"Set RTS Signal");
			anz=3;
			SetMessageWin(SET_RTS,TRUE);
		}
		else
		{
			/* if the CTS Signal is reset by an applikation */
			/* the RTS Signal is reset */
			/* Application can not recieve data */
			CheckDlgButton(hWireDialog, IDC_WIRE_FC_TDEV, BST_CHECKED);
			CheckDlgButton(hWireDialog, IDC_WIRE_RTS, BST_UNCHECKED);
			if( MPMConnectState == 1){
			   SetVCommState(CLRRTS);						
			}else{
			   EscapeCommFunction(hCom,CLRRTS);
			}
			strcpy(trace,"Reset RTS Signal");
			anz=3;
			SetMessageWin(CLR_RTS,TRUE);
		}
		break;

	

	case DTR:
		if (dwin!=0)
		{
			// if the DSR Signal is set by an applikation
			// the DTR Signal is set 
			CheckDlgButton(hWireDialog, IDC_WIRE_DTR, BST_CHECKED);
			if( MPMConnectState == 1){
			   SetVCommState(SETDTR);						
			}else{
			   EscapeCommFunction(hCom,SETDTR);
			}
			strcpy(trace,"Set DTR Signal");
			anz=3;
			SetMessageWin(SET_DTR,TRUE);
		}
		else
		{
			// if the DSR Signal is set by an appDSRation
			// the DTR Signal is set 
			CheckDlgButton(hWireDialog, IDC_WIRE_DTR, BST_UNCHECKED);
			if( MPMConnectState == 1){
			   SetVCommState(CLRDTR);						
			}else{
			   EscapeCommFunction(hCom,CLRDTR);
			}
			strcpy(trace,"Reset DTR Signal");
			anz=3;
			SetMessageWin(CLR_DTR,TRUE);
		}
		break;


	// Set from Port
	case CTS:
		// if the CTS Signal changes state
		if (dwin!=0)
		{
			CheckDlgButton(hWireDialog, IDC_WIRE_CTS, BST_CHECKED);
			CheckDlgButton(hWireDialog, IDC_WIRE_FC_FDEV, BST_UNCHECKED);
			strcpy(trace,"CTS Signal is set");
			anz=4;
			SetMessageWin(SET_CTS,TRUE);
		}
		else
		{
			CheckDlgButton(hWireDialog, IDC_WIRE_CTS, BST_UNCHECKED);
			CheckDlgButton(hWireDialog, IDC_WIRE_FC_FDEV, BST_CHECKED);
			strcpy(trace,"CTS Signal is reset");
			anz=4;
			SetMessageWin(CLR_CTS,TRUE);
		}
		break;

	case DSR: 
		// if the DSR Signal changes state
		if (dwin!=0)
		{
			CheckDlgButton(hWireDialog, IDC_WIRE_DSR, BST_CHECKED);
			strcpy(trace,"DSR Signal is set");
			anz=4;
			SetMessageWin(SET_DSR,TRUE);
		}
		else
		{
			CheckDlgButton(hWireDialog, IDC_WIRE_DSR, BST_UNCHECKED);
			strcpy(trace,"DSR Signal is reset");
			anz=4;
			SetMessageWin(CLR_DSR,TRUE);
		}
		break;
	
	case DCD: 
		// if the DCD Signal changes state
		if (dwin!=0)
		{
			CheckDlgButton(hWireDialog, IDC_WIRE_DCD, BST_CHECKED);
			strcpy(trace,"DCD Signal is set");
			anz=4;
		}
		else
		{
			CheckDlgButton(hWireDialog, IDC_WIRE_DCD, BST_UNCHECKED);
			strcpy(trace,"DCD Signal is reset");
			anz=4;
		}
		break;
	}
	WriteWIRETrace(trace, NULL, 0, WRITE_ACT, anz);
}


/* ------------------------------------------------------------------ */
/* ------------------- P O R T   F U N C T I O N S ------------------ */
/* ------------------------------------------------------------------ */

/* ---------------------------------------------------------- */
/* - Closes the open Port if one's open						- */
/* ---------------------------------------------------------- */
BOOL CloseWIRECom(void)
{
	if(hCom != INVALID_HANDLE_VALUE)
	{
		// set stop-connected flag to TRUE
		bStopThread = TRUE;		
  
		// disable event notification and wait for thread to halt
		SetCommMask( hCom, 0 );

		// block until thread has been halted
		while( dwThreadID!=0 );

		// purge any outstanding reads/writes 
		PurgeComm( hCom, PURGE_TXABORT | PURGE_RXABORT |
                     PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
    
		// close device handle
		CloseHandle( hCom ) ;
		hCom=INVALID_HANDLE_VALUE;

		// clean up event objects
		CloseHandle( stOverlapedRead.hEvent ) ;
		CloseHandle( stOverlapedWrite.hEvent ) ;

		SetMessageWin(CLOSE,TRUE);

		WriteWIRETrace("Closed open Port", NULL, 0, WRITE_ACT, 3);
		return TRUE;
	}
	else 
	{
		WriteWIRETrace("Error: Closed open Port", NULL, 0, WRITE_ACT, 4);
		return FALSE;
	}
}

/* ---------------------------------------------------------- */
/* - Open and inits the chosen Port							- */
/* ---------------------------------------------------------- */
BOOL InitWIRECom(unsigned int uiComNr, unsigned int uiBaudNr)
{
	int i=0;
	char cComNr[6], cErrorMsg[50];
	ULONG uiSpeed;
	static  DWORD dwCreationFlags;

   stOverlapedWrite.Offset = 0 ;
	stOverlapedWrite.OffsetHigh = 0 ;
	stOverlapedRead.Offset = 0 ;
	stOverlapedRead.OffsetHigh = 0 ;

	// create I/O event used for overlapped reads / writes
	stOverlapedRead.hEvent = CreateEvent( NULL,    // no security
                                        TRUE,    // explicit reset req
                                        FALSE,   // initial event reset
                                        NULL ) ; // no name

	stOverlapedWrite.hEvent = CreateEvent( NULL,    // no security
                                         TRUE,    // explicit reset req
                                         FALSE,   // initial event reset
                                         NULL ) ; // no name

	CloseHandle(hCom);

// ---------  get Speed out of CurSel  ---------
	switch (uiBaudNr)
	{
		case 0: uiSpeed=2400; break;
		case 1: uiSpeed=4800; break;
		case 2: uiSpeed=9600; break;
		case 3: uiSpeed=19200; break;
		case 4: uiSpeed=38400; break;
		case 5: uiSpeed=57600; break;
		case 6: uiSpeed=115200; break;
		case 7: uiSpeed=128000; break;
		case 8: uiSpeed=256000; break;
	}

// ---------  Open chosen Port  ---------
	sprintf(cComNr, "COM%d:",uiComNr);
	hCom =	CreateFile(cComNr,
			GENERIC_READ | GENERIC_WRITE,
			0, 
			NULL, 
			OPEN_EXISTING,
			FILE_FLAG_OVERLAPPED,
			0);

	if(hCom == INVALID_HANDLE_VALUE)	// CreateFile failed
	{
		// Error message
		sprintf(cErrorMsg,"Unable to open COM%d: port", uiComNr);
		MessageBox (NULL,cErrorMsg, NULL, MB_ICONERROR);
		SetMessageWin(OPEN,FALSE);
		return FALSE;
	}

	SetWireComSpeed(uiSpeed);
// -----  Creating Thread -----
	
	// create prosess dwWatchSerCom()
	if( NULL == ( hReadThread=
                CreateThread( (LPSECURITY_ATTRIBUTES) NULL, 0,
                              (LPTHREAD_START_ROUTINE) dwWatchSerComWire,
                              0, dwCreationFlags, &dwThreadID)) )
	{
		CloseHandle(hReadThread);
		MessageBox (NULL,"Unable to create the read thread", NULL, MB_ICONERROR);
		
		SetMessageWin(OPEN,FALSE);
      return FALSE;
	}

 	SetThreadPriority(hReadThread, THREAD_PRIORITY_NORMAL);
	SetMessageWin(OPEN,TRUE);

	bStopThread=FALSE;

	// cErrorMsg is used for normal Msg
	sprintf(cErrorMsg,"Opened Port %s",cComNr);
	cErrorMsg[strlen(cErrorMsg)-1]='\0';
	WriteWIRETrace(cErrorMsg, NULL, 0, WRITE_ACT, 3);

	return TRUE;
}

/* ---------------------------------------------------------- */
/* - Sets the Baudrate of the opened Port					- */
/* ---------------------------------------------------------- */
void SetWireComSpeed(unsigned int uispeed)
{
	int i;
	DCB dcbCom;

// ----------  Set the UART speed  ----------
	// Load Settings of hCom into Structure dcbCom
	GetCommState(hCom, &dcbCom);	

	// Now figure out how many times to count down from 115200
	switch (uispeed)
	{
		case 2400: dcbCom.BaudRate=CBR_2400; i=6; break;
		case 4800: dcbCom.BaudRate=CBR_4800; i=5; break;
		case 9600: dcbCom.BaudRate=CBR_9600; i=4; break;
		case 19200: dcbCom.BaudRate=CBR_19200; i=3; break;
		case 38400: dcbCom.BaudRate=CBR_38400; i=2; break;
		case 57600: dcbCom.BaudRate=CBR_57600; i=1; break;
		case 115200: dcbCom.BaudRate=CBR_115200; i=0; break;
		case 128000: dcbCom.BaudRate=CBR_128000; i=0; break;
		case 256000: dcbCom.BaudRate=CBR_256000; i=0; break;
	}
	// Act Baudrate has to be known in file ddwireinit.c
	SetBaudrateVar(uispeed);

	dcbCom.fBinary = TRUE;
	dcbCom.fParity = TRUE;
	dcbCom.fOutxCtsFlow    = FALSE;  // ignore possible hangups
	dcbCom.fOutxDsrFlow    = FALSE;    // don't wait on the DSR line
	dcbCom.fDtrControl     = DTR_CONTROL_DISABLE; //0;
	dcbCom.fDsrSensitivity = FALSE;
	dcbCom.fTXContinueOnXoff = TRUE;
	dcbCom.fOutX           = FALSE; // no XON/XOFF control
	dcbCom.fInX            = FALSE;
	dcbCom.fErrorChar      = FALSE;
	dcbCom.fNull           = FALSE;
	dcbCom.fRtsControl     = RTS_CONTROL_DISABLE; //0
	dcbCom.fAbortOnError   = FALSE;
	dcbCom.ByteSize        = 8;
	dcbCom.Parity          = NOPARITY;
	dcbCom.StopBits        = ONESTOPBIT;

	// Set new Settings to hCom
	SetCommState(hCom, &dcbCom);
}

/* ---------------------------------------------------------- */
/* - Thread Main function to watch the serial Port			- */
/* ---------------------------------------------------------- */
DWORD dwWatchSerComWire(void)
{
	BYTE		Byte;
	BOOL		fReadStat=TRUE;
	DWORD		dwCommModemStatus, dwError, dwBytesTransferred, dwErrorFlags, dwCommStat=0;
	COMSTAT ComStat;
	static  BOOL bStopRead = FALSE, bEscaped=FALSE;
	static int anz=0;
	static unsigned long rec=0;
	char mess[20];

// ---------------------------------------------
  
	// Specify a set of events to be monitored for the port.
	SetCommMask (hCom, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);
	
	while (!bStopThread) 
	{
		dwCommModemStatus = 0 ;
		// Wait for an event to occur for the port.
		WaitCommEvent(hCom, &dwCommModemStatus, NULL);

		if( SetCommMask (hCom, EV_CTS|EV_DSR|EV_RLSD) )			
		{
			if(dwCommModemStatus&EV_CTS)
			{// a CTS Signal was detected
				// changed into which state
				GetCommModemStatus(hCom,&dwCommStat);
				// Inform App
				SignalEvent(CTS, dwCommStat & MS_CTS_ON, MS_CTS_ON);
				// shows state in win
				//SetSignalInWin(CTS, dwCommStat & MS_CTS_ON);
				// starts or stopps Transmit Prozess
				RecFlowC(CTS, dwCommStat & MS_CTS_ON, MS_CTS_ON);
			}

			if(dwCommModemStatus&EV_DSR)
			{// a DSR Signal was detected
				// not necessary at the moment
				// changed into which state
				GetCommModemStatus(hCom,&dwCommStat);
				// Inform App
				SignalEvent(DSR,dwCommStat & MS_DSR_ON, MS_DSR_ON);
				// shows state in win
				//SetSignalInWin(DSR, dwCommStat & MS_DSR_ON);
			}

			if(dwCommModemStatus&EV_RLSD)
			{// a CTS Signal was detected
				// changed into which state
				GetCommModemStatus(hCom,&dwCommStat);
				// Inform App
				SignalEvent(DCD,dwCommStat & MS_RLSD_ON, MS_RLSD_ON);
				// shows state in win
				//SetSignalInWin(DCD, dwCommStat & MS_RLSD_ON);
			}
		}

		// Re-specify the set of events to be monitored for the port.
		if( SetCommMask (hCom, EV_RXCHAR) )			
		{	
			// wenn ein Zeichen empfangen wurde
			if (dwCommModemStatus & EV_RXCHAR) 
			{
				// Loop for waiting for the data stream.
      			do																										
				{
					// Is Flow Control set?
					if (bFlow_Control==1)
						continue;

					// Liest ein Byte aus dem Buffer
					fReadStat = ReadFile(hCom, &Byte, 1, &dwBytesTransferred, &stOverlapedRead);			
					if(!fReadStat)
					{
						if (GetLastError() == ERROR_IO_PENDING)
						{
							while(!GetOverlappedResult(hCom, &stOverlapedRead, &dwBytesTransferred, TRUE ))
							{
								dwError = GetLastError();
								if(dwError == ERROR_IO_INCOMPLETE)
								{	// normal result if not finished
									continue;
								}
								else
								{	// an error occurred, try to recover
									dwBytesTransferred = 0 ;
									ClearCommError(hCom, &dwErrorFlags, &ComStat) ;
									MessageBox (NULL,"Error by reading from serial port ", NULL, MB_ICONERROR);
									break;
								}
							}

						}
						else
						{	// some other error occurred
							dwBytesTransferred = 0 ;
							ClearCommError(hCom, &dwErrorFlags, &ComStat) ;
							MessageBox (NULL,"Error by reading from serial port ", NULL, MB_ICONERROR);
						}
					}

					if(dwBytesTransferred !=0)
					{
						if(!bStopRead)
						{
							WIRESerComRead(Byte);
							WriteWIRETrace(NULL, &Byte, 1, WRITE_RECIEVED_BUFFER, 0);
							// dwBytesTransferred=0;
								// show count of recieved and sent Bytes
							rec++;
							sprintf(mess,"Recieved Bytes: %d",rec);
							SetDlgItemText(hWireDialog,IDC_WIRE_REC,mess);
						}
					}

				} while (dwBytesTransferred !=0);
			} // end of "if (dwCommModemStatus & EV_RXCHAR)"
	
		} // end of "if( SetCommMask (hCom, EV_RXCHAR) )"			

		SetCommMask (hCom, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);
	} // end of "while (!bStopThread)" 

  
  // --------------------------------------------

	// clear flags
	hReadThread=NULL;
	dwThreadID=0;

	return 0;
}

/* ---------------------------------------------------------- */
/* - Write function to send a given buffer					- */
/* ---------------------------------------------------------- */
unsigned int WriteSerComWire(char* cBuffer, unsigned int len)
{

	//when using MPM connection ,use specified function 
	if( MPMConnectState == 0 ){	

	DWORD dwBytesWritten=0, dwError, dwBytesSent=0, dwErrorFlags;
	BOOL bWriteState;
	COMSTAT ComStat;
	static unsigned long sent=0;
	char mess[20];

	if (!(hCom==INVALID_HANDLE_VALUE))
	{
		bWriteState=WriteFile(hCom, cBuffer, (DWORD)len, &dwBytesWritten, &stOverlapedWrite);
		if (!bWriteState)
		{
			if(GetLastError()==ERROR_IO_PENDING)
			{
				while(!GetOverlappedResult( hCom, &stOverlapedWrite, &dwBytesWritten, TRUE ))
				{	
					dwError = GetLastError();
					if(dwError == ERROR_IO_INCOMPLETE)
					{
						// normal result if not finished
						dwBytesSent += dwBytesWritten;
						continue;
					}
					else
						MessageBox (NULL,"Error on writing ", NULL, MB_ICONERROR);
				}

				dwBytesSent += dwBytesWritten;

				if( dwBytesSent != len )
					// wenn die Anzahl der zu sendeten Bytes ungleich den gesendeten
					MessageBox (NULL,"Error by writing to serial port ", NULL, MB_ICONERROR);
			}
			else
			{
				// some other error occurred
				ClearCommError( hCom, &dwErrorFlags, &ComStat );
				MessageBox (NULL,"Error on writing", NULL, MB_ICONERROR);
			} // end of: if(GetLastError()==ERROR_IO_PENDING)
		}
	}

	// Write Bytes to TraceFile
	WriteWIRETrace(NULL, (unsigned char*)cBuffer, len, WRITE_SENT_BUFFER, 0);
	
	sent+=len;
	sprintf(mess,"Sent Bytes: %d",sent);
	SetDlgItemText(hWireDialog,IDC_WIRE_SENT,mess);
	
	return dwBytesWritten;
	}

	//For MPM connnection use the following code. 
	else {
		static unsigned long sendNum = 0;
		unsigned int temp;
		if( len == 0 )
		{
			return (0);
		}
		sendNum+=len;
		temp = SendFrameToMPMWire(cBuffer, len);
		return (temp);
	}
}


/* ------------------------------------------------------------------ */
/* -------------------- F L O W   C O N T R O L --------------------- */
/* ------------------------------------------------------------------ */

/* ----------------------------------------------------------- */
/* - Shows that Flow Control (in direction from Port) is set - */
/* - No more Bytes can be stored in ringbuffer				 - */
/* ----------------------------------------------------------- */
void SetWireFlowControl(unsigned int fc, stSerDevStatus ST)
{
	char Buf;

	bFlow_Control=fc;
	if(bFlow_Control==1)
	{
		CheckDlgButton(hWireDialog, IDC_WIRE_FC_FDEV, BST_CHECKED);
		if((ST.DCE_to_DTE==FC_HARD)||(ST.DCE_to_DTE==FC_BOTH))
			// set line to inform the connected device, that no more data can be stored
			SetSignalInWin(RTS,1);
		
		if((ST.DCE_to_DTE==FC_SOFT)||(ST.DCE_to_DTE==FC_BOTH))
		{
			// send xoff char
			Buf=(char)ST.xoffSign;
			WriteSerComWire(&Buf,1);
		}
	}

	if(bFlow_Control==0)
	{
		CheckDlgButton(hWireDialog, IDC_WIRE_FC_FDEV, BST_UNCHECKED);
		if((ST.DCE_to_DTE==FC_HARD)||(ST.DCE_to_DTE==FC_BOTH))
			// reset line -> more data can be stored
			SetSignalInWin(RTS,0);

		if(ST.DCE_to_DTE==FC_SOFT)
		{
			// send xon char
			Buf=(char)ST.xonSign;
			WriteSerComWire(&Buf,1);
		}
	}
}
/* ---------------------------------------------------------------- */
/* - Shows that Flow Control (in direction to Application) is set - */
/* - No more Bytes can be stored by Application					  - */
/* ---------------------------------------------------------------- */
void SetAppFlowControl(unsigned int fc)
{
	if(fc==0)
		CheckDlgButton(hWireDialog, IDC_WIRE_FC_TAPP, BST_UNCHECKED);
	if(fc==1)
		CheckDlgButton(hWireDialog, IDC_WIRE_FC_TAPP, BST_CHECKED);
	if(fc==2)
		CheckDlgButton(hWireDialog, IDC_WIRE_FC_FAPP, BST_CHECKED);
	if(fc==3)
		CheckDlgButton(hWireDialog, IDC_WIRE_FC_FAPP, BST_UNCHECKED);
}


/* ------------------------------------------------------------------ */
/* --------------- T R A C E F I L E   A N D   T I M E -------------- */
/* ------------------------------------------------------------------ */

/* ---------------------------------------------------------- */
/* - Writes actions and Bytes into a trace file				- */
/* ---------------------------------------------------------- */
void WriteWIRETrace(char * cFile, unsigned char *cBuf,unsigned int len,  TYP Typ, int lengthOfText)
{
	static char cFileName[50];
	FILE *fp=NULLP;
	unsigned int i;
	SYSTEMTIME st;

	if(bLogFileYN==FALSE)
		return; 

	/* new trace file */
	if (Typ==CREATE_NEW_TRACE_FILE)
	{
		// Does file already exist?
		if((fp=fopen(cFile,"r"))!=NULL)
		{
			fclose(fp);
			if((i=MessageBox(NULL,"Would you like to replace it?\nYes    -> replace file\nNo     -> append to file\nCancel -> no logfile", "File already existing!", MB_ICONQUESTION|MB_YESNOCANCEL|MB_APPLMODAL))==IDYES)
			{
				fp=fopen(cFile,"w");
				fclose(fp);
				SetMessageWin(TRACEOV,TRUE);
			}
			if(i==IDCANCEL)
			{
				CheckDlgButton(hWireDialog, IDC_WIRE_CHLOG, BST_UNCHECKED);
				bLogFileYN=FALSE;
				SetDlgItemText(hWireDialog,IDC_WIRE_CHLOG,"Logfile");
				return;
			}
			if(i==IDNO)
			{
				fp=fopen(cFile,"a");
				fclose(fp);
				SetMessageWin(TRACEAP,TRUE);
			}
		}
		else
		{
			if((fp=fopen(cFile,"w"))==NULL)
			{
				MessageBox(NULL,"Wrong File Path!", "Error", MB_ICONERROR|MB_OK);
				SetMessageWin(TRACE,FALSE);
			}
			else
			{
				fclose(fp);
				SetMessageWin(TRACE,TRUE);
			}
		
		}

		sprintf(cFileName,"Logfile (%s)",cFile);

		SetDlgItemText(hWireDialog,IDC_WIRE_CHLOG,cFileName);

		strcpy(cFileName,cFile);
		return;
	}

	
	/* Old Trace File */
	if (cFileName==NULLP)/* is there a file name ?*/
		return;
	
	/* open File */
	fp=fopen(cFileName,"a");
	if (fp==NULL)
	{
		MessageBox(NULL,"Can not access file!", "Error", MB_ICONERROR);
		return;
	}

	/* Writing to File */	
	GetSystemTime(&st); /* needed for time stamp */

	if((Typ==WRITE_SENT_BUFFER)||(Typ==WRITE_RECIEVED_BUFFER))
	{

		for(i=0;i<len;i++)
		{
			if(Typ==WRITE_SENT_BUFFER)
				fprintf(fp,"01 %0 2X",(BYTE)cBuf[i]);
			else
				fprintf(fp,"00 %0 2X",(BYTE)cBuf[i]);

			fprintf(fp," (%02d.%02d.%d %02d:%02d:%02d,%03d)\n",st.wDay, st.wMonth, st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
		}
	}
	else
	{
		if(Typ==WRITE_ACT)
			fprintf(fp,"02 %d %s",lengthOfText, cFile);
		if(Typ==WRITE_BUF)
			fprintf(fp,"03 %d %s",lengthOfText, cFile);
		fprintf(fp," (%02d.%02d.%d %02d:%02d:%02d,%03d)\n",st.wDay, st.wMonth, st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
	}
	
	fclose(fp);
}

/* --------------------------------------------------------------- */
/* - Returns actual time in long (minutes, seconds, milliseconds)- */
/* --------------------------------------------------------------- */
long GetActTime(void)
{
	SYSTEMTIME st;
	
	GetSystemTime(&st);
	return ((st.wMinute*60*1000) + (st.wSecond*1000) + st.wMilliseconds);
}

/* --------------------------------------------------------------- */
/* - function shows the actual status of the port lines			 - */
/* --------------------------------------------------------------- */
void detectLines(void)
{
   if(MPMConnectState==0) {  
	DWORD dwCommStat;

	GetCommModemStatus(hCom,&dwCommStat);
	
	// Inform App
	SignalEvent(CTS, dwCommStat & MS_CTS_ON, MS_CTS_ON);
	// starts or stopps Transmit Prozess
	RecFlowC(CTS, dwCommStat & MS_CTS_ON, MS_CTS_ON);
	
	// Inform App
	SignalEvent(DSR,dwCommStat & MS_DSR_ON, MS_DSR_ON);

	// Inform App
	SignalEvent(DCD,dwCommStat & MS_RLSD_ON, MS_RLSD_ON);
    }else{
	DWORD dwSignals; 
	int preRTS=0,preCTS=0,preDTR=0,preDSR=0,preRI=0,preCD=0;
	if( !avsdGetControlSignals(MPMWirePort, &dwSignals)){
		MessageBox(DispGetWinHandle(),"Can't get signals in RecMPMFlowEventFun()!", "Error", MB_ICONERROR);
		return;
	}
	
 	if(dwSignals & AVSD_SIGNAL_RTS)		preRTS = 1;
	if(dwSignals & AVSD_SIGNAL_CTS)		preCTS = 1;
	if(dwSignals & AVSD_SIGNAL_DTR)		preDTR = 1;
	if(dwSignals & AVSD_SIGNAL_DSR)		preDSR = 1;
	if(dwSignals & AVSD_SIGNAL_RI)		preRI   = 1;
	if(dwSignals & AVSD_SIGNAL_CD)		preCD  = 1;

	// Inform App
	SignalEvent(CTS, preCTS, 1);
	// starts or stopps Transmit Prozess
	RecFlowC(CTS, preCTS, 1);
	
	// Inform App
	SignalEvent(DSR,preDSR, 1);

	// Inform App
	SignalEvent(DCD,preCD, 1);	
    }		
}

/* --------------------------------------------------------------- */
/* - function shows fc mode in group box (direction: in coming)	 - */
/* --------------------------------------------------------------- */
void SetDlgTextInFC(FCMODE a)
{
	switch (a)
	{
	case FC_NONE: SetDlgItemText(hWireDialog, IDC_WIRE_IN_CON, "In flow control - FC_NONE"); break;
	case FC_SOFT: SetDlgItemText(hWireDialog, IDC_WIRE_IN_CON, "In flow control - FC_SOFT"); break;
	case FC_HARD: SetDlgItemText(hWireDialog, IDC_WIRE_IN_CON, "In flow control - FC_HARD"); break;
	case FC_BOTH: SetDlgItemText(hWireDialog, IDC_WIRE_IN_CON, "In flow control - FC_BOTH"); break;
	}
	
}
/* --------------------------------------------------------------- */
/* - function shows fc mode in group box (direction: out)		 - */
/* --------------------------------------------------------------- */
void SetDlgTextOutFC(FCMODE a)
{
	switch (a)
	{
	case FC_NONE: SetDlgItemText(hWireDialog, IDC_WIRE_OUT_CON, "Out flow control - FC_NONE"); break;
	case FC_SOFT: SetDlgItemText(hWireDialog, IDC_WIRE_OUT_CON, "Out flow control - FC_SOFT"); break;
	case FC_HARD: SetDlgItemText(hWireDialog, IDC_WIRE_OUT_CON, "Out flow control - FC_HARD"); break;
	case FC_BOTH: SetDlgItemText(hWireDialog, IDC_WIRE_OUT_CON, "Out flow control - FC_BOTH"); break;
	}
}

/* ------------------------------------------------------------------ */
/* - Use Virtual Serial Driver API to get data from Virtual COM port  */
/* - and put it into wire buffer	     							  */	
/* ------------------------------------------------------------------ */
BOOL InitMPMWire()
{

	BOOL bRes;

	if( !avsdIsPortPluggedIn(MPMWirePort, &bRes) )	//Check if the port plugged or not 
	{
		MessageBox(DispGetWinHandle(),"Error in check the virtual port has been pluged!","Error",MB_ICONERROR | MB_OK);
		return FALSE;
	}

	if( bRes == VARIANT_FALSE )							//If not plugged, try to plug it 
	{
		if( !avsdPluginPort(MPMWirePort,FALSE) )	//Plug the port! 
		{
			MessageBox(DispGetWinHandle(),"Error in plugging the virtual port !","Error",MB_ICONERROR | MB_OK);
			return FALSE;
		}

		if( !avsdIsPortPluggedIn(MPMWirePort, &bRes) )	//Check if the port plugged or not 
		{
			MessageBox(DispGetWinHandle(),"Error in check the virtual port has been pluged!!","Error",MB_ICONERROR | MB_OK);
			return FALSE;
		}
		
		if( bRes == VARIANT_FALSE  )
		{
			MessageBox(DispGetWinHandle(),"Can not allocate COM port for MPM connection!","Error",MB_ICONERROR | MB_OK);
			return FALSE;
		}
	}

	if( !avsdIsPortOpened(MPMWirePort, &bRes) )			// Get the port opened/closed state
	{
		MessageBox(DispGetWinHandle(),"Error in check the virtual port's status !","Error",MB_ICONERROR | MB_OK);
		return FALSE;
	}

	if(bRes != VARIANT_FALSE)							// Check if this port has been opened or not
	{
		MessageBox(DispGetWinHandle(),"Wire Port has been opened by other Application!","Error",MB_ICONERROR | MB_OK);
		return FALSE;
	}


//thread for event start
	// Close all events if they were opened
		if(hDataEvent) CloseHandle(hDataEvent);
        if(hFlowEvent) CloseHandle(hFlowEvent);

		// Clear event handles
		hDataEvent = NULL;
		hFlowEvent = NULL;

		// Get the Data event handle
		hDataEvent = avsdGetDataEvent(MPMWirePort);
		bStopDataEventThread = FALSE;
		// Start event monitoring thread
	    hRecMPMDataEventThread =  CreateThread(NULL,0,RecMPMDataEventFun,0,0,&dwRecThreadMPMDataEventId);		//Create thread for reading data from Virtual COM port

     	if ( hRecMPMDataEventThread == NULL )
	    {
     		CloseHandle(hRecMPMDataEventThread);
			MessageBox (DispGetWinHandle(),"Unable to create the thread for data event handle", NULL, MB_ICONERROR);
			return FALSE;
		}

		SetThreadPriority(hRecMPMDataEventThread, THREAD_PRIORITY_NORMAL);

/*
		// Get the Flow event handle
		hFlowEvent = avsdGetFlowEvent(MPMWirePort);
		bStopFlowEventThread = FALSE;
		// Start event monitoring thread
		hRecMPMFlowEventThread =  CreateThread(NULL,0,RecMPMFlowEventFun,0,0,&dwRecThreadMPMFlowEventId);		//Create thread for detect the flow control

		if ( hRecMPMFlowEventThread == NULL )
		{
			CloseHandle(hRecMPMFlowEventThread);
			MessageBox (DispGetWinHandle(),"Unable to create the thread for flow event handle", NULL, MB_ICONERROR);
			return FALSE;
		}	

		SetThreadPriority(hRecMPMFlowEventThread, THREAD_PRIORITY_NORMAL);
*/

//Thread for event end

	bStopThread = FALSE;		
	
	InitIOHandleWire();
	// No flow control
	bFlow_Control=0;
	detectLines();	
	return TRUE;	

}


/* ------------------------------------------------------------------ */
/* - Thread function for detect which kind of event happened in    
/* - Virtual COM port and process it								 */
/* ------------------------------------------------------------------ */
DWORD WINAPI RecMPMFlowEventFun(LPVOID pParam)
{	

	int preRTS=0,preCTS=0,preDTR=0,preDSR=0,preRI=0,preCD=0;
	int afterRTS=0,afterCTS=0,afterDTR=0,afterDSR=0,afterRI=0,afterCD=0;
	DWORD dwSignals;
	char log[100];
	
	while(!bStopFlowEventThread)
	{

		if( !avsdGetControlSignals(MPMWirePort, &dwSignals)){
			MessageBox(DispGetWinHandle(),"Can't get signals in RecMPMFlowEventFun()!", "Error", MB_ICONERROR);
			return(-1);
		}
	
		if(dwSignals & AVSD_SIGNAL_RTS)
			preRTS = 1;
		else 
			preRTS = 0;
		if(dwSignals & AVSD_SIGNAL_CTS)
			preCTS = 1;
		else
			preCTS = 0;
		if(dwSignals & AVSD_SIGNAL_DTR)
			preDTR = 1;
		else
			preDTR = 0;
		if(dwSignals & AVSD_SIGNAL_DSR)
			preDSR = 1;
		else
			preDSR = 0;
		if(dwSignals & AVSD_SIGNAL_RI)
			preRI  = 1;
		else
			preRI  = 0;
		if(dwSignals & AVSD_SIGNAL_CD)
			preCD  = 1;
		else
			preCD  = 0;

		if( WaitForSingleObject(hFlowEvent,INFINITE) == WAIT_OBJECT_0 ){
			if( !avsdGetControlSignals(MPMWirePort, &dwSignals)){
				MessageBox(DispGetWinHandle(),"Can't get signals!", "Error", MB_ICONERROR);
				return(-1);
			}
	
			if(dwSignals & AVSD_SIGNAL_RTS)	
				afterRTS = 1;
			else
				afterRTS = 0;
			if(dwSignals & AVSD_SIGNAL_CTS)	
				afterCTS = 1;
			else
                afterCTS = 0;	
			if(dwSignals & AVSD_SIGNAL_DTR)
				afterDTR = 1;
			else
				afterDTR = 0;
			if(dwSignals & AVSD_SIGNAL_DSR)
				afterDSR = 1;
			else
				afterDSR = 0;
			if(dwSignals & AVSD_SIGNAL_RI)
				afterDSR = 1;
			else
				afterDSR = 0;
			if(dwSignals & AVSD_SIGNAL_CD)
				afterCD  = 1;	
			else
				afterCD  = 0;


			afterCTS = afterRTS ;
			if( afterCTS == 1 ){
				SetVCommState(SET_CTS);
			}else{
				SetVCommState(CLR_CTS);
			}


			if(preCTS != afterCTS){
				SignalEvent(CTS, afterCTS , 1);
				RecFlowC(CTS,afterCTS,1);
			}

			if(preDSR != afterDSR){
				SignalEvent(DSR,afterDSR,1);
			}	
			// Put to log
			sprintf(log,"COM%d: Signals = 0x%08X after",MPMWirePort,dwSignals);
		}//end if(waitForSingle.)
	}//end while();

	return(1);
}

/* ------------------------------------------------------------------ */
/* - Thread function for reading data from Virtual Serial Port        */
/* - and put it into wire buffer	     							  */	
/* ------------------------------------------------------------------ */
DWORD WINAPI RecMPMDataEventFun(LPVOID pParam)
{	

   BYTE recBuf[65536];   //used to store data which receive from com port in one time
   unsigned long i = 0;
   unsigned long countNum  = 0;

   Sleep(2000);         // waiting the initialization of COM port 
	
   while(!bStopDataEventThread)
   {
      if( WaitForSingleObject(hDataEvent,INFINITE) == WAIT_OBJECT_0 ){
         countNum = 0;
         memset(recBuf,0,65536);
         if( !avsdReadFromPortBuffer( MPMWirePort,recBuf,65536,&countNum) ){
            if( GetLastError() == ERROR_NO_MORE_ITEMS ){
               break;
            }else{
               char errorInfo[100] = "Can not read data from buffer !";
               sprintf(errorInfo,"Can not read data from buffer! %d",GetLastError());
               MessageBox(DispGetWinHandle(),errorInfo,"Error",MB_ICONERROR | MB_OK);
               return(-1);
            }		
         }
         if (countNum == 0) 
            break;
         for(i=0;i< countNum;i++ ){
            WIRESerComRead( recBuf[i] ) ;
         }
		
       }//end if
    }//end while()
    return(1);
}


/* ------------------------------------------------------------------ */
/* - Use Virtual Serial Driver API to write data to Virtual COM port  */
/*																	  */	
/* ------------------------------------------------------------------ */

unsigned int SendFrameToMPMWire(char *pSend, int Length)
{

	//Write to Virtual COM port
	unsigned long sendNum;

	if( !avsdWriteToPortBuffer( MPMWirePort , (unsigned char *)pSend , Length , &sendNum) )
	{
		MessageBox(DispGetWinHandle(),"send() in MPM virutal com port error!","Error",MB_ICONERROR | MB_OK);
		return(0);
	}

	if( sendNum!=Length ){
		MessageBox(DispGetWinHandle(),"send not finished!!","Error",MB_ICONERROR | MB_OK);
		return(0);
	}
		
	return (sendNum);
}

/* ------------------------------------------------------------------  */
/* - Stop the connection between MPM and emulator,just stop the reading */
/* - thread															   */	
/* ------------------------------------------------------------------   */
void CloseMPMWire()
{
		bStopThread = TRUE;				  // set stop-connected flag to TRUE

		bStopDataEventThread = TRUE;
		CloseHandle(hDataEvent);
		CloseHandle(hRecMPMDataEventThread);

		bStopFlowEventThread = TRUE;
		CloseHandle(hFlowEvent);
		CloseHandle(hRecMPMFlowEventThread);

		//while( dwRecThreadMPMWireId!=0 ); // block until thread has been halted
		
		MPMConnectState = 0 ;             // change the status of MPM connection;
}

/* ------------------------------------------------------------------  */
/* - Set Virtual Com port's status, 								 */	
/* - Used to replace the function EscapeCommFunction(hCom,SETDTR)       */
/* ------------------------------------------------------------------   */
void SetVCommState(int signal)
{
/*
	DWORD dwSignals;

	if( !avsdGetControlSignals(MPMWirePort, &dwSignals))
	{
		MessageBox(DispGetWinHandle(),"Can't get signals in SetVCommState()!", "Error", MB_ICONERROR);
		return;
	}
	
	switch(signal) {
		case SETRTS:
			dwSignals = dwSignals|AVSD_SIGNAL_RTS;
			avsdSetControlSignals(MPMWirePort,dwSignals);
			break;
		case CLRRTS:
			dwSignals = dwSignals&AVSD_SIGNAL_NO_RTS;
			avsdSetControlSignals(MPMWirePort,dwSignals);
			break;
		case SETDTR:
			dwSignals = dwSignals|AVSD_SIGNAL_DTR;
			avsdSetControlSignals(MPMWirePort,dwSignals);
			break;
		case CLRDTR:
			dwSignals = dwSignals&AVSD_SIGNAL_NO_DTR;
			avsdSetControlSignals(MPMWirePort,dwSignals);
			break;
		case SET_CTS:
			dwSignals = dwSignals|AVSD_SIGNAL_CTS;
			avsdSetControlSignals(MPMWirePort,dwSignals);
			break;
		case CLR_CTS:
			dwSignals = dwSignals&AVSD_SIGNAL_NO_CTS;
			avsdSetControlSignals(MPMWirePort,dwSignals);
			break;
		default:
			break;
	}
*/
}

/* ------------------------------------------------------------------  */
/* - Function for create log file                                           */
/* ------------------------------------------------------------------   */
void CreateMPMLogfile(void)
{
	 FILE *fp = NULLP;
	 fp=fopen( recvMPMLogFile,"w");
     if (fp==NULL)
     {
		MessageBox(DispGetWinHandle(),"Can not access file!", "Error", MB_ICONERROR);
		return;
     }
	 fclose(fp);

	 fp=fopen( sendMPMLogFile,"w");
     if (fp==NULL)
     {
		MessageBox(DispGetWinHandle(),"Can not access file!", "Error", MB_ICONERROR);
		return;
     }
	 fclose(fp);
}

/* ------------------------------------------------------------------  */
/* - Fcuntion for write log info to file							 */	
/* ------------------------------------------------------------------   */
void WriteMPMTrace(char *cFile, unsigned char *Msg, unsigned int len, unsigned int iType)
{
    FILE *fp = NULLP;
	unsigned int i;

    fp=fopen(cFile,"a");
    if (fp==NULL)
    {
		MessageBox(DispGetWinHandle(),"Can not access file!", "Error", MB_ICONERROR);
		return;
    }

    // Writing to File
	if(iType == 1)
	   fprintf(fp,"%d Bytes Sent \t",len );
	else
	   fprintf(fp,"%d Bytes Recieved \t",len );

	for(i=0;i<len;i++)
	{
		fprintf(fp,"%0 2X  ",(BYTE)Msg[i]);
		//fprintf(fp,"%c",Msg[i]);
	}

	fprintf(fp,"\n" );
	
	fclose(fp);
}
