0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Android SIP API : REGISTER リクエストの有効期間と再送信

Last updated at Posted at 2020-10-16

概要

SIP REGISTER リクエストの有効期間

REGISTER リクエストには有効期間 (Expires) を指定することができます。

REGISTER の有効期間に関する動作を簡単にまとめると以下のような感じです。

  • クライアントは、REGISTER リクエストの Expires に希望する期間を指定して、送信。
  • サーバーは、レスポンスにサーバー自身が希望する期間を指定して、送信。サーバーが指定した期間は、クライアントが希望した値かもしれないし、サーバーが希望する別の値に変更しているかもしれない。
  • クライアントは、レスポンスに書かれた期間を過ぎた後(または期間に近づいた際に)、 REGISTER リクエストを再送信することが必要。

Android SIP API の auto registration 機能

Android SIP API には auto registration 機能があり、この機能を有効にした場合は REGISTER リクエストの送信・再送信は android 側が行ってくれます。

auto registration を使用しない場合、SipManager.register(SipProfile localProfile, int expiryTime, SipRegistrationListener listener)SipSession.register(int expiryTime) を使用して REGISTER リクエストの送信を指示します。引数expiryTime に期間を指定できます。

問題

Android SIP API の auto registration を使用する場合、どのくらいの期間を指定しているのか、サーバーからの応答に指示された期間をどう処理しているのか、わからなかったためコードを調べました。

コードの調査

以下のサイトを使用しました。ブランチは android-7.0.0_r35 としました。

結論

結論を先に書きます。

auto registration 機能を使用する場合には

  • REGISTER リクエストには有効期間に 3600 秒を設定して送信している。
  • REGISTER リクエストのレスポンスに書かれた有効期間の60秒前に、REGISTER リクエストを再送する。
    • (レスポンスに書かれた有効期間が 3600 秒であれば、3600 - 60 秒後に再送信)
    • レスポンスに有効期間が書かれていない場合は、有効期間を3600秒として動作する。

SipManager.open からの呼び出し階層

auto registration を使用する場合は、
SipManager.open(SipProfile localProfile, PendingIntent incomingCallPendingIntent, SipRegistrationListener listener) を使用すると思います。呼び出しをたどってみます。

SipManager.open(SipProfile localProfile, PendingIntent incomingCallPendingIntent, SipRegistrationListener listener)
SipService.open3(SipProfile localProfile, PendingIntent incomingCallPendingIntent, SipRegistrationListener listener, String opPackageName)
SipSessionGroupExt.openToReceiveCalls()
SipAutoReg.start(SipSessionGroup group)
SipSessionImpl.unregister
SipSessionImpl.doCommandAsync(final EventObject command)
SipSessionImpl.processCommand(EventObject command)
SipSessionImpl.process(EventObject command)
SipSessionImpl.readyForCall(EventObject evt)
SipSessionImpl.readyForCall, 1091

SipSessionImpl.unregister ...
まずは、既にサーバーに登録されている状態を解除しようとするようです。
(解除は、REGISTER リクエストを使用しますが、Expires に 0 を指定)

SipSessionImpl.readyForCall ...
SipHelper.sendRegister が REGISTER リクエストを送信しているようです。
mState は SipSession.State.DEREGISTRING になります。

REGISTER リクエストのレスポンス処理

レスポンスを正常に受信できたと仮定すると、以下の呼び出しになるはずです。

SipSessionGroup.processResponse(ResponseEvent event)
SipSessionGroup.process(EventObject event)
SipSessionImpl.process(EventObject evt)
SipSessionImpl.registeringToReady(EventObject evt)
SipSessionImpl.onRegistrationDone(int duration)
SipAutoReg.onRegistrationDone(ISipSession session, int duration)
SipAutoReg.run()
SipSessionImpl.register(int duration)

SipSessionImpl.registeringToReady ...
ステータスコードが 200 だった場合は、mState は SipSession.State.REGISTER ではないので、引数 duration に -1 を渡して onRegistrationDone を実行します。

SipSessionImpl.onRegistrationDone ...
mProxy のメソッド呼び出しにより、mProxy にセットされているリスナが呼び出されます。

SipAutoReg.onRegistrationDone ...
引数 duration は -1 のため、run() が実行されます。

SipAutoReg.run ...
引数 duration に 定数 EXPIRE_TIME を渡して register を実行します。

REGISTER リクエストの送信に関するコード

SipHelper.sendRegister について調べてみます。

1

REGISTER リクエストを作成しているのは、SipHelper.sendRegister(SipProfile userProfile, String tag, int expiry)
222 行 : 引数 expiry がリクエストにセットされる。

2

SipHelper.sendRegister の呼び出し元は、SipSessionImpl.readyForCall(EventObject evt)
引数expriy には、変数duration を指定している。
変数duration は、RegisterCommand.getDuration() の値がセットされている。

3

RegisterCommand.getDuration() は、インスタンス時の引数duration を返す。
RegisterCommand を作成しているのは、SipSessionGroup.register(int duration)
SipSessionGroup.register の引数duration を変更せず使用して、RegisterCommand をインスタンス化する。

4

SipSessionGroup.register の呼び出し元はいくつかあるが、auto registration 時は以下の2つ。

どちらも、定数EXPIRY_TIMEを指定している。EXPIRY_TIME は 3600。

REGISTER リクエストの応答処理に関するコード

REGISTER リクエストに対するレスポンスの処理を調べてみます。

1

レスポンスから Expires を取得しているのは、SipSessionImpl.getExpiryTime(Response response)
取得できなかった場合は、EXPRIY_TIME (3600) を返している。

2

SipSessionImpl.getExpiryTime(Response response) の呼び出し元は、SipSessionImpl.registeringToReady(EventObject evt)

getExpiryTime で取得した値は、SipSessionImpl.onRegistrationDone に渡す。

3

SipSessionImpl.onRegistrationDonemProxy.onRegistrationDone を呼ぶ。

mProxy は、setListener でセットされる。呼び出し元をたどると以下のように SipAutoReg クラスがある。
SipSessionImpl.setListener
new SipSessionImpl
SipSessionImpl.createSession
SipAutoReg.start

SipAutoReg.onRegistrationDone は、SipAutoReg.restartduration - MIN_EXPIRY_TIME を渡す。
MIN_EXPIRY_TIME は 60 。
(おそらく、期限が切れる60秒前に再送するため)

4

SipAutoReg.restart はタイマーを実行する。タイマーの期間は duration * 1000 ミリ秒後。
タイマーにより、SipAutoReg.run が実行され、mSession.register を実行。
(mSession.register ... REGISTER リクエストの送信指示)

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?