www.pudn.com > TsapiCallRouting.rar > Opentsrv.cpp


// opentsrv.cpp : implementation file 
// 
// This file handles the Open Tserver dialog 
// 
 
#include "stdafx.h" 
#include "resource.h" // replace with theApp header if needed 
#include "opentsrv.h" 
#include "utilities.h" 
#include "global.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char BASED_CODE THIS_FILE[] = __FILE__; 
#endif 
char requestVersion[] = "7";	 
///////////////////////////////////////////////////////////////////////////// 
// COpenTsrv dialog 
 
 
COpenTsrv::COpenTsrv(CWnd* pParent /*=NULL*/) 
	: CDialog(COpenTsrv::IDD, pParent) 
{ 
	//{{AFX_DATA_INIT(COpenTsrv) 
	m_Login = _T(""); 
	m_Password = _T(""); 
	m_Tserver = _T(""); 
	//}}AFX_DATA_INIT 
} 
 
// For non-MFC folks, this is a helper routine for passing data back-and-forth 
//  from this class to the Open Tserver dialog. 
void COpenTsrv::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(COpenTsrv) 
	DDX_Control(pDX, IDC_TSERVERLIST, m_TserverListControl); 
	DDX_Control(pDX, IDOK, m_OKControl); 
	DDX_Text(pDX, IDC_LOGIN, m_Login); 
	DDV_MaxChars(pDX, m_Login, 48); 
	DDX_Text(pDX, IDC_PASSWORD, m_Password); 
	DDV_MaxChars(pDX, m_Password, 48); 
	DDX_CBString(pDX, IDC_TSERVERLIST, m_Tserver); 
	//}}AFX_DATA_MAP 
} 
 
// For non-MFC folks, this map replaces the large "switch" statement found in 
//  straight C Windows programs. The ON_MESSAGE() lines were added manually. 
//  Read them as "when a message of type {first argument} is received, call 
//   the method {second argument}" 
BEGIN_MESSAGE_MAP(COpenTsrv, CDialog) 
	ON_MESSAGE(WM_TSAPIACSCONFIRMATION, OnTsapiAcsConfirmation) 
	//{{AFX_MSG_MAP(COpenTsrv) 
	ON_CBN_SELCHANGE(IDC_TSERVERLIST, OnSelchangeTserverlist) 
	ON_EN_CHANGE(IDC_LOGIN, OnChangeLogin) 
//	ON_EN_CHANGE(IDC_DEVICEID, OnChangeDeviceid) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
 
///////////////////////////////////////////////////////////////////////////// 
// COpenTsrv message handlers 
 
extern "C" 
{ 
 
// this callback function is used by the csta dll (via acsEnumServerNames) 
// lParam contains a pointer to the combo box on the Open Tserver dialog 
// name contains 1 registered Tserver service - put it into the combo box. 
Boolean AddToList(char* name, unsigned long lParam) 
{ 
	CComboBox* lBox = (CComboBox*)lParam; 
	return(lBox->AddString(name) >= 0);     
} 
 
} 
 
// dialog initialization 
BOOL COpenTsrv::OnInitDialog()  
{ 
	CDialog::OnInitDialog(); 
	 
	CenterWindow(); 
 
	// want CSTA-type services 
	// AddToList() is the callback function 
	// pass the address of the combo box to be returned in the AddToList() callback	 
	acsEnumServerNames(ST_CSTA, AddToList, (unsigned long)(CComboBox*)&m_TserverListControl); 
 
	UpdateData(FALSE); 
 
	// must have a Tserver, login and device (password may also be needed, depending on 
	//  the Tserver selected) 
 
	return TRUE;  // return TRUE unless you set the focus to a control 
} 
 
// for every change to the Login ID field, this method is called 
void COpenTsrv::OnChangeLogin()  
{ 
	UpdateData(TRUE); 
	 
	// must have a Tserver, login and device (password may also be needed, depending on 
	//  the Tserver selected) 
	m_OKControl.EnableWindow(!m_Tserver.IsEmpty() && !m_Login.IsEmpty());	 
} 
 
// as each Tserver in the Tserver combo box is selected, this method is called 
void COpenTsrv::OnSelchangeTserverlist()  
{ 
	UpdateData(TRUE); // get server name out of the combo box control 
 
	// get authorization information for the selected Tserver 
	ACSAuthInfo_t authInfo;	 
	if(acsQueryAuthInfo((ServerID_t*)(LPCTSTR)m_Tserver,  &authInfo) == ACSPOSITIVE_ACK) 
	{  
		switch(authInfo.authType) 
		{ 
		 case AUTH_LOGIN_ID_ONLY: 
		 case AUTH_LOGIN_ID_IS_DEFAULT: 
		 case ANY_LOGIN_ID:  
	 		// no login or password needed  
	 		m_Login = authInfo.authLoginID; 
			UpdateData(FALSE); 
	 		break;  
		 default: // login (and maybe password) are needed 
	 		break; 
		} 
	} 
 
	// must have a Tserver, login and device (password may also be needed, depending on 
	//  the Tserver selected) 
	m_OKControl.EnableWindow(!m_Tserver.IsEmpty() && !m_Login.IsEmpty());	 
} 
 
// for every change to the Device ID field, this method is called 
void COpenTsrv::OnChangeDeviceid()  
{ 
	UpdateData(TRUE); 
	 
	// must have a Tserver, login and device (password may also be needed, depending on 
	//  the Tserver selected) 
	m_OKControl.EnableWindow(!m_Tserver.IsEmpty() && !m_Login.IsEmpty());	 
} 
 
// If the OK button is pressed, this method is called 
void COpenTsrv::OnOK()  
{ 
	if(!UpdateData(TRUE)) 
	{ 
		AfxMessageBox("Returning from here"); 
		return; 
	} 
 
	// attempt to open a stream to the selected Tserver 
	ServerID_t advertisingName;      
	ATTPrivateData_t             privateData; 
	lstrcpy(advertisingName, m_Tserver); 
	LoginID_t loginID; 
	lstrcpy(loginID, m_Login); 
	Passwd_t passwd; 
	lstrcpy(passwd, m_Password); 
	AppName_t appname; 
	lstrcpy(appname, "TSAPI Sample"); 
	Version_t version; 
	lstrcpy(version, "TS1-2"); 
	PrivateDataNegotiated = false; 
	// before opening the stream, create the hidden window which will process all 
	//  of the TSAPI events. 
	m_TsapiWndPtr = new CTsapiWnd; 
	m_TsapiWndPtr->m_TsapiController = m_TsapiController; 
	m_TsapiWndPtr->DoCreate(); 
	// The application will generate the invoke IDs. 
	// Use a pointer to the window here (and for all ACS requests) for the invoke ID - 
	//  this specifies which window applies to this request. The TSAPI window looks at 
	//  the invoke ID of all ACS events and assumes they are window pointers. The event is 
	//  then forwarded to that window. 
	 
	 
	// We want private data version 6 so we will use attMakeVersionString() 
	// to make the private data buffer. 
	// this buffer will hold the formated private data message 
    (void)strcpy(privateData.vendor, "VERSION");// required for private data version negotiation 
    privateData.data[0] = PRIVATE_DATA_ENCODING;// required for private data version negotiation 
	// use attMakeVersionString() to format the private data buffer to request Avaya's private data with requestVersion 
    if (attMakeVersionString(requestVersion, &privateData.data[1]) > 0) { 
            privateData.length = strlen(&privateData.data[1]) + 2; 
    } 
    else { 
            privateData.length = 0; 
    } 
	 
 
	RetCode_t rc = acsOpenStream(&m_TsapiWndPtr->m_AcsHandle, APP_GEN_ID, 
						(InvokeID_t)this, ST_CSTA, &advertisingName, &loginID, &passwd, &appname, 
						ACS_LEVEL1, &version, 10, 5, 50, 5, (PrivateData_t *)&privateData); 
	if(rc < 0) 
	{ 
		// failure for some reason, specified in rc as a RetCode_t (defined in acs.h). 
		delete m_TsapiWndPtr; 
		m_TsapiWndPtr = 0; 
		AfxMessageBox("open stream failed"); 
		return;  
	} 
	 
	// no conf events are being processed yet, so don't wait for it yet... 
	 
	// set up event notification on this acs stream 
	// all TSAPI events will be sent to the TSAPI window (m_TsapiWndPtr) via the 
	//  WM_TSAPIMSG message. 
	// The last parameter set to FALSE indicates that the application will handle draining 
	//  the TSAPI event queue from the CSTA dll. TRUE would indicate the dll should send a 
	//  WM_TSAPIMSG per TSAPI event. With FALSE, the dll sends a WM_TSAPIMSG only when the 
	//  TSAPI event queue goes from empty to non-empty. This allows the application to drain 
	//  the TSAPI event queue at its own pace, without overflowing the Windows message queue. 
	rc = acsEventNotify(m_TsapiWndPtr->m_AcsHandle, m_TsapiWndPtr->GetSafeHwnd(), WM_TSAPIMSG, FALSE); 
	if(rc < 0) 
	{ 
		// failure for some reason, specified in rc as a RetCode_t (defined in acs.h). 
		acsAbortStream(m_TsapiWndPtr->m_AcsHandle, NULL); 
		delete m_TsapiWndPtr; 
		m_TsapiWndPtr = 0; 
		AfxMessageBox("event notify failed"); 
		return;  
	} 
	 
	// once the event notify is processed, conf events will come back from the 
	//  TSAPI DLL                            
} 
 
// This method is called when an ACS Confirmation Event is received that is forwarded to 
//  this dialog. 
LRESULT COpenTsrv::OnTsapiAcsConfirmation(WPARAM wParam, LPARAM lParam) 
{ 
	static char func[]="COpenTsrv::OnTsapiAcsConfirmation"; 
	// this dialog should either get an open stream conf event or 
	//  a universal failure event 
	switch(m_TsapiWndPtr->m_EventBufPtr->eventHeader.eventType) 
	{ 
	 case ACS_OPEN_STREAM_CONF: 
		 { 
						 
			 CString csAUF = ""+m_TsapiWndPtr->m_EventBufPtr->event.acsConfirmation.invokeID; 
			 
			 CString debugStr; 
			 
						  
			 debugStr.Format( "ACS_OPEN_STREAM_CONF(acsHandle=%d)", m_TsapiWndPtr->m_AcsHandle); 
			 
			  DBG2_OUT( func, "%s %s", csAUF.GetString(), debugStr.GetString() ); 
			   
			 if ( m_TsapiWndPtr->m_AttPrivateData.length == 0 ) 
			 { 
				 acsAbortStream(m_TsapiWndPtr->m_AcsHandle, NULL); 
				 return 0; 
			 } 
 
			   
	        if ( strcmp( m_TsapiWndPtr->m_AttPrivateData.vendor, ECS_VENDOR_STRING ) )  
			{ 
				acsAbortStream(m_TsapiWndPtr->m_AcsHandle, NULL); 
				return 0; 
			} 
 
	        if ( m_TsapiWndPtr->m_AttPrivateData.data[0] != PRIVATE_DATA_ENCODING || 
		        strcmp( &m_TsapiWndPtr->m_AttPrivateData.data[1], requestVersion ) != 0 ) 
			{ 
				acsAbortStream(m_TsapiWndPtr->m_AcsHandle, NULL); 
				return 0; 
			} 
			 
			// we have successfully negotiated the private data version 
			PrivateDataNegotiated = true; 
			EndDialog(IDOK); 
			// this is what we want... 
		 } 
		break; 
	 case ACS_UNIVERSAL_FAILURE_CONF: 
		 {	// failure for some reason. This could be invalid login/password, no permissions, 
		//  or several other failure codes (listed in acsdefs.h). 
		CString *csAUF = makeACSUFStr( m_TsapiWndPtr->m_EventBufPtr->event.acsUnsolicited.u.failureEvent.error ); 
		CString debugStr; 
		debugStr.Format( "ACS_UNIVERSAL_FAILURE_CONF(acsHandle=%d)", m_TsapiWndPtr->m_AcsHandle); 
		DBG1_OUT( func, "%s %s", csAUF->GetString(), debugStr.GetString() ); 
			 
		acsAbortStream(m_TsapiWndPtr->m_AcsHandle, NULL); 
		delete m_TsapiWndPtr; 
		m_TsapiWndPtr = 0; 
		AfxMessageBox("open stream failed"); 
		return 0;  
		 } 
	 default: 
		 { 
			CString debugStr; 
			CString *csAUF = makeACSUFStr( m_TsapiWndPtr->m_EventBufPtr->event.acsUnsolicited.u.failureEvent.error ); 
			debugStr.Format( "ACS_UNIVERSAL_FAILURE_CONF(acsHandle=%d)", m_TsapiWndPtr->m_AcsHandle); 
			DBG1_OUT( func, "%s %s", csAUF->GetString(), debugStr.GetString() ); 
	 
			acsAbortStream(m_TsapiWndPtr->m_AcsHandle, NULL); 
			delete m_TsapiWndPtr; 
			m_TsapiWndPtr = 0; 
			AfxMessageBox("unexpected response to acsOpenStream"); 
			return 0; 
		 } 
	} 
 
 	return 0; 
}