ISipRegistrationListener.OnRegistrationDone (), дающий слишком высокие значения для времени истечения - PullRequest
0 голосов
/ 03 ноября 2018

Я успешно регистрирую SipProfile с истечением 1 часа. Я вижу сообщение REGISTER в Wireshark на компьютере SIP-сервера, повторно отправленное с авторизацией.
Brekeke немедленно отвечает с STATUS: 200 OK, возвращая 'Expires: 3600'.

Wireshark capture of SIP registration

Обе документы Xamarin и Android говорят мне, что 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)!

Поскольку я видел это постоянно , растущее со временем, я подумал, что это может быть связано с тиками, поэтому я выставил оба и собрал следующую статистику (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 ускользает от меня .. И из этого lExpire больше похоже на ссылку на момент времени, чем на интервал нет?

Но согласно документам я должен получить 3600 без каких-либо масштабных коэффициентов, верно? Что происходит ??!

Android screenshot

ОБНОВЛЕНИЕ (2019-Jan-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() возвращает миллисекунды с момента загрузки , включая время, проведенное во сне.
Время в UNIX / Linux / Java сохраняется как количество секунд с начала эпохи (1970-01-01T00: 00: 00Z).

Страница Википедии показывает текущее время Unix как 1548450313 (2019-01-25T21: 05: 13 + 00: 00), что составляет всего 1000 раз ( с - до - мс множитель!) отличается в диапазоне от lExpire значений, которые я наблюдаю. Формула для mExpiryTime в последней строке как бы вселяет надежду .. "Эврика!"?

Давайте проверим, соответствуют ли они теории " # мс с эпохи ":

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 (записанным в журнале) незначительна - в диапазоне мс!

Мне действительно нравится идея получить срок действия момент вместо продолжительность (который должен быть добавлен к undefined отправная точка). Собирался ответить на мой вопрос ..

Но все же, есть еще неразрешенные загадки :

  1. Почему в документации сказано, что аргумент имеет значение длительность в секундах ?
    Xamarin может просто копировать документы Android, но источник неверен !
    Это действительно, как хромые разработчики Android? Считай, что это должно быть риторически ((.. Кто-нибудь заботится, что запрошенный период истечения может быть превзойден [ down ] сервером PBX / SIP, и, таким образом, он должен перерегистрировать чаще ?
  2. Все вызовы .onRegistrationDone(session, duration) в исходных файлах указывают duration, а не mExpiryTime. Существуют постоянные определения (EXPIRY_TIME = 3600, SHORT_EXPIRY_TIME = 10, MIN_EXPIRY_TIME = 60) и сравнения duration с этими .. Диапазон значений резко отличается между ними (3600 против 15 трлн).
    Как / где mExpiryTime ( момент истечения ) превращает его в аргумент моего метода?
  3. мс с момента загрузки и с (или мс) с эпохи все еще сильно отличаются, что делает такой настройкой?
  4. и, наконец, спрашивая об истечении 1 часа и получив его в ответе OK от SIP-сервера, я ожидаю, что это будет отражено и здесь, поэтому lExpire должно составлять 1 час в будущем, а не Теперь !!

Есть идеи?

...