📄 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -