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

📄 adsmodem.pas

📁 测试用例
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  FInterCmdDelay := adsmDefInterCmdDelay;
  FTildeDelay := adsmDefTildeDelay;

  FExtendTime := adsmDefExtendTime;
  FRetryWaitTime := adsmDefRetryWaitTime;
  FUpdateStatusTime := adsmDefUpdateStatusTime;

  FAutoRetryDial := adsmDefAutoRetryDial;
  FForceHangup := adsmDefForceHangup;
  FMaxDialAttempts := adsmDefMaxDialAttempts;
  FShowStatus := adsmDefShowStatus;
end;

procedure TApdCustomSModem.RefreshModemStatus;
  {Refresh the modem status dialog and call the user event (if hooked)}
var
  TimeRemaining : Longint;

begin
  {Update the modem info class}
  with FStatusInfo, FComPort do begin
    if FModemState = smsUnknown then
      Exit;
    msiModemState := FModemState;
    case FModemState of
      smsDialWait :
        begin
          Dispatcher.TimerTicksRemaining(msTimeoutTrigger, TimeRemaining);
          SetInfoDialWait(FPhoneNumber, FDialAttempt, FMaxDialAttempts,
                          Ticks2Secs(TimeRemaining));
        end;
      smsDialCycle :
        begin
          Dispatcher.TimerTicksRemaining(msTimeoutTrigger, TimeRemaining);
          SetInfoDialCycle(FPhoneNumber, FDialAttempt+1, FMaxDialAttempts,{!!.01}
                           Ticks2Secs(TimeRemaining));
        end;
      smsAnswerWait :
        begin
          Dispatcher.TimerTicksRemaining(msTimeoutTrigger, TimeRemaining);
          SetInfoAnswerWait(Ticks2Secs(TimeRemaining));
        end;
      smsAutoAnswerWait :
        begin
          SetInfoAutoAnswerWait(FAnswerOnRing, msRingReceiveCount);
        end;
    end;

    {Show/Hide the status display if appropriate}
    if FShowStatus and
      Assigned(FStatusDisplay) then begin
      case FModemState of
        smsReady, smsAutoAnswerBackground, smsConnected:
          if msStatusVisible and
             ((FModemStateFlags and smsBatchInProgress) = 0) then begin
            msStatusVisible := False;
            FStatusDisplay.Hide;
          end;
      else
        begin
          if not msStatusVisible then begin
            msStatusVisible := True;
            FStatusDisplay.Show;
            FStatusDisplay.Repaint;
          end;
          FStatusDisplay.UpdateDisplay(FStatusInfo);
        end;
      end;
    end;

    {Call the user's status hook}
    if Assigned(FConnectionStatus) then
      FConnectionStatus(Self, FStatusInfo);
  end;
end;

procedure TApdCustomSModem.SetModemState(ModemState : TApdSModemStates);
  {Update the modem state variable and call any procedures hooked on status}
begin
  if ModemState <> FModemState then begin
    FModemState := ModemState;

    if (FModemState = smsReady) or
       (FModemState = smsUnknown) then
      {Disable status trigger}
      FComPort.Dispatcher.SetTimerTrigger(msUpdateStatusTrigger,
                       Secs2Ticks(FUpdateStatusTime), False)
    else
      {Enable status trigger}
      FComPort.Dispatcher.SetTimerTrigger(msUpdateStatusTrigger,
                       Secs2Ticks(FUpdateStatusTime), True);

    if (FModemState = smsDialWait) or
       (FModemState = smsDialCycle) and
       (not FStatusDisplay.msButtonCycle.Enabled) then begin
      FStatusDisplay.msButtonCycle.Enabled := True;
      FStatusDisplay.Repaint;
    end else if (FStatusDisplay.msButtonCycle.Enabled) then begin
      FStatusDisplay.msButtonCycle.Enabled := False;
      FStatusDisplay.Repaint;
    end;

    if (FModemState <> smsUnknown) then
      RefreshModemStatus;
  end;
end;

function TApdCustomSModem.msResponseMatches(StringToMatch : String) : Boolean;
  {Check if the latest modem response contains string to match}
begin
  if (pos(StringToMatch, msModemResponse) > 0) then begin
    Result := True;
    FStatusInfo.AddSendRecvData('[recv] ' + StringToMatch);
  end else
    Result := False;
end;

function TApdCustomSModem.msResponseIsBusy : Boolean;
  {Check if the latest modem response contains BusyMsg}
begin
  Result := msResponseMatches(FBusyMsg);
end;

procedure TApdCustomSModem.msCheckForResponseTags;
  {Check if the connect responses contain ErrorCompression, DataCompression
   or ConnectSpeed tags}
var
  S,
  TempStr,
  ErrorCorrection,
  DataCompression : String;
  CommaPos : Integer;
begin
    S := FErrorCorrectionMsg + ',';
    while Length(S) > 0 do begin
      CommaPos := Pos(',', S);
      if CommaPos = 0 then CommaPos := Length(S);
      TempStr := Copy(S, 1, CommaPos-1);
      if Pos(TempStr, S) > 0 then begin
        If Length(ErrorCorrection) > 0 then ErrorCorrection := ErrorCorrection + ',';
        ErrorCorrection := ErrorCorrection + TempStr;
      end;
       S := Copy(S, CommaPos + 1, Length(S));
    end;

    S := FDataCompressionMsg + ',';
    while Length(S) > 0 do begin
      CommaPos := Pos(',', S);
      if CommaPos = 0 then CommaPos := Length(S);
      TempStr := Copy(S, 1, CommaPos-1);
      if Pos(TempStr, S) > 0 then begin
        If Length(DataCompression) > 0 then DataCompression := DataCompression + ',';
        DataCompression := DataCompression + TempStr;
      end;
       S := Copy(S, CommaPos + 1, Length(S));
    end;

    if Length(msModemResponse) > Length(FConnectMsg) then begin
      TempStr := Copy(msModemResponse, Length(FConnectMsg) + 1, Length(msModemResponse));
      S := msModemResponse;
      FConnectSpeed := StrToIntDef(msModemResponse, 0);
    end;
    FStatusInfo.SetInfoConnected(ErrorCorrection, DataCompression, FConnectSpeed);
end;

function TApdCustomSModem.msResponseIsConnect : Boolean;
  {Check if the latest modem response contains ConnectMsg}
begin
  Result := msResponseMatches(FConnectMsg);
  if Result then begin
    {check for error correction, data compression tags in connect responses}
    msCheckForResponseTags;                                        
  end;
end;

function TApdCustomSModem.msResponseIsError : Boolean;
  {Check if the latest modem response contains ErrorMsg}
begin
  Result := msResponseMatches(FErrorMsg);
end;

function TApdCustomSModem.msResponseIsNoCarrier : Boolean;
  {Check if the latest modem response contains NoCarrierMsg}
begin
  Result := msResponseMatches(FNoCarrierMsg);
end;

function TApdCustomSModem.msResponseIsNoDialTone : Boolean;
  {Check if the latest modem response contains NoDialToneMsg}
begin
  Result := msResponseMatches(FNoDialToneMsg);
end;

function TApdCustomSModem.msResponseIsOk : Boolean;
  {Check if the latest modem response contains OkMsg}
begin
  Result := msResponseMatches(FOkMsg);
end;

function TApdCustomSModem.msResponseIsRing : Boolean;
  {Check if the latest modem response contains RingMsg}
begin
  Result := msResponseMatches(FRingMsg);
end;


procedure TApdCustomSModem.msPrepareForResponse(TimeoutTicks : Cardinal);
  {Reset a response timer and initialize the response string}
begin
  msModemResponse := '';
  msCRLFIndex := 0;
  FComPort.SetTimerTrigger(msTimeoutTrigger, TimeoutTicks, True);
end;

procedure TApdCustomSModem.msPrepareForCmdResponse;
begin
  msPrepareForResponse(FCmdTimeout);
end;

procedure TApdCustomSModem.msPrepareForDialResponse;
begin
  msPrepareForResponse(Secs2Ticks(FDialTimeout));
end;

procedure TApdCustomSModem.msPrepareForAnswerResponse;
begin
  msPrepareForResponse(Secs2Ticks(FAnswerTimeout));
end;

procedure TApdCustomSModem.msPrepareForAutoAnswerResponse;
begin
  msPrepareForResponse(FRingWaitTimeout);
end;

procedure TApdCustomSModem.msPrepareForConnectInfoResponse;
begin
  msPrepareForResponse(FConnectInfoTimeout);
end;

procedure TApdCustomSModem.DisplayWaitForResult(Responses : String; Index : Cardinal);
var
  Rsp : String;
  i   : Integer;                                                     
  j   : Cardinal;

begin
  Rsp := '';
  i := 1;
  j := 1;
  while (i < Length(Responses)) and
        (j < Index) do begin
    if (Responses[i] = MultiResponseSeparator) then
      inc(j);
    inc(i);
  end;
  if (j = Index) then begin
    while (i < Length(Responses)) and
          (Responses[i] <> MultiResponseSeparator) do begin
      Rsp := Rsp + Responses[i];
      inc(i);
    end;
  end;
  FStatusInfo.AddSendRecvData('[recv] ' + Rsp);
  FStatusDisplay.UpdateDisplay(FStatusInfo);
end;

procedure TApdCustomSModem.Answer;
  {Answer the modem immediately -- not documented for general use}
begin
  if (FModemStateFlags and smsWaitForInProgress) <> 0 then
    {modem is already waiting for data; prevent reentrancy}
    raise EModemBusy.Create(ecModemBusy, False);

  {make sure modem is ready}
  VerifyStarted;

  FComPort.FlushInBuffer;
  FStatusDisplay.msEraseAllValues;

  {If already dialing, then we have an implied Cancel; if already
   connected, then we have an implied Hangup}
  FModemStateFlags := FModemStateFlags or smsBatchInProgress;
  Hangup;

  {If Initialize failed, exit}
  FModemStateFlags := FModemStateFlags and not smsBatchInProgress;
  if (FModemState <> smsReady) then
    Exit;

  {Send the answer command and let the state machine handle the response}
  msPrepareForAnswerResponse;
  PutStringModem(FAnswerCmd);
  SetModemState(smsAnswerWait);
end;

procedure TApdCustomSModem.AutoAnswer(RingCount : Byte);
  {Tell modem to auto answer on Nth ring}
begin
  if (FModemStateFlags and smsWaitForInProgress) <> 0 then
    {modem is already waiting for data; prevent reentrancy}
    raise EModemBusy.Create(ecModemBusy, False);

  {If already dialing, then we have an implied Cancel; if already
   connected, then we have an implied Hangup}
  FModemStateFlags := FModemStateFlags or smsBatchInProgress;
  Hangup;
  Initialize;

  FModemStateFlags := FModemStateFlags and not smsBatchInProgress;
  if (FModemState <> smsReady) then
    Exit;

  msPrepareForCmdResponse;
  SetModemState(smsAutoAnswerBackground);
  msRingReceiveCount := 0;
  FAnswerOnRing := RingCount;
end;

procedure TApdCustomSModem.Cancel;
  {Cancel current modem operation (e.g., dialing)}
var
  ExpectedResponses : String;

begin
  if (FModemStateFlags and smsWaitForInProgress) <> 0 then
    {modem is already waiting for data; prevent reentrancy}
    raise EModemBusy.Create(ecModemBusy, False);

  {make sure modem is ready}
  VerifyStarted;

  with FComPort do begin
    {If connected, then Cancel implies Hangup}
    If (msModemStatusTrigger <> 0) then
      Hangup
    else begin
      {Cancel any active timers}
      Dispatcher.SetTimerTrigger(msTimeoutTrigger, 0, False);

      if (FModemState = smsDialWait) or
         (FModemState = smsAnswerWait) then begin
        {Need to cancel the dial or answer in progress}
        FModemStateFlags := FModemStateFlags or smsWaitForInProgress;
        SetModemState(smsCancel);
        ExpectedResponses := OkMsg + #13+#10 + MultiResponseSeparator +
                             ErrorMsg + #13#10 + MultiResponseSeparator +
                             NoCarrierMsg + #13#10 + MultiResponseSeparator +
                             FDialCancelCmd;
        {Send the cancel command}
        {$IFDEF Win32}
        PrepareWait;
        {$ENDIF}
        PutStringModem(FDialCancelCmd);
        {Wait for a response from the modem or a timeout}
        WaitForMultiString(ExpectedResponses, CmdTimeout, FAllowYielding,
                           IgnoreCase, MultiResponseSeparator);

        FModemStateFlags := FModemStateFlags and not smsWaitForInProgress;
      end;

      FComPort.FlushInBuffer;
      SetModemState(smsReady);
    end;
  end;
end;

procedure TApdCustomSModem.Dial(AutoRetry : Boolean);
  {Attempt connection}
begin
  if (FModemStateFlags and smsWaitForInProgress) <> 0 then
    {modem is already waiting for data; prevent reentrancy}
    raise EModemBusy.Create(ecModemBusy, False);

  if (FPhoneNumber <> '') then begin
    FStatusDisplay.msEraseAllValues;

    FDialAttempt := 1;

⌨️ 快捷键说明

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