📄 tspi.c
字号:
}
lpAddressCaps->dwNeededSize += cbDevClassLen;
exitPoint:
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetAddressCaps 0x%x\n"), rc));
return rc;
} // TSPI_lineGetAddressCaps
LONG
TSPIAPI
TSPI_lineGetAddressStatus(
HDRVLINE hdLine,
DWORD dwAddressID,
LPLINEADDRESSSTATUS lpAddressStatus
)
{
LONG rc;
PTLINEDEV pLineDev;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineGetAddressStatus\n")));
rc = 0;
InitVarData((LPVOID)lpAddressStatus, sizeof(LINEADDRESSSTATUS));
if ((pLineDev = GetLineDevfromHandle ((DWORD)hdLine)) == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineGetAddressStatus ** Invalid hdLine\n")));
rc = LINEERR_INVALLINEHANDLE;
goto exitPoint;
}
if(dwAddressID != 0) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineGetAddressStatus ** Invalid AddressID\n")));
rc = LINEERR_INVALADDRESSID;
goto exitPoint;
}
if (pLineDev->dwCallFlags & CALL_ACTIVE) {
lpAddressStatus->dwNumInUse = 1;
lpAddressStatus->dwNumActiveCalls = (pLineDev->dwCallState != LINECALLSTATE_IDLE) ? 1 : 0;
} else {
lpAddressStatus->dwNumInUse = 0;
lpAddressStatus->dwNumActiveCalls = 0;
};
lpAddressStatus->dwAddressFeatures = (pLineDev->dwCallFlags & CALL_ALLOCATED) ? 0 : LINEADDRFEATURE_MAKECALL;
exitPoint:
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetAddressStatus 0x%x\n"), rc));
return rc;
} // TSPI_lineGetAddressStatus
LONG
TSPIAPI
TSPI_lineGetCallInfo(
HDRVCALL hdCall,
LPLINECALLINFO lpCallInfo
)
{
PTLINEDEV pLineDev;
LONG rc;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineGetCallInfo\n")));
InitVarData((LPVOID)lpCallInfo, sizeof(LINECALLINFO));
if ((pLineDev = GetLineDevfromHandle ((DWORD)hdCall)) == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineGetCallInfo Invalid hdCall\n")));
rc = LINEERR_INVALCALLHANDLE;
goto exitPoint;
}
rc = 0;
lpCallInfo->dwLineDeviceID = pLineDev->dwDeviceID;
lpCallInfo->dwAddressID = 0;
lpCallInfo->dwBearerMode = pLineDev->dwCurBearerModes;
lpCallInfo->dwRate = pLineDev->dwCurrentBaudRate;
lpCallInfo->dwMediaMode = pLineDev->dwCurMediaModes;
lpCallInfo->dwAppSpecific = 0;
lpCallInfo->dwCallStates = pLineDev->dwCallFlags & CALL_INBOUND ?
(LINECALLSTATE_IDLE |
LINECALLSTATE_OFFERING |
LINECALLSTATE_ACCEPTED |
LINECALLSTATE_CONNECTED |
LINECALLSTATE_DISCONNECTED |
LINECALLSTATE_UNKNOWN) :
(LINECALLSTATE_IDLE |
LINECALLSTATE_DIALTONE |
LINECALLSTATE_DIALING |
LINECALLSTATE_PROCEEDING |
LINECALLSTATE_CONNECTED |
LINECALLSTATE_DISCONNECTED |
LINECALLSTATE_UNKNOWN);
lpCallInfo->dwOrigin = pLineDev->dwCallFlags & CALL_INBOUND ?
LINECALLORIGIN_INBOUND : LINECALLORIGIN_OUTBOUND;
lpCallInfo->dwReason = pLineDev->dwCallFlags & CALL_INBOUND ?
LINECALLREASON_UNAVAIL : LINECALLREASON_DIRECT;
lpCallInfo->dwCallerIDFlags = LINECALLPARTYID_UNAVAIL;
lpCallInfo->dwCalledIDFlags = LINECALLPARTYID_UNAVAIL;
lpCallInfo->dwConnectedIDFlags = LINECALLPARTYID_UNAVAIL;
lpCallInfo->dwRedirectionIDFlags = LINECALLPARTYID_UNAVAIL;
lpCallInfo->dwRedirectingIDFlags = LINECALLPARTYID_UNAVAIL;
lpCallInfo->dwAddressType = LINEADDRESSTYPE_PHONENUMBER;
exitPoint:
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetCallInfo %x\n"), rc));
return rc;
} // TSPI_lineGetCallInfo
LONG
TSPIAPI
TSPI_lineGetCallStatus(
HDRVCALL hdCall,
LPLINECALLSTATUS lpCallStatus
)
{
PTLINEDEV pLineDev;
LONG rc;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineGetCallStatus\n")));
InitVarData((LPVOID)lpCallStatus, sizeof(LINECALLSTATUS));
if ((pLineDev = GetLineDevfromHandle ((DWORD)hdCall)) == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineGetCallStatus Invalid hdCall\n")));
rc = LINEERR_INVALCALLHANDLE;
goto exitPoint;
}
rc = 0;
//
// Current call information
//
lpCallStatus->dwCallState = pLineDev->dwCallState;
lpCallStatus->dwCallStateMode = pLineDev->dwCallStateMode;
// if we are in takeover mode, disallow all dwCallFeatures
if (!pLineDev->fTakeoverMode) {
switch(lpCallStatus->dwCallState) {
case LINECALLSTATE_OFFERING:
lpCallStatus->dwCallFeatures = LINECALLFEATURE_ACCEPT |
LINECALLFEATURE_SETCALLPARAMS |
LINECALLFEATURE_DROP;
// We can only answer if a possible media mode is DATAMODEM.
if (pLineDev->dwCurMediaModes & LINEMEDIAMODE_DATAMODEM) {
lpCallStatus->dwCallFeatures |= LINECALLFEATURE_ANSWER;
}
break;
case LINECALLSTATE_DIALTONE:
lpCallStatus->dwCallFeatures = LINECALLFEATURE_DROP;
break;
case LINECALLSTATE_DIALING:
lpCallStatus->dwCallFeatures = LINECALLFEATURE_DROP;
if (DEVST_PORTCONNECTWAITFORLINEDIAL == pLineDev->DevState) {
lpCallStatus->dwCallFeatures |= LINECALLFEATURE_DIAL;
}
break;
case LINECALLSTATE_ACCEPTED:
lpCallStatus->dwCallFeatures = LINECALLFEATURE_SETCALLPARAMS|LINECALLFEATURE_DROP;
// We can only answer if a possible media mode is DATAMODEM.
if (pLineDev->dwCurMediaModes & LINEMEDIAMODE_DATAMODEM) {
lpCallStatus->dwCallFeatures |= LINECALLFEATURE_ANSWER;
}
break;
case LINECALLSTATE_CONNECTED:
lpCallStatus->dwCallFeatures = LINECALLFEATURE_SETCALLPARAMS |
LINECALLFEATURE_DROP;
break;
case LINECALLSTATE_UNKNOWN:
case LINECALLSTATE_PROCEEDING:
case LINECALLSTATE_DISCONNECTED:
lpCallStatus->dwCallFeatures = LINECALLFEATURE_DROP;
break;
case LINECALLSTATE_IDLE:
default:
lpCallStatus->dwCallFeatures = 0;
break;
}
}
exitPoint:
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetCallStatus %x\n"), rc));
return rc;
} // TSPI_lineGetCallStatus
static const WCHAR szProviderName[] = TEXT("UNIMODEM");
//
// Determine Telephony capabilites for the specified device.
//
// NOTES:
// WinCE UNIMODEM uses a DWORD of DevSpecific information (denoted by
// LINEDEVCAPS.dwDevSpecificSize and LINEDEVCAPS.dwDevSpecificOffset).
// The format of of these 4 bytes is that the first WORD is a device type
// and the second WORD is an "active" indicator (0 for PC card modems that
// have been removed).
//
// The provider name is stored in the ProviderInfo section (denoted by
// LINEDEVCAPS.dwProviderInfoSize and LINEDEVCAPS.dwProviderInfoOffset).
//
LONG TSPIAPI
TSPI_lineGetDevCaps(
DWORD dwDeviceID,
DWORD dwTSPIVersion,
DWORD dwExtVersion,
LPLINEDEVCAPS lpLineDevCaps
)
{
PTLINEDEV pLineDev;
int cbLineNameLen = 0;
int cbProviderNameLen = 0;
int cbDevClassLen = 0;
int cbAvailMem = 0;
DWORD dwRet = SUCCESS;
UNIMODEM_INFO UmdmInfo;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineGetDevCaps\n")));
InitVarData((LPVOID)lpLineDevCaps, sizeof(LINEDEVCAPS));
// We need to fill in a device caps struct specific to
// the device.
if ((pLineDev = GetLineDevfromID ((DWORD)dwDeviceID)) == NULL)
return LINEERR_NODEVICE;
// Check to see how much memory we'll need.
cbLineNameLen = (wcslen(pLineDev->szFriendlyName) + 1) * sizeof(WCHAR);
cbProviderNameLen = (wcslen(szProviderName) + 1) * sizeof(WCHAR);
cbDevClassLen = sizeof(g_szzClassList);
cbAvailMem = (int) (lpLineDevCaps->dwTotalSize - lpLineDevCaps->dwUsedSize);
// Enter the size we ideally need.
lpLineDevCaps->dwNeededSize = lpLineDevCaps->dwUsedSize +
cbLineNameLen + // room for linename
cbProviderNameLen + // room for provider name
cbDevClassLen + // room for device class list
(2*sizeof(WORD)); // and room for DevSpecific info
// NOTE - In CE, there is no VCOMM available for an app to determine the device
// type (modem or DCC/NULL). So, the DevSpecific field contains a UNIMODEM_INFO
// which indicates the device type (DT_NULL, DT_PCMCIA_MODEM, etc) and a flag
// which is 1 if the device is ready/available, or 0 if the device is not currently
// available ( a removed PCMCIA card, etc.) and the size of the MTU that PPP should
// use. See UNIMODEM_INFO definition in public\common\oak\inc\unimodem.h
if (cbAvailMem >= sizeof(UNIMODEM_INFO) )
{
UmdmInfo.wDeviceType = pLineDev->wDeviceType;
UmdmInfo.wActive = pLineDev->wDeviceAvail;
UmdmInfo.dwPPPMTU = pLineDev->dwPPPMTU;
memcpy(((LPSTR)lpLineDevCaps + lpLineDevCaps->dwUsedSize), &UmdmInfo, sizeof(UNIMODEM_INFO));
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:TSPI_lineGetDevCaps Storing Device Type %d, available %d, PPPMTU %d\n"),
pLineDev->wDeviceType,
pLineDev->wDeviceAvail,
pLineDev->dwPPPMTU));
lpLineDevCaps->dwDevSpecificSize = sizeof(UNIMODEM_INFO);
lpLineDevCaps->dwDevSpecificOffset = lpLineDevCaps->dwUsedSize;
lpLineDevCaps->dwUsedSize += sizeof(UNIMODEM_INFO);
cbAvailMem -= sizeof(UNIMODEM_INFO);
}
else
{
lpLineDevCaps->dwDevSpecificSize = 0;
lpLineDevCaps->dwDevSpecificOffset = 0;
lpLineDevCaps->dwNeededSize += sizeof(WORD);
}
// If the provider info fits, then also append the line name
if (cbAvailMem >= cbLineNameLen)
{
wcscpy((LPWSTR)((LPSTR)lpLineDevCaps + lpLineDevCaps->dwUsedSize),
pLineDev->szFriendlyName);
lpLineDevCaps->dwLineNameSize = cbLineNameLen;
lpLineDevCaps->dwLineNameOffset = lpLineDevCaps->dwUsedSize;
lpLineDevCaps->dwUsedSize += cbLineNameLen;
cbAvailMem -= cbLineNameLen;
}
else
{
lpLineDevCaps->dwLineNameSize = 0;
lpLineDevCaps->dwLineNameOffset = 0;
}
if (cbAvailMem >= cbProviderNameLen)
{
wcscpy((LPWSTR)((LPSTR)lpLineDevCaps + lpLineDevCaps->dwUsedSize), szProviderName);
lpLineDevCaps->dwProviderInfoSize = cbProviderNameLen;
lpLineDevCaps->dwProviderInfoOffset = lpLineDevCaps->dwUsedSize;
lpLineDevCaps->dwUsedSize += cbProviderNameLen;
cbAvailMem -= cbProviderNameLen;
}
else
{
lpLineDevCaps->dwProviderInfoSize = 0;
lpLineDevCaps->dwProviderInfoOffset = 0;
}
// TODO - We don't have permanent ID's yet.
lpLineDevCaps->dwPermanentLineID = 0;
lpLineDevCaps->dwStringFormat = STRINGFORMAT_UNICODE;
lpLineDevCaps->dwAddressModes = LINEADDRESSMODE_ADDRESSID;
lpLineDevCaps->dwNumAddresses = 1;
// Bearer mode & information
lpLineDevCaps->dwMaxRate = pLineDev->dwMaxDCERate;
lpLineDevCaps->dwBearerModes = pLineDev->dwBearerModes;
// Media mode
lpLineDevCaps->dwMediaModes = pLineDev->dwMediaModes;
// We can simulate wait-for-bong if the modem isn't capable of
// supporting it.
lpLineDevCaps->dwDevCapFlags = pLineDev->dwDevCapFlags |
LINEDEVCAPFLAGS_DIALBILLING |
LINEDEVCAPFLAGS_CLOSEDROP;
lpLineDevCaps->dwRingModes = 1;
lpLineDevCaps->dwMaxNumActiveCalls = 1;
// Line device state to be notified
lpLineDevCaps->dwLineStates = LINEDEVSTATE_CONNECTED |
LINEDEVSTATE_DISCONNECTED |
LINEDEVSTATE_OPEN |
LINEDEVSTATE_CLOSE |
LINEDEVSTATE_INSERVICE |
LINEDEVSTATE_OUTOFSERVICE |
LINEDEVSTATE_REMOVED |
LINEDEVSTATE_RINGING |
LINEDEVSTATE_REINIT;
lpLineDevCaps->dwLineFeatures = LINEFEATURE_MAKECALL;
//
// Don't go beyond older version app's buffer
//
if (lpLineDevCaps->dwTotalSize >= sizeof(LINEDEVCAPS)) {
lpLineDevCaps->dwSettableDevStatus = 0;
// Copy device classes if it fits
if (cbAvailMem >= cbDevClassLen) {
memcpy((LPBYTE)lpLineDevCaps + lpLineDevCaps->dwUsedSize, g_szzClassList, cbDevClassLen);
lpLineDevCaps->dwDeviceClassesSize = cbDevClassLen;
lpLineDevCaps->dwDeviceClassesOffset= lpLineDevCaps->dwUsedSize;
lpLineDevCaps->dwUsedSize += cbDevClassLen;
cbAvailMem -= cbDevClassLen;
} else {
lpLineDevCaps->dwDeviceClassesSize = 0;
lpLineDevCaps->dwDeviceClassesOffset = 0;
}
lpLineDevCaps->dwAddressTypes = LINEADDRESSTYPE_PHONENUMBER;
lpLineDevCaps->dwAvailableTracking = 0;
}
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetDevCaps x%X\n"), dwRet));
return dwRet;
}
//
// WINCE NOTE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -