📄 directorynumber.cpp
字号:
// 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 + -