Re: [asterisk-users] Asterisk / PHP-AGI / pthreads
Hi Satish :) You reminded me of my teacher of old school days. Very well explained. I have somewhat similar requirement where I need to play some announcements to entertain a caller while passing/processing some data through webservice call (). do you want to use C or PHP? -Thorsten- -- _ -- Bandwidth and Colocation Provided by http://www.api-digital.com -- New to Asterisk? Join us for a live introductory webinar every Thurs: http://www.asterisk.org/hello asterisk-users mailing list To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/asterisk-users
Re: [asterisk-users] Asterisk / PHP-AGI / pthreads
On Fri, Jun 21, 2013 at 1:20 PM, Thorsten Göllner t...@ovm-group.com wrote: Hi Satish :) You reminded me of my teacher of old school days. Very well explained. I have somewhat similar requirement where I need to play some announcements to entertain a caller while passing/processing some data through webservice call (). do you want to use C or PHP? -Thorsten- Hi Thorsten Normally I use 'PHPAGI' in my Asterisk applications but as I said want to explore C as an option. Thanks, --Satish Barot -- _ -- Bandwidth and Colocation Provided by http://www.api-digital.com -- New to Asterisk? Join us for a live introductory webinar every Thurs: http://www.asterisk.org/hello asterisk-users mailing list To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/asterisk-users
Re: [asterisk-users] Asterisk / PHP-AGI / pthreads
On Thu, 20 Jun 2013, Satish Barot wrote: Would you mind sharing a sample of your pthread-ed C AGI? This will help someone like me who has written AGI in Perl/PHP and now exploring C AGI. The source code for this particular AGI is about 600 lines and uses my own AGI library (written before other C AGI libraries were available) so I don't think it has a whole lot of value to other programmers. First a little background on why I used pthreads in this AGI... The application was an adult chat platform. (Mostly) guys call in to chat to (mostly) women and pay $1 to $4 per minute. At the end of the call, the accumulated charges are billed to their their credit card. Charges to credit cards usually take 2 transactions. The first transaction ('OPEN') places a temporary 'hold' on the card for $XXX. At the end of the call, a second transaction ('SALE') finalizes the billing for the actual charges for the call. (This '2 step' process is why you may have trouble charging an expensive dinner after checking into a hotel -- the hotel may have placed a 'hold' against your credit limit for the expected charge for your entire stay.) As originally implemented, Asterisk would play a prompt asking the caller to enter their card details. After the caller entered a 'valid' card number (that passes Luhn mod 10) and expiration date (between the current month current year and current year + 7). My AGI would then play a prompt ('Please wait while your card is being verified') and then transmit the card details to our card processor. Getting a response from the card processor takes a second or so. My AGI returned the card processor response code as the 'priority' so the dialplan could continue to the main menu or play a prompt indicating why the card details failed. After 3 failures, a caller was played a prompt instructing them on alternative billing methods (high rate NPAs, check by phone, etc). This client was extremely particular about the 'caller experience' and thought the 'second or so' of silence while the card was being verified was excessive and had to be eliminated. Since the card processing time was not under my control, my solution was to change my AGI to create a second thread to play the 'please wait' prompt while the 'main line' code shipped off the card details to the processor. When I got the processor's response (which was usually before the prompt finished playing), the 'main line' code would 'join' the prompt thread. If the prompt thread was finished playing the prompt, execution continued immediately. If the prompt thread was still playing the prompt, execution continued as soon as the prompt thread received the AGI response from Asterisk. None of this took any special programming or synchronizing from me. It all 'just worked' because of the way pthreads are implemented. So, what did I learn that would be of value to you? Really understand the AGI protocol and you won't make a bunch of silly mistakes. The AGI protocol is very simple: 1) Read the AGI environment from stdin before you do anything in your AGI that interacts with Asterisk. 2) Write your AGI request to stdout. 3) Read Asterisk's AGI response from stdin. 4) Rinse, lather, repeat (steps 2 3). If you use an established AGI library (like you really, really should), this should be taken care of automagically, but understanding what's really going on will help when things don't work as expected. The number 1 mistake new AGI programmers make is not reading the AGI environment. Sometimes they 'get away' with it, some times they don't. The number 2 mistake is not reading the responses (step 3). Again, sometimes it works, sometimes it doesn't The number 3 mistake new (and old salts like me still make on occasion) is doing any I/O on stdin or stdout. A lot of bad debugging centers around 'throw in a printf somewhere to see what's going on' instead of using 'real programmer' tools like gdb*. If you're using an established AGI library, the crucial relationship between steps 2 and 3 will be take care of -- unless you're using multiple threads. If thread 1 issues an AGI request (writing to stdout) and then thread 2 issues an AGI request (also writing to stdout) before thread 1 reads it's response, you've broken the protocol and bad things will happen. Maybe not immediately, but certainly when you're demonstrating the system to your boss. So my first suggestion (after using an established library and without knowing what your use case is) would be to 'designate' a single thread as 'the Asterisk' thread and only interact (via stdin and stdout) with Asterisk in that thread. If that's not feasible, you're going to need some sort of 'semaphore' mechanism so you don't 'intermingle' your AGI requests and responses and thereby violate the AGI protocol. Another couple of suggestions unrelated to threads, but are best (IMNSHO) practices for AGIs in general: 1) Use getopt_long().
Re: [asterisk-users] Asterisk / PHP-AGI / pthreads
On Thu, Jun 20, 2013 at 10:54 PM, Steve Edwards asterisk@sedwards.comwrote: On Thu, 20 Jun 2013, Satish Barot wrote: Would you mind sharing a sample of your pthread-ed C AGI? This will help someone like me who has written AGI in Perl/PHP and now exploring C AGI. The source code for this particular AGI is about 600 lines and uses my own AGI library (written before other C AGI libraries were available) so I don't think it has a whole lot of value to other programmers. First a little background on why I used pthreads in this AGI... The application was an adult chat platform. (Mostly) guys call in to chat to (mostly) women and pay $1 to $4 per minute. At the end of the call, the accumulated charges are billed to their their credit card. Charges to credit cards usually take 2 transactions. The first transaction ('OPEN') places a temporary 'hold' on the card for $XXX. At the end of the call, a second transaction ('SALE') finalizes the billing for the actual charges for the call. (This '2 step' process is why you may have trouble charging an expensive dinner after checking into a hotel -- the hotel may have placed a 'hold' against your credit limit for the expected charge for your entire stay.) As originally implemented, Asterisk would play a prompt asking the caller to enter their card details. After the caller entered a 'valid' card number (that passes Luhn mod 10) and expiration date (between the current month current year and current year + 7). My AGI would then play a prompt ('Please wait while your card is being verified') and then transmit the card details to our card processor. Getting a response from the card processor takes a second or so. My AGI returned the card processor response code as the 'priority' so the dialplan could continue to the main menu or play a prompt indicating why the card details failed. After 3 failures, a caller was played a prompt instructing them on alternative billing methods (high rate NPAs, check by phone, etc). This client was extremely particular about the 'caller experience' and thought the 'second or so' of silence while the card was being verified was excessive and had to be eliminated. Since the card processing time was not under my control, my solution was to change my AGI to create a second thread to play the 'please wait' prompt while the 'main line' code shipped off the card details to the processor. When I got the processor's response (which was usually before the prompt finished playing), the 'main line' code would 'join' the prompt thread. If the prompt thread was finished playing the prompt, execution continued immediately. If the prompt thread was still playing the prompt, execution continued as soon as the prompt thread received the AGI response from Asterisk. None of this took any special programming or synchronizing from me. It all 'just worked' because of the way pthreads are implemented. So, what did I learn that would be of value to you? Really understand the AGI protocol and you won't make a bunch of silly mistakes. The AGI protocol is very simple: 1) Read the AGI environment from stdin before you do anything in your AGI that interacts with Asterisk. 2) Write your AGI request to stdout. 3) Read Asterisk's AGI response from stdin. 4) Rinse, lather, repeat (steps 2 3). If you use an established AGI library (like you really, really should), this should be taken care of automagically, but understanding what's really going on will help when things don't work as expected. The number 1 mistake new AGI programmers make is not reading the AGI environment. Sometimes they 'get away' with it, some times they don't. The number 2 mistake is not reading the responses (step 3). Again, sometimes it works, sometimes it doesn't The number 3 mistake new (and old salts like me still make on occasion) is doing any I/O on stdin or stdout. A lot of bad debugging centers around 'throw in a printf somewhere to see what's going on' instead of using 'real programmer' tools like gdb*. If you're using an established AGI library, the crucial relationship between steps 2 and 3 will be take care of -- unless you're using multiple threads. If thread 1 issues an AGI request (writing to stdout) and then thread 2 issues an AGI request (also writing to stdout) before thread 1 reads it's response, you've broken the protocol and bad things will happen. Maybe not immediately, but certainly when you're demonstrating the system to your boss. So my first suggestion (after using an established library and without knowing what your use case is) would be to 'designate' a single thread as 'the Asterisk' thread and only interact (via stdin and stdout) with Asterisk in that thread. If that's not feasible, you're going to need some sort of 'semaphore' mechanism so you don't 'intermingle' your AGI requests and responses and thereby violate the AGI protocol. Another couple of suggestions unrelated
Re: [asterisk-users] Asterisk / PHP-AGI / pthreads
On Mon, Jun 17, 2013 at 7:22 PM, Steve Edwards asterisk@sedwards.comwrote: On Mon, 17 Jun 2013, Thorsten Göllner wrote: does anyone have experience with Asterisk-AGI-Scripts in PHP while using pthreads in PHP? Are there any limitations or problems known? I've written 'pthread-ed' AGIs in C. The only 'pthread related' limitation I stumbled into is that you can only execute a single AGI request at a time -- which is kind of obvious if you understand the AGI protocol. My use case was playing a file ('Please wait while we authorize your credit card') while processing the credit request. Since our card processor almost always returned the credit response before the end of the file, the 'user experience' was that the credit request was instantaneous. -- Thanks in advance, --**--** - Steve Edwards sedwa...@sedwards.com Voice: +1-760-468-3867 PST Newline Fax: +1-760-731-3000 -- Steve, Would you mind sharing a sample of your pthread-ed C AGI? This will help someone like me who has written AGI in Perl/PHP and now exploring C AGI. Thanks, --Satish -- _ -- Bandwidth and Colocation Provided by http://www.api-digital.com -- New to Asterisk? Join us for a live introductory webinar every Thurs: http://www.asterisk.org/hello asterisk-users mailing list To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/asterisk-users
[asterisk-users] Asterisk / PHP-AGI / pthreads
Hi there, does anyone have experience with Asterisk-AGI-Scripts in PHP while using pthreads in PHP? Are there any limitations or problems known? Best regards -Thorsten- -- _ -- Bandwidth and Colocation Provided by http://www.api-digital.com -- New to Asterisk? Join us for a live introductory webinar every Thurs: http://www.asterisk.org/hello asterisk-users mailing list To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/asterisk-users
Re: [asterisk-users] Asterisk / PHP-AGI / pthreads
On Mon, 17 Jun 2013, Thorsten Göllner wrote: does anyone have experience with Asterisk-AGI-Scripts in PHP while using pthreads in PHP? Are there any limitations or problems known? I've written 'pthread-ed' AGIs in C. The only 'pthread related' limitation I stumbled into is that you can only execute a single AGI request at a time -- which is kind of obvious if you understand the AGI protocol. My use case was playing a file ('Please wait while we authorize your credit card') while processing the credit request. Since our card processor almost always returned the credit response before the end of the file, the 'user experience' was that the credit request was instantaneous. -- Thanks in advance, - Steve Edwards sedwa...@sedwards.com Voice: +1-760-468-3867 PST Newline Fax: +1-760-731-3000-- _ -- Bandwidth and Colocation Provided by http://www.api-digital.com -- New to Asterisk? Join us for a live introductory webinar every Thurs: http://www.asterisk.org/hello asterisk-users mailing list To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/asterisk-users