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 + -
显示快捷键?