/* Ċ Ġ* ĠCopyright Ġ@ Ġ 2 0 1 8 Ġ- ĠPresent , Ġ 8 x 8 ĠInc Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġorg . j its i . rtp . util Ċ Ċ import Ġorg . j its i . utils . Time Utils Ċ Ċ class ĠR tp Utils Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġ[ size Bytes ] ĠMUST Ġincluding Ġpadding Ġ( i . e . Ġit Ġshould Ġbe Ġ 3 2 - bit Ġword Ġaligned ) ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġcalculate R tcp Length FieldValue ( size Bytes : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( size Bytes Ġ% Ġ 4 Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠException (" Invalid ĠR TCP Ġsize Ġvalue ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ( size Bytes Ġ/ Ġ 4 ) Ġ- Ġ 1 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠGet Ġthe Ġnumber Ġof Ġbytes Ġneeded Ġto Ġpad Ġ[ data Size Bytes ] Ġbytes Ġto Ġa Ġ 4 - byte Ġword Ġboundary . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun ĠgetNum Padding Bytes ( data Size Bytes : ĠInt ): ĠInt Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( data Size Bytes Ġ% Ġ 4 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 Ġ-> Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 Ġ-> Ġ 3 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 2 Ġ-> Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 3 Ġ-> Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ 0 Ġ// ĠThe Ġabove Ġis Ġex haustive . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠReturns Ġthe Ġdelta Ġbetween Ġtwo ĠR TP Ġsequence Ġnumbers , Ġtaking Ġinto Ġaccount ĊĠĠĠĠĠĠĠĠ Ġ* Ġrol lover . Ġ ĠThis Ġwill Ġreturn Ġthe Ġ' short est ' Ġdelta Ġbetween Ġthe Ġtwo ĊĠĠĠĠĠĠĠĠ Ġ* Ġsequence Ġnumbers Ġin Ġthe Ġform Ġof Ġthe Ġnumber Ġyou 'd Ġadd Ġto Ġb Ġto Ġget Ġa . Ġe . g .: ĊĠĠĠĠĠĠĠĠ Ġ* Ġget SequenceNumber Delta ( 1 , Ġ 1 0 ) Ġ-> Ġ- 9 Ġ( 1 0 Ġ+ Ġ- 9 Ġ= Ġ 1 ) ĊĠĠĠĠĠĠĠĠ Ġ* Ġget SequenceNumber Delta ( 1 , Ġ 6 5 5 3 0 ) Ġ-> Ġ 7 Ġ( 6 5 5 3 0 Ġ+ Ġ 7 Ġ= Ġ 1 ) ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return Ġthe Ġdelta Ġbetween Ġtwo ĠR TP Ġsequence Ġnumbers Ġ( modulo Ġ 2 ^ 1 6 ). ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġget SequenceNumber Delta ( a : ĠInt , Ġb : ĠInt ): ĠInt Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget SequenceNumber Delta As Short ( a , Ġb ). toInt () ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠLike Ġ[ get SequenceNumber Delta ], Ġbut Ġreturning Ġthe Ġdelta Ġas Ġa Ġ[ Short ]. ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* ĠTODO : Ġsince Ġ[ Short ] Ġcan Ġfully Ġrepresent Ġsequence Ġnumber Ġdelt as , ĊĠĠĠĠĠĠĠĠ Ġ* ĠĠ Ġchange Ġthis Ġto Ġbe Ġthe Ġpublic ĠAPI ? ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġinline Ġfun Ġget SequenceNumber Delta As Short ( a : ĠInt , Ġb : ĠInt ): ĠShort Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/* ĠCo erc ing Ġto Ġshort Ġforces Ġdiff Ġto Ġthe Ġrange Ġ- 0 x 8 0 0 0 Ġ- Ġ 0 x 7 fff , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhich Ġis Ġwhat Ġwe Ġwant . Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( a Ġ- Ġb ). to Short () ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠApply Ġa Ġdelta Ġto Ġa Ġgiven Ġsequence Ġnumber Ġand Ġreturn Ġthe Ġresult Ġ( t aking ĊĠĠĠĠĠĠĠĠ Ġ* Ġrol lover Ġinto Ġaccount ) ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġstart Ġthe Ġstarting Ġsequence Ġnumber ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġdelta Ġthe Ġdelta Ġto Ġbe Ġapplied ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return Ġthe Ġsequence Ġnumber Ġresulting Ġfrom Ġdoing Ġ" start Ġ+ Ġdelta " ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġapply SequenceNumber Delta ( start : ĠInt , Ġdelta : ĠInt ): ĠInt Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( start Ġ+ Ġdelta ) Ġand Ġ 0 xffff ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠApply Ġa Ġdelta Ġto Ġa Ġgiven ĠR TP Ġtimestamp Ġand Ġreturn Ġthe Ġresult Ġ( t aking ĊĠĠĠĠĠĠĠĠ Ġ* Ġrol lover Ġinto Ġaccount ) ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġstart Ġthe Ġstarting Ġtimestamp ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġdelta Ġthe Ġdelta Ġto Ġbe Ġapplied ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return Ġthe Ġtimestamp Ġresult Ġfrom Ġdoing Ġ" start Ġ+ Ġdelta " ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġapply Timestamp Delta ( start : ĠLong , Ġdelta : ĠLong ): ĠLong Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( start Ġ+ Ġdelta ) Ġand Ġ 0 xffff _ ffff L ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġis New er SequenceNumber Than ( a : ĠInt , Ġb : ĠInt ): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget SequenceNumber Delta As Short ( a , Ġb ) Ġ> Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġis Ol der SequenceNumber Than ( a : ĠInt , Ġb : ĠInt ): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget SequenceNumber Delta As Short ( a , Ġb ) Ġ< Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġis New er Timestamp Than ( a : ĠLong , Ġb : ĠLong ): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Timestamp Diff As Int ( a , Ġb ) Ġ> Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġis Ol der Timestamp Than ( a : ĠLong , Ġb : ĠLong ): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Timestamp Diff As Int ( a , Ġb ) Ġ< Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠReturns Ġthe Ġdifference Ġbetween Ġtwo ĠR TP Ġtimestamps . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return Ġthe Ġdifference Ġbetween Ġtwo ĠR TP Ġtimestamps . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġget Timestamp Diff ( a : ĠLong , Ġb : ĠLong ): ĠLong Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Timestamp Diff As Int ( a , Ġb ). to Long () ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠReturns Ġthe Ġdifference Ġbetween Ġtwo ĠR TP Ġtimestamps Ġas Ġan Ġ[ Int ]. ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* ĠTODO : Ġsince Ġ[ Int ] Ġcan Ġfully Ġrepresent Ġtimestamp Ġdelt as , ĊĠĠĠĠĠĠĠĠ Ġ* ĠĠ Ġchange Ġthis Ġto Ġbe Ġthe Ġpublic ĠAPI ? ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġinline Ġfun Ġget Timestamp Diff As Int ( a : ĠLong , Ġb : ĠLong ): ĠInt Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/* ĠCo erc ing Ġto Ġint Ġforces Ġdiff Ġto Ġthe Ġrange Ġ- 0 x 8 0 0 0 _ 0 0 0 0 Ġ- Ġ 0 x 7 fff _ ffff , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhich Ġis Ġwhat Ġwe Ġwant . Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( a Ġ- Ġb ). toInt () ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠReturns Ġa Ġsequence Ġof ĠIn ts Ġfrom Ġolder Seq Num Ġ( exclusive ) Ġto Ġnewer Seq Num Ġ( exclusive ), ĊĠĠĠĠĠĠĠĠ Ġ* Ġtaking Ġrol lover Ġinto Ġaccount ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġsequence Numbers Between ( older Seq Num : ĠInt , Ġnewer Seq Num : ĠInt ): ĠSequence < Int > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġcurr Seq Num Ġ= Ġolder Seq Num ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġgenerate Sequence Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurr Seq Num Ġ= Ġ( curr Seq Num Ġ+ Ġ 1 ) Ġ% Ġ 0 x 1 _ 0 0 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( curr Seq Num Ġ== Ġnewer Seq Num ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurr Seq Num ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠGiven Ġ[ timestamp Ms ] Ġ( a Ġtimestamp Ġin Ġmilliseconds ), Ġconvert Ġit Ġto Ġan ĠN TP Ġtimestamp Ġrepresented ĊĠĠĠĠĠĠĠĠ Ġ* Ġas Ġa Ġpair Ġof Ġints : Ġthe Ġfirst Ġone Ġbeing Ġthe Ġmost Ġsignificant Ġword Ġand Ġthe Ġsecond Ġbeing Ġthe Ġleast ĊĠĠĠĠĠĠĠĠ Ġ* Ġsignificant Ġword . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġmillis To N tp Timestamp ( timestamp Ms : ĠLong ): ĠLong Ġ= ĠTime Utils . to N tp Time ( timestamp Ms ) ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġconvert R tp Timestamp To Ms ( rtp Timestamp : ĠInt , Ġticks PerSecond : ĠInt ): ĠLong Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ(( rtp Timestamp Ġ/ Ġ( ticks PerSecond . toDouble ())) Ġ* Ġ 1 0 0 0 ). to Long () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠInt . is Padding (): ĠBoolean Ġ= Ġthis . to Byte (). is Padding () Ċ fun ĠByte . is Padding (): ĠBoolean Ġ= Ġthis Ġ== Ġ 0 x 0 0 . to Byte () Ċ Ċ /** Ċ Ġ* ĠReturns Ġtrue Ġif Ġthe ĠR TP Ġsequence Ġnumber Ġrepresented Ġby Ġ[ this ] Ġrepresents Ġa Ġmore Ġrecent ĠR TP Ġpacket Ġthan Ġthe Ġone Ċ Ġ* Ġrepresented Ġby Ġ[ other Seq Num ] Ċ Ġ*/ Ċ infix Ġfun ĠInt . isNew er Than ( other Seq Num : ĠInt ): ĠBoolean Ġ= ĊĠĠĠ ĠR tp Utils . isNew er SequenceNumber Than ( this , Ġother Seq Num ) Ċ Ċ infix Ġfun ĠInt . is Ol der Than ( other Seq Num : ĠInt ): ĠBoolean Ġ= ĊĠĠĠ ĠR tp Utils . is Ol der SequenceNumber Than ( this , Ġother Seq Num ) Ċ Ċ infix Ġfun ĠLong . isNew er Timestamp Than ( other Timestamp : ĠLong ): ĠBoolean Ġ= ĊĠĠĠ ĠR tp Utils . isNew er Timestamp Than ( this , Ġother Timestamp ) Ċ Ċ infix Ġfun ĠLong . is Ol der Timestamp Than ( other Timestamp : ĠLong ): ĠBoolean Ġ= ĊĠĠĠ ĠR tp Utils . is Ol der Timestamp Than ( this , Ġother Timestamp ) Ċ Ċ /** Ċ Ġ* ĠReturns Ġtrue Ġif Ġgetting Ġto Ġ[ other Seq Num ] Ġfrom Ġthe Ġcurrent Ġsequence Ġnumber Ġinvolves Ġwrapping Ġaround Ċ Ġ*/ Ċ infix Ġfun ĠInt . rolled Over To ( other Seq Num : ĠInt ): ĠBoolean Ġ= ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIf , Ġaccording Ġto Ġ[ is Ol der Than ], Ġ[ this ] Ġis Ġolder Ġthan Ġ[ other Seq Num ] Ġand ĊĠĠĠĠ Ġ* Ġyet Ġ[ other Seq Num ] Ġis Ġless Ġthan Ġ[ this ], Ġthen Ġwe Ġwrapped Ġaround Ġto Ġget Ġfrom Ġ[ this ] Ġto ĊĠĠĠĠ Ġ* Ġ[ other Seq Num ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġthis Ġis Ol der Than Ġother Seq Num Ġ&& Ġother Seq Num Ġ< Ġthis Ċ Ċ /** Ċ Ġ* ĠReturns Ġtrue Ġif Ġ[ this ] Ġis Ġse quent ially Ġafter Ġ[ other Seq Num ], Ġaccording Ġto Ġthe Ġrules Ġof ĠR TP Ġsequence Ċ Ġ* Ġnumbers Ċ Ġ*/ Ċ infix Ġfun ĠInt . is Next After ( other Seq Num : ĠInt ): ĠBoolean Ġ= ĠR tp Utils . get SequenceNumber Delta ( this , Ġother Seq Num ) Ġ== Ġ 1 Ċ Ċ /** Ċ Ġ* ĠReturn Ġthe Ġamount Ġof Ġpackets Ġbetween Ġthe ĠR TP Ġsequence Ġnumber Ġrepresented Ġby Ġ[ this ] Ġand Ġthe Ġ[ other Seq Num ]. Ġ ĠNOTE : Ċ Ġ* Ġ[ this ] Ġmust Ġrepresent Ġan Ġolder ĠR TP Ġsequence Ġnumber Ġthan Ġ[ other Seq Num ] Ġ( TODO : Ġvalidate / enforce Ġthat ) Ċ Ġ*/ Ċ infix Ġfun ĠInt . num Packet sTo ( other Seq Num : ĠInt ): ĠInt Ġ= Ġ- R tp Utils . get SequenceNumber Delta ( this , Ġother Seq Num ) Ġ- Ġ 1 Ċ