SIPフォンを作る【第二回】

こんにちは、マツノです。 SIPフォンを作る、第二回です。

今回は電話っぽい機能を作ります。 電話の着信発信です。 誰かから電話がかかってきたら出る、指定した番号に電話をかけるという機能を解説していきます。

着信待ちをする

REGISTERはできたので、これで登録したアカウントへの着信はこのアプリで受け取れるようになりました しかし、まだ反応を何も書いていないのでINVITE_Requestに対する反応を記述しましょう。

private void OnReceiveRequest(object sender, RequestEventArgs e)

Requestがサーバーから飛んでくるとこいつが呼ばれます 前回でRequestが飛んできたときに呼ばれるイベントハンドラとして登録したやつです。


 private void OnReceiveRequest(object sender, RequestEventArgs e)
 {
    client.AcceptRequest(e.Request);
 }

ただ反応するだけであればこれでOK_Responseが返りSIP通信を用いた通信は確立するけれど何もRTP通信をしていないので何も情報はやり取りできない。 SIPサーバーや相手のクライアントアプリによっては通信に必要な情報が足りないとして通信が確立しないこともある。 なので、INVITE_Requestに含まれているSDP(SessionDescriptionProtocol)を使ってRTP通信の用意を速やかに進め、いつでも開始できる状態でOK_ResponseにこちらのSDP載せて返す必要がある。


 private void OnReceiveRequest(object sender, RequestEventArgs e)
 {
  if (e.Request.Method == SipMethod.Invite)
  {
  var SDP = e.Request.SessionDescription();

  Prepare_RTP(SDP);

  OK ok = new OK();
  ok.SessionDescription = Generate_SDP();
  var Ok_Response = client.SendResponse(ok, e.Reqiest);

        return;
  }            
 }

といった感じにする。

Prepare_RTP(SD);はRTPを用意するメソッド、後述する。 Generate_SDP();はSDPを作るメソッド、後述する。

あとは後述すると書いた二つのメソッドを実装したら受信専用の電話としては使えるようになる気がする。 しかしそうはならない。 確かに電話がかかってきたら通話ができる状態になったが、受け側が気づかなくても着信したら勝手に通話状態になってしまう。 それはあんまりよろしくないので、INVITE_Requestが来たら一度待ってもらうためにOKではなくRingingを返す。


 Request Ringing_Request_temp;
 private void OnReceiveRequest(object sender, RequestEventArgs e)
 {
  if (e.Request.Method == SipMethod.Invite)
  {
  client.SendResponseRinging(e.Request);
  Ringing_Request_temp = e.Request;
  Picup_GUI_Active();        
      
  return;
  }            
 }

 public void Picup()
 {
  var SDP = e.Request.SessionDescription();

  Prepare_RTP(SDP);

  OK ok = new OK();
  ok.SessionDescription = Generate_SDP();
  var Ok_Response = client.SendResponse(ok, e.Reqiest);
 }

Picup_GUI_Enable(); 電話に出るボタンをアクティブにするメソッド、内容はPicup()を任意のタイミングで叩けるButton等をactiveにさえすればなんでも良い。 Picup()は待機状態にしたあと任意のタイミングで呼び出すことで着信を受け入れ、電話に出ることができる。

電話に今出られないというときはReject_Requestを投げます。


  public void Regect()
  {
   client.RejectRequest(ringing_Req);
   Picup_GUI_Disble();
  }

Picup_GUI_Disble(); 電話に出るボタンを非表示にするメソッド、内容はPicup_GUI_Enable();の逆のことをできれば何でもよい。

電話を発信する

登録する、受信するとできたので次は発信をしていきます。

発信するときはINVITE_Requestを投げます。

 private RequestResponse inviteRequestResponse;
 public async void Invite()
 {
  invit_now = true;

  await Task.Run(() =>
  {
      inviteRequestResponse = client.Invite("sip:" + username.text    + "@" + domain.text + ":" + port.text, 
                         "sip:" + call_target.text + "@" + domain.text + ":" + port.text,
                         "sip:" + username.text    + "@" + client.LocalIPEndPoint.ToString(),
                         Generate_SDP());
    var SDP = inviteRequestResponse.Response.SessionDescription;
    Prepare_RTP(SDP);
    client.Ack(inviteRequestResponse);
    
  });
 }

INVITE_Requestには自分のアカウントのSIPアドレス、送信先のSIPアドレス、自分のローカルのSIPアドレス、SDPを載せます。 それぞれInputTextのtextを参照させています。

Inviteは相手がOKを返してくるまで値が返ってこないので、awateで非同期にして値が返ってきたらRTPを開始してAckを返して通信が確立したことを示します。 Inviteの返り値は後から使うのでclassフィールドに入れておきましょう。

発信着信はこんな感じです。 次回では途中に出てきたメソッドの解説をしていきます。

Matsuno

AR VR Engineer

SIPフォンを作る【第二回】

お気軽に
お問い合わせください。

お問い合わせ