📄 tspi.c
字号:
}
// Do we have a phone number?
//
if (!fDoTakeover)
{
if (IS_NULL_MODEM(pLineDev) ||
pLineDev->DevMiniCfg.fwOptions & MANUAL_DIAL)
{
*pLineDev->szAddress = '\0';
DEBUGMSG(ZONE_MISC|ZONE_CALLS,
(TEXT("UNIMODEM:TSPI_lineMakeCall - Manual dial, zeroing dial string\n")));
// Turn on blind dialing if this is MANUAL_DIAL.
if (pLineDev->DevMiniCfg.fwOptions & MANUAL_DIAL)
{
pLineDev->dwDialOptions |= MDM_BLIND_DIAL;
}
}
else
{
// Validate lpszDestAddress and get the processed form of it.
DEBUGMSG(ZONE_MISC|ZONE_CALLS,
(TEXT("UNIMODEM:TSPI_lineMakeCall - validating destination address\n")));
dwRet = ValidateAddress(pLineDev, lpszDestAddress, pLineDev->szAddress);
if (SUCCESS != dwRet)
{
DEBUGMSG(ZONE_FUNC|ZONE_ERROR|ZONE_CALLS,
(TEXT("UNIMODEM:-TSPI_lineMakeCall ** Invalid Address\n")));
return dwRet;
}
// if the lpszDestAddress was NULL or "", then we just want to do a
// dialtone detection. We expect that lineDial will be called.
// Setting the szAddress to ";" will do this.
if ('\0' == pLineDev->szAddress[0])
{
dwSize = sizeof(szSuffix);
if (ERROR_SUCCESS != MdmRegGetValue( pLineDev,
szSettings,
szDialSuffix,
REG_SZ,
(PUCHAR)szSuffix,
&dwSize) )
{
wcscpy(szSuffix, TEXT(";"));
}
wcscpy(pLineDev->szAddress, szSuffix);
}
}
}
// Record the call attributes
pLineDev->htCall = htCall;
pLineDev->dwCallFlags = CALL_ALLOCATED;
*lphdCall = (HDRVCALL)pLineDev;
// We allow making a call to an already-opened line if the line is monitoring
// a call. Therefore, if the line is in use, try making a call. The make-call
// routine will return error if the state is not appropriate.
//
dwRet = DevlineOpen(pLineDev);
if ((dwRet == SUCCESS) || (dwRet == LINEERR_ALLOCATED)) {
if (fDoTakeover) {
DEBUGMSG(ZONE_MISC|ZONE_CALLS ,(TEXT("UNIMODEM:TSPI_lineMakeCall - Takeover\n")));
// For takeover, we don't actually do any calling. Just open the
// port so that the application can get the device handle from
// lineGetID.
if ((pLineDev->DevState == DEVST_DISCONNECTED) ||
(pLineDev->DevState == DEVST_PORTLISTENING)) {
// We can only go into passthrough if device is not in use
// OK, the device was opened above, so now we just need to
// let the apps know that the callstate has changed.
pLineDev->dwCallState = LINECALLSTATE_UNKNOWN;
pLineDev->DevState = DEVST_CONNECTED;
pLineDev->fTakeoverMode = TRUE;
SetAsyncOp(pLineDev, PENDING_LINEMAKECALL);
SetAsyncStatus(pLineDev, 0);
NewCallState(pLineDev, LINECALLSTATE_CONNECTED, LINECONNECTEDMODE_ACTIVE);
dwRet = 0;
} else {
dwRet = LINEERR_OPERATIONFAILED;
}
} else {
pLineDev->DevState = DEVST_PORTCONNECTDIAL;
dwRet = ControlThreadCmd(pLineDev, PENDING_LINEMAKECALL, dwRequestID);
}
}
// Check if an error occurs
//
if (IS_TAPI_ERROR(dwRet))
{
DEBUGMSG(ZONE_CALLS,
(TEXT("UNIMODEM:TSPI_lineMakeCall Ret Code x%X, invalidating pending ID.\n"),
dwRet ));
// Deallocate the call from this line
pLineDev->htCall = NULL;
pLineDev->dwCallFlags = 0;
*lphdCall = NULL;
} else {
dwRet = SetAsyncID(pLineDev, dwRequestID);
}
DEBUGMSG(ZONE_FUNC|ZONE_CALLS, (TEXT("UNIMODEM:-TSPI_lineMakeCall, dwRet x%X\n"), dwRet));
return dwRet;
} // TSPI_lineMakeCall
LONG TSPIAPI
TSPI_lineNegotiateTSPIVersion(
DWORD dwDeviceID,
DWORD dwLowVersion,
DWORD dwHighVersion,
LPDWORD lpdwTSPIVersion
)
{
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineNegotiateTSPIVersion\n")));
// Check the range of the device ID
//
if ((dwDeviceID == INITIALIZE_NEGOTIATION) || (GetLineDevfromID(dwDeviceID) != NULL))
{
// Check the version range
//
if((dwLowVersion > SPI_VERSION) || (dwHighVersion < SPI_VERSION))
{
*lpdwTSPIVersion = 0;
DEBUGMSG(ZONE_FUNC,
(TEXT("UNIMODEM:-TSPI_lineNegotiateTSPIVersion - SPI Ver x%X out of TAPI range x%X..x%X\n"),
SPI_VERSION, dwLowVersion, dwHighVersion));
return LINEERR_INCOMPATIBLEAPIVERSION;
}
else
{
*lpdwTSPIVersion = SPI_VERSION;
DEBUGMSG(ZONE_FUNC,
(TEXT("UNIMODEM:-TSPI_lineNegotiateTSPIVersion - Ver x%X\n"),
SPI_VERSION));
return SUCCESS;
};
};
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineNegotiateTSPIVersion - No Device\n")));
// The requested device doesn't exist.
return LINEERR_NODEVICE;
}
LONG TSPIAPI
TSPI_lineOpen(
DWORD dwDeviceID,
HTAPILINE htLine,
LPHDRVLINE lphdLine,
DWORD dwTSPIVersion,
LINEEVENT lineEventProc)
{
PTLINEDEV pLineDev;
DEBUGMSG(ZONE_FUNC,
(TEXT("UNIMODEM:+TSPI_lineOpen DevID x%X, HTapiLine x%X, SPI Ver x%X\n"),
dwDeviceID, htLine, dwTSPIVersion));
// Validate the device ID
if ((pLineDev = GetLineDevfromID(dwDeviceID)) == NULL) {
DEBUGMSG(ZONE_ERROR,
(TEXT("TSPI_lineOpen, could not find device for dwId x%X\n"),
dwDeviceID));
return LINEERR_NODEVICE;
}
EnterCriticalSection(&pLineDev->OpenCS);
// Update the line device
*lphdLine = (HDRVLINE)pLineDev;
pLineDev->lpfnEvent = lineEventProc;
DEBUGMSG((lineEventProc != TspiGlobals.fnLineEventProc) & ZONE_WARN,
(TEXT("UNIMODEM:TSPI_lineOpen lineEventProc != TspiGlobals.fnLineEventProc\n")));
pLineDev->htLine = htLine;
LeaveCriticalSection(&pLineDev->OpenCS);
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineOpen\n")));
return SUCCESS;
}
LONG TSPIAPI
TSPI_lineSetDevConfig(
DWORD dwDeviceID,
LPVOID const lpDeviceConfig,
DWORD dwSize,
LPCWSTR lpszDeviceClass
)
{
PTLINEDEV pLineDev;
PDEVMINICFG pDevMiniCfg;
#ifdef DEBUG
DWORD dwTemp;
#endif
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineSetDevConfig\n")));
// Validate the requested device class
//
if (!ValidateDevCfgClass(lpszDeviceClass))
{
DEBUGMSG(ZONE_FUNC|ZONE_ERROR,
(TEXT("UNIMODEM:-TSPI_lineSetDevConfig : LINEERR_INVALDEVICECLASS\n")));
return LINEERR_INVALDEVICECLASS;
}
// Validate the buffer
//
if (lpDeviceConfig == NULL)
{
DEBUGMSG(ZONE_FUNC|ZONE_ERROR,
(TEXT("UNIMODEM:-TSPI_lineSetDevConfig : LINEERR_INVALPOINTER\n")));
return LINEERR_INVALPOINTER;
}
// Validate the device ID
//
if ((pLineDev = GetLineDevfromID(dwDeviceID)) == NULL)
{
DEBUGMSG(ZONE_FUNC|ZONE_ERROR,
(TEXT("UNIMODEM:-TSPI_lineSetDevConfig : LINEERR_NODEVICE\n")));
return LINEERR_NODEVICE;
}
// verify the structure size and version
//
pDevMiniCfg = (PDEVMINICFG)lpDeviceConfig;
if ( (dwSize != sizeof(DEVMINICFG)) ||
(pLineDev->DevMiniCfg.wVersion != (pDevMiniCfg->wVersion)) )
{
DEBUGMSG(ZONE_FUNC|ZONE_ERROR,
(TEXT("UNIMODEM:-TSPI_lineSetDevConfig : LINEERR_INVALPARAM\n")));
return LINEERR_INVALPARAM;
}
// Get the new settings
pLineDev->DevMiniCfg = *pDevMiniCfg;
#ifdef DEBUG
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:DevConfig set :\n")));
if( MDM_FLOWCONTROL_HARD & pLineDev->DevMiniCfg.dwModemOptions )
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:\tHardware Flow Control\n")));
else if( MDM_FLOWCONTROL_SOFT & pLineDev->DevMiniCfg.dwModemOptions )
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:\tSoftware Flow Control\n")));
else
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:\tNo Flow Control\n")));
if (MANUAL_DIAL & pLineDev->DevMiniCfg.fwOptions )
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:\tManual Dialing\n")));
if (TERMINAL_PRE & pLineDev->DevMiniCfg.fwOptions )
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:\tPredial Terminal\n")));
if (TERMINAL_POST & pLineDev->DevMiniCfg.fwOptions )
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:\tPostdial Terminal\n")));
if ( MDM_BLIND_DIAL & pLineDev->DevMiniCfg.dwModemOptions )
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:\tBlind Dialing\n")));
dwTemp = wcslen(pLineDev->DevMiniCfg.szDialModifier);
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM: Dial Modifier len %d\n"),
dwTemp));
if( dwTemp )
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM: Dial Modifier string %s\n"),
pLineDev->DevMiniCfg.szDialModifier));
#endif
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineSetDevConfig\n")));
return SUCCESS;
}
//
// Enable the opened line to detect an inbound call.
//
LONG TSPIAPI
TSPI_lineSetDefaultMediaDetection(
HDRVLINE hdLine,
DWORD dwMediaModes
)
{
PTLINEDEV pLineDev;
LONG rc = LINEERR_OPERATIONFAILED; // assume failure
DWORD dwOrigMediaModes;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineSetDefaultMediaDetection\n")));
pLineDev = GetLineDevfromHandle((DWORD)hdLine);
if (!pLineDev) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineSetDefaultMediaDetection: invalid hdLine 0x%x\n"), hdLine));
rc = LINEERR_INVALLINEHANDLE;
goto exitPoint;
}
// Check the requested modes. There must be only our media modes.
// In addition, don't allow INTERACTIVEVOICE to be used for listening.
//
if (dwMediaModes & ~(pLineDev->dwMediaModes & ~LINEMEDIAMODE_INTERACTIVEVOICE)) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineSetDefaultMediaDetection: invalid dwMediaModes 0x%x\n"), dwMediaModes));
rc = LINEERR_INVALMEDIAMODE;
goto exitPoint;
}
EnterCriticalSection(&pLineDev->OpenCS);
LeaveCriticalSection(&pLineDev->OpenCS);
//
// If no detection and a detection is requested
//
dwOrigMediaModes = pLineDev->dwDetMediaModes;
if ((dwOrigMediaModes == 0) && (dwMediaModes)) {
pLineDev->dwDetMediaModes = dwMediaModes;
rc = ControlThreadCmd(pLineDev, PENDING_LISTEN, INVALID_PENDINGID);
if (rc) {
pLineDev->dwDetMediaModes = dwOrigMediaModes;
}
} else {
//
// we are stopping detection OR adjusting the detection media modes
//
//
// If we are detecting and requested not to, then stop the control thread
//
if (dwOrigMediaModes && (dwMediaModes == 0) &&
(DEVST_PORTLISTENING == pLineDev->DevState ||
DEVST_PORTLISTENINIT == pLineDev->DevState)) {
pLineDev->dwDetMediaModes = 0;
ControlThreadCmd(pLineDev, PENDING_EXIT, INVALID_PENDINGID);
}
pLineDev->dwDetMediaModes = dwMediaModes;
rc = ERROR_SUCCESS;
}
exitPoint:
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineSetDefaultMediaDetection 0x%x\n"), rc));
return rc;
} // TSPI_lineSetDefaultMediaDetection
LONG
TSPIAPI
TSPI_lineSetMediaMode(
HDRVCALL hdCall,
DWORD dwMediaMode
)
{
LONG rc;
PTLINEDEV pLineDev;
if ((pLineDev = GetLineDevfromHandle ((DWORD)hdCall)) == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineSetMediaMode ** Invalid Handle\n")));
rc = LINEERR_INVALCALLHANDLE;
goto exitPoint;
}
// Check the requested modes. There must be only our media modes
//
if (dwMediaMode & ~pLineDev->dwMediaModes) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineSetMediaMode ** Invalid dwMediaMode\n")));
rc = LINEERR_INVALMEDIAMODE;
goto exitPoint;
}
rc = 0;
if (pLineDev->dwCurMediaModes != dwMediaMode) {
pLineDev->dwCurMediaModes = dwMediaMode;
CallLineEventProc(
pLineDev,
pLineDev->htCall,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -