[asterisk-dev] IAX internet draft (draft-guy-iax-00)

Tim Panton tim at mexuar.com
Mon Mar 6 14:39:56 MST 2006


On 6 Mar 2006, at 20:01, Derek Smithies wrote:

> Hi,
>
>>>   Consequently, there are times when the timestamp (on the sending
>>> side)
>>>    has to be "tweaked" high by 3, to differentiate between two
>>> different
>>>    frames.  A lagrq frame does not increase the oseqno at the  
>>> sending
>>>    side.
>>
>> I don't see why you say that. I think the +3 stuff is a work around
>> for a
>> specific implementation problem, not a protocol requirement.
>> The combination of oseqno with ack'ness makes a packet unique.
>>
> I am sorry - I do remember reading something about this +3 business  
> was a
> jiter buffer saviour. From the code:
>
> /* On a dataframe, use last value + 3 (to accomodate jitter buffer
>                shrinking) if appropriate unless it's a genuine  
> frame */
> if (genuine) {
> 	/* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
> 	if (ms <= p->lastsent)
> 		ms = p->lastsent + 3;
> } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
>   /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into
>                               the predicted stream stamps */
> 	ms = p->lastsent + 3;
> }

I'm none too clear on the purpose of this, but it seems to be  
specific to
the way that the current jitterbuffer is implemented, not intrinsic  
to the protocol.

I'm deliberately staying away from looking too deeply at the  
IAXclient codebase,
it should be possible to implement it just from the RFC (I couldn't,  
I needed
some advice). Perhaps SteveK can comment?

>
>
> =====================
>
>>>  A timestamp MUST also be assigned for the
>>>    call, beginning at 0 and incrementing each millisecond
>>> is unclear.
>>> Incrementing by what value??
>>>
>>> In fact::
>>>  The timestamp has  units of milliseconds.
>>>  Thus, the maximum timestamp in a 16bit field is 65.535 seconds.
>>
>> No, timestamp is either a 32 bit field (fullframe) or a 15 bit field
>> (miniframes).
>>
>> If you wrap a 32 bit counter in a single call, you have other
>> problems.......
>>
> No, you misunderstand me completetly. completely.

oops, sorry.

>
> The maximum timestamp value you can squeeze into a 16 bit field,  
> such as
> in a mini frame, 65.535 ms. From iax2 packet dumps, immediately prior
> to this value wrapping around when this value wraps, one full frame
> of voice is sent.

Yes, true.

>
> I was not talking about the 32 bit value wrapping around.
> I was talking about the 16 bit value wrappng around.

Ah, ok. for some reason I had 15 bits stuck in my head as the length
of a miniframe timestamp (i.e. ~33 secs) but you are right, it is
16 bits.

I must be being stupid, but I still can't see the issue, the RFC says
that the timestamps are in ms since the begining of the the call:


    Timestamp
       The Timestamp field contains a 32-bit timestamp maintained by an
       IAX peer for a given call.  The timestamp is an incrementally
       increasing representation of the number of milliseconds since the
       first transmission of the call.

    Timestamp
       Mini frames carry a 16-bit timestamp, which is the lower 16 bits
       of the transmitting peer's full 32-bit timestamp for the call.
       The timestamp allows synchronization of incoming frames so that
       they may be processed in chronological order instead of the
       (possibly different) order in which they are received.  The 16- 
bit
       timestamp wraps after 65.536 seconds, at which point a full frame
       SHOULD be sent to notify the remote peer that its timestamp has
       been reset.  A call must continue to send mini frames starting
       with timestamp 0 even if acknowledgment of the resynchronization
       is not received.

What do you feel we need to add here ?

Our send code (in java - so char is a 16 bit unsigned) looks a bit  
like this:

                 char mstamp = (char) (0xffff & _stamp);
                 if (_first || (mstamp < _lastminisent)) {
                     _first = false;
                     VoiceFrame vf = new VoiceFrame(_call);
                     // send a full audio frame
                 }
                 else {
                     // send a miniframe
                     MiniFrame mf = new MiniFrame(_call);
                 }
		_lastminisent = mstamp;


Tim.


Tim Panton
tim at mexuar.com






More information about the asterisk-dev mailing list