Acess to Asterisk Server - TpasAgi lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- tanguy · 2013-05-30 06:20 Hello, I'm looking for a library to acces to a asterisk server ( phone server  : http://www.asterisk.org/  ) i find on google a reference to an  old tpasagi file but i can't find anywhere my goal  is just to make a simple notification program Many thanks to any help ---------------------------------------------------------------------- cpalx · 2013-05-30 12:12 i'm not sure, but i think you can make cgi applications for asterisk ans use some asterisk APIs ---------------------------------------------------------------------- tanguy · 2013-05-30 14:13 yes i can rewrite but if can find the unit  tpasAgi the work is less ---------------------------------------------------------------------- InRong · 2013-05-31 14:12 Try this archive http://web.archive.org/web/20110428174621/http://www.leebo.dreamhoster s.com/asterisk/pasagi.pas ---------------------------------------------------------------------- tanguy · 2013-05-31 14:33 Many thanks for your help i give you some feedback ---------------------------------------------------------------------- ipcroc · 2013-05-31 22:06 ...I did not use the TPasAgi library, instead I used the telnet protocol to communicate with the Asterisk box. It worked reasonably well. Use the guideline below: From iNet LCL tab, select Telnet component.Populate the relevant parameters in accordance to your Asterisk.Connect to Asterisk.Login into Asterisk.Use the Telnet OnReceive event to parse the responses in accordance to the commands you sent to Asterisk.Send commands to Asteriks.Repeat steps 5 and 6 above until you need to logout from Asterisk.Logout/Disconnect from Asterisk. The trick is to understand the AMI protocol, specifically the concept around "Action ID" and "Event ID". Regards. ---------------------------------------------------------------------- tanguy · 2013-06-03 06:47 yes in fact tpasagi is not what i need i try with your solution if you've some example code for decoding it can help  me Many thanks for your solution ---------------------------------------------------------------------- ipcroc · 2013-06-03 12:06 ...well, then try the following code snippets. Unfortunately I do not have an Asterisk box nearby, but the code segments below are an extract from the application sources as I had used it: Code: [Select]{****function returns an integer incremented by 1.****} function  incrementActionId(ids:string):string; var i : integer; begin  i               := strtoint(ids)+1;  result          := inttostr(i);  form1.edTaskID.Text:= result; end; {****function returns a string consisting of a properly structured command      required to be sent to Asterisk.****} function  doAmiCommand(commandRequired,actionID:string):string; var commandString : string; begin   result := '';   commandString := 'Action: Command'+#13+#10+                    'ActionID: '+incrementActionId(actionID)+#13+#10+                    'Command: '+commandRequired+#13+#10+#13+#10;   if commandString <> '' then   form1.telnet.SendMessage(commandString); end; {****Function return a string describing the channel type of a SIP Peer.****} function extractSipPeers_type(s:TStringlist):string; var i : integer;     p : integer; begin {-----------------Sample event output from Asterisk after executing ami Event: PeerEntry ActionID: 3 Channeltype: SIP ObjectName: 400 ChanObjectType: peer IPaddress: 192.168.11.104 IPport: 2048 Dynamic: yes Natsupport: yes VideoSupport: no TextSupport: no ACL: yes Status: OK (40 ms) RealtimeDevice: no }   i := 2;   p := 14;   result := copy(trim(s[i]),p,length(s[i])+1-p); end; {****Connect to Asterisk.****} procedure TForm1.MenuItem2Click(Sender: TObject); begin   telnet.Host:= 'Your Asterisk box IP address'; //  dtmunetwork.telnet.co;   try    telnet.Connect();   except     showmessage('Error in connecting to host: ' + telnet.Host);   end; end; {****Login to Asteriks.****} procedure TForm1.mnuLoginClick(Sender: TObject); var commandstr  : string;     username    : string;     password    : string; begin    username   := 'admfn';    password   := 'elxhst750xp';   if form1.CheckBoxUseEvents.Checked then   begin    commandstr := 'Action: Login'+#13+#10+                  'ActionID: '+incrementActionId(editTaskID.Text)+#13+#10+                  'Username: '+username+#13+#10+                  'Secret: '+password+#13+#10+                  'Events: on'+#13+#10+                   #13+#10;   end   else   begin    commandstr := 'Action: Login'+#13+#10+                  'ActionID: '+incrementActionId(editTaskID.Text)+#13+#10+                  'Username: '+username+#13+#10+                  'Secret: '+password+#13+#10+                  'Events: off'+#13+#10+                   #13+#10;   end;   dtmunetwork.telnet.SendMessage(commandstr); end; {****Sent AMI command "sippeer" to Asterisk.****} procedure TForm1.btnShowSipUsersClick(Sender: TObject); begin   doAmiCommand('sip show users',form1.edTaskID.Text); end; Refer to the code snippet below for parsing the output from Asterisk. The technique I used was to capture the output into a TStringlist (sl and nl) variables and parse the content accordingly: Code: [Select]procedure maskAmiString(amistr:TStringlist); var i         : integer;     block     : integer;     //some pbx string has multiple repeats of content                              //contained under the same context.     blocksize : integer;     //block size determines number of iterations                              //required to parse a macthed block.     x         : integer;     //extension 204 on fnpbx has a bug in listing of peer entry     sl        : TStringlist; //primarily used as a container for string received from PBX     nl        : TSTringlist; //primarily used as sub container to process block specific pbx strings     newstr    : ansistring; begin   if amistr.Count = 0 then   begin    showmessage('amistr stringlist is empty.');    exit;   end;   sl := TStringlist.Create;   nl := TStringlist.Create;   {the sl features used in next 3 lines ensure that string from pbx is delimited correctly}   sl.StrictDelimiter := true;   sl.Delimiter       := #10;   sl.DelimitedText   := amistr.Text;   form1.Memo2.Lines.Add('');   form1.Memo2.Lines.Add('DEBUG: Received data string from processing received string...');   form1.Memo2.Lines.Add('New amistr Index 0 string = '+amistr[0]);   form1.Memo2.Lines.Add('');   {traverse content of container sl and do special context processing depending    string matching required.}   if sl.Count > 0 then   begin {-----start parse "sippeer" event solicited-----------}       {process context on match of solicited "Event PeerEntry"}       if (pos('Event: PeerEntry',sl.Text) > 0) and (pos('Event: PeerlistComplete',sl.Text) > 0) then       begin            for i := 0 to sl.Count-1 do            begin               if pos('Event: PeerEntry',sl[i]) > 0 then               begin                  block := i;                  {debug                  form1.Memo2.Lines.Add('New block found at index      : '+inttostr(block));                  form1.Memo2.Lines.Add('Value of for "loop i" variable: '+inttostr(i));                  }                  blocksize := 14;                  while block < i + blocksize do                  begin                     if sl[block] <> #13 then                     begin                       nl.Add(trim(sl[block]));                     end;                     inc(block);                  end;               end;               {remove items in sl that are empty lines.}               slDeleteEmptyLines(nl,nil);              {debug              form1.Memo2.Lines.Add('Value of "block" variable     : '+inttostr(block));              }                  //extract SIP circuitry parameters from event PeerEntry                  if nl.Text <> '' then extractSipPeers_type(nl);                  {displaySipPeersSolicited(form2.ListView2,                                           extractSipPeers_type(nl),                                           extractSipPeers_number(nl),                                           extractSipPeers_status(nl));}               nl.Clear;            end;            sl.Clear;       end; {-----end parse sip peer event solicited-----------}  end;   sl.Free;   nl.Free; end; All the above should be able to provide some direction on way of approaching your solution. Regards. ---------------------------------------------------------------------- tanguy · 2013-06-05 08:18 It's ok just to have write a wrapper