📄 tapiline.cpp
字号:
if(NULL == m_pActiveCall->GetStateSemHandle()) return -1L; // failed to alloc mutex
return 0L; // why 0?....
}
// Remove active or any other call
void CTapiLine::RemoveCall(CTapiCall *pCall)
{
// Protect this against async returns that may try to do something w/pCall!!!
// first claim the call list mutex
HANDLE hStateSem;
DWORD dwWS;
TRACE("*** TALKER32 ***: RemoveCall entering wait for sem\n");
DWORD dwrc = WaitForSingleObject(m_hCallSem, 15000);
if(dwrc != WAIT_OBJECT_0)
{
TRACE("*** TALKER32 ***: RemoveCall #%lx wait for sem failed rc=%lx\n", pCall, dwrc);
return;
}
if(pCall == NULL) pCall = m_pActiveCall;
if(pCall == NULL) goto FinishRemoveCall; // nothing to do
hStateSem = pCall->GetStateSemHandle();
if(hStateSem) // in case somebody else tries to call UpdateCallState...
{
WaitForSingleObject(hStateSem, 5000);
CloseHandle(hStateSem);
}
// cleanup async requests associated with this call here !!!
dwWS = pCall->GetWaveStatus();
if(dwWS != WAVE_IDLE) // Defer removing call ???...
TRACE("*** TALKER32 ***: removing call while WAVE state=%d\n", dwWS);
delete pCall;
if(pCall == m_pActiveCall) m_pActiveCall = NULL;
FinishRemoveCall:
TRACE("*** TALKER32 ***: RemoveCall %lx releasing mutex\n", pCall);
ReleaseMutex(m_hCallSem);
return;
}
// purge (all) calls on the line, no questions asked
void CTapiLine::ctlPurgeCalls()
{
TRACE("*** TALKER32 ***: Enter PurgeCalls for line %d\n", m_dwLineID);
// for now only delete the active call. When the calls storage is impl, add logic
if(NULL == m_pActiveCall) return;
// Do for all calls
RemoveCall();
TRACE("*** TALKER32 ***: Exit PurgeCalls for line %d\n", m_dwLineID);
}
// React to changes in call status; needs to be protected
// Call NotifyFrontEnd after this function to update indicators
void CTapiLine::ctlUpdateCallStatus(WORD wFunction, DWORD dwStatus, CTapiCall *pCall)
{
switch(wFunction)
{
case 0: // status change is NOT a result of async return
pCall->UpdateCallState((WORD) dwStatus);
break;
case FUNCTION_MAKECALL:
// case FUNCTION_DIAL:
if(dwStatus < 0)
{
if(pCall) // do not try to drop; can only drop calls that were made
{
pCall->UpdateCallState(IDLE, IDLE, LINECALLSTATE_UNKNOWN, MAKE_FAILED);
ctlLineDeallocateCall(pCall);
}
}
else pCall->UpdateCallState(PROGRESS);
break;
case FUNCTION_DROP: // if failed, find out the reason
if(m_pActiveCall==NULL || !IsBadReadPtr(pCall, 32))
{
TRACE("*** TALKER32 ***: Trying to update call state for invalid pCall, pCall=%lx, m_pActive=%lx\n",
pCall, m_pActiveCall);
break;
}
if(dwStatus < 0) // do NOT try to deallocate or change state
{
// mark it as tried to drop & failed
pCall->UpdateCallState(0xffff, 0xffff, 0xffff, DROP_FAILED);
}
else pCall->UpdateCallState(DROPPING);
break;
case FUNCTION_ANSWER:
// does not mean we have an active connection yet
if(dwStatus < 0) // don't know what to do, try to drop...
{
pCall->UpdateCallState(DROPPING, 0xffff, 0xffff, ANSWER_FAILED);
ctlLineDrop(m_pActiveCall);
}
break;
case FUNCTION_DEVSPEC:
if(dwStatus & 0x80000000)
ctlUpdateDevSpecStatus(DEVSPEC_STARTFAILED);
else ctlUpdateDevSpecStatus(dwStatus ? DEVSPEC_RESULTFAILED : DEVSPEC_IDLE);
//ctlUpdateDevSpecStatus(DEVSPEC_PROGRESS);
break;
case FUNCTION_FORWARD:
TRACE("TALKER32: lineForward reply status=%lx\n", dwStatus);
break;
default:
break;
m_pApp->NotifyFrontEnd(m_dwLineID); // always update front end
} // end of switch(wFunction)
}
// Update call info based on HCALL
BOOL CTapiLine::ctlUpdateCallInfo(HCALL hCall, LPLINECALLINFO lpCallInfo)
{
// find the call, delete the current CALLINFO if any, set new CALLINFO
if(m_pActiveCall->m_hCall != hCall) return FALSE; // for now
// m_pActiveCall->UpdateCallInfo(lpCallInfo); // must be protected
return FALSE; // always for now, so the caller deletes CALLINFO
}
// get the id of the wave device corresponding to the line
// COMMENTS: wave devices use an unsigned integer id. we must allocate enough
// space for this id to be returned from the driver.
void CTapiLine::ctlGetWaveDeviceID (WORD wType)
{
LONG lrc;
DWORD dwID;
VARSTRING *pvsVarStr = (VARSTRING *) new char[sizeof(VARSTRING) + 64];
// allocate 4 extra bytes for wave id.
if(pvsVarStr == NULL) goto GetIDFail;
pvsVarStr->dwTotalSize = sizeof (VARSTRING) + 64;
if ((lrc = lineGetID (m_hLine, 0, 0, LINECALLSELECT_LINE,
pvsVarStr, wType == WAVEIN ? "wave/in" : wType == WAVEOUT ? "wave/out" : "xxx")) < 0)
goto GetIDFail;
// if the returned id was not binary, something is wrong
if (!m_bRemote && pvsVarStr->dwStringFormat != STRINGFORMAT_BINARY)
{
#ifdef TAPI20
if(pvsVarStr->dwStringFormat == STRINGFORMAT_ASCII || pvsVarStr->dwStringFormat == STRINGFORMAT_UNICODE)
{
m_bRemote = TRUE; // the line is running remotely
m_csName = ((BYTE *)pvsVarStr+sizeof(VARSTRING));
m_csName += "\\";
}
#endif
//goto GetIDFail;
}
dwID = (DWORD) *((BYTE *)pvsVarStr+sizeof(VARSTRING)); // get id
delete pvsVarStr;
if(wType == WAVEIN) m_uiWaveInID = (UINT)(WORD) dwID;
else if(wType == WAVEOUT) m_uiWaveOutID = (UINT)(WORD) dwID;
return;
GetIDFail:
if(pvsVarStr != NULL) delete pvsVarStr;
}
//call lineGetLineDevStatus here
LPLINEDEVSTATUS CTapiLine::ctlGetLineDevStatus()
{
LPLINEDEVSTATUS lpDevStatus = NULL;
LONG lrc = 0;
DWORD dwSize = sizeof(LINEDEVSTATUS)+1000;
DWORD i;
// keep trying until buffer is big enough
for (i=0; i<2; i++)
{
lpDevStatus = (LPLINEDEVSTATUS) new char[dwSize];
if (lpDevStatus == NULL)
return NULL;
lpDevStatus->dwTotalSize = dwSize;
lrc = lineGetLineDevStatus(m_hLine,lpDevStatus);
if(lrc < 0) goto FinishLineGetDevStatus;
dwSize = lpDevStatus->dwNeededSize;
if(dwSize <= lpDevStatus->dwTotalSize) break; // success
delete (char *) lpDevStatus;
}
return lpDevStatus;
FinishLineGetDevStatus:
if (lpDevStatus != NULL)
delete (LPBYTE) lpDevStatus;
return NULL;
}
// Configuration dialog
void CTapiLine::ctlConfigDialog(HWND hWnd, LPSTR lpClass)
{
lineConfigDialog(m_dwLineID, hWnd, lpClass);
}
LONG CTapiLine::ctlLineDevSpecific(DWORD dwFunc, DWORD dwAddressID, HCALL hCall,
LPVOID lParams, DWORD dwSize)
{
LONG lrc;
TRACE("*** TALKER32: calling DevSpec dwSize=%d\n", dwSize);
lrc = lineDevSpecific(m_hLine, dwAddressID, hCall, lParams, dwSize);
if(lrc < 0)
{ // need to report an error
TRACE("*** TALKER32: DevSpec failed on line %d\n", m_dwLineID);
return lrc;
}
TRACE("*** TALKER32: DevSpec asyncID=%d\n",lrc);
ctlUpdateDevSpecStatus(DEVSPEC_STARTING);
// update the function in the beginning of execution ONLY
ctlUpdateDevSpecFunction(dwFunc);
m_pApp->SetAsyncID((DWORD) lrc, MAKING, FUNCTION_DEVSPEC,
(LPVOID) this, (LPVOID) m_pActiveCall);
return lrc;
}
LONG CTapiLine::ctlLineForward(LPSTR lpDest)
{
if(!lpDest) return -1;
LPLINEFORWARDLIST lpLFL = (LPLINEFORWARDLIST) new char[sizeof(LINEFORWARDLIST) + lstrlen(lpDest)+8];
if(!lpLFL) return -1;
BOOL bAllAddr = TRUE;
DWORD dwAddrID = 0L;
HCALL hCC;
LONG lrc;
lpLFL->dwNumEntries = 1;
lpLFL->dwTotalSize = sizeof(LINEFORWARDLIST) + lstrlen(lpDest)+8;
lpLFL->ForwardList[0].dwForwardMode = LINEFORWARDMODE_UNCOND;
lpLFL->ForwardList[0].dwCallerAddressSize = 0;
lpLFL->ForwardList[0].dwCallerAddressOffset = 0;
lpLFL->ForwardList[0].dwDestCountryCode = 0;
lpLFL->ForwardList[0].dwDestAddressSize = (DWORD)lstrlen(lpDest);
lpLFL->ForwardList[0].dwDestAddressOffset = sizeof(LINEFORWARDLIST);
memcpy((LPBYTE)lpLFL+sizeof(LINEFORWARDLIST), lpDest, lstrlen(lpDest)+1);
lrc = lineForward(m_hLine, bAllAddr, dwAddrID, lpLFL, 4, &hCC, NULL);
if(lrc < 0)
TRACE("*** TALKER32: lineForward failed on line %d rc=%lx\n", m_dwLineID, lrc);
else m_pApp->SetAsyncID((DWORD) lrc, MAKING, FUNCTION_FORWARD,
(LPVOID) this, NULL);
delete (LPBYTE) lpLFL;
return lrc;
}
// Determine if the line is running on the remote computer
// Since MS doesn't provide a standard way, use whatever mechanism is available for the SP
// Override this function to implement a better way
BOOL IsLineRemote(LPLINEDEVCAPS lpDC)
{
int nInd;
CString csTemp;
if(!lpDC->dwLineNameOffset) return FALSE;
csTemp.Format("%s", (LPSTR)((LPBYTE)lpDC + lpDC->dwLineNameOffset));
csTemp.MakeUpper();
if(-1 == csTemp.Find("DXXXB")) return FALSE; // non-Dialogic TSP
if(-1 == (nInd = csTemp.Find("\\"))) return FALSE; // computer name not a part of board name
csTemp = csTemp.Left(nInd);
char szName[MAX_COMPUTERNAME_LENGTH+1];
DWORD dwSize = MAX_COMPUTERNAME_LENGTH+1;
if(!GetComputerName(szName, &dwSize)) return FALSE; // Name unavailable for some reason
if(!strcmpi(szName, (LPCTSTR)csTemp)) return FALSE; // Same name
return TRUE; // Finally, the names ARE different
}
/* call lineGetLineDevCaps here
LPLINEDEVSTATUS CTapiLine::ctlGetLineDevCaps()
{
LPLINEDEVCAPS lpDevCaps = NULL;
LONG lrc = 0;
DWORD dwSize = sizeof(LINEDEVCAPS)+1000;
DWORD i;
// keep trying until buffer is big enough
for (i=0; i<2; i++)
{
lpDevStatus = (LPLINEDEVSTATUS) new char[dwSize];
if (lpDevStatus == NULL)
return NULL;
lpDevStatus->dwTotalSize = dwSize;
lrc = lineGetLineDevStatus(m_hLine,lpDevStatus);
if(lrc < 0) goto FinishLineGetDevStatus;
dwSize = lpDevStatus->dwNeededSize;
if(dwSize <= lpDevStatus->dwTotalSize) break; // success
delete (char *) lpDevStatus;
}
return lpDevStatus;
FinishLineGetDevStatus:
if (lpDevStatus != NULL)
delete (LPBYTE) lpDevStatus;
return NULL;
} */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -