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

📄 awmodem.pas

📁 测试用例
💻 PAS
📖 第 1 页 / 共 5 页
字号:
        TentativeLineIdx := 0;

        { establish a timeout for baud rate }
        Code := Port.AddTimerTrigger;
        if (Code < ecOK) then begin
          {Port.aGotError(Code);}
          ConnectSpeed := 0;
          ModemState   := msNone;
          TimeoutIdx   := 0;
          DispatchToModemClientsNoParm(apw_ConnectFailed);
        end else begin
          TimeoutIdx := Code;
          Code := Port.SetTimerTrigger(TimeoutIdx, BaudWait, True);
          if (Code < ecOK) then begin
            {Port.aGotError(Code);}
            ConnectSpeed := 0;
            ModemState   := msNone;
            DispatchToModemClientsNoParm(apw_ConnectFailed);
          end else
            DispatchToModemClientsNoParm(apw_ModemConnect);
        end;
      end;
    end;

    procedure CheckModemFeaturesPrim;
      {-Cycle through all error correction tags and data compression tags
        to see if we've received one.  If so, set the appropriate modem flag
        and continue waiting for the connect response }
    var
      Code : Integer;

      function IsErrorCorrectionTag : Bool;
        {-Return TRUE if we've received an error correction tag }
      var
        I : Cardinal;

      begin
        with Modem^ do
          for I := 1 to NumErrors do
            if (ErrorTags[I].TriggerIdx = TrigIdx) then begin
              IsErrorCorrectionTag := True;
              Exit;
            end;
        IsErrorCorrectionTag := False;
      end;

      function IsDataCompressionTag : Bool;
        {-Return TRUE if we've received a data compression tag }
      var
        I : Cardinal;

      begin
        with Modem^ do
          for I := 1 to NumComps do
            if (CompressTags[I].TriggerIdx = TrigIdx) then begin
              IsDataCompressionTag := True;
              Exit;
            end;
        IsDataCompressionTag := False;
      end;

    begin
      if IsErrorCorrectionTag then begin
        {$IFDEF DispatchDebug}
        DebugOut('Got an error correction tag');
        {$ENDIF}

        Code := DisableErrorCorrectionTags(Modem);
        if (Code < ecOK) then begin
          {Modem^.Port.aGotError( Code);}
          Exit;
        end;
        DispatchToModemClientsNoParm(apw_GotErrCorrection);
        Modem^.ErrorCorrection := True;
      end else if IsDataCompressionTag then begin
        {$IFDEF DispatchDebug}
        DebugOut('Got a data compression tag');
        {$ENDIF}

        DisableDataCompressionTags(Modem);
        DispatchToModemClientsNoParm(apw_GotDataCompression);
        Modem^.DataCompression := True;
      end;
    end;

    procedure CheckModemFeatures;
    begin
      with Modem^ do
        case Msg of
          apw_TriggerData:
            begin
              CheckModemFeaturesPrim;
              if ErrorCorrection and DataCompression then begin
                {$IFDEF DispatchDebug}
                DebugOut('All modem features received');
                {$ENDIF}
                Port.RemoveTrigger(TimeoutIdx);
                ModemState   := msNone;
                DispatchToModemClientsNoParm(apw_ModemIsConnected)
              end; { if }
            end; { apw_TriggerData }

          apw_TriggerTimer:
            if (TrigIdx = TimeoutIdx) then begin
              {$IFDEF DispatchDebug}
              DebugOut('Giving up waiting for features');
              {$ENDIF}

              DisableFeatureTags(Modem);
              Port.RemoveTrigger(TimeoutIdx);
              ModemState   := msNone;
              DispatchToModemClientsNoParm(apw_ModemIsConnected);
            end; { apw_TriggerTimer }
        end; { case }
    end;

    procedure HandleConnectionAttemptResponse;
      {-The modem is attempting to connect, be it via an answer or
        a dial.  This routine processes the responses that can
        be returned during a connect attempt }
    var
      ResponseCode : Integer;
      Code         : Integer;
      WasDialing   : Bool;

    begin
      with Modem^ do
        case Msg of
          apw_TriggerTimer:
            if (TrigIdx = TimeoutIdx) then begin

              { decrement the countdown value.  If it's zero, then    }
              { the dial attempt has failed, otherwise, notify our    }
              { clients that they should update their status displays }

              Dec(CountDown);
              if (CountDown = 0) then begin
                WasDialing := (ModemState = msDialing);
                AbortConnectAttempt(True);
                if WasDialing then
                  DispatchToModemClientsNoParm(apw_DialTimeout)
                else
                  DispatchToModemClientsNoParm(apw_AnswerTimeout);
              end else begin
                { reset the timer trigger }
                Code := Port.SetTimerTrigger(TimeoutIdx, TickSeconds, True);
                if (Code < ecOK) then begin
                  AbortConnectAttempt(True);
                  Exit;
                end;

                if (ModemState = msDialing) then
                  DispatchToModemClients(apw_DialCount, CountDown, 0)
                else
                  DispatchToModemClients(apw_AnswerCount, CountDown, 0);
              end; { else }
            end; { apw_TriggerTimer }

          apw_TriggerData:
            begin

              { we've received some kind of a message from the }
              { modem.  find out which and act accordingly     }

              ResponseCode := FindResponseCode;
              if (ResponseCode <> 0) then

                { we've received a response, not an error correction }
                { or data compression tag.                           }

                case ResponseCode of
                  RspConnect: EstablishConnection;

                  RspBusy:
                    begin
                      { the modem we're trying to call is busy.      }
                      { abort the connect attempt and notify clients }
                      AbortConnectAttempt(True);
                      DispatchToModemClientsNoParm(apw_ModemBusy);
                    end; { RspBusy }

                  RspVoice:
                    begin
                      AbortConnectAttempt(False);
                      DispatchToModemClientsNoParm(apw_ModemVoice);
                    end; { RspVoice }

                  RspNoCarrier:
                    begin
                      AbortConnectAttempt(False);
                      DispatchToModemClientsNoParm(apw_ModemNoCarrier);
                    end; { RspNoCarrier }

                  RspNoDialTone:
                    begin
                      AbortConnectAttempt(False);
                      DispatchToModemClientsNoParm(apw_ModemNoDialTone);
                    end; { RspNoDialTone }

                  RspError:
                    begin
                      AbortConnectAttempt(False);
                      DispatchToModemClientsNoParm(apw_ModemError);
                    end; { RspError }
                end { case ResponseCode }
              else
                CheckModemFeaturesPrim;
            end; { apw_TriggerData }
        end; { case Msg }
    end; { procedure }

    function ModemGetChar(var Ch : Char) : Integer;
      {-Get a character from the modem }
    begin
      with Modem^ do begin
        ModemGetChar := Port.GetChar(Ch);

        if (ModemState <> msNone) then
          if (Ch = #10) or (Ch = #13) then
            BlankPending := True
          else begin
            if BlankPending then begin
              FillChar(LastString, SizeOf(LastString), 0);
              LastStringLen := 0;
              BlankPending := False;                                
            end;
            if (LastStringLen < Pred(SizeOf(LastString))) then begin
              LastString[LastStringLen] := Ch;
              Inc(LastStringLen);
            end;
          end;
        {$IFDEF DispatchDebug}
        DebugOut('Got char from modem: ' + Ch);
        {$ENDIF}

        Inc(OnChar);
      end;
    end;

    procedure ShutDownSpeedWait;
      {-Stop waiting for speed indicators from the modem }
    {var
      Code : Integer;}

    begin
      with Modem^ do begin
        {$IFDEF DispatchDebug}
        DebugOut('Shutting down DTE rate wait');
        {$ENDIF}
        Port.RemoveTrigger(TimeoutIdx);
        ModemState := msNone;
      end;
    end;

    procedure UpdateLineSpeed;
      {-Change the line speed, if required, to the received baud rate }
    {var
      Code : Integer;}

    begin
      with Modem^ do
        if not LockDTE then begin
          {$IFDEF DispatchDebug}
          DebugOut('Updating line speed');
          {$ENDIF}
          Port.SetLine(ConnectSpeed, DontChangeParity,
                           DontChangeDataBits, DontChangeStopBits);
        end;
    end;

    procedure EnterFeatureWait;
      {-Enter the msWaitFeatures state }
    var
      Code : Integer;

    begin
      with Modem^ do begin
        {$IFDEF DispatchDebug}
        DebugOut('Enabling feature wait');
        {$ENDIF}
        ModemState := msNone;

        Code := Port.AddTimerTrigger;
        if (Code < ecOK) then begin
          DispatchToModemClientsNoParm(apw_ConnectFailed);
          Exit;
        end;

        TimeoutIdx := Code;

        Code := Port.SetTimerTrigger(TimeoutIdx, FeatureWait, True);
        if (Code < ecOK) then begin
          Port.RemoveTrigger(TimeoutIdx);
          DispatchToModemClientsNoParm(apw_ConnectFailed);
          Exit;
        end;

        ModemState := msWaitFeatures;
      end;
    end;

    procedure GetLineSpeedStart;
      {-Get the beginning of the line speed from the modem }
    var
      Ch       : Char;
      IsNumber : Bool;
      Code     : Integer;

    begin
      with Modem^ do
        case Msg of
          apw_TriggerTimer:
            if (TrigIdx = TimeoutIdx) then begin
              { we haven't received a baud rate, assume 300 baud }
              ShutdownSpeedWait;
              ConnectSpeed := 300;
              UpdateLineSpeed;

              DispatchToModemClients(apw_GotLineSpeed, 0, ConnectSpeed);

              { wait half a second for any feature tags that may yet come in }
              EnterFeatureWait;
            end; { if }

          apw_TriggerData:
            { if we haven't received all feature tags yet, check for them }
            if not (ErrorCorrection and DataCompression) then
              CheckModemFeaturesPrim;

          apw_TriggerAvail:
            begin
              repeat
                { try to find the beginning of the baud rate }
                Code := ModemGetChar(Ch);
                if (Code < ecOK) then begin
                  ShutDownSpeedWait;
                  {Port.aGotError(Code);}
                  DispatchToModemClientsNoParm(apw_ConnectFailed);
                  Exit;
                end; { if }

                {$IFDEF DispatchDebug}
                DebugOut('Waiting for #, got ' + Ch);
                {$ENDIF}

                IsNumber := (Ch >= '0') and (Ch <= '9');
              until (OnChar > NumChars) or IsNumber;

              if IsNumber then begin
                TentativeLineIdx      := 1;
                TentativeLineSpeed[0] := Ch;

                ModemState := msWaitTerm;
              end else
                Exit;

              ModemState := msWaitTerm;
            end; { apw_TriggerAvail }
        end; { case }
    end; { procedure }

    procedure GetLineSpeedEnd;
      {-Get the rest of the line speed from the modem }
    var
      Code     : Integer;
      Ch       : Char;
      IsNumber : Bool;

    begin
      with Modem^ do
        case Msg of
          apw_TriggerTimer:
            if (TrigIdx = TimeoutIdx) then begin
              { we haven't received a baud rate, assume 300 baud }
              ShutdownSpeedWait;
              ConnectSpeed := 300;
              UpdateLineSpeed;

              { wait half a second for any feature tags that may yet come in }
              EnterFeatureWait;
            end; { if }

          apw_TriggerData:
            { if we haven't received all feature tags yet, check for them }
            if not (ErrorCorrection and DataCompression) then
              CheckModemFeaturesPrim;

          apw_TriggerAvail:
            begin
              repeat
                Code := ModemGetChar(Ch);
                if (Code < ecOK) then begin
                  ShutdownSpeedWait;
                  {Port.aGotError(Code);}
                  DispatchToModemClientsNoParm(apw_ConnectFailed);
                  Exit;
                end;

                {$IFDEF DispatchDebug}
                DebugOut('Waiting for terminator, got ' + Ch);
                {$ENDIF}

                TentativeLineSpeed[TentativeLineIdx] := Ch;
                Inc(TentativeLineIdx);

                if (TentativeLineIdx < TentBaudLen) then
                  IsNumber := (Ch >= '0') and (Ch <= '9')
                else
                  IsNumber := True;
              until (OnChar > NumChars) or not IsNumber;

              { if the last character was not a number, then we got the rate }
              if not IsNumber then begin
                TentativeLineSpeed[TentativeLineIdx-1] := #0;

                {$IFDEF DispatchDebug}
                DebugOutTagSt('Got line speed: ', TentativeLineSpeed);
                {$ENDIF}

                { can't fail except for memory overwrite }
                Str2LongZ(TentativeLineSpeed, ConnectSpeed);

⌨️ 快捷键说明

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