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

📄 tspi.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    HDRVLINE               hdLine,
    HTAPICALL              htCall,
    LPHDRVCALL             lphdCall,
    LPCWSTR                lpszDestAddress,
    DWORD                  dwCountryCode,
    LPLINECALLPARAMS const lpCallParams
    )
{
    PTLINEDEV pLineDev;
    DWORD dwRet;
    BOOL  fDoTakeover = FALSE;
    WCHAR szSuffix[16];
    DWORD dwSize;
    DCB commDCB;

    DEBUGMSG(ZONE_FUNC|ZONE_CALLS, (TEXT("UNIMODEM:+TSPI_lineMakeCall\n")));

    if ((pLineDev = GetLineDevfromHandle ((DWORD)hdLine)) == NULL) {
        DEBUGMSG(ZONE_FUNC|ZONE_ERROR|ZONE_CALLS,
                 (TEXT("UNIMODEM:-TSPI_lineMakeCall ** Invalid Handle\n")));
        return LINEERR_INVALLINEHANDLE;
    }
    
     // See if we have a free call struct.
    if (pLineDev->dwCallFlags & CALL_ALLOCATED) {
        DEBUGMSG(ZONE_FUNC|ZONE_ERROR|ZONE_CALLS,
                 (TEXT("UNIMODEM:-TSPI_lineMakeCall ** Call already allocated\n")));
        return LINEERR_CALLUNAVAIL;
    }    

    // By default, don't do blind dialing.
    pLineDev->dwDialOptions &= ~MDM_BLIND_DIAL;

     // Examine LINECALLPARAMS, if present
    if (lpCallParams) {
        DEBUGMSG(ZONE_FUNC|ZONE_ERROR|ZONE_CALLS,
                 (TEXT("UNIMODEM:TSPI_lineMakeCall - Check CallParams\n")));
        
         // verify media mode
        if (lpCallParams->dwMediaMode & ~pLineDev->dwMediaModes) {
            DEBUGMSG(ZONE_FUNC|ZONE_ERROR|ZONE_CALLS,
                     (TEXT("UNIMODEM:-TSPI_lineMakeCall ** Invalid Media Mode\n")));
            return LINEERR_INVALMEDIAMODE;
        }
        DEBUGMSG(ZONE_MISC,
                 (TEXT("UNIMODEM:TSPI_lineMakeCall - verified media modes\n")));
        
         // verify bearer mode
        if ((~pLineDev->dwBearerModes) & lpCallParams->dwBearerMode) {
            DEBUGMSG(ZONE_FUNC|ZONE_ERROR|ZONE_CALLS,
                     (TEXT("UNIMODEM:-TSPI_lineMakeCall ** Invalid Bearer Mode 0x%x vs 0x%x\n"),
                      pLineDev->dwBearerModes, lpCallParams->dwBearerMode));
            return LINEERR_INVALBEARERMODE;
        }

        if (lpCallParams->dwBearerMode & LINEBEARERMODE_PASSTHROUGH) {
            fDoTakeover = TRUE;
        } else {
             // We're not requested to do passthrough.  Can we actually
             // dial the media modes without passthrough?  This is to
             // prevent G3FAX from being used without passthrough...
             // (We can only dial with DATAMODEM)
            if ((lpCallParams->dwMediaMode &
                 (LINEMEDIAMODE_DATAMODEM)) == 0) {
                DEBUGMSG(ZONE_FUNC|ZONE_ERROR|ZONE_CALLS,
                         (TEXT("UNIMODEM:-TSPI_lineMakeCall ** Invalid Media Mode\n")));
                return LINEERR_INVALMEDIAMODE;
            }
        }

        pLineDev->dwCurBearerModes = lpCallParams->dwBearerMode;
        pLineDev->dwCurMediaModes = lpCallParams->dwMediaMode;

        DEBUGMSG(ZONE_MISC,
                 (TEXT("UNIMODEM:TSPI_lineMakeCall - got media & bearer modes\n")));

        if (!(lpCallParams->dwCallParamFlags & LINECALLPARAMFLAGS_IDLE)) {
            DEBUGMSG(ZONE_WARN|ZONE_CALLS,
             (TEXT("UNIMODEM:TSPI_lineMakeCall LINECALLPARAMFLAGS_IDLE: not set, no dialtone detect\n") ));
             // Turn on blind dialing
            pLineDev->dwDialOptions |= MDM_BLIND_DIAL;
        }

        if ((lpCallParams->dwAddressType) && (lpCallParams->dwAddressType != LINEADDRESSTYPE_PHONENUMBER)) {
            DEBUGMSG(ZONE_FUNC|ZONE_ERROR, (TEXT("UNIMODEM:-TSPI_lineMakeCall ** Invalid Address Type\n")));
            return LINEERR_INVALADDRESS;
        }

        //
        // Set the devconfig if specified
        //
        if (lpCallParams->dwDeviceConfigSize && lpCallParams->dwDeviceClassSize) {
            dwRet = TSPI_lineSetDevConfig(pLineDev->dwDeviceID,
                                          (LPVOID)(((DWORD)lpCallParams) + lpCallParams->dwDeviceConfigOffset),
                                          lpCallParams->dwDeviceConfigSize,
                                          (LPVOID)(((DWORD)lpCallParams) + lpCallParams->dwDeviceClassOffset)
                                          );

                        if (dwRet) {
                RETAILMSG((TRUE), (TEXT("UNIMODEM:-TSPI_lineMakeCall ** Invalid device config in CALLPARAMS\n")));
                DEBUGMSG(ZONE_FUNC|ZONE_ERROR,(TEXT("UNIMODEM:-TSPI_lineMakeCall ** Invalid device config in CALLPARAMS\n")));
                //return dwRet;
            }
            else 
            {
                // Enable devconfig settings
                GetCommState( pLineDev->hDevice, &commDCB );
                SetDCBfromDevMiniCfg(&commDCB, &(pLineDev->DevMiniCfg));
                SetCommState( pLineDev->hDevice, &commDCB );
            }
        }

        // We should preserve other fields of call params for call info
        // Currently we look at: dwBearerMode, dwMediaMode, dwCallParamFlags, dwAddressType and dwDeviceConfig
            
    } else {
         // set the standard defaults - for peg tapi it is DATAMODEM
        ASSERT(pLineDev->dwMediaModes & LINEMEDIAMODE_DATAMODEM);
        pLineDev->dwCurMediaModes = LINEMEDIAMODE_DATAMODEM;

        pLineDev->dwCurBearerModes = pLineDev->dwBearerModes & ~LINEBEARERMODE_PASSTHROUGH;
    }

     // 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;

    if (fDoTakeover) {
        //
        // Stop UnimodemControlThread for a passthrough connection
        //
        pLineDev->fTakeoverMode = TRUE;
        ControlThreadCmd(pLineDev, PENDING_EXIT, INVALID_PENDINGID);
    }

     // 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)) {
        NewCallState(pLineDev, LINECALLSTATE_UNKNOWN, 0L);
        if (fDoTakeover) {
            DEBUGMSG(1|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->DevState = DEVST_CONNECTED;

                SetAsyncOp(pLineDev, PENDING_LINEMAKECALL);
                NewCallState(pLineDev, LINECALLSTATE_CONNECTED, LINECONNECTEDMODE_ACTIVE);
                SetEvent(pLineDev->hCallComplete);
                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);
        if (fDoTakeover) {
            SetAsyncStatus(pLineDev, 0);
        }
    }

    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;
    }

    MdmRegGetLineValues(pLineDev);

    if (IsDynamicDevice(pLineDev)) {
        // Create the dynamic device
		WCHAR szPrefix[4];
		memcpy(szPrefix, pLineDev->szDeviceName, 6);
		szPrefix[3] = 0;

        pLineDev->DevMiniCfg.hPort =
        pLineDev->hDynamicPort     =
            RegisterDevice( 
                szPrefix,						            // Prefix
                pLineDev->szDeviceName[3]-_T('0'),          // Index
                pLineDev->DevMiniCfg.wszDriverName,         // Dll
                (DWORD)&pLineDev->DevMiniCfg.pConfigBlob    // Context
                );
    
        if (pLineDev->hDynamicPort == NULL ) {
            DEBUGMSG(ZONE_ERROR, (TEXT("TSPI_lineOpen, RegisterDevice( failed %d\n"), dwDeviceID));
            return LINEERR_INVALPARAM;
        }
    }

    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

⌨️ 快捷键说明

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