⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 directorynumber.cpp

📁 利用AVAYA AES的TASPI开发的一套软电话系统,仅供参考,ACTIVEX形式的.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// DirectoryNumber.cpp : Implementation of CDirectoryNumber
#include "stdafx.h"
#include "LucentCti.h"
#include "MichelleCTI.h"
#include "DirectoryNumber.h"

/////////////////////////////////////////////////////////////////////////////
// CDirectoryNumber

extern BOOL B2C(BSTR bStr,char* pBuf,int nBufLen);
extern BSTR C2B(const char *c);
extern void WriteLog(char* pData);

#define PROCESS (strcmp((char*)&m_deviceId,m_thisDevice.deviceID)==0)

BOOL CALLBACK DialingDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if(uMsg==WM_COMMAND) {
		if(LOWORD(wParam)==IDCANCEL) {
			while(!::PostMessage(NULL, UM_CANCELDIAL, (WPARAM)0, (LPARAM)0))
				Sleep(100);
		}
		return(TRUE);
	}
	return(FALSE);
}

STDMETHODIMP_(BOOL) CDirectoryNumber::MakeCall(BSTR dn, LPKVLIST data)
{
	// TODO: Add your implementation code here
	
	BOOL bRet=FALSE;
	DeviceID_t callId;
	WriteLog("Make call service.");
	if (B2C(dn,(char*)&callId,sizeof(DeviceID_t)))
	{
		RetCode_t ret=-1;

		BOOL bSave=m_bIsCmdMsg;
		m_bIsCmdMsg=TRUE;
		if (data )
		{
			ATTPrivateData_t privateData;
			memset(&privateData,0,sizeof(ATTPrivateData_t));
			ATTUserToUserInfo_t attData;
			memset(&attData,0,sizeof(ATTUserToUserInfo_t ));
			attData.type=UUI_IA5_ASCII;
			
			if (KVListToAppString(data,(char*)attData.data.value,sizeof(attData.data.value)-1))
			{
				attData.data.length=strlen((char*)attData.data.value);
				ret=attV6MakeCall(&privateData,NULL,FALSE,&attData);
				if (ret==0)
					ret=cstaMakeCall(m_serverHandle,m_invokeId,&m_deviceId,&callId,(PrivateData_t*)&privateData);
			}
		}
		if (ret!=0)
			ret=cstaMakeCall(m_serverHandle,m_invokeId,&m_deviceId,&callId,NULL);
		m_lErrCode=ERR_INI;
		m_ErrMsg="";
		if (ACSPOSITIVE_ACK==ret)
		{
			MSG msg;
			BOOL bQuit=FALSE;//Quit the getmessage loop?
			while (GetMessage(&msg,NULL,0,0))
			{
				if (msg.message==UM_CMDMSG)
				{
					switch(msg.wParam)
					{
					case UM_APIFAILED:
						if (m_lErrCode==0||msg.wParam==CSTA_CONNECTION_CLEARED)
						{
							m_lErrCode=LUCENT_MAKECALL_ERR;
							m_ErrMsg="Make call failed.";
						}
						bQuit=TRUE;
						ReleaseCall(NULL);
						break;
					case CSTA_ORIGINATED:	// null/initiated -> connected (LOCAL only)
						bRet=OnCallDial();
						bQuit=TRUE;
					}
				}
				if (bQuit) break;
			}
		}else
		{
			m_lErrCode=ret;
			m_ErrMsg="Make call return an error.";
		}
		m_bIsCmdMsg=bSave;
	}else
	{
		m_lErrCode=LUCENT_INVALID_PARAM;
		m_ErrMsg="Invalid parameter.";
	}

	if (!bRet)
	{
		char tep[300]={0};
		wsprintf((char*)&tep,"error:%s,code:%d",m_ErrMsg.c_str(),m_lErrCode);
		WriteLog((char*)&tep);
	}
	return bRet;
}

STDMETHODIMP_(BOOL) CDirectoryNumber::AnswerCall(BSTR connid)
{
	// TODO: Add your implementation code here
	BOOL ret=FALSE;
	WriteLog("Answer cal service.");
	if (!m_bConnect)
	{
		BOOL bSave=m_bIsCmdMsg;
		m_bIsCmdMsg=TRUE;
		RetCode_t retCode=cstaAnswerCall(m_serverHandle,m_invokeId,
											&m_activeConnId,NULL);
		m_lErrCode=ERR_INI;
		m_ErrMsg="";
		if (retCode==ACSPOSITIVE_ACK)
		{
			MSG msg;
			while (GetMessage(&msg,NULL,0,0))
			{
				if (msg.message==UM_CMDMSG)
				{
					if (msg.wParam==UM_APIFAILED||msg.wParam==CSTA_CONNECTION_CLEARED)
					{
						if (m_lErrCode==ERR_INI)
						{
							m_lErrCode=LUCENT_ANSWERCALL_ERR;
							m_ErrMsg="Answercall failed.";
						}
						break;
					}
					else if (msg.wParam==CSTA_ESTABLISHED)
					{
						ret=TRUE;
						break;
					}
				}
			}
		}else
		{
			m_lErrCode=ret;
			m_ErrMsg="AnswerCall retun an error";
		}
		m_bIsCmdMsg=bSave;
	}else
		ret=TRUE;
	if (!ret)
	{
		char tep[300]={0};
		wsprintf((char*)&tep,"error:%s,code:%d",m_ErrMsg.c_str(),m_lErrCode);
		WriteLog((char*)&tep);
	}
	return ret;
}

BOOL CDirectoryNumber::Initialize(BSTR deviceId,ACSHandle_t serverHandle,InvokeID_t invokeId)
{
	BOOL ret=FALSE;
	DeviceID_t device;
	WriteLog("Monitor device service.");
	if (B2C(deviceId,device,sizeof(DeviceID_t)))
	{
		strcpy(m_deviceId,device);
		// now, attempt to put a device monitor on the specified device. No filtering is requested,
		//  but the PBX may place filtering on the monitor. You will be notified of the filtering
		//  placed on the monitor in the monitor confirmation event.
		CSTAMonitorFilter_t noFilter;
		noFilter.call = 0;
		noFilter.feature = 0;
		noFilter.agent = 0;
		noFilter.maintenance = 0;
		noFilter.privateFilter = 0;
		// create a device record in the TSAPI window for this device. This device record will be
		//  used to track all calls for this device and is also used to determine which window should
		//  handle the TSAPI events that are received for each device.

		//begin a inner message loop(not fire out)
		BOOL bSave=m_bIsCmdMsg;
		m_bIsCmdMsg=TRUE;
		RetCode_t rc = cstaMonitorDevice(serverHandle,
						invokeId, &device, &noFilter, NULL);
		if (rc>=0)
		{
			MSG msg;
			BOOL bQuit=FALSE;
			while (GetMessage(&msg,NULL,0,0))
			{
				if (msg.message==UM_CMDMSG)
				{
					switch (msg.wParam)
					{
					case CSTA_MONITOR_CONF:
						bQuit=TRUE;
						ret=TRUE;
						break;
					case UM_APIFAILED:
						bQuit=TRUE;
						break;
					}
				}
				if (bQuit)
					break;
			}
			if (ret)
			{
				m_invokeId=invokeId;
				m_serverHandle=serverHandle;

			}
		}else
		{
			m_lErrCode=rc;
			m_ErrMsg="cstaMonitorDevice return an error.";
		}
		m_bIsCmdMsg=bSave;
	}else
	{
		m_lErrCode=LUCENT_INVALID_PARAM;
		m_ErrMsg="Invalid parameter.";
	}
	if (!ret)
	{
		char tep[300]={0};
		wsprintf((char*)&tep,"error:%s,code:%d",m_ErrMsg.c_str(),m_lErrCode);
		WriteLog((char*)&tep);
	}
	return ret;
}

void CDirectoryNumber::Uninitialize()
{
	if (m_monitorId) 
	{
		StopMonitor(m_monitorId);
		m_invokeId=0;
	}
	if (m_splitMonitorId)
	{
		StopMonitor(m_splitMonitorId);
		m_splitMonitorId=0;
	}
	return ;
}

BOOL CDirectoryNumber::DefaultHandler(dnevent* pEvent)
{

	BOOL notFire=FALSE;
	if (pEvent)
	{
		CSTAEvent_t* cstaEvent=pEvent->m_cstaEvent;
		if (cstaEvent)
		{
			switch(cstaEvent->eventHeader.eventClass)
			{
			case ACSCONFIRMATION:
				if (cstaEvent->eventHeader.eventType==ACS_UNIVERSAL_FAILURE_CONF)
				{
					m_lErrCode=cstaEvent->event.cstaConfirmation.u.universalFailure.error;
					m_ErrMsg="Monitor device failed.";
					DNPostMessage(UM_CMDMSG,UM_APIFAILED,0);
					char pTemp[100]={0};
					wsprintf(pTemp,"ACSCONFIRMATION error code:%d(dn)",m_lErrCode);
					WriteLog(pTemp);
				}
				//This message will never be sent out
				notFire=TRUE;
				break;
			case ACSUNSOLICITED:
				m_lErrCode=cstaEvent->event.acsUnsolicited.u.failureEvent.error;
				m_ErrMsg="acs unsolicited failed.";
				DNPostMessage(UM_CMDMSG,UM_APIFAILED,0);
				{
					char pTemp[100]={0};
					wsprintf(pTemp,"ACSUNSOLICITED error code:%d(dn)",m_lErrCode);
					WriteLog(pTemp);
				}
				//This message will never be sent out
				notFire=TRUE;
				break;
			case CSTACONFIRMATION:
				//This message will never be sent out
				notFire=TRUE;
				switch(cstaEvent->eventHeader.eventType)
				{
				case CSTA_UNIVERSAL_FAILURE_CONF:
					 m_lErrCode=cstaEvent->event.cstaConfirmation.u.universalFailure.error;
					 m_ErrMsg="CSTA_UNIVERSAL_FAILURE_CONF ";
					 DNPostMessage(UM_CMDMSG,UM_APIFAILED,0);
					 {
						char pTemp[100]={0};
						wsprintf(pTemp,"CSTACONFIRMATION error code:%d(dn)",m_lErrCode);
						WriteLog(pTemp);
					 }
					 break;
				 case CSTA_MONITOR_CONF:
					 // The monitor device confirmation, get the monitor cross ref id
					 if (m_monitorId)
					 {// this is the split monitor id
						 m_splitMonitorId=cstaEvent->event.cstaConfirmation.u.monitorStart.monitorCrossRefID;
					 }else
					 {//This is the dn monitor id
						 m_monitorId=cstaEvent->event.cstaConfirmation.u.monitorStart.monitorCrossRefID;
						 //initialize the connecton id
						 memset(&m_activeConnId,0,sizeof(ConnectionID_t));
						 strcpy((char*)&m_activeConnId.deviceID,(char*)&m_deviceId);
						 memset(&m_holdConnId,0,sizeof(ConnectionID_t));
						 strcpy((char*)&m_holdConnId.deviceID,(char*)&m_deviceId);
					 }
					 while (!PostMessage(NULL,UM_CMDMSG,cstaEvent->eventHeader.eventType,0))
						 Sleep(100);
					 break;
				 case CSTA_QUERY_AGENT_STATE_CONF:
					 switch (cstaEvent->event.cstaConfirmation.u.queryAgentState.agentState)
					 {
					 case AG_NULL:
						 m_agentStat=AS_Logout;
						 m_bLogged=FALSE;
						 break;
					 case AG_NOT_READY:
						 m_agentStat=AS_NotReady;
						 m_bLogged=TRUE;
						 break;
					 case AG_WORK_NOT_READY:
						 m_bLogged=TRUE;
						 m_agentStat=AS_AfterCallWork;
						 break;
					 case AG_READY:
						 m_agentStat=AS_Ready;
						 m_bLogged=TRUE;
						 break;
					 }
					 DNPostMessage(UM_CMDMSG,cstaEvent->eventHeader.eventType,0);
					 break;
				 case CSTA_MAKE_CALL_CONF:
				 case CSTA_CLEAR_CONNECTION_CONF:
				 case CSTA_ANSWER_CALL_CONF:
				 case CSTA_HOLD_CALL_CONF:
				 case CSTA_RETRIEVE_CALL_CONF:
				 case CSTA_CONFERENCE_CALL_CONF:
				 case CSTA_TRANSFER_CALL_CONF: 
				 case CSTA_CLEAR_CALL:
				 case CSTA_CONSULTATION_CALL_CONF:
				 default://Post error message
					 DNPostMessage(UM_CMDMSG,cstaEvent->eventHeader.eventType,0);
					 break;
				}
				//This kind of message should not be fired
				notFire=TRUE;
				break;
			case CSTAUNSOLICITED:
				//This message may be sent out
				notFire=FALSE;
				switch(cstaEvent->eventHeader.eventType)
				{
					case CSTA_FAILED:
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.failed);
//						if (PROCESS)
//						{
							//After connect to a call, connect to destinated dn failed
							//It must not be a message from invoked csta api
							m_lErrCode=cstaEvent->event.cstaUnsolicited.u.failed.cause;
							m_ErrMsg="CSTAEventCause_t error";
							while (!PostMessage(NULL,UM_CMDMSG,UM_APIFAILED,0))
								Sleep(100);
							{
								char pTemp[100]={0};
								wsprintf(pTemp,"CSTAUNSOLICITED CSTA_FAILED error code:%d(dn)",m_lErrCode);
								WriteLog(pTemp);
							 }
//						}
						notFire=TRUE;
						break;
					case CSTA_MONITOR_ENDED:
						//It must not be a message from invoked csta api
						while (!PostMessage(NULL,UM_CMDMSG,UM_APIFAILED,0))
							Sleep(100);
						notFire=TRUE;
						break;
					case CSTA_SERVICE_INITIATED: // null -> initiated (LOCAL only)
						//get the new connection id

						//Because never receive other device's this event, it's not 
						//neccessary to get call info
						m_activeConnId.callID=cstaEvent->event.cstaUnsolicited.u.serviceInitiated.initiatedConnection.callID;
						break;
					case CSTA_ORIGINATED: // null/initiated -> connected (LOCAL only)
						//get the new connection id
						//Because never receive other device's this event, it's not 
						//neccessary to get call info
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.originated );

						if (PROCESS)
						{
							m_activeConnId.callID=cstaEvent->event.cstaUnsolicited.u.originated.originatedConnection.callID;
							if (!m_bIsCmdMsg)
							{// 
								ReplyMessage(0l);
								m_bIsCmdMsg=TRUE;
								OnCallDial();
								m_bIsCmdMsg=FALSE;
							}
						}
						break;
					case CSTA_DELIVERED: // null -> alerting
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.delivered);
						if (PROCESS)
						{
							//get the new connection id
							m_activeConnId.callID=cstaEvent->event.cstaUnsolicited.u.delivered.connection.callID;
							
							// if this event will be fired out, fill it out
							if (!notFire)
								FillEvent(pEvent);
						}
						break;
					case CSTA_NETWORK_REACHED: // null -> connected (REMOTE only)
						break;
					case CSTA_ESTABLISHED:	// alerting/connected -> connected
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.established);
						if (PROCESS)
						{
							//get the new connection id
							m_bConnect=TRUE;
							m_activeConnId.callID=cstaEvent->event.cstaUnsolicited.u.established.establishedConnection.callID;
							
							// if this event will be fired out, fill it out
							if (!notFire)
								FillEvent(pEvent);
						}
						break;
					case CSTA_DIVERTED: // alerting -> null
						break;
					case CSTA_HELD: // connected -> held
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.held );
						if (PROCESS)
						{
							m_holdConnId.callID=m_activeConnId.callID;
							m_activeConnId.callID=0;
							
							// if this event will be fired out, fill it out
							if (!notFire)
								FillEvent(pEvent);
						}
						break;
					case CSTA_RETRIEVED: // held -> connected
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.retrieved);

						if (PROCESS)
						{
							m_activeConnId.callID=m_holdConnId.callID;
							m_holdConnId.callID=0;
							m_bConnect=TRUE;
							// if this event will be fired out, fill it out
							if (!notFire)
								FillEvent(pEvent);
						}
						break;
					case CSTA_CONFERENCED: // held & connected -> connected (3 different connections)
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.conferenced);

//						if (PROCESS)
//						{
						m_holdConnId.callID=0;
						if (cstaEvent->event.cstaUnsolicited.u.conferenced.conferenceConnections.count>0)
							m_activeConnId.callID=cstaEvent->event.cstaUnsolicited.u.conferenced.conferenceConnections.connection[0].party.callID;
						else 
							m_activeConnId.callID=0;
						m_bConnect=TRUE;
//						}
						break;
					case CSTA_TRANSFERRED: // held & connected -> connected or null (3 different connections)
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.transferred);

						if (PROCESS)
						{//This connection is cleared
							m_bConnect=FALSE;
							m_holdConnId.callID=0;
							m_activeConnId.callID=0;
						}else
						{//a new connection is built
							m_holdConnId.callID=0;
							if (cstaEvent->event.cstaUnsolicited.u.transferred.transferredConnections.count>0)
							m_activeConnId.callID=cstaEvent->event.cstaUnsolicited.u.transferred.transferredConnections.connection[0].party.callID;
						}
						break;
					case CSTA_CALL_CLEARED: // * -> null (for all connections in call)
						//clear the active connection id
						//this message will never be recieved

						m_bConnect=FALSE;
						m_holdConnId.callID=0;
						m_activeConnId.callID=0;
						// if this event will be fired out, fill it out
						if (!notFire)
							FillEvent(pEvent);
						break;
					case CSTA_CONNECTION_CLEARED: // * -> null
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.connectionCleared);

						if (PROCESS)
						{
							m_activeConnId.callID=0;
							m_bConnect=FALSE;
							// if this event will be fired out, fill it out
							if (!notFire)
								FillEvent(pEvent);
						}
						break;
					case CSTA_LOGGED_ON:
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.loggedOn);
						if (PROCESS)
							m_bLogged=TRUE;
						break;
					case CSTA_LOGGED_OFF:
						GetCallInfo(&cstaEvent->event.cstaUnsolicited.u.loggedOff);
						if (PROCESS)
							m_bLogged=FALSE;
						break;
				}//case CSTAUNSOLICITED
				if (m_bIsCmdMsg)
				{// This is all cmd message, and should not be fired
					if (cstaEvent->eventHeader.eventType!=CSTA_FAILED 
						 || cstaEvent->eventHeader.eventType!=CSTA_MONITOR_ENDED)
					{
						while (!PostMessage(NULL,UM_CMDMSG,cstaEvent->eventHeader.eventType,0))
							Sleep(100);
					}
					notFire=TRUE;
				}
				// If this device is ringing, fire this event out always
				if (cstaEvent->eventHeader.eventClass==CSTAUNSOLICITED 
					&& cstaEvent->eventHeader.eventType==CSTA_DELIVERED
					&& PROCESS)
					notFire=FALSE;
				break;
			}//switch

			{
				char temp[300]={0};
				wsprintf((char*)&temp,"DN receive event: eventClass:%d,eventType %d,MonitoerDeviece %s, EventDevice %s, notFire:%d",
							cstaEvent->eventHeader.eventClass,
							cstaEvent->eventHeader.eventType,
							m_deviceId,m_thisDevice.deviceID ,
							notFire);
				WriteLog((char*)&temp);
			}
		}//if (cstaEvent)
	if (notFire) delete pEvent;
	else ReplyMessage(0l);
	}//if (pEvent)
	return notFire;
}


BOOL CDirectoryNumber::KVListToAppString(IKVList* pkvlist, char* pAppString,UINT bufLen)
{
	//Transform character: "/"
	//	/k:  type : key
	//	/s:	type: string
	//	/i:	type: int
	//	/b:	type: binary
	//	/l:	type: binary length (/l23/l)
	//sample:  /kRick/sMyname/kName/i100
	BOOL bReturn=TRUE;

	if (pkvlist)
	{
		KVRESULTS res=pkvlist->InitScanLoop();
		if (KVR_Successful==res)
		{
			IKVPair* pkvpair=NULL;
			while (pkvpair=pkvlist->NextPair())
			{
				pkvpair->AddRef();

				BSTR key=NULL;
				char* pKey=NULL;
				if (SUCCEEDED(pkvpair->get_Key(&key)))
				{
					if (GetAnsiFromBSTR(&pKey,key))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -