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

📄 adsmodem.pas

📁 测试用例
💻 PAS
📖 第 1 页 / 共 5 页
字号:
    property NoDialToneMsg : String
      read FNoDialToneMsg write FNoDialToneMsg;
    property OkMsg : String
      read FOkMsg write FOkMsg;
    property RingMsg : String
      read FRingMsg write FRingMsg;

    property AnswerTimeout : Cardinal
      read FAnswerTimeout write FAnswerTimeout default adsmDefAnswerTimeout;
    property CmdTimeout : Cardinal
      read FCmdTimeout write FCmdTimeout default adsmDefCmdTimeout;
    property ConnectInfoTimeout : Cardinal
      read FConnectInfoTimeout write FConnectInfoTimeout
      default adsmDefConnectInfoTimeout;
    property DialTimeout : Cardinal
      read FDialTimeout write FDialTimeout default adsmDefDialTimeout;
    property RingWaitTimeout : Cardinal
      read FRingWaitTimeout write FRingWaitTimeout
      default adsmDefRingWaitTimeout;

    property DTRDropHoldDelay : Cardinal
      read FDTRDropHoldDelay write FDTRDropHoldDelay
      default adsmDefDTRDropHoldDelay;
    property InterCharDelay : Cardinal
      read FInterCharDelay write FInterCharDelay default adsmDefInterCharDelay;
    property InterCmdDelay : Cardinal
      read FInterCmdDelay write FInterCmdDelay default adsmDefInterCmdDelay;
    property TildeDelay : Cardinal
      read FTildeDelay write FTildeDelay default adsmDefTildeDelay;

    property AutoRetryDial : Boolean
      read FAutoRetryDial write FAutoRetryDial default adsmDefAutoRetryDial;
    property ConnectSpeed : Cardinal
      read FConnectSpeed;
    property DialAttempt : Cardinal
      read FDialAttempt;
    property ExtendTime : Cardinal
      read FExtendTime write FExtendTime;
    property ForceHangup : Boolean
      read FForceHangup write FForceHangup default adsmDefForceHangup;
    property LockDTE : Boolean
      read FLockDTE write FLockDTE;
    property MaxDialAttempts : Cardinal
      read FMaxDialAttempts write FMaxDialAttempts;
    property PreferredPortSpeed : Cardinal
      read FPreferredPortSpeed write FPreferredPortSpeed;
    property RetryWaitTime : Cardinal
      read FRetryWaitTime write FRetryWaitTime;
    property ShowStatus : Boolean
      read FShowStatus write FShowStatus default adsmDefShowStatus;

    property ModemState : TApdSModemStates
      read FModemState write SetModemState;
    property ModemStateFlags : Cardinal
      read FModemStateFlags write FModemStateFlags;
    property OnConnectionStatus : TApdSModemEvent
      read FConnectionStatus write FConnectionStatus;

    procedure Answer;
      {Answer the modem immediately -- not documented}
    procedure AutoAnswer(RingCount : Byte);
      {Tell modem to auto answer on Nth ring}
    procedure Cancel;
      {Cancel current modem operation (e.g., dialing)}
    procedure Dial(AutoRetry : Boolean);
      {Attempt connection}
    procedure ExtendConnectTime(ExtraSeconds : Integer);
      {Extend the timer for the current connect attempt}
    procedure Hangup;
      {Break modem connection}
    procedure Initialize;
      {Return modem to known state}
    procedure PutStringModem(ModemString : String);
      {Send the string to the modem}
    procedure Redial;
      {Cause an immediate redial}
  end;

  TApdSModem = class(TApdCustomSModem)
  protected
    FModemIniName       : String;
    FModemName          : String;

  public
    constructor Create(AOwner : TComponent); override;
    procedure ModifyInitCommand;
    function SelectModem: Boolean;
    procedure SetAllDefaults; override;
    procedure SetModemIniName(NewIniFileName : String); virtual;
    procedure SetModemName(ModemName : String); virtual;

  published
    property ComPort;
    property ModemIniName : String
      read FModemIniName write SetModemIniName;
    property ModemName : String
      read FModemName write SetModemName;
    property PhoneNumber;
    property ShowStatus;

    property OnConnectionStatus;
  end;

  TApdSModemStatusDisplay = class(TForm)
    msGroupBox1: TGroupBox;
    msAction: TLabel;
    msActionInfo: TLabel;
    msInfo1: TLabel;
    msInfo2: TLabel;
    msInfo3: TLabel;
    msInfo4: TLabel;
    msValue1: TLabel;
    msValue2: TLabel;
    msValue3: TLabel;
    msValue4: TLabel;
    msGroupBox2: TGroupBox;
    msMessages: TMemo;
    msButtonExtend: TButton;
    msButtonCycle: TButton;
    msButtonCancel: TButton;
    procedure msButtonExtendClick(Sender: TObject);
    procedure msButtonCycleClick(Sender: TObject);
    procedure msButtonCancelClick(Sender: TObject);
    procedure msEraseAllValues;
  private
    { Private declarations }
    msdCurrentRow : Integer;                                        
  protected
    procedure UpdateDisplay(ModemStatus : TApdSModemStatusInfo);
  public
    { Public declarations }
    SModem : TApdCustomSModem;
  end;

procedure GetModemDatabaseEntries(ModemIniName : String;
            var ModemList : TStringList; AtDesignTime : Boolean);

const
  {character used to delimit responses when combined in one string}
  MultiResponseSeparator  : Char = '|';
  MultiCmdSeparator       : Char = '|';
  SModemDataPtrID         = 5;

implementation

{Status display form}
{$R *.DFM}

const
  IgnoreCase              = True;

{- TApdSModem State Machine -------------------------------}

procedure TApdCustomSModem.SimpleModemStateMachine(Msg, wParam : Cardinal;
                                 lParam : Longint);
  {- Handle data flow to and from the simple modem component}
const
  msAvailTrigger = $FFFF;   {simulate a handle for an avail trigger}

var
  TriggerID : Cardinal absolute wParam;
  Finished : Boolean;

  function CollectResponse : Boolean;
    {- Check for text responses}
  var
    c        : Char;

  begin
    {Collect characters until CR/LF}
    Finished := False;
    CollectResponse := False;
    while ComPort.CharReady and not Finished do begin
      c := ComPort.getChar;
      msModemResponse := msModemResponse + c;
      if ComPort.CheckForString(msCRLFIndex, c, #13#10, True) then begin
        msModemResponse := Trim(msModemResponse);
        if (msModemResponse <> '') then begin
          {Got a text response}
          Finished := True;
          CollectResponse := True;
          {Add completed message to connect response buffer}
          if Length(msConnectResponses) + Length(msModemResponse) < 255 then
            msConnectResponses := msConnectResponses + msModemResponse;

          {All error responses are aborts}
          if msResponseIsError then
            SetModemState(smsAbort);
        end;
      end;
    end;
  end;

begin
  {Find which modem instance we are working with}
  {Dispatcher := TApdBaseDispatcher(PortList[LH(lParam).H]);
  with Dispatcher do begin
    Dispatcher.GetDataPointer(Pointer(SModem), SModemDataPtrID);}

    with {SModem, }FComPort do begin
      {If it's a TriggerAvail message, then force the TriggerID to msAvailTrigger}
      if (Msg = APW_TRIGGERAVAIL) then
        TriggerID := msAvailTrigger;

      {Exit immediately on triggers that aren't ours}
      if (TriggerID <> msAvailTrigger) and
         (TriggerID <> msTimeoutTrigger) and
         (TriggerID <> msModemStatusTrigger) and
         (TriggerID <> msUpdateStatusTrigger) then
        Exit;

      {Exit when in connected state unless the DCD status trigger fired}
      if (FModemState = smsConnected) and
         (TriggerID <> msModemStatusTrigger) then
        Exit;

      {Process until we encounter a wait condition}
      repeat
        {Show status periodically}
        if (TriggerID = msUpdateStatusTrigger) or msForceUpdateStatus then begin
          msForceUpdateStatus := False;
          RefreshModemStatus;
          SetTimerTrigger(msUpdateStatusTrigger,
                           Secs2Ticks(FUpdateStatusTime), True);

          {If it was just our timer for a status update, we're done}
          if (TriggerID = msUpdateStatusTrigger) then
            Exit;
        end;

        {Preprocess pending modem responses while in certain states}
        case FModemState of
          smsAutoAnswerBackground,
          smsAutoAnswerWait,
          smsAnswerWait,
          smsDialWait,
          smsConnectWait :
            begin
              if (TriggerID = msAvailTrigger) and (not CollectResponse) then
                {Entire message not ready, exit until more received}
                Exit;
            end;
        end;

        {Process the current modem state}
        case FModemState of
          smsReady,
          smsUnknown :
            {Nothing to do...exit}
            Exit;

          smsAutoAnswerBackground,
          smsAutoAnswerWait :
            begin
              {If message received was RingMsg then we need to increment
               the ring received count.  If RingRecvCount = RingToAnswerOn,
               then we need to clear the RingWaitTimeout timer, send AnswerCmd,
               set a connect timer, prepare for a response, and change to
               AnswerWait state.  If not enough rings have been received, then
               we need to set a timer for RingWaitTimeout and we are done.
              }
              if (FModemState = smsAutoAnswerBackground) then begin
                {Show status when first ring is detected}
                if (TriggerID = msAvailTrigger) then
                  SetModemState(smsAutoAnswerWait);
                Exit;
              end;                                                  
              if (TriggerID = msAvailTrigger) then begin
                if msResponseIsRing then begin
                  inc(msRingReceiveCount);
                  if (msRingReceiveCount = FAnswerOnRing) then begin
                    msPrepareForAnswerResponse;
                    PutStringModem(FAnswerCmd);
                    SetModemState(smsAnswerWait);
                  end else begin
                    {Not enough rings received yet; set timer for next ring}
                    Dispatcher.SetTimerTrigger(msTimeoutTrigger,
                                     FRingWaitTimeout, True);
                  end;
                end else
                  msPrepareForAutoAnswerResponse;
              end else if (TriggerID = msTimeoutTrigger) then begin
                {Didn't receive next ring within specified time, so reset count}
                {Log the fact that we received rings but didn't answer}
                msRingReceiveCount := 0;
                {Modem state stays as AutoAnswerWait}
              end;
            end;

          smsAnswerWait :
            begin
              {We're in the process of answering and waiting for ConnectMsg
               to be received.  Other possible messages to watch for include
               NoCarrier.
              }
              if (TriggerID = msAvailTrigger) then begin
                if msResponseIsConnect then begin
                  {Set a timer to watch for optional data (e.g., data comp.)}
                  Dispatcher.SetTimerTrigger(msTimeoutTrigger,
                                   FConnectInfoTimeout, True);
                  SetModemState(smsConnectWait);
                end else if msResponseIsNoCarrier then begin
                  {Didn't get a connect}
                  SetModemState(smsReady);
                end else begin
                  {Got something else we didn't expect, ignore it}
                end;
              end else if (TriggerID = msTimeoutTrigger) then begin
                {Didn't get a connect}
                SetModemState(smsReady);
              end;
            end;

          smsDialWait :
            begin
              {We're in the process of dialing a call.  We could arrive here
               if we receive any of the following -- NoCarrierMsg,
               NoDialToneMsg, ConnectMsg, or timeout while waiting for data.
              }
              if (TriggerID = msAvailTrigger) then begin
                if msResponseIsConnect then begin
                  {Set a timer to watch for optional data (e.g., data comp.)}
                  msPrepareForConnectInfoResponse;
                  SetModemState(smsConnectWait);
                end else if msResponseIsNoCarrier or
                            msResponseIsBusy then begin
                  {If we're in auto-retry mode, set a timer for the retry delay}
                  if AutoRetryDial then begin
                    Dispatcher.SetTimerTrigger(msTimeoutTrigger,
                                     Secs2Ticks(FRetryWaitTime), True);
                    SetModemState(smsDialCycle);
                    Exit;
                  end else begin
                    SetModemState(smsReady);
                  end;
                end else if msResponseIsNoDialTone then begin
                  FStatusDisplay.UpdateDisplay(FStatusInfo);
                  Dispatcher.SetTimerTrigger(msTimeoutTrigger, 0, False);
                  SetModemState(smsNoDialTone);
                  { one-time status, return to smsReady }
                  SetModemState(smsReady);
                end else
                  {It wasn't a response we were looking for}
                  msPrepareForDialResponse;

              end else if (TriggerID = msTimeoutTrigger) then begin
                {Didn't get a connect, so send the cancel command (and cycle?)}
                PutStringModem(FDialCancelCmd);
                if AutoRetryDial and
                  (FDialAttempt < FMaxDialAttempts) then begin         {!!.01}
                  Dispatcher.SetTimerTrigger(msTimeoutTrigger,
                                   Secs2Ticks(FRetryWaitTime), True);
                  SetModemState(smsDialCycle);
                  Exit;
                end else
                  SetModemState(smsReady);
              end;
            end;

          smsDialCycle :
            begin
              if (TriggerID = msTimeoutTrigger) then begin
                PutStringModem(FDialCmd + ' ' + FPhoneNumber + FDialTerminatorCmd);
                inc(FDialAttempt);
                msPrepareForDialResponse;
                SetModemState(smsDialWait);
              end;
              Exit;                                                    {!!.01}
            end;

          smsConnectWait :
            begin
              {We received a connect message already; now we're waiting for
               optional connect data (e.g., data compression messages) or
               a timeout if no other connect information is sent.}
              if (TriggerID = msAvailTrigger) then begin
                {Got optional connect info or other end sent data very quickly}

⌨️ 快捷键说明

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