Astarisk Call File_Can wait or get response to start playback? - asterisk

Channel: $number
Application: Playback
Data: $outputfilename
When callee answers the phone, s/he misses the first one or two words. So I would like to wait untill s/he gives any response like "hello?' or "alo" and then start playback. Is there anyway to make it done in the call file?
If there is not at least I would like to wait 1 or 2 seconds. Does wait(2) works here?

Use
Channel: $number
Application: Playback
Data: beep&silence/2&$outputfilename
That way it will play beep, which probably will be not heared by human, but for sure will start rtp process. After that 2 second wait(silence file) which may be required for echocancel training or connection process. That way you message will go clear.

You can create new dialplan context. In it You add Wait application and then Palyback. In call file you can connect number to this new context by specifying it directly or dialing to it via Dial(Local/XXX#new-context)
http://www.voip-info.org/wiki/view/Asterisk+auto-dial+out

The issue you're having is the RTP stream not being fully "up". Until the call is established, RTP (sound) isn't shipped. So, if you "start talking" right away, you loose words. This is a dialplan side problem, because it depends on both ends of the call being in the "shipping sound" phase.
Using Answer() ; Wait() will not always fix this issue on VoIP connections, because it doesn't actually get the audio stream moving. Wait() is more for cranky T1 lines with slow set-up speeds where you are literally waiting for the rest of the hardware to catch up.
You can get around this by just playing 1 or 2 seconds (1 works 80% of the time) of silence. Eg:
[answering_context]
exten => s,1,Verbose(2,Example of good audio discipline)
same => n, Playback(silence/1)
same => n, Playback(the_real_message_you_want_to_send)
"Silence" is technically "still sound", but the human can't tell if you are shedding packets or clipping words during "silence". By the time the the_real_message_you_want_to_send gets played, the audio stream will be fully stable.
Cheers!

Related

LWIP: How exactly does the TCP_INTERVAL relate to the reception of ACK Messages?

I am trying to implement a data transfer from an embedded board to a PC. For this, I need to use low latency communication and I am bound to use Ethernet with TCP/IP.
Furthermore, I'm using the lwip stack.
First of all, I disabled nagle algorithm, because I have to send small packets of data (10 KB) and I want them to be sent as soon as possible, without waiting for intermediate ACKS.
The Wireshark Log shows me that this is working quite fine (the whole data is being sent to the PC in about 1msec).
After that, the PC takes about 200msec to send the last ACK (because the last Segment is not maximum size).
The problem is now, that on the embedded processor, it takes a very long time, until the lwip gives my application the message, that all of the data has been ACKED.
When I decrease the TCP_INTERVAL (to let's say 5), it speeds up greatly.
I am wondering, why lwip behaves like this? I would think that the Periodic-TCP-Tasks (which are being called according to the TCP_INTERVAL) have nothing to do with the Handling of the received frames (which is really another call in the main).
I hope I could state my problem somehow understandable, if not I would appreciate feedback, so I can improve my question!
Thanks!
EDIT:
After more debugging, I found out that the process of sending data results in the following function calls:
My main calls tcp_write(...)
tcp_tmr() is called multiple times (through the LwIP_Periodic_Handle() function). This happens seven times. During the eigth call:
tcp_output() is called. During this call, all segments which were added during the last tcp_write() call are sent by calling tcp_output_segment().
So now it is clear that if I reduce the TCP_INTERVAL, of course the data gets sent sooner, because the tcp_tmr() function is called more quickly.
but my question is still: Is this the normal behaviour? It seems a bit odd, that lwIP is waiting such a long time before actually sending the data.
Since Youre doing this My main calls tcp_write(...)
use tcp_output() immediately after tcp_write
or else use tcp_write() in tcp_recv callback

Detect silence while playing sound

I am developing an java-asterisk application that is calling subscribers to deliver messages. At some moments during the call, I need to monitor whether the subscriber is talking or is silent. I need to monitor that for a fairly long time (1-3 seconds) but don't want to interrupt the flow of the outgoing message.
The way I am doing it now is as below
streamFile(*file A*);
exec("WaitForSilence","300,1,1");
waitStatus=getVariable("WAITSTATUS");
streamFile(*file B*);
This works fine but it is only a 300ms detect and a 1s timeout, so from the subscriber point of view the silence between file A and file B is almost unnoticeable. But if I want to listen for longer (say 3 seconds for example) then the subscriber's experience will be ruined.
What I would need is a function similar to "WaitForSilence" but that:
runs in parallel to the script;
delivers its outcome in a variable channel with a name that I define (as there might be several calls to the function, and I need to get all the results)
I've been looking for more than aweek now and couldn't find a way to do that. Any ideas?
Code you provided will do wait, after that will do playback.
There are no way do that simple in one application.
Posible ways:
1) create c/c++ application(asterisk guru skill required) for that.
2) create enother channel, mix it with ChanSpy and in that channel do silence detect. Complexity - expert in asterisk.
Both are not so short(more then 2-3 screens of code), so can't be described in this site.
You can also try use Background application, but i am afraid it will not work too.

TCP Connection slows down after 10.000 packets

I am using the QT implementation of the TCP stack to control a robot. We exchange short msgs (<200Byte) and have a round trip time of about 8ms. After maybe 10.000 Packets in each direction, the connection slows down and i have to wait about 1 sec for the answer of my packet. If I restart my program, and reconnect, I again get the 8ms RTT.
For me it sounds like some kind of buffer is filling up but I havn't worked with TCP much, so maybe some one could give me a hint.
The problem is in the code that you're not showing. Likely the slot that gets executed on readyRead() is not emptying the buffer.
It is acceptable for the buffer not to be completely empty, say when you're reading complete lines/packets.
It is not acceptable for the buffer size to be constantly growing.
At the end of your slot reading slot, check if bytesAvailable() is non-zero. It can only be non-zero in case #1. Even then, you should be able to place an upper bound on it - say some small multiple of packet size or maximum line length. If the bound is ever exceeded, you've got a bug in your code.
It is just a wild guess, but a common catch by using qt sockets is that you need to delete the socket object by yourself ( for example with "deleteLater()") on error and disconnection.
Example code:
connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
The event loop will then remove the socket the next time it is able to do it.
The QTcpSockets or AbstractSockets don't delete themselfs on close() or on leaving the scope (because then the Signal/Slots won't work).

tcp connect timeout (unix/windows portable)

I'm using perl (which hopefully shouldn't affect anything), but I need to know how I can set a timeout for the connect operation. The problem is I can't wait forever for the connect operation to happen. If it doesn't happen within a few seconds, I'd rather give-up and move on.
socket(my $sock, PF_INET, SOCK_STREAM, (getprotobyname('tcp'))[2]);
setsockopt($sock, SOL_SOCKET, SO_SNDTIMEO, 10); # send timeout
print "connecting...\n";
connect($sock, sockaddr_in(80,scalar gethostbyname('lossy.host.com')));
print "connected...\n";
The problem is, if the connection to "lossy.host.com" is "lossy" or slow or anything but fast, I'd rather give up than make the user wait. (Think of it as a side-effect to a program that does something else... the user probably doesn't expect this script to communicate with a server somewhere...).
Threading Case: How would you interrupt the connect()? Would you just detach the thread and forget about it?
You can use fcntl to set the socket to be non-blocking, then select with a timeout waiting for it to become readable. If it doesn't become readable before the timeout, you could close it at that point.
I know how to do this in C, but not perl, otherwise I'd give you an example. The perlfunc manpage says that all of these functions exist and a cursory read seems to say they'll work like you want.
Edit: sorry, missed the part where perlfunc says they may not be available on non-Unix systems, and indeed, fcntl isn't available on win32. There is an IO::Socket library that you can use that will do the right thing on Windows though.
Here's sample code that works for me (on linux anyway):
#!/usr/bin/perl
use IO::Socket::INET;
use IO::Select;
$sock = IO::Socket::INET->new('PeerAddr' => 'lossy.host.com',
'PeerPort' => 80,
'Blocking' => 0 );
$sel = IO::Select->new( $sock );
#writes = $sel->can_write(10);
if ( $sock->connected ) {
print "socket is connected\n";
} else {
print "socket not connected after however long\n";
$sock->close;
}
You could spawn a separate thread to do it, and then do a timed wait for a result. If you don't receive a result in an appropriate amount of time, give up waiting and just let the thread continue. It will eventually time out, or you might be able to kill the thread.
To answer the initial question, I don't think there's a way to change the connect() timeout, at least not through a sockets API. On Windows, I wouldn't be surprised if there's a registry key you could change that would affect it, but I don't know what it would be.
If you end up doing the threaded case wherein you detach the connecting thread without killing it, beware the following: Windows only lets you have a maximum of 10 pending outgoing TCP connections (the 11th will block until one of the pending ones times out).
This was the cause of much frustration for me. I think MS put this in to prevent botnets from spreading or something. I don't think there's any way to switch it off either.

Receiving image through winsocket

i have a proxy server running on my local machine used to cache images while surfing. I set up my browser with a proxy to 127.0.0.1, receive the HTTP requests, take the data and send it back to the browser. It works fine for everything except large images. When I receive the image info, it only displays half the image (ex.: the top half of the google logo) heres my code:
char buffer[1024] = "";
string ret("");
while(true)
{
valeurRetour = recv(socketClient_, buffer, sizeof(buffer), 0);
if(valeurRetour <= 0) break;
string t;
t.assign(buffer,valeurRetour);
ret += t;
longueur += valeurRetour;
}
closesocket(socketClient_);
valeurRetour = send(socketServeur_, ret.c_str(),longueur, 0);
the socketClient_ is non-blocking. Any idea how to fix this problem?
You're not making fine enough distinctions among the possible return values of recv.
There are two levels here.
The first is, you're lumping 0 and -1 together. 0 means the remote peer closed its sending half of the connection, so your code does the right thing here, closing its socket down, too. -1 means something happened besides data being received. It could be a permanent error, a temporary error, or just a notification from the stack that something happened besides data being received. Your code lumps all such possibilities together, and on top of that treats them the same as when the remote peer closes the connection.
The second level is that not all reasons for getting -1 from recv are "errors" in the sense that the socket is no longer useful. I think if you start checking for -1 and then calling WSAGetLastError to find out why you got -1, you'll get WSAEWOULDBLOCK, which is normal since you have a non-blocking socket. It means the recv call cannot return data because it would have to block your program's execution thread to do so, and you told Winsock you wanted non-blocking calls.
A naive fix is to not break out of the loop on WSAEWOULDBLOCK but that just means you burn CPU time calling recv again and again until it returns data. That goes against the whole point of non-blocking sockets, which is that they let your program do other things while the network is busy. You're supposed to use functions like select, WSAAsyncSelect or WSAEventSelect to be notified when a call to the API function is likely to succeed again. Until then, you don't call it.
You might want to visit The Winsock Programmer's FAQ. (Disclaimer: I'm its maintainer.)
Have you analyzed the transaction at the HTTP level i.e. checked Headers?
Are you accounting for things like Chunked transfers?
I do not have a definite answer in part because of the lack of details given here.

Resources