ISipRegistrationListener.OnRegistrationDone()给出的过期时间值太高

时间:2018-11-02 22:35:00

标签: android xamarin.android sip

我已成功注册一个有效期为1小时的SipProfile。我在SIP服务器计算机上的Wireshark中看到REGISTER消息,已通过授权重新发送。
Brekeke立即回复状态为:200 OK,并传回“ Expires:3600”。

Wireshark capture of SIP registration

XamarinAndroid这两个文档都告诉我lExpire应该是在注册过期前的几秒钟内持续时间,因此它表示一个间隔。我想公开接收到的值,因此将TimeSpan.TicksPerSecond乘以(转换为TimeSpan),则3600将导致0.01:00:00

void    ISipRegistrationListener.OnRegistrationDone( string lclPrfUri, long lExpire )
{
    long    l=  DateTime.Now.Ticks;
    double  d=  (double)l / lExpire;
    string  s=  string.Format( "RegSucced( '{0}', {1} ), {2}, {3}", lclPrfUri, lExpire,
                    new TimeSpan( lExpire * TimeSpan.TicksPerSecond )
                        .ToString( "d\\.hh\\:mm\\:ss" ), d );
    ..
}

但是我得到的lExpire值在1.5万亿(1'541'195'345'242)之间!

随着时间的推移,我发现它不断地增长,我认为这可能与Ticks有关,所以我同时暴露了这两种情况并收集了以下统计信息(H == T + 1小时-预期到期) :

    #  DT.Now.Ticks (T)     lExpire (E)     T/E ratio   T+36000000000 (H)   H/E ratio
    1  636767624266839520   1541183611836   413167.918  636767660266839520  413167.941
    2  636767669188704010   1541188122398   413166.738  636767705188704010  413166.761
    3  636767670260843180   1541188229643   413166.710  636767706260843180  413166.733
    4  636767670974718350   1541188301027   413166.691  636767706974718350  413166.715
    5  636767693193745790   1541190522922   413166.110  636767729193745790  413166.133

尽管413166的 magic 逃脱了我的注意,但比率却出乎意料地保持一致。从这一点来看,lExpire看起来更像是对某个时间点的引用,而不是间隔,不是吗?

但是根据文档,我应该在没有任何缩放因子的情况下得到3600,对吗? 发生了什么事?!

Android screenshot

更新(2019年1月25日)

终于接近答案了。浏览Android源文件(例如https://android.googlesource.com/platform/frameworks/base/+/431bb2269532f2514861b908d5fafda8fa64da79/voip/java/com/android/server/sip/SipService.java),我发现了以下片段:

@Override
public void onRegistrationDone(ISipSession session, int duration) {
    if (DEBUG) Log.d(TAG, "onRegistrationDone(): " + session); 
    synchronized (SipService.this) { 
        if (notCurrentSession(session)) return; 

        mProxy.onRegistrationDone(session, duration); 

        if (duration > 0) { 
            mSession.clearReRegisterRequired(); 
            mExpiryTime = SystemClock.elapsedRealtime() + (duration * 1000);
    ..

SystemClock.elapsedRealtime() returns milliseconds since boot,包括睡眠时间。
保持UNIX / Linux / Java中的时间as number of seconds since epoch(1970-01-01T00:00:00Z)。

Wikipedia的页面显示当前Unix时间为1548450313(2019-01-25T21:05:13 + 00:00),仅是1000次( s -to- ms < / em>乘数!)的范围与我观察到的lExpire值不同。最后一行mExpiryTime的公式有点希望。.“ Eureka!”?

让我们检查它们是否符合“ 自时代以来的毫秒数”理论:

DateTime    dtEpoch =   new DateTime( 1970, 1, 1, 0, 0, 0, DateTimeKind.Utc );

void    ISipRegistrationListener.OnRegistrationDone( string lclPrfUri, long lExpire )
{
    DateTime    dt =    dtEpoch.AddMilliseconds( lExpire ).ToLocalTime( );
    string  s=  string.Format( "RegSucced( '{0}', {1}, {2} )", lclPrfUri, lExpire,
                                    dt.ToString( "yyyy-MM-dd HH:mm:ss.fff" ) );
    ..
}

昨天的屏幕截图-进行了添加(洋红色箭头标记了公开的值): Android screenshots

如您所见,lExpire转换为时间与DateTime.Now(记录在日志中)之间的差异可以忽略不计-在ms范围内!

我实际上很喜欢被赋予过期 而不是 duration 的想法(需要将其添加到未定义的 起点)。正要回答我的问题。

但是,仍有一些未解决的未解之谜

  1. 为什么文档说参数是持续时间(秒)
    Xamarin可能只是在复制Android文档,但来源有误
    这真的是多么糟糕的Android开发者吗?认为应该是真实的((.. 是否有人在意请求的有效期可能被PBX / SIP服务器压倒[ down ],因此他们不得不更频繁地重新注册
  2. 在源文件中对.onRegistrationDone(session, duration)的所有调用都指定duration,而不是mExpiryTime。 有常量定义(EXPIRY_TIME = 3600,SHORT_EXPIRY_TIME = 10,MIN_EXPIRY_TIME = 60)以及duration与它们的比较。 两者之间的取值范围完全不同(3600与15万亿)。
    mExpiryTime(失效时刻)如何/在何处成为我方法的参数?
  3. 自启动以来的
  4. ms 和自时期以来的 s(或ms)仍然非常不同,是什么使那个进行调整?
  5. 最后,要求1小时的到期时间并在SIP服务器的OK答复中收到它,我希望这也会在这里得到反映,因此 lExpire应该是将来的1小时,而不是< em>现在

有什么想法吗?

0 个答案:

没有答案