Hi Matthew,

On 01/28/2014 01:00 AM, Matthew Jordan wrote:
In res_rtp_asterisk, the packet is read from the socket in
ast_rtp_read. This is also the place where the read data is converted
into a frame of the appropriate type. The payload for the voice frame
is obtained in the actual RTP packet itself:

     rtp->f.src = "RTP";
     rtp->f.mallocd = 0;
     rtp->f.datalen = res - hdrlen;
     rtp->f.data.ptr = rtp->rawdata + hdrlen + AST_FRIENDLY_OFFSET;
     rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET;
     rtp->f.seqno = seqno;

Later on, an ast_frdup most likely pulled the frame off of the rtp
engine and re-malloc'd it; however, this is code that happens all the
time and wouldn't have perturbed the datalen. Your problem is most
likely coming from whatever RTP packet was sent to Asterisk. You may
want to look at a pcap of the message traffic that caused the problem
to determine what about the packet is causing the issue.

It may be necessary for something either in res_rtp_asterisk or
res_fax_spandsp to verify that the number of samples in the RTP packet
(or what the voice frame has in it before it gets handed off) matches
what is expected.


Thank you very much for explanation. I'm not very familiar with RTP source code, this makes things more clear to me (but there is still lot of code, which I don't understand). Please be so kind, and look at this:

In my setup, I should have 20ms A-law frames from RTP, and 20ms A-law frames from DAHDI (alawtosln). With sampling frequency 8000 Hz, I should have 50 frames per second, and every frame should have (8000/50)=160 samples inside. A-law samples are stored as 16bit integers, so all samples int he frame should be 320 bytes long.

Now please look at the values, which are stored inside ast_frame structure. I dump contents of structure in res_fax_spandsp, just before frame pointer is passed to modem_connect_tones_rx(). Following sequence of frames is RTP part of a call, just after call was answered:

{ frametype=2, datalen=160, samples=160, mallocd=1, mallocd_hdr_len=562, offset=64, src=RTP, flags=1, ts=10300, len=20, seqno=55975, data.ptr=0x82cfcb8 } { frametype=2, datalen=160, samples=160, mallocd=0, mallocd_hdr_len=0, offset=76, src=RTP, flags=1, ts=10320, len=20, seqno=55976, data.ptr=0xb54013c0 } { frametype=2, datalen=160, samples=160, mallocd=0, mallocd_hdr_len=0, offset=76, src=RTP, flags=1, ts=10340, len=20, seqno=55977, data.ptr=0xb54013c0 } { frametype=2, datalen=160, samples=160, mallocd=0, mallocd_hdr_len=0, offset=76, src=RTP, flags=1, ts=10360, len=20, seqno=55978, data.ptr=0xb54013c0 } { frametype=2, datalen=160, samples=160, mallocd=0, mallocd_hdr_len=0, offset=76, src=RTP, flags=1, ts=10380, len=20, seqno=55979, data.ptr=0xb54013c0 } { frametype=2, datalen=160, samples=160, mallocd=0, mallocd_hdr_len=0, offset=76, src=RTP, flags=1, ts=10400, len=20, seqno=55980, data.ptr=0xb54013c0 } { frametype=2, datalen=160, samples=160, mallocd=0, mallocd_hdr_len=0, offset=76, src=RTP, flags=1, ts=10420, len=20, seqno=55981, data.ptr=0xb54013c0 } { frametype=2, datalen=160, samples=160, mallocd=0, mallocd_hdr_len=0, offset=76, src=RTP, flags=1, ts=10440, len=20, seqno=55982, data.ptr=0xb54013c0 } { frametype=2, datalen=160, samples=160, mallocd=0, mallocd_hdr_len=0, offset=76, src=RTP, flags=1, ts=10460, len=20, seqno=55983, data.ptr=0xb54013c0 } { frametype=2, datalen=160, samples=160, mallocd=0, mallocd_hdr_len=0, offset=76, src=RTP, flags=1, ts=10480, len=20, seqno=55984, data.ptr=0xb54013c0 }

And now, look at the A-law frames coming from DAHDI:

{ frametype=2, datalen=320, samples=160, mallocd=1, mallocd_hdr_len=722, offset=64, src=alawtolin, flags=0, ts=0, len=0, seqno=0, data.ptr=0x84d1138 } { frametype=2, datalen=320, samples=160, mallocd=1, mallocd_hdr_len=722, offset=64, src=alawtolin, flags=0, ts=0, len=0, seqno=0, data.ptr=0x84d1138 } { frametype=2, datalen=320, samples=160, mallocd=1, mallocd_hdr_len=722, offset=64, src=alawtolin, flags=0, ts=0, len=0, seqno=0, data.ptr=0x84d1138 } { frametype=2, datalen=320, samples=160, mallocd=1, mallocd_hdr_len=722, offset=64, src=alawtolin, flags=0, ts=0, len=0, seqno=0, data.ptr=0x84d1138 } { frametype=2, datalen=320, samples=160, mallocd=1, mallocd_hdr_len=722, offset=64, src=alawtolin, flags=0, ts=0, len=0, seqno=0, data.ptr=0x84d1138 } { frametype=2, datalen=320, samples=160, mallocd=1, mallocd_hdr_len=722, offset=64, src=alawtolin, flags=0, ts=0, len=0, seqno=0, data.ptr=0x84d1138 } { frametype=2, datalen=320, samples=160, mallocd=1, mallocd_hdr_len=722, offset=64, src=alawtolin, flags=0, ts=0, len=0, seqno=0, data.ptr=0x84d1138 } { frametype=2, datalen=320, samples=160, mallocd=1, mallocd_hdr_len=722, offset=64, src=alawtolin, flags=0, ts=0, len=0, seqno=0, data.ptr=0x84d1138 } { frametype=2, datalen=320, samples=160, mallocd=1, mallocd_hdr_len=722, offset=64, src=alawtolin, flags=0, ts=0, len=0, seqno=0, data.ptr=0x84d1138 } { frametype=2, datalen=320, samples=160, mallocd=1, mallocd_hdr_len=722, offset=64, src=alawtolin, flags=0, ts=0, len=0, seqno=0, data.ptr=0x84d1138 }


In file include/asterisk/frame.h there is struct ast_frame defined, and I see that:
        int datalen;             /*! Length of data */
        int samples;           /*! Number of samples in this frame */
int mallocd; /*! Was the data malloc'd? i.e. should we free it when we discard the frame? */

I think that if in both cases we have A-law samples, we have also 320 bytes of data in both cases, and so we should have "datalen" set to 320 in both cases. But for RTP frames, "datalen" is set to 160. It is impossible to store 320 bytes into 160bytes space. Datalen should be 320 also for RTP frame. "Datalen" is set probably somewehere in frame.c, I don't know yet where it is exactly (for this frame). But I see in frame.c that "datalen" and also "samples" are used when allocating memory and copying data, and if have bad value there, I expect that bad things may happen. I think this could be the problem what we are looking for, but maybe I am completely wrong... I'm not sure. What do you think?

Also I don't understand other difference. Frames coming from DAHDI has mallocd=1 and data.ptr points always to the same address, for all frames. But frames from RTP are different - first frame (which sometimes causes segfault) has very different data.ptr address, and has mallocd=1. Next RTP frames has mallocd=0, and data.ptr is now different as at the first frame, but remains the same for all next frames. Is it the correct behavior, or is there something wrong? Why first RTP frame in the call is stored on the other memory address, than all other RTP frames?

Thank you very much

--
Michal Rybarik

--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
  http://lists.digium.com/mailman/listinfo/asterisk-dev

Reply via email to