modem.c

来自「wince下的源代码集合打包」· C语言 代码 · 共 1,340 行 · 第 1/3 页

C
1,340
字号
    DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-ProcessModemFailure %d\n"), rc));    return rc;}   // ProcessModemFailureBOOLGetMonitorCommand(    PTLINEDEV pLineDev    ){    LPWSTR lpszTemp;    DWORD dwSize;    //    // For manual dial modems, don't listen for incoming calls    //    if (pLineDev->DevMiniCfg.fwOptions & MANUAL_DIAL) {        FreeNextCmd(pLineDev);        return TRUE;    }    if (MdmRegGetValue(            pLineDev,            szSettings,            szMonitor,            REG_SZ,            NULL,            &dwSize) == ERROR_SUCCESS) {        lpszTemp = TSPIAlloc(dwSize);        if (!lpszTemp) {            DEBUGMSG(ZONE_THREAD, (TEXT("UNIMODEM:GetMonitorCommand - Monitor cmd alloc failed 1\n")));            goto gmc_DefaultMonitorCmd;        }        if (MdmRegGetValue(                pLineDev,                szSettings,                szMonitor,                REG_SZ,                (PUCHAR)lpszTemp,                &dwSize) == ERROR_SUCCESS) {                pLineDev->lpstrNextCmd = MdmConvertCommand(lpszTemp, NULL, NULL);            TSPIFree(lpszTemp);        } else {            goto gmc_DefaultMonitorCmd;        }    } else {gmc_DefaultMonitorCmd:        pLineDev->lpstrNextCmd = TSPIAlloc(strlen(szDefaultMonitorCmd)+1);        if (!pLineDev->lpstrNextCmd) {            DEBUGMSG(ZONE_THREAD, (TEXT("UNIMODEM:GetMonitorCommand - Monitor cmd alloc failed 2\n")));            return FALSE;        }        strcpy(pLineDev->lpstrNextCmd, szDefaultMonitorCmd);    }    return TRUE;}BOOLDoModemInit(    PTLINEDEV pLineDev    ){    DCB commDCB;    BOOL bRet;    //    // Turn off hardware flow control while sending commands.    //    GetCommState( pLineDev->hDevice, &commDCB );    commDCB.fRtsControl = RTS_CONTROL_ENABLE;    commDCB.fOutxCtsFlow = 0;    SetCommState( pLineDev->hDevice, &commDCB );    bRet = ModemInit(pLineDev);    //    // Restore original settings    //    SetDCBfromDevMiniCfg(&commDCB, &(pLineDev->DevMiniCfg));    SetCommState( pLineDev->hDevice, &commDCB );    return bRet;}//// Send commands and listen for responses until the line is closed//DWORDUnimodemControlThread(    PTLINEDEV pLineDev    ){    MODEMRESPCODES MdmResp;    DWORD rc;    BOOL  bPendingOp;    HTAPICALL hPrevCall;    EnterCriticalSection(&pLineDev->OpenCS);    bPendingOp = !((PENDING_LISTEN == pLineDev->dwPendingType) || (INVALID_PENDINGOP == pLineDev->dwPendingType));    DEBUGMSG(ZONE_FUNC|ZONE_THREAD, (TEXT("+UnimodemControlThread(%d)\n"), pLineDev->dwDeviceID));    if (bPendingOp) {        DEBUGMSG(ZONE_THREAD, (L"UnimodemControlThread(%d) PendingOp=%s\n",            pLineDev->dwDeviceID, GetPendingName(pLineDev->dwPendingType)));    }    if (pLineDev->dwPendingType == PENDING_LINEMAKECALL) {        hPrevCall = pLineDev->htCall;    }    rc = DevlineOpen(pLineDev);    if ((rc) && (rc != LINEERR_ALLOCATED)) {        DEBUGMSG(ZONE_THREAD, (TEXT("UnimodemControlThread(%d) DevlineOpen failed\n"), pLineDev->dwDeviceID));        goto uct_endCS;    }    FreeNextCmd(pLineDev);    if (IS_NULL_MODEM(pLineDev)) {        SetCommMask(pLineDev->hDevice, EV_DEFAULT);    } else {        //        // Don't init a manual dial modem        //        if (pLineDev->DevMiniCfg.fwOptions & MANUAL_DIAL) {            SetCommMask(pLineDev->hDevice, EV_DEFAULT);        } else {            //            // If modeminit fails, we sure won't be able to anything!            //            if (!DoModemInit(pLineDev)) {                pLineDev->DevState = DEVST_DISCONNECTED;                DEBUGMSG(ZONE_THREAD, (TEXT("UnimodemControlThread(%d) ModemInit failed\n"), pLineDev->dwDeviceID));                goto uct_endCS;            }        }    }    LeaveCriticalSection(&pLineDev->OpenCS);        if (pLineDev->dwPendingType == PENDING_LINEMAKECALL) {        pLineDev->DevState = DEVST_PORTCONNECTDIAL;        ProcessModemFailure(pLineDev);    } else {        pLineDev->DevState = DEVST_PORTLISTENING;        if (!IS_NULL_MODEM(pLineDev)) {            //            // Not making a call so monitor the line for incoming calls.            //            if (!GetMonitorCommand(pLineDev)) {                goto uct_end;            }        }    }    bPendingOp = FALSE;    MdmResp = MODEM_FAILURE;uct_monitor:        //    // Monitor modem responses    //    while (pLineDev->DevState != DEVST_DISCONNECTED) {        if ((pLineDev->DevState == DEVST_PORTLISTENING) || (pLineDev->DevState == DEVST_PORTLISTENOFFER)) {            if (pLineDev->lpstrNextCmd) {                if (!MdmSendCommand(pLineDev, pLineDev->lpstrNextCmd)) {                    goto uct_end;                }            }            EnterCriticalSection(&pLineDev->OpenCS);            //            // If the user did an open/close in quick succession then check for it.            //            switch (pLineDev->dwPendingType) {            case PENDING_EXIT:                MdmResp = MODEM_EXIT;                goto uct_endCS;                break;            case PENDING_LINEMAKECALL:                pLineDev->DevState = DEVST_PORTCONNECTDIAL;                MdmResp = MODEM_FAILURE;                LeaveCriticalSection(&pLineDev->OpenCS);                goto uct_process;                break;            }            if (pLineDev->lpstrNextCmd) {                if (IS_NULL_MODEM(pLineDev)) {                    //                    // We only get here if we just responded with "CLIENTSERVER" to someone's "CLIENT",                    // so no further responses are needed. The connection is established.                    //                    MdmResp = MODEM_CONNECT;                    SetEvent(pLineDev->hCallComplete);                    LeaveCriticalSection(&pLineDev->OpenCS);                } else {                    //                    // Some modems don't respond to the monitor command until an incoming call is made,                    // but some modems do respond to the monitor command so we wait for a MODEM_RING response.                    //                    if ((MdmResp = MdmGetResponse(pLineDev, pLineDev->lpstrNextCmd, LEAVECS)) == MODEM_SUCCESS) {                        if (pLineDev->dwPendingType == PENDING_LISTEN) {                            MdmResp = MdmGetResponse(pLineDev, pLineDev->lpstrNextCmd, NOCS);                        }                    }                }            } else {                PurgeComm(pLineDev->hDevice, PURGE_RXCLEAR|PURGE_TXCLEAR);                //                // DCC server has no specific monitor command.                // Also for manual dial, this thread needs to be in a WaitCommEvent                //                MdmResp = MdmGetResponse(pLineDev, "listening", LEAVECS);            }        }uct_process:        FreeNextCmd(pLineDev);        switch (MdmResp) {        case MODEM_RING:            DEBUGMSG(ZONE_THREAD, (TEXT("UnimodemControlThread(%d) MODEM_RING\n"), pLineDev->dwDeviceID));            ProcessModemRing(pLineDev);            break;        case MODEM_CARRIER:        case MODEM_PROTOCOL:        case MODEM_PROGRESS:            DEBUGMSG(ZONE_THREAD, (TEXT("UnimodemControlThread(%d) LINECALLSTATE_PROCEEDING\n"), pLineDev->dwDeviceID));            ProcessModemProceeding(pLineDev);            break;        case MODEM_CONNECT:            DEBUGMSG(ZONE_THREAD, (TEXT("UnimodemControlThread(%d) LINECALLSTATE_CONNECTED\n"), pLineDev->dwDeviceID));            ProcessModemConnect(pLineDev);            break;        case MODEM_SUCCESS:            DEBUGMSG(ZONE_THREAD, (TEXT("UnimodemControlThread(%d) MODEM_SUCCESS\n"), pLineDev->dwDeviceID));            ProcessModemSuccess(pLineDev);            break;                case MODEM_FAILURE:            DEBUGMSG(ZONE_THREAD, (TEXT("UnimodemControlThread(%d) MODEM_FAILURE\n"), pLineDev->dwDeviceID));            if (ProcessModemFailure(pLineDev)) {                goto uct_end;            }            break;        case MODEM_EXIT:            DEBUGMSG(ZONE_THREAD, (TEXT("UnimodemControlThread(%d) MODEM_EXIT\n"), pLineDev->dwDeviceID));            goto uct_end;            break;        }   // switch        MdmResp = MODEM_FAILURE;    }   // whileuct_end:    //    // Go back to monitoring for incoming calls if needed    //    if (pLineDev->dwDetMediaModes) {        //        // Make sure the handle is still valid.        //        if (SetCommMask(pLineDev->hDevice, EV_DEFAULT)) {            pLineDev->DevState = DEVST_PORTLISTENING;            if (IS_NULL_MODEM(pLineDev)) {                DEBUGMSG(ZONE_THREAD, (TEXT("UnimodemControlThread(%d) Continue monitoring\n"), pLineDev->dwDeviceID));                goto uct_monitor;            }            if (GetMonitorCommand(pLineDev)) {                pLineDev->dwNumRings = 0;                EnterCriticalSection(&pLineDev->OpenCS);                if (pLineDev->dwPendingStatus == LINEERR_ALLOCATED) {                    SetAsyncStatus(pLineDev, LINEERR_OPERATIONFAILED);                }                LeaveCriticalSection(&pLineDev->OpenCS);                DEBUGMSG(ZONE_THREAD, (TEXT("UnimodemControlThread(%d) Continue monitoring\n"), pLineDev->dwDeviceID));                goto uct_monitor;            }        }    }    EnterCriticalSection(&pLineDev->OpenCS);    //    // Special case for PASSTHROUGH connections    //    if (pLineDev->fTakeoverMode) {        pLineDev->bControlThreadRunning = FALSE;        LeaveCriticalSection(&pLineDev->OpenCS);        DEBUGMSG(ZONE_THREAD|ZONE_FUNC, (TEXT("-UnimodemControlThread(%d) - PASSTHROUGH\n"), pLineDev->dwDeviceID));        return 0;    }uct_endCS:    FreeNextCmd(pLineDev);    // Make sure that we do not leave anything open    SetWatchdog(pLineDev, 0 ); // Cancel watchdog    DevlineClose(pLineDev, TRUE);    pLineDev->bControlThreadRunning = FALSE;    LeaveCriticalSection(&pLineDev->OpenCS);    if (bPendingOp) {        if (pLineDev->dwPendingType == PENDING_LINEMAKECALL) {            pLineDev->htCall = hPrevCall;            NewCallState(pLineDev, LINECALLSTATE_DISCONNECTED, 0L);            pLineDev->htCall = NULL;        }        SetAsyncStatus(pLineDev, LINEERR_OPERATIONFAILED);    }    DEBUGMSG(ZONE_THREAD|ZONE_FUNC, (TEXT("-UnimodemControlThread(%d)\n"), pLineDev->dwDeviceID));    return 0;}   // UnimodemControlThreadLONGStartControlThread(    PTLINEDEV pLineDev    ){    HANDLE hThd;    LONG rc;    DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+StartControlThread\n")));    rc = 0;    if (pLineDev->bControlThreadRunning == FALSE) {        pLineDev->bControlThreadRunning = TRUE;        hThd = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)UnimodemControlThread,                             pLineDev, 0, NULL );        if (!hThd) {            NKDbgPrintfW( TEXT("Unable to Create UnimodemControlThread\n") );            pLineDev->bControlThreadRunning = FALSE;            rc = LINEERR_OPERATIONFAILED;        } else {            CeSetThreadPriority(hThd, g_dwUnimodemThreadPriority);            CloseHandle(hThd);        }    }    DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-StartControlThread returning %x\n"), rc));    return rc;}   // StartControlThreadLONGSignalControlThread(    PTLINEDEV pLineDev    ){    LONG rc;    DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+SignalControlThread\n")));    //    // Signal UnimodemListenThread    //    rc = ToggleCommMask(pLineDev);    DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-SignalControlThread returning %x\n"), rc));    return rc;}   // SignalControlThread//// All TSPI_line* functions that need access to the modem go through here.// The UnimodemControlThread sends the actual commands and processes the// responses//LONGControlThreadCmd(    PTLINEDEV pLineDev,    DWORD dwPendingOP,    DWORD dwPendingID    ){    LONG rc;    DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+ControlThreadCmd\n")));    // Fail current outstanding async request (if any) and remember this one    SetAsyncOp(pLineDev, dwPendingOP);    EnterCriticalSection(&pLineDev->OpenCS);    if (pLineDev->bControlThreadRunning) {        switch (dwPendingOP) {        case PENDING_LINEDROP:        case PENDING_EXIT:        case PENDING_LINEANSWER:        case PENDING_LINEDIAL:        case PENDING_LINEMAKECALL:        case PENDING_LISTEN:            rc = SignalControlThread(pLineDev);            break;        default:            rc = 0;            break;        }    } else {        switch (dwPendingOP) {        case PENDING_LINEMAKECALL:        case PENDING_LISTEN:            rc = StartControlThread(pLineDev);            break;        case PENDING_EXIT:        default:            rc = LINEERR_OPERATIONFAILED;            break;        }    }    if (rc == 0) {        switch (dwPendingOP) {        case PENDING_LINEANSWER:        case PENDING_LINEDIAL:        case PENDING_LINEDROP:        case PENDING_LINEMAKECALL:            rc = dwPendingID;            break;        }    }    LeaveCriticalSection(&pLineDev->OpenCS);    DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-ControlThreadCmd returning %x\n"), rc));    return rc;}   // ControlThreadCmd

⌨️ 快捷键说明

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