How to buffer DTMF in Asterisk? - asterisk

Consider the following AGI script. The dialplan entry for it is simply exten => *,1,AGI(test.agi). Analog card TDM410P is used.
#!/bin/sh
read REPLY; while [ "$REPLY" ]; do
read REPLY
done
#sleep 5
echo ANSWER; read REPLY
#sleep 5
while [ 1 ]; do
echo WAIT FOR DIGIT -1; read REPLY
echo $REPLY >>/tmp/agi
done
The problem is this: I take the phone off-hook and press *12345 very fast; the result is that the first one or two digits are sometimes lost (i.e., not recorded to /tmp/agi).
How to make it so that asterisk will buffer DTMF digits until they are read?
EDIT
I guess I need to create pseudoterminal (because it can buffer data) in the channel and write dtmf digits to it as soon as they are decoded, and set the name of the pseudoterminal slave in channel variables. Then AGI script will take the name of pty slave from AGI initialization data and will just read from the pty slave instead of via "WAIT FOR DIGIT".
So, does anybody know how to hack asterisk chan_dahdi? Or maybe there is a higher channel layer, not tied to specific module? Where should I look? Any hints...

AGI script already have STDIN which do buffering for you.
If you are not reading it, it will be in buffer.
Your issue with DTMF not related to AGI nor buffering. Check "DTMF Radio Relax" or just check you have correct DTMF settings on trunk.

Related

Generating IVR on Asterisk without duration, get DTMF input from user and then process it

I hope cyber Asterisk gurus would be able to help me in this regard. I am trying to create an IVR filter using Asterisk. My desired configuration goal is:
1:When a user dial into the Asterisk, the user should hear IVR(but there should be no charging on initial IVR). I want to send the IVR in in initial 183 Session in progress without any duration starting on my phone.
2:Once a user input some digit via DTMF, then the call should be processed and charging etc should take place
I would really appreciate you guys input in this regard. Thanks
You can use power of local channel combine with NoCDR. In beginning of your IVR use NoCDR() function, and after DTMF check use Dial to local channel contex with rest of yout logic.
[ivr]
exten => 100,1,NoCDR()
exten => 100,n(read),Read(variable)
exten => 100,n,GotoIf($[ ${variable} = 1 ]?go_1:read)
exten => 100,n(go_1)Dial(Local/${exten}#dtmf_1_logic)
[dtmf_1_logic]
.....
In that case you should have one CDR from dtmf_1_logic context with call duration with you are looking for

Tcl fileevent reads what was sent previously

I'm a fresh tcl user and I've been working on recently on a script, that uses serial port. My greatest problem so far is that I can't effectively read my serial port.
I'm using fileevent to read, but it catches what was send previously. However if I dont send anything before, it waits for external data and catches it. My code:
global forever
proc read_serial {serial} {
set msg [read $serial]
set listOfLetters [split $msg {} ]
set serialIPinHex ""
foreach iChar $listOfLetters { ;#conversion to hex
scan $iChar "%c" decimalValue
set hexValue [format "%02X" $decimalValue ]
set hexValue "0x$hexValue"
set serialIPinHex "$serialIPinHex $hexValue"
}
puts "MCU RESPONSE: $serialIPinHex"
global forever
set forever 1 ;# end event loop
}
set serial [open com1 r+]
fconfigure $serial -mode "19200,n,8,1"
fconfigure $serial -blocking 0 -buffering none
fconfigure $serial -translation binary -encoding binary
fileevent $serial readable [list read_serial $serial ]
global forever
puts -nonewline $serial \x31\xce
flush $serial
delay 10
vwait forever
flush $serial
close $serial
The effect is "MCU RESPONSE: x31 xce", while it should await for sth to come by serial (in my understanding). I'm sure there is no echo function on the other end. Thanks in advance for your help. I hope my bug is not embarassing, I spend last few hours looking for it...
The main thing to note about serial ports is that they are slow. Really slow. A modern computer can run round the block three times before a serial port has passed one character over (well, metaphorically). That means you're going to get characters coming one at a time and you've got to deal with that.
You're advised to use read $serial 1 and to append that to a buffer you are keeping, or write your code to handle a single byte at a time. If you were using line-oriented messaging, you could take advantage of gets's good behaviour in non-blocking mode (the fblocked command is designed to support this), but read isn't quite so friendly (since it knows nothing about record separators).
Don't worry about missing a byte if you use read $serial 1; if there's one left, your callback will get called again immediately to deal with it.

GotoIf hash key pressed at the end of Record command

We ask the caller to record their name then press hash key #. If the hash key has been pressed they should move to next step, otherwise go back and ask them to record the name again.
exten => s,n(RecordName), Playback(Please Record Your Name After Beeb then press '#')
exten => s,n,Record(recordpath/namefile.wav,60)
exten => s,n,GotoIf ('# isn't pressed')?RecordName)
Is there any way to detect if # is pressed at the end of Record command?
Please check documentation of Record command.
It clearly say which variables it set on # key.
pro-sip*CLI> core show application Record
-= Info about application 'Record' =-
[Synopsis]
Record to a file.
[Description]
If filename contains '%d', these characters will be replaced with a number
incremented by one each time the file is recorded. Use 'core show file formats'
to see the available formats on your system User can press '#' to terminate
the recording and continue to the next priority. If the user hangs up during
a recording, all data will be lost and the application will terminate.
${RECORDED_FILE}: Will be set to the final filename of the recording.
${RECORD_STATUS}: This is the final status of the command
DTMF:A terminating DTMF was received ('#' or '*', depending upon
option 't')
SILENCE:The maximum silence occurred in the recording.
SKIP:The line was not yet answered and the 's' option was specified.
TIMEOUT:The maximum length was reached.
HANGUP:The channel was hung up.
ERROR:An unrecoverable error occurred, which resulted in a WARNING
to the logs.
[Syntax]
Record(filename.format[,silence[,maxduration[,options]]])
[Arguments]
format
Is the format of the file type to be recorded (wav, gsm, etc).
silence
Is the number of seconds of silence to allow before returning.
maxduration
Is the maximum recording duration in seconds. If missing or 0 there
is no maximum.
options
a: Append to existing recording rather than replacing.
n: Do not answer, but record anyway if line not yet answered.
q: quiet (do not play a beep tone).
s: skip recording if the line is not yet answered.
t: use alternate '*' terminator key (DTMF) instead of default '#'
x: Ignore all terminator keys (DTMF) and keep recording until hangup.
k: Keep recorded file upon hangup.
y: Terminate recording if *any* DTMF digit is received.
[See Also]
Not available

How can I call an "AT command" in Codesys for a GSM modem? Not standard send_sms, etc

I have a GSM modem and a PLC. The PLC sees a modem (I use a *.lib and functional block "openPort"), but I don't understand how send an "AT command" to the modem, for example, "ate0".
First, to increase your understanding of AT commands in general, read the V.250 specification. That will go a long way in making you an AT command expert.
Then for the actual implementation, I do not know Codesys, so the following is pseudo code of the structure you should have for handling AT commands:
the_modem = openPort();
...
// Start sending ATE0
writePort(the_modem, "ATE0\r");
do {
line = readLinePort(the_modem);
} while (! is_final_result_code(line))
// Sending of ATE0 command finished (successfully or not)
...
closePort(the_modem);
Whatever you do, never, never use delay, sleep or similar as a substitute for waiting for the final result code. You can look at the code for atinout for an example for the is_final_result_code function (you can also compare to isFinalResponseError and isFinalResponseSuccess in ST-Ericsson's U300 RIL, although note that CONNECT is not a final result code. It is an intermediate result code, so the name isFinalResponseSuccess is not 100% correct).

Asterisk playback sound file into ConfBridge?

I'm trying to make a conference and play a sound file in the background of the conference. How can I make this possible?
this obviously wouldn't work because the sound file will be played before entering the conference.
exten => s,1,playback(some/soundfile)
same => n,confbridge(1)
Thanks in advance!
Wanted to add my solution here in case anyone ever needs it.
first make a context for the conf bridge in extensions.conf:
[conf-msg]
exten => s,1,ConfBridge(01)
where 01 is the bridge number
Then via the command line you can do:
asterisk -x 'channel originate local/s#conf-msg application Playback file'
Its really as simple as that.
You have create new call,simple method using call files.
http://www.voip-info.org/wiki/view/Asterisk+auto-dial+out
After that you have place one of call legs to your conference like this
Channel: Local/1111#conference
Application: Playback
Data: some/soundfile
Where conference is context to get to ur conference room.
No need do spy or somethign like that,that is wast of time/cpu
See here for a similar question:
Asterisk- How to 'whisper' music using ChanSpy(), or any alternative?
Basically, you want to add a participant that points to a local channel (as above, only enter the channel instead of spying), play your sounds, then hangup.
Same answers, but for many confBridge:
In extension.conf:
[autobridge]
exten => _X.,1,ConfBridge(${EXTEN})
Then, like tgwaste's answer, you could initiate message into conference room 1234, by using originate:
originate local/1234#autobridge application Playback en_US/tt-monkeys
from console or a manager connection,
Or as arheops's answer suggest, by adding a file in outgoing spool dir:
printf "Channel: Local/%d#autobridge\nApplication: %s\nData: %s\n" \
1234 Playback sound/file >/var/spool/asterisk/outgoing/f-$RANDOM
from anything at filesystem level ( with correct permissions, could be shared! :-).

Resources