[jitsi-dev] documenting ice4j interactions


#1

I've been trying to document how ice4j is to be used in a SIP
application, but I'd appreciate some feedback:

- I'm particularly concerned with the lifecycle of the Agent object and
the related DatagramSockets, how and exactly when they should be created
and shared with classes that do RTP and SIP signaling

Some of the things that are not completely clear:

- should the application wait until the Agent is in the TERMINATED
state before using the DatagramSocket objects?

- should the application call Agent.free()?

- if the application calls Agent.free(), are the DatagramSocket objects
meant to remain valid for the application to use?

* caller: application creates an Agent object (draft-ietf-mmusic-ice-19
s12.1.1: object could be created in advance, maybe gather candidates
while the user is dialing a number/scrolling through contacts?)
- create SDP for INVITE using candidates from Agent
- send the INVITE

* callee:
- receives INVITE,
- detects ICE attributes in SDP,
- creates Agent object (draft-ietf-mmusic-ice-19 s12.1.1 - maybe create
the Agent and gather candidates before the user finishes dialing a number
- creates streams (copies remote ufrag/pwd, copies remote candidates)
- creates SDP for 183,
- adds candidates from Agent to SDP
- sends 183
- invokes:
     iceAgent.setControlling(false);
     iceAgent.startConnectivityEstablishment();

* caller:
- receive a 183 with SDP
- detects ICE attributes in SDP
- detects that a local Agent exists
     iceAgent != null
- ensures that checks are not already running (maybe duplicate 183):
     iceAgent.getState() == IceProcessingState.WAITING
- extracts remote (callee) candidates from SDP
- gives the candidates to the local Agent
- invokes the ICE algorithm:
     iceAgent.setControlling(true);
     iceAgent.startConnectivityEstablishment();

* callee and caller both wait for more SIP packets (maybe CANCEL?)
    OR for a callback in IceProcessingListener.propertyChange

* callee:
- receive ICE COMPLETED callback
- copy the DatagramSocket objects from Component
  .getSelectedPair()
       .getLocalCandidate()
             .getDatagramSocket()
- give the DatagramSocket objects to the classes for RTP send/receive
- start to alert user (audible ringing sounds)
- send 180 or maybe 183 (with ringback tones as audio, using the
DatagramSockets created by the ICE Agent)
- call Agent.free() ???

* caller:
- receive ICE COMPLETED
- copy the DatagramSocket objects from Component
  .getSelectedPair()
       .getLocalCandidate()
             .getDatagramSocket()
- give the DatagramSocket objects to the classes for RTP send/receive
- wait for 180 or another 183 (with ringback?)
- (maybe) give visual feedback to user to advise ICE status good, maybe
start ringback
- call Agent.free() ???

* callee:
- user answers phone
- send 200 OK with same SDP as in the 183

* caller:
- receive 200 OK
- note: RFC 3262. and also (draft-ietf-mmusic-ice-19 s12.1.1) emphasize
that the SDP offer in any 18x messages must be identical to the final
SDP in 18x messages. Therefore, caller does not need to check for any
new candidates or repeat ICE when it receives the 2xx with SDP.
- send ACK


#2

Hi Daniel,

Le 11/01/12 16:43, Daniel Pocock a �crit :

I've been trying to document how ice4j is to be used in a SIP
application, but I'd appreciate some feedback:

- I'm particularly concerned with the lifecycle of the Agent object and
the related DatagramSockets, how and exactly when they should be created
and shared with classes that do RTP and SIP signaling

Some of the things that are not completely clear:

- should the application wait until the Agent is in the TERMINATED
state before using the DatagramSocket objects?

You can use the DatagramSocket as soon as ICE is completed.

- should the application call Agent.free()?

You can, but in case you didn't do it, free() is called when the Agent is garbage collected (see Agent.finalize()).
Typically Agent.free() is used when you close the call.

- if the application calls Agent.free(), are the DatagramSocket objects
meant to remain valid for the application to use?

According to the code, socket from candidates are closed.

* caller: application creates an Agent object (draft-ietf-mmusic-ice-19
s12.1.1: object could be created in advance, maybe gather candidates
while the user is dialing a number/scrolling through contacts?)
- create SDP for INVITE using candidates from Agent
- send the INVITE

Note that ICE is become an RFC, see RFC5245 rather than draft-ietf-mmusic-ice-19. I recommend you to see
IceUdpTransportManager.startConnectivityEstablishment in Jitsi source for beginning ICE session (remote candidates (at least one couple (RTP, RTCP) should be there before calling iceAgent.startConnectivityEstablishment()).

* callee:
- receives INVITE,
- detects ICE attributes in SDP,
- creates Agent object (draft-ietf-mmusic-ice-19 s12.1.1 - maybe create
the Agent and gather candidates before the user finishes dialing a number
- creates streams (copies remote ufrag/pwd, copies remote candidates)
- creates SDP for 183,
- adds candidates from Agent to SDP
- sends 183
- invokes:
      iceAgent.setControlling(false);
      iceAgent.startConnectivityEstablishment();

* caller:
- receive a 183 with SDP
- detects ICE attributes in SDP
- detects that a local Agent exists
      iceAgent != null
- ensures that checks are not already running (maybe duplicate 183):
      iceAgent.getState() == IceProcessingState.WAITING
- extracts remote (callee) candidates from SDP
- gives the candidates to the local Agent
- invokes the ICE algorithm:
      iceAgent.setControlling(true);
      iceAgent.startConnectivityEstablishment();

* callee and caller both wait for more SIP packets (maybe CANCEL?)
     OR for a callback in IceProcessingListener.propertyChange

* callee:
- receive ICE COMPLETED callback
- copy the DatagramSocket objects from Component
   .getSelectedPair()
        .getLocalCandidate()
              .getDatagramSocket()
- give the DatagramSocket objects to the classes for RTP send/receive
- start to alert user (audible ringing sounds)
- send 180 or maybe 183 (with ringback tones as audio, using the
DatagramSockets created by the ICE Agent)
- call Agent.free() ???

No Agent.free() here.

* caller:
- receive ICE COMPLETED
- copy the DatagramSocket objects from Component
   .getSelectedPair()
        .getLocalCandidate()
              .getDatagramSocket()
- give the DatagramSocket objects to the classes for RTP send/receive
- wait for 180 or another 183 (with ringback?)
- (maybe) give visual feedback to user to advise ICE status good, maybe
start ringback
- call Agent.free() ???

No Agent.free() here.

* callee:
- user answers phone
- send 200 OK with same SDP as in the 183

* caller:
- receive 200 OK
- note: RFC 3262. and also (draft-ietf-mmusic-ice-19 s12.1.1) emphasize
that the SDP offer in any 18x messages must be identical to the final
SDP in 18x messages. Therefore, caller does not need to check for any
new candidates or repeat ICE when it receives the 2xx with SDP.
- send ACK

* close call:
- SIP messages, ...
- iceAgent.free().

Regards,

···

--
Seb