📄 admdm.pas
字号:
FCallerIDProvided := False;
CheckReady;
{$IFDEF AdModemDebug}
FComPort.AddStringToLog('dial');
{$ENDIF}
PrepForConnect(True);
FPhoneNumber := ANumber;
PassthroughMode := False;
if not Initialized then
Initialize;
FStartTime := AdTimeGetTime;
DoStatus(msDial);
Postmessage(Handle, apw_StartDial, 0, 0);
end;
procedure TAdCustomModem.DoCallerID;
{ Generate the OnModemCallerID event }
begin
FCallerIDProvided := True;
{$IFDEF AdModemDebug}
FComPort.AddStringToLog('CallerID');
{$ENDIF}
if Assigned(FOnModemCallerID) then
FOnModemCallerID(Self, FCallerIDInfo);
end;
procedure TAdCustomModem.DoConnect;
{ Generate the OnModemConnect event }
begin
PrepForConnect(False);
if not PassthroughMode then begin
if DCDTrigger = 0 then
DCDTrigger := FComPort.AddStatusTrigger(stModem);
FComPort.SetStatusTrigger(DCDTrigger, msDCDDelta, True);
FConnected := True;
end;
if Assigned(FOnModemConnect) then
FOnModemConnect(Self);
end;
procedure TAdCustomModem.DoDisconnect;
{ Generate the OnModemDisconnect event }
begin
PrepForConnect(False);
if Assigned(FOnModemDisconnect) then
FOnModemDisconnect(Self);
end;
procedure TAdCustomModem.DoFail(Failure : Integer);
{ Generate the OnModemFail event }
begin
FFailCode := Failure;
{$IFDEF AdModemDebug}
FComPort.AddStringToLog('Fail: ' + IntToStr(FFailCode));
{$ENDIF}
if Assigned(FOnModemFail) then
FOnModemFail(Self, Failure)
else
case FFailCode of
ecModemRejectedCommand :
raise EModemRejectedCommand.CreateUnknown(Format('Modem rejected command:'#13#10'%s',[LastCommand]), 0);
ecModemBusy :
raise EModemBusy.CreateUnknown('Modem is doing something else', 0);
ecDeviceNotSelected :
raise EDeviceNotSelected.CreateUnknown('Device not selected', 0);
ecModemNotResponding :
raise EModemNotResponding.CreateUnknown('No response from modem', 0);
ecModemDetectedBusy :
raise EModemDetectedBusy.CreateUnknown('Called number was busy', 0);
ecModemNoDialTone :
raise ENoDialTone.CreateUnknown('No dialtone', 0);
ecModemNoCarrier :
raise ENoCarrier.CreateUnknown('No carrier', 0);
ecModemNoAnswer :
raise ENoAnswer.CreateUnknown('No answer', 0);
end;
end;
procedure TAdCustomModem.DoLog(LogCode: TApdModemLogCode);
{ generate the OnModemLog event }
begin
if Assigned(FOnModemLog) then
FOnModemLog(Self, LogCode);
end;
procedure TAdCustomModem.DoStatus(NewModemState: TApdModemState);
{ change FModemState and generate the event }
var
S : string;
Action : TApdModemStatusAction;
FirstState : Boolean;
begin
if FModemState <> NewModemState then begin
FirstState := True;
{ state changed, is it log-worthy? }
case NewModemState of
msIdle : if FModemState in [msAutoAnswerWait..msConnectWait] then
DoLog(mlConnectFail)
else
DoLog(mlNone);
msAutoAnswerBackground : DoLog(mlAutoAnswer);
msAnswerWait : DoLog(mlAnswer);
msDial : DoLog(mlDial);
msConnected : DoLog(mlConnect);
msHangup : DoLog(mlCancel);
msCancel : DoLog(mlCancel);
end;
end else
FirstState := False;
FModemState := NewModemState;
if Assigned(FOnModemStatus) then
FOnModemStatus(Self, ModemState);
if Assigned(FStatusDisplay) then begin
{ update the status display }
if FStatusDisplay.Started then
S := ModemStatusMsg(FModemState)
else
S := '';
case FModemState of
msConnectWait, msAutoAnswerWait :
if FirstState then
Action := msaUpdate
else
Action := msaDetailReplace;
msIdle, msConnected : Action := msaClose;
else
Action := msaUpdate;
end;
FStatusDisplay.UpdateDisplay(Self,
ModemStatusMsg(FModemState), { the status line }
IntToStr(ElapsedTime div 1000),
S, { for the detail list }
Action);
end;
end;
function TAdCustomModem.FailureCodeMsg(
const FailureCode: Integer): string;
{ convert a FailureCode into a string }
begin
Result := ErrorMsg(FailureCode); {!!.04}
(*case FailureCode of
ecDeviceNotSelected : Result := 'Device not selected';
ecModemRejectedCommand : Result := 'Modem rejected command';
ecModemBusy : Result := 'Modem is doing something else';
ecModemNotResponding : Result := 'Modem not responding';
ecModemDetectedBusy : Result := 'Called number is busy';
ecModemNoDialtone : Result := 'No dialtone';
ecModemNoCarrier : Result := 'No carrier';
ecModemNoAnswer : Result := 'No answer';
end;*)
end;
function TAdCustomModem.GetDevConfig: TApdModemConfig;
{ return the TApdModemConfig structure defining the selected modem }
begin
Result := FModemConfig;
end;
function TAdCustomModem.GetElapsedTime: DWORD;
begin
if FStartTime = 0 then
Result := 0 { not timing }
else
Result := AdTimeGetTime - FStartTime;
end;
function TAdCustomModem.GetNegotiationResponses: TStringList;
{ return the negotiation responses for this connection }
begin
Result := FNegotiationResponses;
end;
procedure TAdCustomModem.Initialize;
{ initialize the modem }
function PoundReplace(const str : string; Value : Integer) : string;
{ some modem init strings have variable params, replace them here }
var
I : Integer;
begin
Result := str;
I := Pos('<#>', Result);
{ remove the '<#>' }
Delete(Result, I, 3);
{ add the value }
Insert(IntToStr(Value), Result, I);
end;
var
ConfigInit : string;
begin
{ set the msInitializing state }
DoStatus(msInitializing);
{$IFDEF AdModemDebug}
FComPort.AddStringToLog('Initialize');
{$ENDIF}
if not DeviceSelected then {!!.04}
raise EDeviceNotSelected.Create(ecDeviceNotSelected, False);
if not SendCommands(LmModem.Init) then begin
{ fake it, using generic reset }
SendCommand(LmModem.Reset);
end;
ConfigInit := LmModem.Settings.Prefix + ' ';
with FModemConfig do begin
{ port settings }
FComPort.DataBits := DataBits;
FComPort.Parity := Parity;
FComPort.StopBits := StopBits;
{ speaker options }
case SpeakerVolume of
svLow : ConfigInit := ConfigInit + LmModem.Settings.SpeakerVolume_Low + ' ';
svMed : ConfigInit := ConfigInit + LmModem.Settings.SpeakerVolume_Med + ' ';
svHigh : ConfigInit := ConfigInit + LmModem.Settings.SpeakerVolume_High + ' ';
end;
case SpeakerMode of
smOff : ConfigInit := ConfigInit + LmModem.Settings.SpeakerMode_Off + ' ';
smOn : ConfigInit := ConfigInit + LmModem.Settings.SpeakerMode_On + ' ';
smDial : ConfigInit := ConfigInit + LmModem.Settings.SpeakerMode_Dial + ' ';
end;
{ connection control }
case FlowControl of
fcOff : ConfigInit := ConfigInit + LmModem.Settings.FlowControl_Off + ' ';
fcHard : ConfigInit := ConfigInit + LmModem.Settings.FlowControl_Hard + ' ';
fcSoft : ConfigInit := ConfigInit + LmModem.Settings.FlowControl_Soft + ' ';
end;
if ecOff in ErrorControl then
ConfigInit := ConfigInit + LmModem.Settings.ErrorControl_Off + ' '
else begin
ConfigInit := ConfigInit + LmModem.Settings.ErrorControl_On + ' ';
if ecForced in ErrorControl then
ConfigInit := ConfigInit + LmModem.Settings.ErrorControl_Forced + ' ';
if ecCellular in ErrorControl then
ConfigInit := ConfigInit + LmModem.Settings.ErrorControl_Cellular + ' ';
end;
if Compression then
ConfigInit := ConfigInit + LmModem.Settings.Compression_On + ' '
else
ConfigInit := ConfigInit + LmModem.Settings.Compression_Off + ' ';
case Modulation of
smBell : ConfigInit := ConfigInit + LmModem.Settings.Modulation_Bell + ' ';
smCCITT : ConfigInit := ConfigInit + LmModem.Settings.Modulation_CCITT + ' ';
smCCITT_V23 : ConfigInit := ConfigInit + LmModem.Settings.Modulation_CCITT_V23 + ' ';
end;
if BlindDial then
ConfigInit := ConfigInit + LmModem.Settings.Blind_On
else
ConfigInit := ConfigInit + LmModem.Settings.Blind_Off;
ConfigInit := ConfigInit +
PoundReplace(LmModem.Settings.CallSetupFailTimer, CallSetupFailTimeout) + ' ';
ConfigInit := ConfigInit +
PoundReplace(LmModem.Settings.InactivityTimeout, InactivityTimeout) + ' ';
ConfigInit := ConfigInit + LmModem.Settings.Terminator;
{$IFDEF AdModemDebug}
FComPort.AddStringToLog('Init 1');
{$ENDIF}
SendCommand(ConvertXML(ConfigInit));
if ExtraSettings <> '' then begin
{$IFDEF AdModemDebug}
FComPort.AddStringToLog('Init 2');
{$ENDIF}
SendCommand(ConvertXML(ExtraSettings + #13));
end;
end;
Initialized := True;
end;
function TAdCustomModem.ModemLogToString(
LogCode: TApdModemLogCode): string;
{ convert a LogCode into a string }
begin
case LogCode of
mlNone : Result := 'None, nothing to log';
mlDial : Result := 'Dialing';
mlAutoAnswer : Result := 'Initiated AutoAnswer';
mlAnswer : Result := 'Answering an incoming call';
mlConnect : Result := 'Connected';
mlCancel : Result := 'Call cancelled';
mlBusy : Result := 'Called number was busy';
mlConnectFail : Result := 'Connection attempt failed';
else Result := 'Undefined modem log code';
end;
end;
function TAdCustomModem.ModemStatusMsg(Status: TApdModemState): string;
{ convert a status code into a string }
var
Plural : char;
begin
case Status of
msUnknown :
Result := 'Hasn''t been initialized';
msIdle :
Result := 'Idle and ready';
msInitializing :
Result := 'Starting initialization process';
msAutoAnswerBackground :
Result := 'AutoAnswer no rings received';
msAutoAnswerWait :
begin
if (FAnswerOnRing - FRingCount) > 1 then
Plural := 's'
else
Plural := ' ';
Result := Format('AutoAnswer waiting for %d more ring%s',
[FAnswerOnRing - FRingCount, Plural]);
end;
msAnswerWait :
Result := 'Answering call waiting for connect';
msDial :
Result := Format('Dialing %s', [FPhoneNumber]);
msConnectWait :
Result := 'Waiting for remote to answer';
msConnected :
Result := 'Connected';
msHangup :
Result := 'Starting hangup process';
msCancel :
Result := 'Starting cancel process';
else
Result := 'Undefined modem state';
end;
end;
procedure TAdCustomModem.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if not (csDesigning in ComponentState) then
exit;
if (Operation = opRemove) then begin
{ see if our com port is going away }
if (AComponent = FComPort) then
ComPort := nil;
{ see if our status dialog is going away }
if (AComponent = FStatusDisplay) then
StatusDisplay := nil;
end else if (Operation = opInsert) then begin
{Check for a com port being installed}
if not Assigned(FComPort) and (AComponent is TApdCustomComPort) then
ComPort := TApdCustomComPort(AComponent);
if not Assigned(FStatusDisplay) and (AComponent is TAdAbstractModemStatus) then
StatusDisplay := TAdAbstractModemStatus(AComponent);
end;
end;
procedure TAdCustomModem.PrepForConnect(EnableTriggers: Boolean);
begin
if EnableTriggers then begin
{ somebody set us up the trigger }
if DCDTrigger > 0 then
FComPort.RemoveTrigger(DCDTrigger);
DCDTrigger := FComPort.AddStatusTrigger(stModem);
FComPort.SetStatusTrigger(DCDTrigger, msDCDDelta, True);
if StatusTimerTrigger > 0 then
FComPort.RemoveTrigger(StatusTimerTrigger);
StatusTimerTrigger := FComPort.AddTimerTrigger;
FComPort.SetTimerTrigger(StatusTimerTrigger, 1000, True);
end else begin
if DCDTrigger > 0 then begin
FComPort.RemoveTrigger(DCDTrigger);
DCDTrigger := 0;
end;
if StatusTimerTrigger > 0 then begin
FComPort.RemoveTrigger(StatusTimerTrigger);
StatusTimerTrigger := 0;
end;
end;
FNegotiationResponses.Clear;
end;
procedure TAdCustomModem.ResponseStringPacket(Sender: TObject;
Data: String);
var
Res : Integer;
begin
{ we've detected a string ending with #13#10, see if it is }
{ something we are looking for }
{ assume it's not }
OKResponse := False;
ErrorResponse := False;
ConnectResponse := False;
WaitingForResponse := True;
{ if we're waiting for the connection, add the response to the list }
if FModemState in [msConnectWait, msAnswerWait] then begin
if Data <> #13#10 then begin
{$IFDEF AdModemDebug}
FComPort.AddStringToLog('Informative response');
{$ENDIF}
FNegotiationResponses.Add(Data);
end;
end;
Res := CheckErrors(Data);
if Res <> ecOK then begin
ErrorResponse := True;
WaitingForResponse := False;
if (FModemState = msHangup) and (Res = ecModemNoCarrier) then
{ we've disconnected, handle it a little }
else begin
DoFail(Res);
Exit;
end;
end;
{ check for caller ID tags }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -