Summary:ASTERISK-13051: [patch] Can't record early media after sending a "183 Session Progress".
Reporter:Nahuel Greco (nahuelgreco)Labels:
Date Opened:2008-11-11 14:40:31.000-0600Date Closed:2008-11-18 16:47:53.000-0600
Versions:Frequency of
Environment:Attachments:( 0) sip-early-media-recording-1.4.22.patch
( 1) sip-early-media-recording-
Suposse you have the following extension defined in extensions.conf:

   exten => 7,1,Playback(beep,noanswer)
   exten => 7,2,Record(test.wav,0,10,n)
   exten => 7,3,Playback(beep,noanswer)

And you have "progressinband" set to "yes" in sip.conf. Asterisk will send a
"183 Session Progress" with an SDP and then it will send the RTP audio for
the first beep. The calling party will hear it correctly, and then the Record
application will be executed (note the "n" parameter used to not answer the
call, similar to the "noanswer" one in the Playback app).

In Asterisk 1.2.x, the Record line works ok, the calling party records to
test.wav successfully, but in 1.4.x and 1.6.x, the Record app will always
generate a 44 bytes .wav file, that is, a void wav (44 bytes are for the
header). This problem also happens if you use the Monitor application.

I think the incoming audio is "silenced" in the sip_read() function at
chan_sip.c, in 1.4.x this code was added at the end of the function:

  /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */
  if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) {
             fr = &ast_null_frame;

The "183 Session Progress" packet can be sent from two functions, from a couple
of points in sip_write() like in:

  if ((ast->_state != AST_STATE_UP) &&
      !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
      !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
           transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
           ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);

and from sip_indicate():

   if ((ast->_state != AST_STATE_UP) &&
       !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
       !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
           p->invitestate = INV_EARLY_MEDIA;
           transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
           ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);

As you can note, p->invitestate is not set to INV_EARLY_MEDIA in sip_write(),
so if the 183 is sent from that point, then sip_read() will silence any
incoming audio. Because this, Record will not record anything. This can be
fixed by setting the p->invitestate variable to INV_EARLY_MEDIA in all the 183
sending points. I'm attaching a patch for 1.4.22 and another for doing
that, but I'm not sure if this is a bug or there is a rationale behind not
setting that variable in these points. At first look it seems an oversight when
adding the invitestate variable from 1.2.x to 1.4.x, and by only affecting a rare case like this (recording early media) it becomed unnoticed.

Comments:By: Mark Michelson (mmichelson) 2008-11-18 16:45:27.000-0600

Thanks for the patch. When I initially viewed it, I thought that it wasn't right because of the comment explaining what the INV_EARLY_MEDIA state was. Basically, I interpreted the comment to mean that we would set this only if we received a 18X response, not if we sent one. After searching through the source, though, I see that this state is used for both sending and receiving 18X responses, so when I commit your patch, I also am going to update the doxygen describing INV_EARLY_MEDIA so that it doesn't cause confusion again.

Btw, another nitpick about the patch is that you used spaces instead of tabs at the beginning of the lines you added. Please be sure to read the coding guidelines located in the doc/ directory of the Asterisk source. Aside from that, great detective work and thank you for explaining the problem with such detail in your bug report. Reporters like you make this job a lot easier :)

By: Digium Subversion (svnbot) 2008-11-18 16:47:52.000-0600

Repository: asterisk
Revision: 157503

U   branches/1.4/channels/chan_sip.c

r157503 | mmichelson | 2008-11-18 16:47:52 -0600 (Tue, 18 Nov 2008) | 13 lines

Add some missing invite state changes necessary in the sip_write
function. Not setting the invite state correctly on the call was
resulting in the Record application leaving empty files. I also
have updated the doxygen comment next to the declaration of the
INV_EARLY_MEDIA constant to reflect that we also use this state
when we *send* a 18X response to an INVITE.

(closes issue ASTERISK-13051)
Reported by: nahuelgreco
     sip-early-media-recording-1.4.22.patch uploaded by nahuelgreco (license 162)
 Tested by: putnopvut