Hello StackOverflow community, I ran into a problem with one of my Delphi projects. Wrote a sip-phone class to call clients. Works fine so far but I need the program to wait until the call is done. thats how I start a call with client:
procedure TDialog_TelefonVOIP_Test.ButtonQuickCallClick(Sender: TObject);
var
tmpTel: TTelefon;
begin
tmpTel := TTelefon.Create(Self, '192.168.x.y', 'xy', '******', True);
try
tmpTel.Call('001726599722', True, 'This is a text to speech test. Is this working?');
finally
FreeAndNil(tmpTel);
end;
end;
The problem is that the program runs into FreeAndNil(tmpTel)
before the call is done.
Heres the simplified code of my TTelefon class:
unit TEST_Telefon;
interface
uses
Classes, SysUtils, Controls, Dialogs, Vcl.ExtCtrls, Vcl.Forms, System.Threading,
sipclient, call, ringtone;
type
RCallData = record
Call: ICall;
Number: string;
TTS: Boolean;
TTSText: string;
end;
var
CallData: RCallData;
SIP_Client: Tsipclient;
type
TTelefon = class(TObject)
private
FServerConnected: Boolean;
FRinging: Boolean;
FCallConnected: Boolean;
Caller: TComponent;
procedure OnAnswer(Sender: TObject; const aCall: ICall);
procedure OnHangUp(Sender: TObject; const aCall: ICall);
protected
function Connect(const aServer, aUser, aPass: string): Boolean;
function Disconnect(): Boolean;
public
Server: string;
User: string;
Pass: string;
property ServerConnected: Boolean read FServerConnected;
property Ringing: Boolean read FRinging;
property CallConnected: Boolean read FCallConnected;
constructor Create(aCaller: TComponent; const aServer, aUser, aPass: string; aConnect: Boolean=True);
destructor Destroy(); override;
function Call(aNumber: string; aTTS: Boolean=False; aTTSText: String=''): Boolean;
function HangUp(aDisconnect: Boolean=False): Boolean;
function GetAnrufStatus(aAnruf: ICall=nil): string;
end;
implementation
{ TTelefon }
constructor TTelefon.Create(aCaller: TComponent; const aServer, aUser, aPass: string; aConnect: Boolean=True);
begin
try
Caller := aCaller;
if not Assigned(SIP_Client) then
SIP_Client := TSIPclient.Create(Caller);
SIP_Client.OnAnswer := OnAnswer;
SIP_Client.OnBye := OnHangup;
Server := aServer;
User := aUser;
Pass := aPass;
FServerConnected := False;
FCallConnected := False;
FRinging := False;
if aConnect then
FServerConnected := Connect(Server, User, Pass);
except
on e: Exception do
ShowMessage(e.Message);
end;
end;
function TTelefon.Connect(const aServer, aUser, aPass: string): Boolean;
var
tmpConnected: Boolean;
begin
Result := False;
try
tmpConnected := False;
SIP_Client.Host := aServer;
SIP_Client.User := aUser;
SIP_Client.Password := aPass;
SIP_Client.Proxy := aServer;
SIP_Client.Active := True;
SIP_Client.Register;
tmpConnected := True;
Result := tmpConnected;
except
on e: Exception do
ShowMessage(e.Message);
end;
end;
function TTelefon.Call(aNumber: string; aTTS: Boolean=False; aTTSText: String=''): Boolean;
var
tmpOK: Boolean;
begin
try
tmpOK := False;
if not FServerConnected then
FServerConnected := Connect(Server, User, Pass);
if FServerConnected then
begin
CallData.Number := aNumber;
CallData.TTS := aTTS;
CallData.TTSText := aTTSText;
if not Assigned(CallData.Call) then
CallData.Call := SIP_Client.Call(CallData.Number)
else if CallData.Call.State = csRinging then
CallData.Call.Answer()
end;
Result := tmpOK;
except
on e: Exception do
ShowMessage(e.Message);
end;
end;
function TTelefon.HangUp(aDisconnect: Boolean=False): Boolean;
var
tmpAufgelegt: Boolean;
begin
Result := False;
try
tmpAufgelegt := False;
if FCallConnected then
begin
if Assigned(CallData.Call) then
CallData.Call.EndCall();
tmpAufgelegt := True;
if aDisconnect and FServerConnected then
tmpAufgelegt := Disconnect();
end
else
tmpAufgelegt := True;
OnHangUp(nil, CallData.Call);
Result := tmpAufgelegt;
except
on e: Exception do
ShowMessage(e.Message);
end;
end;
function TTelefon.Disconnect(): Boolean;
begin
Result := False;
try
SIP_Client.Active := False;
FServerConnected := False;
Result := not FServerConnected;
except
on e: Exception do
ShowMessage(e.Message);
end;
end;
procedure TTelefon.OnAnswer(Sender: TObject; const aCall: ICall);
begin
inherited;
try
if Assigned(aCall) then
CallData.Call := aCall;
FCallConnected := True;
FRinging := False;
if CallData.TTS AND (CallData.TTSText <> '') then
begin
Sleep(50);
if not Assigned(CallData.Call) then
CallData.Call := aCall;
CallData.Call.PlayText(CallData.TTSText, Integer(0));
end;
except
on e: Exception do
ShowMessage(e.Message);
end;
end;
procedure TTelefon.OnHangUp(Sender: TObject; const aCall: ICall);
begin
inherited;
try
if Assigned(aCall) then
CallData.Call := aCall;
FCallConnected := False;
except
on e: Exception do
ShowMessage(e.Message);
end;
end;
destructor TTelefon.Destroy();
begin
try
try
if FCallConnected then
HangUp();
if FServerConnected then
Disconnect();
finally
FreeAndNil(SIP_Client);
end;
except
on e: Exception do
ShowMessage(e.Message);
end;
end;
end.
What am i doing wrong?
I think i need the functionality of ShowModal()
inside the Call()
method. Is that possible?
I would be glad if anyone could help me!
Greetings
Morris F