📄 awmodem.pas
字号:
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 + -