Subject: RE: [Sip] The Problem with PRACK

From: "Michael Hammer \(mhammer\)" <[email-masked]>
Date: Mon, 20 Mar 2006 09:37:18 -0500

Ummm...  I thought some one else indicated that the problem is with
Offer/Answer, not PRACK.

I also thought the principle behind Offer/Answer was that the SDP
negotiation was independent of the signaling message it was carried in,
*so long* as those messages were reliable.  However, it was pointed out
to me that you can't put an Offer in this or that message, indicating to
me that perhaps the Offer/Answer was complicated by the permutations of
messages where it can or can not be carried.  On some PSTN gateways this
may be complicated because the MGC generally handles the SIP
termination, while the SDP is terminated by the MG, once it has been
passed from SIP to MGCP or H.248 and vice versa.

Anyway, I haven't seen the 50+ state diagram from Vancouver either, but
it would be good to have that distributed on the mail list.  I must have
missed that one if it was.

Mike

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]] 
> Sent: Monday, March 20, 2006 6:51 AM
> To: [email-masked]; [email-masked]; 
> [email-masked]
> Cc: [email-masked]; [email-masked]
> Subject: RE: [Sip] The Problem with PRACK
> 
> Hi,
> 
> I fully agree with Christer. I think the only thing that can 
> be done at the moment is to follow the normal process in IETF 
> (the one, that IETF also demanded from 3GPP, so people should 
> know it), i.e.
> 
> First investigate and write down requirements in an 
> interndet-draft Second change the standards where necessary.
> 
> So I propose a study/requirements I-D, in which people can 
> 	- state problems with PRACK
> 	- summarize existing implementations and possible 
> impacts to them if PRACK gets changed
> 	- investigate impact on other standards bodies (3g2 3gpp tispan
> oma) when PRACK/precos get changed
> 	- propose and evaluate possible changes
> 
> Based on the discussion I saw so far I do not see any way to 
> start changing the RFCs right now. I would even doubt if the 
> result of this investigation will be changing the existing RFCs. 
> 
> Best regards
> Georg
> 
> --
> Georg Mayer - Nokia
> http://www.nokia.com/openness
> http://www.imsbook.com
>  
> 
> >-----Original Message-----
> >From: ext Christer Holmberg (JO/LMF)
> >[mailto:[email-masked]]
> >Sent: 20 March, 2006 12:51
> >To: [email-masked]; Koivusalo Erkki (Nokia-TP-MSW/Helsinki)
> >Cc: [email-masked]; [email-masked]
> >Subject: RE: [Sip] The Problem with PRACK
> >
> >
> >Hi,
> >
> >I am not Cisco, but I do have experience from PSTN GW 
> implementation :)
> >
> >If we for the moment forget about preconditions and 3GPP, one 
> >reason a GW wants to use PRACK is to be able to send/receive 
> >an SDP answer in a reliable 18x, because they may require it 
> >in order to support "early media" etc (in which case one can't 
> >wait until 200 OK). Like it or not, but in all environments it 
> >simply isn't acceptable to "start listening for media from 
> >whoever/wherever/whatever once the INVITE has been sent".
> >
> >Another reason is
> >SIP-I/SIP-t/SIP-whatver-you-call-it-when-you-encapsulate-ISUP-i
> >nformatio
> >n, where ISUP information is sent in a reliable 18x. No, Juha, 
> >it was NOT 3GPP who wanted ISUP encapsulation, so you don't 
> >have to blame it on them :)
> >
> >Another reason, maybe more theoretical at the moment, is that 
> >one wants to send non-SDP related requests before 200 OK, and 
> >in that case you need a reliable 18x to provide establish a 
> route set.
> >
> >In any case, I don't think one can simply say "We don't need 
> >to care why PRACK causes problem - let's just get rid of it 
> >all". In that case we have to throw away the whole 
> >offer/answer mechanism (and a lot of other SIP features too), 
> >because I know it still causes interop problems - even without PRACK.
> >
> >One needs to identity WHY it causes problem. As I said 
> >earlier, from my experience PRACK has caused very little 
> >problem when it comes to provide reliable 18x responses. I 
> >believe the problems are related to offer/answer, and that is 
> >what was said in the initial mail of this whole thread. Most 
> >other people here seem to agree that the problems are related 
> >to offer/answer. 
> >
> >I haven't heard anyone else than Juha saying that PRACK is bad 
> >a such, eventhough there have been some discussions on how it 
> >could be improved (mandate Rseq value 1 for first response etc 
> >etc etc).
> >
> >Regards,
> >
> >Christer
> >
> >
> >
> >-----Original Message-----
> >From: Juha Heinanen [mailto:[email-masked]]
> >Sent: 20. maaliskuuta 2006 12:23
> >To: [email-masked]
> >Cc: [email-masked]; [email-masked]; [email-masked]
> >Subject: RE: [Sip] The Problem with PRACK
> >
> >[email-masked] said:
> >
> >> - Your customers have bought lots of SIP phones with PRACK 
> >> implementation
> >>   (with offer/answer if I understand you correctly)
> >
> >i don't know if with or w/o offer answer and i don't care.  
> >the thing that i know is that when new software has come out, 
> >phones that used to interoperate well with others, stopped doing so.
> >
> >> So do you have any idea, why those SIP phones used in non-3gpp 
> >> environment have implemented PRACK which has caused so much 
> >problems ?
> >
> >> I do not believe they have added PRACK support.
> >
> >i have seen PRACK request flying in my ethernet dumps and haev 
> >identified the reason of problems being due to PRACK.  ask 
> >cisco, why they have implemented PRACK in their SIP/PSTN GWs, not me.
> >
> >-- juha
> >
> >
> >_______________________________________________
> >Sip mailing list  https://www1.ietf.org/mailman/listinfo/sip
> >This list is for NEW development of the core SIP Protocol Use 
> >[email-masked] for questions on current sip 
> >Use [email-masked] for new developments on the application of sip
> >
> 
> _______________________________________________
> Sip mailing list  https://www1.ietf.org/mailman/listinfo/sip
> This list is for NEW development of the core SIP Protocol
> Use [email-masked] for questions on current sip
> Use [email-masked] for new developments on the application of sip
> 

_______________________________________________
Sip mailing list  https://www1.ietf.org/mailman/listinfo/sip
This list is for NEW development of the core SIP Protocol
Use [email-masked] for questions on current sip
Use [email-masked] for new developments on the application of sip

---

From: Adam Roach <[email-masked]>
Date: Mon, 20 Mar 2006 09:39:41 -0600

>missed that one if it was.

Because the graphic doesn't work well on a mailing list, I've put it
here in text format. If you want the visual impact of the graph that
Rohan put up at IETF64, grab the PDF file at
http://scm.sipfoundry.org/viewsvn/*checkout*/resiprocate/main/resip/dum/doc/dum-fsms1.pdf

This comes from the Dialog Usage Manager in the resiprocate stack; the
transition is denoted as "oldstate->newstate"; the trigger and
subsequent actions are indicated following that line.

UAC_Start -> UAC_Early
  trigger = on1xxI
   action = app::onNewSession
   action = timer::StaleCall
   action = app::onProvisional

UAC_Start -> UAC_Early
  trigger = on1xxI-early
   action = app::onNewSession
   action = timer::StaleCall
   action = app::onProvisional
   action = app::onEarlyMedia

UAC_Start -> UAC_EarlyWithOffer
  trigger = on1xxI-offer
   action = app::onNewSession
   action = timer::StaleCall
   action = app::onProvisional
   action = app::onOffer

UAC_Start -> UAC_EarlyWithAnswer
  trigger = on1xxI-answer
   action = app::onNewSession
   action = timer::StaleCall
   action = app::onProvisional
   action = app::onAnswer
   action = send::PRACK

UAC_Start -> UAC_Answered
  trigger = on2xxI-offer
   action = app::onNewSession
   action = app::onOffer
   action = app::onConnected

UAC_Start -> Connected
  trigger = on2xxI-answer
   action = send::ACK
   action = app::onNewSession
   action = app::onAnswer
   action = app::onConnected

UAC_Start -> Terminated
  trigger = on2xxI
   action = send::ACK
   action = send::BYE
   action = app::onFailure
   action = app::onTerminated

UAC_Start -> Terminated
  trigger = onInviteFailure
  trigger = onGeneralFailure
   action = app::onFailure
   action = app::onTerminated
   action = dum::destroy

UAC_Start -> Terminated
  trigger = onRedirect
   action = app::onRedirected

UAC_Start -> Assert
  trigger = dum::cancel
   action = assert

UAC_Early -> UAC_Early
  trigger = on1xxI
   action = timer::StaleCall
   action = app::onProvisional
   action = send::PRACK

UAC_Early -> UAC_Early
  trigger = on1xxI-early
   action = timer::StaleCall
   action = app::onProvisional
   action = app::onEarlyMedia

UAC_Early -> UAC_EarlyWithOffer
  trigger = on1xxI-offer
   action = timer::StaleCall
   action = app::onProvisional
   action = app::onOffer

UAC_Early -> UAC_EarlyWithAnswer
  trigger = on1xxI-answer
   action = timer::StaleCall
   action = app::onProvisional
   action = app::onAnswer
   action = send::PRACK

UAC_Early -> UAC_Answered
  trigger = on2xxI-offer
   action = app::onOffer
   action = app::onConnected

UAC_Early -> Connected
  trigger = on2xxI-answer
   action = send::ACK
   action = app::onAnswer
   action = app::onConnected

UAC_Early -> Terminated
  trigger = on2xxI
   action = send::ACK
   action = send::BYE
   action = app::onFailure
   action = app::onTerminated

UAC_Early -> Terminated
  trigger = onInviteFailure
  trigger = onGeneralFailure
   action = app::onFailure
   action = app::onTerminated
   action = dum::destroy

UAC_Early -> UAC_Cancelled
  trigger = dum::cancel
   action = timer::cancel

UAC_Early -> Terminated
  trigger = onRedirect
   action = app::onRedirected

UAC_Early -> Assert
  trigger = dum::provideAnswer
   action = assert

UAC_Early -> Assert
  trigger = dum::provideOffer
   action = assert

UAC_Early -> Terminated
  trigger = dum::end
   action = send::BYE
   action = app::onTerminated

UAC_EarlyWithOffer -> UAC_EarlyWithOffer
  trigger = on1xxI
   action = timer::StaleCall
   action = app::onProvisional
   action = send::PRACK

UAC_EarlyWithOffer -> UAC_SentAnswer
  trigger = dum::provideAnswer
   action = send::PRACK-answer

UAC_EarlyWithOffer -> Terminated
  trigger = on2xxI
  trigger = on2xxI-answer
   action = send::ACK
   action = send::BYE
   action = app::onFailure
   action = app::onTerminated

UAC_EarlyWithOffer -> Terminated
  trigger = onRedirect
   action = app::onRedirected

UAC_EarlyWithOffer -> Terminated
  trigger = onInviteFailure
  trigger = onGeneralFailure
   action = app::onFailure
   action = app::onTerminated
   action = dum::destroy

UAC_EarlyWithOffer -> UAC_Cancelled
  trigger = dum::cancel
   action = timer::cancel

UAC_EarlyWithOffer -> Assert
  trigger = dum::provideOffer
   action = assert

UAC_EarlyWithOffer -> Terminated
  trigger = dum::end
   action = send::BYE
   action = app::onTerminated

UAC_EarlyWithAnswer -> UAC_EarlyWithAnswer
  trigger = on1xxI
   action = timer::StaleCall
   action = app::onProvisional
   action = send::PRACK

UAC_EarlyWithAnswer -> Connected
  trigger = on2xxI
   action = send::ACK
   action = app::onConnected

UAC_EarlyWithAnswer -> Terminated
  trigger = on2xxI-offer
   action = send::ACK
   action = send::BYE
   action = app::onFailure
   action = app::onTerminated

UAC_EarlyWithAnswer -> UAC_ReceivedUpdateEarly
  trigger = onUpdate
   action = app::onOffer

UAC_EarlyWithAnswer -> UAC_SentUpdateEarly
  trigger = dum::provideOffer
   action = send::UPDATE

UAC_EarlyWithAnswer -> Terminated
  trigger = onRedirect
   action = app::onRedirected

UAC_EarlyWithAnswer -> Terminated
  trigger = onInviteFailure
  trigger = onGeneralFailure
   action = app::onFailure
   action = app::onTerminated
   action = dum::destroy

UAC_EarlyWithAnswer -> UAC_Cancelled
  trigger = dum::cancel
   action = timer::cancel

UAC_EarlyWithAnswer -> Terminated
  trigger = dum::end
   action = send::BYE
   action = app::onTerminated

UAC_EarlyWithAnswer -> Assert
  trigger = dum::provideAnswer
   action = assert

UAC_SentUpdateEarly -> UAC_EarlyWithAnswer
  trigger = on2xxU
   action = app::onAnswer

UAC_SentUpdateEarly -> UAC_EarlyWithAnswer
  trigger = onUpdate
   action = send::491

UAC_SentUpdateEarly -> UAC_EarlyWithAnswer
  trigger = on491U
   action = app::onOfferRejected

UAC_SentUpdateEarly -> UAC_SentUpdateConnected
  trigger = on2xxI
   action = send::ACK

UAC_SentUpdateEarly -> UAC_Cancelled
  trigger = dum::cancel
   action = timer::cancel

UAC_SentUpdateEarly -> Assert
  trigger = dum::provideAnswer
   action = assert

UAC_SentUpdateEarly -> Assert
  trigger = dum::provideOffer
   action = assert

UAC_SentUpdateEarly -> Terminated
  trigger = onRedirect
   action = app::onRedirected

UAC_SentUpdateEarly -> Terminated
  trigger = onInviteFailure
  trigger = onGeneralFailure
   action = app::onFailure
   action = app::onTerminated
   action = dum::destroy

UAC_SentUpdateEarly -> Terminated
  trigger = dum::end
   action = send::BYE
   action = app::onTerminated

UAC_SentUpdateConnected -> Connected
  trigger = on2xxU
   action = app::onAnswer

UAC_SentUpdateConnected -> Connected
  trigger = onUpdateFailure
   action = app::onOfferRejected

UAC_SentUpdateConnected -> Connected
  trigger = on491U
   action = glare

UAC_SentUpdateConnected -> Assert
  trigger = dum::cancel
   action = assert

UAC_SentUpdateConnected -> Assert
  trigger = dum::provideAnswer
   action = assert

UAC_SentUpdateConnected -> Assert
  trigger = dum::provideOffer
   action = assert

UAC_SentUpdateConnected -> Terminated
  trigger = dum::end
   action = send::BYE
   action = app::onTerminated

UAC_ReceivedUpdateEarly -> Terminated
  trigger = onRedirect
   action = app::onRedirected

UAC_ReceivedUpdateEarly -> UAC_EarlyWithAnswer
  trigger = dum::provideAnswer
   action = send::200U-answer

UAC_ReceivedUpdateEarly -> UAC_EarlyWithAnswer
  trigger = dum::reject
   action = send::488U

UAC_ReceivedUpdateEarly -> UAC_Cancelled
  trigger = dum::cancel
   action = timer::cancel

UAC_ReceivedUpdateEarly -> Terminated
  trigger = dum::end
   action = send::BYE
   action = app::onTerminated

UAC_ReceivedUpdateEarly -> Assert
  trigger = dum::provideAnswer
   action = assert

UAC_ReceivedUpdateEarly -> Assert
  trigger = dum::provideOffer
   action = assert

UAC_Answered -> Connected
  trigger = dum::provideAnswer
   action = send::ACK-answer
   action = app::onConnected

UAC_Answered -> Assert
  trigger = dum::provideOffer
   action = assert

UAC_Answered -> Terminated
  trigger = dum::end
   action = send::BYE
   action = app::onTerminated

UAC_Answered -> Assert
  trigger = dum::cancel
   action = assert

UAC_SentAnswer -> UAC_EarlyWithAnswer
  trigger = on2xxP

UAC_SentAnswer -> Connected
  trigger = on2xxI
   action = send::ACK
   action = app::onConnected

UAC_SentAnswer -> Terminated
  trigger = on1xxI-offer
  trigger = on1xxI-answer
   action = send::ACK
   action = send::BYE
   action = app::onFailure
   action = app::onTerminated

UAC_SentAnswer -> Terminated
  trigger = on2xxI-offer
  trigger = on2xxI-answer
   action = send::ACK
   action = send::BYE
   action = app::onFailure
   action = app::onTerminated

UAC_SentAnswer -> UAC_EarlyWithAnswer
  trigger = on1xxI
   action = timer::StaleCall
   action = app::onProvisional
   action = send::PRACK

UAC_SentAnswer -> Terminated
  trigger = onRedirect
   action = app::onRedirected

UAC_SentAnswer -> Terminated
  trigger = onInviteFailure
  trigger = onGeneralFailure
   action = app::onFailure
   action = app::onTerminated
   action = dum::destroy

UAC_SentAnswer -> Terminated
  trigger = dum::end
   action = send::BYE
   action = app::onTerminated

UAC_SentAnswer -> UAC_QueuedUpdate
  trigger = dum::provideOffer
   action = store::offer

UAC_SentAnswer -> UAC_Cancelled
  trigger = dum::cancel
   action = timer::cancel

UAC_SentAnswer -> Assert
  trigger = dum::provideAnswer
   action = assert

UAC_QueuedUpdate -> UAC_SentUpdateEarly
  trigger = on2xxP
   action = send::UPDATE-offer

UAC_QueuedUpdate -> SentUpdate
  trigger = on2xxI
   action = send::ACK
   action = app::onConnected
   action = send::UPDATE-offer

UAC_QueuedUpdate -> Terminated
  trigger = on1xxI-offer
  trigger = on1xxI-answer
   action = send::ACK
   action = send::BYE
   action = app::onFailure
   action = app::onTerminated

UAC_QueuedUpdate -> Terminated
  trigger = on2xxI-offer
  trigger = on2xxI-answer
   action = send::ACK
   action = send::BYE
   action = app::onFailure
   action = app::onTerminated

UAC_QueuedUpdate -> UAC_QueuedUpdate
  trigger = on1xxI
   action = timer::StaleCall
   action = app::onProvisional
   action = send::PRACK

UAC_QueuedUpdate -> Terminated
  trigger = onRedirect
   action = app::onRedirected

UAC_QueuedUpdate -> Terminated
  trigger = onInviteFailure
  trigger = onGeneralFailure
   action = app::onFailure
   action = app::onTerminated
   action = dum::destroy

UAC_QueuedUpdate -> Terminated
  trigger = dum::end
   action = send::BYE
   action = app::onTerminated

UAC_QueuedUpdate -> UAC_Cancelled
  trigger = dum::cancel
   action = timer::cancel

UAC_QueuedUpdate -> Assert
  trigger = dum::provideAnswer
   action = assert

UAC_QueuedUpdate -> Assert
  trigger = dum::provideOffer
   action = assert

UAC_Cancelled -> Terminated
  trigger = onTimerCancel
   action = send::487
   action = app::onTerminated

UAC_Cancelled -> Terminated
  trigger = on2xxI
  trigger = on2xxI-offer
  trigger = on2xxI-answer
   action = send::ACK
   action = send::BYE
   action = app::onTerminated

UAC_Cancelled -> Terminated
  trigger = onRedirect
   action = app::onRedirected

UAC_Cancelled -> Terminated
  trigger = onInviteFailure
  trigger = onGeneralFailure
   action = app::onFailure
   action = app::onTerminated
   action = dum::destroy

UAC_Cancelled -> UAC_Cancelled
  trigger = dum::cancel

UAC_Cancelled -> Terminated
  trigger = dum::end
   action = send::BYE
   action = app::onTerminated

Connected -> SentUpdate
  trigger = dum::provideOffer
   action = send::UPDATE

Connected -> SentReinvite
  trigger = dum::provideOffer
   action = send::INVITE

Connected -> SentReinviteNoOffer
  trigger = dum::requestOffer
   action = send::INVITE

Connected -> ReceivedUpdate
  trigger = onUpdate
   action = app::onOffer

Connected -> ReceivedReinvite
  trigger = onInvite-offer
   action = app::onOffer

Connected -> ReceivedReinviteNoOffer
  trigger = onInvite
   action = app::onOfferRequired

Connected -> Connected
  trigger = on2xxP

Connected -> Connected
  trigger = on2xxI
   action = resend::ACK

Connected -> Connected
  trigger = onTimer2xx
   action = resend::2xx

Connected -> Connected
  trigger = onCancel
   action = send::200C

Connected -> Terminated
  trigger = dum::end
   action = send::BYE

Connected -> Terminated
  trigger = onBye
   action = send::200B
   action = app::onTerminated

SentUpdate -> Connected
  trigger = on2xxU
   action = app::onAnswer

SentUpdate -> Connected
  trigger = onUpdateFailure
   action = app::onOfferRejected

SentUpdate -> SentUpdate
  trigger = onUpdate
  trigger = onInvite
   action = send::491

SentUpdate -> SentUpdateGlare
  trigger = on491U
   action = timer::491

SentUpdate -> Terminated
  trigger = onGeneralFailure
   action = app::onTerminated
   action = send::BYE

SentUpdate -> Terminated
  trigger = dum::end
   action = send::BYE

SentUpdateGlare -> SentUpdate
  trigger = onTimer491
   action = resend::UPDATE

SentUpdateGlare -> ReceivedUpdate
  trigger = onUpdate
   action = app::onOfferRejected
   action = app::onOffer

SentUpdateGlare -> ReceivedReinvite
  trigger = onInvite-offer
   action = app::onOfferRejected
   action = app::onOffer

SentUpdateGlare -> Terminated
  trigger = dum::end
   action = send::BYE

SentReinvite -> Connected
  trigger = on2xxI-answer
   action = app::onAnswer
   action = send::ACK

SentReinvite -> Connected
  trigger = on2xxI
   action = app::onIllegalNegotiation
   action = send::ACK

SentReinvite -> Connected
  trigger = onInviteFailure
   action = app::onOfferRejected

SentReinvite -> SentReinvite
  trigger = onInvite
  trigger = onUpdate
   action = send::491

SentReinvite -> SentReinviteGlare
  trigger = on491I
   action = timer::491

SentReinvite -> WaitingToTerminate
  trigger = dum::end

SentReinviteGlare -> SentReinvite
  trigger = onTimer491
   action = resend::INVITE

SentReinviteGlare -> ReceivedUpdate
  trigger = onUpdate
   action = app::onOfferRejected
   action = app::onOffer

SentReinviteGlare -> ReceivedReinvite
  trigger = onInvite-offer
   action = app::onOfferRejected
   action = app::onOffer

SentReinviteGlare -> ReceivedReinviteNoOffer
  trigger = onInvite
   action = app::onOfferRejected
   action = app::onOfferRequired

SentReinviteGlare -> Terminated
  trigger = dum::end
   action = send::BYE

SentReinviteNoOffer -> SentReinviteAnswered
  trigger = on2xxI-offer
   action = app::onOffer

SentReinviteNoOffer -> Connected
  trigger = on2xxI
   action = app::onIllegalNegotiation
   action = send::ACK

SentReinviteNoOffer -> Connected
  trigger = onInviteFailure
   action = app::onOfferRequestRejected

SentReinviteNoOffer -> SentReinviteNoOffer
  trigger = onInvite
  trigger = onUpdate
   action = send::491

SentReinviteNoOffer -> SentReinviteNoOfferGlare
  trigger = on491I
   action = timer::491

SentReinviteNoOffer -> WaitingToTerminate
  trigger = dum::end

SentReinviteAnswered -> Connected
  trigger = dum::provideAnswer
   action = send::ACK-answer

SentReinviteAnswered -> Terminated
  trigger = dum::end
   action = app::onTerminated
   action = send::BYE

SentReinviteNoOfferGlare -> SentReinviteNoOffer
  trigger = onTimer491
   action = resend::INVITE

SentReinviteNoOfferGlare -> ReceivedUpdate
  trigger = onUpdate
   action = app::onOfferRequestRejected
   action = app::onOffer

SentReinviteNoOfferGlare -> ReceivedReinvite
  trigger = onInvite
   action = app::onOfferRequestRejected
   action = app::onOffer

SentReinviteNoOfferGlare -> ReceivedReinviteNoOffer
  trigger = onInvite
   action = app::onOfferRequestRejected
   action = app::onOfferRequired

SentReinviteNoOfferGlare -> Terminated
  trigger = dum::end
   action = send::BYE

ReceivedUpdate -> Connected
  trigger = dum::provideAnswer
   action = send::200U

ReceivedUpdate -> Connected
  trigger = dum::reject
   action = send::488U

ReceivedUpdate -> Terminated
  trigger = dum::end
   action = send::488U
   action = send::BYE

ReceivedUpdate -> ReceivedUpdate
  trigger = onInvite
  trigger = onUpdate
   action = send::500

ReceivedReinvite -> Answered
  trigger = dum::provideAnswer
   action = send::200I
   action = timer::200I
   action = timer::NoAck

ReceivedReinvite -> Connected
  trigger = dum::reject
   action = send::488U

ReceivedReinvite -> Terminated
  trigger = dum::end
   action = send::488I
   action = send::BYE

ReceivedReinvite -> ReceivedReinvite
  trigger = onInvite
  trigger = onUpdate
   action = send::500

Answered -> Answered
  trigger = onTimer2xx
   action = resend::2xx

Answered -> WaitingToOffer
  trigger = dum::provideOffer
   action = store::offer

Answered -> WaitingToRequestOffer
  trigger = dum::requestOffer

Answered -> Connected
  trigger = onAck
   action = timer::NoAck
   action = app::onAckNotReceived

Answered -> WaitingToHangup
  trigger = dum::end

WaitingToOffer -> WaitingToOffer
  trigger = onTimer2xx
   action = resend::2xx

WaitingToOffer -> SentUpdate
  trigger = onAck
   action = send::UPDATE-offer

WaitingToOffer -> SentReinvite
  trigger = onAck
   action = send::INVITE-offer

WaitingToOffer -> SentUpdate
  trigger = onTimerNoAck
   action = app::onOfferRejected
   action = send::UPDATE-offer

WaitingToOffer -> SentReinvite
  trigger = onTimerNoAck
   action = app::onOfferRejected
   action = send::INVITE-offer

WaitingToOffer -> WaitingToHangup
  trigger = dum::end

WaitingToRequestOffer -> WaitingToRequestOffer
  trigger = onTimer2xx
   action = resend::2xx

WaitingToRequestOffer -> SentUpdate
  trigger = onAck
   action = send::UPDATE-offer

WaitingToRequestOffer -> SentReinvite
  trigger = onAck
   action = send::INVITE-offer

WaitingToRequestOffer -> SentReinviteNoOffer
  trigger = onAck
   action = send::INVITE

WaitingToRequestOffer -> SentUpdate
  trigger = onTimerNoAck
   action = app::onOfferRejected
   action = send::UPDATE-offer

WaitingToRequestOffer -> SentReinvite
  trigger = onTimerNoAck
   action = app::onOfferRejected
   action = send::INVITE-offer

WaitingToRequestOffer -> SentReinviteNoOffer
  trigger = onTimerNoAck
   action = app::onOfferRejected
   action = send::INVITE

WaitingToRequestOffer -> WaitingToHangup
  trigger = dum::end

ReceivedReinviteNoOffer -> ReceivedReinviteSentOffer
  trigger = dum::provideOffer
   action = send::200-offer
   action = timer::200I
   action = timer::NoAck

ReceivedReinviteNoOffer -> Connected
  trigger = dum::reject
   action = send::488I

ReceivedReinviteNoOffer -> Terminated
  trigger = dum::end
   action = send::488I
   action = send::BYE

ReceivedReinviteNoOffer -> ReceivedReinviteNoOffer
  trigger = onInvite
  trigger = onUpdate
   action = send::500

ReceivedReinviteSentOffer -> Connected
  trigger = onAck-answer
   action = app::onAnswer

ReceivedReinviteSentOffer -> Connected
  trigger = onAck
   action = app::onOfferRejected

ReceivedReinviteSentOffer -> ReceivedReinviteSentOffer
  trigger = onTimer2xx
   action = resend::2xxI

ReceivedReinviteSentOffer -> Connected
  trigger = onTimerNoAck
   action = app::onOfferRejected

ReceivedReinviteSentOffer -> WaitingToHangup
  trigger = dum::end

WaitingToTerminate -> Terminated
  trigger = on2xxI
   action = send::ACK
   action = send::BYE

WaitingToTerminate -> Terminated
  trigger = onInviteFailure
   action = send::BYE

WaitingToHangup -> Terminated
  trigger = onAck
   action = send::BYE

WaitingToHangup -> Terminated
  trigger = onTimerNoAck
   action = send::BYE

Terminated -> Terminated
  trigger = onResponse
   action = dum::destroy

Terminated -> Terminated
  trigger = onRequest
   action = send::481
   action = dum::destroy

UAS_Start -> UAS_Offer
  trigger = onInvite-offer
   action = app::onNewSession
   action = app::onOffer

UAS_Offer -> UAS_OfferProvidedAnswer
  trigger = dum::provideAnswer
   action = store::answer

UAS_Offer -> UAS_EarlyOffer
  trigger = dum::provisional
   action = send::1xx
   action = timer::1xx

UAS_Offer -> Assert
  trigger = dum::accept
   action = assert

UAS_Offer -> Terminated
  trigger = dum::end
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_Offer -> Terminated
  trigger = dum::reject
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_Offer -> Terminated
  trigger = dum::redirect
   action = send::3xxI
   action = app::onTerminated
   action = dum::destroy

UAS_Offer -> Terminated
  trigger = onCancel
   action = app::onTerminated
   action = send::200C
   action = send::487I

UAS_Offer -> Terminated
  trigger = onBye
   action = app::onTerminated
   action = send::200B
   action = send::487I

UAS_OfferProvidedAnswer -> UAS_Accepted
  trigger = dum::accept
   action = send::2xx-answer
   action = timer::2xx
   action = timer::NoAck
   action = app::onConnected

UAS_OfferProvidedAnswer -> UAS_EarlyProvidedAnswer
  trigger = dum::provisional
   action = send::1xx
   action = timer::1xx

UAS_OfferProvidedAnswer -> Terminated
  trigger = dum::end
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_OfferProvidedAnswer -> Terminated
  trigger = dum::reject
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_OfferProvidedAnswer -> Terminated
  trigger = dum::redirect
   action = send::3xxI
   action = app::onTerminated
   action = dum::destroy

UAS_OfferProvidedAnswer -> Terminated
  trigger = onCancel
   action = app::onTerminated
   action = send::200C
   action = send::487I

UAS_OfferProvidedAnswer -> Terminated
  trigger = onBye
   action = app::onTerminated
   action = send::200B
   action = send::487I

UAS_Accepted -> Connected
  trigger = onAck

UAS_Accepted -> UAS_Accepted
  trigger = onCancel
   action = send::200C

UAS_Accepted -> UAS_Accepted
  trigger = onTimer2xx
   action = resend::2xxI

UAS_Accepted -> Terminated
  trigger = onAck-answer
   action = send::BYE

UAS_Accepted -> Terminated
  trigger = onTimerNoAck
   action = app::onAckNotReceived
   action = app::onTerminated
   action = send::BYE

UAS_Accepted -> Terminated
  trigger = onBye
   action = app::onTerminated
   action = send::200B

UAS_Accepted -> UAS_WaitingToHangup
  trigger = dum::end

UAS_Accepted -> UAS_WaitingToOffer
  trigger = dum::provideOffer
   action = store::offer

UAS_WaitingToOffer -> UAS_SentUpdate
  trigger = onAck
   action = send::UPDATE-offer

UAS_WaitingToOffer -> SentReinvite
  trigger = onAck
   action = send::INVITE-offer

UAS_WaitingToOffer -> UAS_WaitingToOffer
  trigger = onCancel
   action = send::200C

UAS_WaitingToOffer -> UAS_WaitingToOffer
  trigger = onTimer2xx
   action = resend::2xxI

UAS_WaitingToOffer -> Terminated
  trigger = onAck-answer
   action = send::BYE

UAS_WaitingToOffer -> Terminated
  trigger = onTimerNoAck
   action = app::onAckNotReceived
   action = app::onTerminated
   action = send::BYE

UAS_WaitingToOffer -> Terminated
  trigger = onBye
   action = app::onTerminated
   action = send::200B

UAS_WaitingToOffer -> UAS_WaitingToHangup
  trigger = dum::end

UAS_EarlyOffer -> UAS_EarlyOffer
  trigger = onTimer1xx
   action = resend::1xx

UAS_EarlyOffer -> UAS_EarlyOffer
  trigger = dum::provisional
   action = send::1xx
   action = timer::1xx

UAS_EarlyOffer -> UAS_EarlyProvidedAnswer
  trigger = dum::provideAnswer
   action = store::answer

UAS_EarlyOffer -> Assert
  trigger = dum::accept
   action = assert

UAS_EarlyOffer -> Terminated
  trigger = dum::end
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_EarlyOffer -> Terminated
  trigger = dum::reject
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_EarlyOffer -> Terminated
  trigger = dum::redirect
   action = send::3xxI
   action = app::onTerminated
   action = dum::destroy

UAS_EarlyOffer -> Terminated
  trigger = onCancel
   action = send::200C
   action = send::487I

UAS_EarlyOffer -> Terminated
  trigger = onBye
   action = app::onTerminated
   action = send::200B
   action = send::487I

UAS_EarlyProvidedAnswer -> UAS_EarlyProvidedAnswer
  trigger = dum::provisional
   action = send::1xx
   action = timer::1xx

UAS_EarlyProvidedAnswer -> UAS_Accepted
  trigger = dum::accept
   action = send::2xx-answer
   action = timer::2xx
   action = timer::NoAck
   action = app::onConnected

UAS_EarlyProvidedAnswer -> Terminated
  trigger = dum::end
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_EarlyProvidedAnswer -> Terminated
  trigger = dum::reject
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_EarlyProvidedAnswer -> Terminated
  trigger = dum::redirect
   action = send::3xxI
   action = app::onTerminated
   action = dum::destroy

UAS_EarlyProvidedAnswer -> Terminated
  trigger = onCancel
   action = app::onTerminated
   action = send::200C
   action = send::487I

UAS_EarlyProvidedAnswer -> Terminated
  trigger = onBye
   action = app::onTerminated
   action = send::200B
   action = send::487I

UAS_Start -> UAS_NoOffer
  trigger = onInvite
   action = app::onNewSession
   action = app::onOfferRequired

UAS_NoOffer -> UAS_ProvidedOffer
  trigger = dum::provideOffer
   action = store::offer

UAS_NoOffer -> UAS_EarlyNoOffer
  trigger = dum::provisional
   action = send::1xx
   action = timer::1xx

UAS_NoOffer -> Assert
  trigger = dum::accept
   action = assert

UAS_NoOffer -> Terminated
  trigger = dum::end
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_NoOffer -> Terminated
  trigger = dum::reject
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_NoOffer -> Terminated
  trigger = dum::redirect
   action = send::3xxI
   action = app::onTerminated
   action = dum::destroy

UAS_NoOffer -> Terminated
  trigger = onCancel
   action = app::onTerminated
   action = send::200C
   action = send::487I
   action = dum::destroy

UAS_NoOffer -> Terminated
  trigger = onBye
   action = app::onTerminated
   action = send::200B
   action = send::487I
   action = dum::destroy

UAS_ProvidedOffer -> UAS_EarlyProvidedOffer
  trigger = dum::provisional
   action = send::1xx-early
   action = timer::1xx

UAS_ProvidedOffer -> UAS_AcceptedWaitingAnswer
  trigger = dum::accept
   action = send::2xxI-offer
   action = timer::2xx
   action = timer::NoAck

UAS_ProvidedOffer -> Terminated
  trigger = dum::end
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_ProvidedOffer -> Terminated
  trigger = dum::reject
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_ProvidedOffer -> Terminated
  trigger = dum::redirect
   action = send::3xxI
   action = app::onTerminated
   action = dum::destroy

UAS_ProvidedOffer -> Terminated
  trigger = onCancel
   action = app::onTerminated
   action = send::200C
   action = send::487I
   action = dum::destroy

UAS_ProvidedOffer -> Terminated
  trigger = onBye
   action = app::onTerminated
   action = send::200B
   action = send::487I
   action = dum::destroy

UAS_EarlyNoOffer -> UAS_EarlyNoOffer
  trigger = onTimer1xx
   action = resend::1xx

UAS_EarlyNoOffer -> UAS_EarlyNoOffer
  trigger = dum::provisional
   action = send::1xx
   action = timer::1xx

UAS_EarlyNoOffer -> UAS_EarlyProvidedOffer
  trigger = dum::provideOffer
   action = store::offer

UAS_EarlyNoOffer -> Assert
  trigger = dum::accept
   action = assert

UAS_EarlyNoOffer -> Terminated
  trigger = dum::end
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_EarlyNoOffer -> Terminated
  trigger = dum::reject
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_EarlyNoOffer -> Terminated
  trigger = dum::redirect
   action = send::3xxI
   action = app::onTerminated
   action = dum::destroy

UAS_EarlyNoOffer -> Terminated
  trigger = onCancel
   action = app::onTerminated
   action = send::200C
   action = send::487I
   action = dum::destroy

UAS_EarlyNoOffer -> Terminated
  trigger = onBye
   action = app::onTerminated
   action = send::200B
   action = send::487I
   action = dum::destroy

UAS_EarlyProvidedOffer -> UAS_EarlyProvidedOffer
  trigger = dum::provisional
   action = send::1xx-early
   action = timer::1xx

UAS_EarlyProvidedOffer -> UAS_AcceptedWaitingAnswer
  trigger = dum::accept
   action = send::2xxI-offer
   action = timer::2xx
   action = timer::NoAck

UAS_EarlyProvidedOffer -> Terminated
  trigger = dum::end
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_EarlyProvidedOffer -> Terminated
  trigger = dum::reject
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_EarlyProvidedOffer -> Terminated
  trigger = dum::redirect
   action = send::3xxI
   action = app::onTerminated
   action = dum::destroy

UAS_EarlyProvidedOffer -> Terminated
  trigger = onCancel
   action = app::onTerminated
   action = send::200C
   action = send::487I
   action = dum::destroy

UAS_EarlyProvidedOffer -> Terminated
  trigger = onTerminated
  trigger = onBye
   action = send::200B
   action = send::487I
   action = dum::destroy

UAS_AcceptedWaitingAnswer -> Connected
  trigger = onAck-answer
   action = app::onAnswer

UAS_AcceptedWaitingAnswer -> UAS_AcceptedWaitingAnswer
  trigger = onCancel
   action = send::200C

UAS_AcceptedWaitingAnswer -> UAS_AcceptedWaitingAnswer
  trigger = onPrack
   action = send::2xxP
   action = send::2xxI-offer

UAS_AcceptedWaitingAnswer -> Terminated
  trigger = onTimer2xx
   action = resend::2xxI

UAS_AcceptedWaitingAnswer -> Terminated
  trigger = onTimerNoAck
   action = send::BYE

UAS_AcceptedWaitingAnswer -> UAS_WaitingToHangup
  trigger = dum::end

UAS_Start -> UAS_OfferReliable
  trigger = onInvite-offer-rel
   action = app::onNewSession
   action = app::onOffer

UAS_Start -> UAS_NoOfferReliable
  trigger = onInvite-rel
   action = app::onNewSession
   action = app::onOfferRequired

UAS_OfferReliable -> UAS_FirstEarlyReliable
  trigger = dum::provideAnswer
   action = send::1xx-answer
   action = timer::1xx

UAS_OfferReliable -> Terminated
  trigger = dum::end
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_OfferReliable -> Terminated
  trigger = dum::reject
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_OfferReliable -> Terminated
  trigger = dum::redirect
   action = send::3xxI
   action = app::onTerminated
   action = dum::destroy

UAS_NoOfferReliable -> UAS_NoOfferReliable
  trigger = dum::provideOffer
   action = store::offer

UAS_NoOfferReliable -> UAS_FirstSentOfferReliable
  trigger = dum::provisional
   action = send::1xx-offer
   action = timer::1xx

UAS_NoOfferReliable -> Terminated
  trigger = dum::end
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_NoOfferReliable -> Terminated
  trigger = dum::reject
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_NoOfferReliable -> Terminated
  trigger = dum::redirect
   action = send::3xxI
   action = app::onTerminated
   action = dum::destroy

UAS_FirstSentOfferReliable -> UAS_FirstSentOfferReliable
  trigger = onTimer1xx
   action = resend::1xx
   action = timer::1xx

UAS_FirstSentOfferReliable -> UAS_EarlyReliable
  trigger = onPrack
   action = send::200P
   action = app::onAnswer

UAS_FirstSentOfferReliable -> Terminated
  trigger = dum::end
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_FirstSentOfferReliable -> Terminated
  trigger = dum::reject
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_FirstSentOfferReliable -> Terminated
  trigger = dum::redirect
   action = send::3xxI
   action = app::onTerminated
   action = dum::destroy

UAS_FirstEarlyReliable -> UAS_FirstEarlyReliable
  trigger = onTimer1xx
   action = resend::1xx
   action = timer::1xx

UAS_FirstEarlyReliable -> UAS_Accepted
  trigger = dum::accept
   action = queue::2xx

UAS_FirstEarlyReliable -> UAS_EarlyReliable
  trigger = onPrack
   action = send::200P

UAS_FirstEarlyReliable -> UAS_WaitingToTerminate
  trigger = dum::end

UAS_FirstEarlyReliable -> Terminated
  trigger = dum::end
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_FirstEarlyReliable -> Terminated
  trigger = dum::reject
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_FirstEarlyReliable -> Terminated
  trigger = dum::redirect
   action = send::3xxI
   action = app::onTerminated
   action = dum::destroy

UAS_EarlyReliable -> UAS_EarlyReliable
  trigger = onPrack
   action = send::200P

UAS_EarlyReliable -> UAS_EarlyReliable
  trigger = dum::provisional
   action = send::1xx
   action = timer::1xx

UAS_EarlyReliable -> UAS_EarlyReliable
  trigger = onTimer1xx
   action = resend::1xx
   action = timer::1xx

UAS_EarlyReliable -> UAS_Accepted
  trigger = dum::accept
   action = send::2xx
   action = timer::2xx

UAS_EarlyReliable -> UAS_ReceivedUpdate
  trigger = onUpdate
   action = app::onOffer

UAS_EarlyReliable -> UAS_SentUpdate
  trigger = dum::provideOffer
   action = send::UPDATE

UAS_EarlyReliable -> Terminated
  trigger = dum::end
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_EarlyReliable -> Terminated
  trigger = dum::reject
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_EarlyReliable -> Terminated
  trigger = dum::redirect
   action = send::3xxI
   action = app::onTerminated
   action = dum::destroy

UAS_Accepted -> Connected
  trigger = onAck

UAS_Accepted -> UAS_Accepted
  trigger = onCancel
   action = send::200C

UAS_Accepted -> UAS_Accepted
  trigger = onPrack
   action = send::2xxP
   action = send::2xxI
   action = timer::2xx

UAS_Accepted -> UAS_Accepted
  trigger = onTimer2xx
   action = resend::2xxI

UAS_Accepted -> Terminated
  trigger = onTimerNoAck
   action = send::BYE

UAS_Accepted -> UAS_WaitingToHangup
  trigger = dum::end

UAS_Accepted -> Terminated
  trigger = onBye
   action = send::200B
   action = app::onTerminated
   action = dum::destroy

UAS_SentUpdate -> UAS_SentUpdateAccepted
  trigger = dum::accept
   action = send::2xxI

UAS_SentUpdate -> UAS_EarlyReliable
  trigger = on2xxU

UAS_SentUpdate -> Terminated
  trigger = dum::end
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_SentUpdate -> Terminated
  trigger = dum::reject
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_SentUpdate -> Terminated
  trigger = dum::redirect
   action = send::3xxI
   action = app::onTerminated
   action = dum::destroy

UAS_SentUpdateAccepted -> UAS_Accepted
  trigger = on2xxU
   action = app::onAnswer

UAS_SentUpdateAccepted -> UAS_Accepted
  trigger = onUpdateFailure
   action = app::onOfferRejected

UAS_SentUpdateAccepted -> UAS_WaitingToHangup
  trigger = dum::end

UAS_ReceivedUpdate -> UAS_ReceivedUpdateWaitingAnswer
  trigger = dum::accept
   action = queue::2xx

UAS_ReceivedUpdate -> UAS_EarlyReliable
  trigger = dum::provideAnswer
   action = send::200U-answer

UAS_ReceivedUpdate -> Terminated
  trigger = dum::end
   action = send::488U
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_ReceivedUpdate -> Terminated
  trigger = dum::reject
   action = send::488U
   action = send::4xxI
   action = app::onTerminated
   action = dum::destroy

UAS_ReceivedUpdate -> Terminated
  trigger = dum::redirect
   action = send::488U
   action = send::3xxI
   action = app::onTerminated
   action = dum::destroy

UAS_ReceivedUpdateWaitingAnswer -> UAS_Accepted
  trigger = dum::provideAnswer
   action = send::2xxU-answer
   action = send::2xxI

UAS_ReceivedUpdateWaitingAnswer -> Terminated
  trigger = dum::end
   action = send::488U
   action = send::4xxI
   action = dum::destroy

UAS_WaitingToTerminate -> Terminated
  trigger = onPrack
   action = send::4xx
   action = dum::destroy

UAS_WaitingToHangup -> Terminated
  trigger = onPrack
   action = send::BYE

UAS_WaitingToHangup -> Terminated
  trigger = onAck
   action = send::BYE

UAS_WaitingToHangup -> Terminated
  trigger = onTimerNoAck
   action = send::BYE

/a

---

From: Adam Roach <[email-masked]>
Date: Mon, 20 Mar 2006 09:34:43 -0600

UAC_Start -> UAC_Early
  trigger = on1xxI

UAC_Start -> UAC_Early
  trigger = on1xxI-early

UAC_Start -> Connected
  trigger = on2xxI-answer
   action = send::ACK

UAC_Start -> Terminated
  trigger = on2xxI
   action = send::ACK
   action = send::BYE
   action = app::onFailure

UAC_Start -> Terminated

UAC_Start -> Terminated
  trigger = onRedirect

UAC_Start -> Assert
  trigger = dum::cancel
   action = assert

UAC_Early -> UAC_Early
  trigger = on1xxI

UAC_Early -> UAC_Early
  trigger = on1xxI-early

UAC_Early -> Connected
  trigger = on2xxI-answer
   action = send::ACK
   action = app::onAnswer

UAC_Early -> Terminated
  trigger = on2xxI
   action = send::ACK
   action = send::BYE
   action = app::onFailure

UAC_Early -> Terminated

UAC_Early -> Terminated
  trigger = onRedirect

UAC_Early -> Assert

UAC_Early -> Assert

UAC_Early -> Terminated
  trigger = dum::end
   action = send::BYE

UAC_Answered -> Assert

UAC_Answered -> Assert
  trigger = dum::cancel
   action = assert

UAC_SentAnswer -> Assert

Connected -> SentUpdate

Connected -> Connected
  trigger = on2xxP

Connected -> Connected
  trigger = on2xxI
   action = resend::ACK

Connected -> Connected
  trigger = onTimer2xx
   action = resend::2xx

Connected -> Connected
  trigger = onCancel
   action = send::200C

Connected -> Terminated
  trigger = dum::end
   action = send::BYE

Connected -> Terminated
  trigger = onBye
   action = send::200B

SentUpdate -> Connected
  trigger = on2xxU
   action = app::onAnswer

SentUpdate -> Connected

SentUpdate -> SentUpdate
  trigger = onUpdate
  trigger = onInvite
   action = send::491

SentUpdate -> Terminated

SentUpdate -> Terminated
  trigger = dum::end
   action = send::BYE

Answered -> Answered
  trigger = onTimer2xx
   action = resend::2xx

Answered -> Connected
  trigger = onAck
   action = timer::NoAck

Terminated -> Terminated
  trigger = onResponse
   action = dum::destroy

Terminated -> Terminated
  trigger = onRequest
   action = send::481
   action = dum::destroy

UAS_Start -> UAS_Offer
  trigger = onInvite-offer

UAS_Offer -> Assert
  trigger = dum::accept
   action = assert

UAS_Offer -> Terminated
  trigger = dum::end
   action = send::4xxI

UAS_Offer -> Terminated
  trigger = dum::reject
   action = send::4xxI

UAS_Offer -> Terminated
  trigger = dum::redirect
   action = send::3xxI

UAS_Offer -> Terminated
  trigger = onCancel

UAS_Offer -> Terminated
  trigger = onBye

UAS_EarlyOffer -> Assert
  trigger = dum::accept
   action = assert

UAS_Start -> UAS_NoOffer
  trigger = onInvite

UAS_NoOffer -> Assert
  trigger = dum::accept
   action = assert

/a

---

From: <[email-masked]>
Date: Tue, 21 Mar 2006 15:45:58 +0200

Hi,

>>>In Vancouver, Rohan put up a slide to demonstrate 
>>>this issue graphically, but its impact hasn't been 
>>>shared on the list. To that end, I'll point out that 
>>>implementing the offer/answer procedures with PRACK 
>>>requires a state machine with at least 52 states and 
>>>329 transitions. That's a *lot* of code, and the 
>>>chances of getting it all right are pretty close to 
>>>zero.

>> If that is the case, I would really ask that slide 
>> with explanations To be published in SIP mailing list. 
>> For instance I was not attending Vancouver meeting, 
>> so I am currently lacking this piece of information.

> Because the graphic doesn't work well on a mailing list, 
> I've put it here in text format. If you want the visual 
> impact of the graph that Rohan put up at IETF64, grab the 
> PDF file...

Thanks. This morning I had a look into the state diagram
both in text and graphical format.

> I would especially like to be explained where this 
> multitude of states and transitions come from for 
> sending offers/answers in PRACK, especially when 
> compared to a solution where those could only be 
> sent in UPDATE.

To my surprise, amongst all the referred 329 transitions
I found only 15 to be related to PRACK method. Further on
I could not find any transition related to sending a PRACK
with offer and only one single transition for sending a
PRACK with answer. So after all, the apparent complexity
of this state machine had no relation to sending offers 
or answers within PRACK ! Deprecating offers within PRACK 
would have absolutely no impact to this state diagram.
Please tell me if I am wrong with this.

After some study of the state diagram I now understand a bit
better where those 52 states and 329 transitions come from.
This is the result from my initial analysis:

1. This state diagram covers both UAC and UAS state machines.
So it is not a single state machine at all.

2. The state machines do not contain only session setup like
I expected. It also covers mid-dialog requests like re-INVITEs,
mid-dialog UPDATEs and BYEs for terminating the session.

3. A big number of state transitions are related to 
cancelling and terminating the dialogs either before or
after the session has been moved to Connected state.

In theory the session setup state machine could be cut  
to half by deprecating offerless INVITEs. This is the source
of most of the complexity in the state machine. But like
discussed earlier in this thread the offerless INVITE
has certain applications and is probably widely deployed,
deprecating it can probably not be done generally. (In 3GPP
they just simply mandate the INVITE to contain an offer, 
which makes the life for implementors much easier. INVITE
without offer will always be rejected with 4xx response.)

Further on what clutters the UAC part of the state diagram
is the fact that in the UAC_Start state the UAC might have
sent the INVITE either with or without offer. I would rather
redraw the diagram so that the UAC_Start state would be an
idle state from which there would be transitions to two states
like UAC_Offer and UAC_NoOffer. UAS part of the state diagram
has been created that way, which makes it much clearer.

The bottom line is that I do not think this state diagram
really provided much input for making decisions about what
to do with offer/answer in PRACK.

Regards,

Erkki
____________________________________

  Erkki Koivusalo
  Nokia Mobile Software
  tel:+358 40 7571197
  mailto:[email-masked]
____________________________________

---

From: "Enrico Marocco" <[email-masked]>
Date: Tue, 21 Mar 2006 11:13:29 -0600

A couple of mounts age we have submitted an informational draft 
(draft-cuda-sipping-ua-fsm-00) describing an alternative and hopefully 
more intuitive formal model for representing the full negotiation.  The 
effort of that draft was on separating and showing relations between the 
three state machine involved in the process (session, media negotiation 
and signalling).

Maybe it could be somewhat userful in this analysis.

Enrico

> subsequent actions are indicated following that line.

[sorry, dropped for honouring 40K size limit]
--------------------------------------------------------------------

CONFIDENTIALITY NOTICE

This message and its attachments are addressed solely to the persons above and may contain confidential information. If you have received the message in error, be informed that any use of the content hereof is prohibited. Please return it immediately to the sender and delete the message. Should you have any questions, please contact us by replying to [email-masked].

        Thank you

                                        www.telecomitalia.it

--------------------------------------------------------------------

---

From: Paul Kyzivat <[email-masked]>
Date: Thu, 23 Mar 2006 15:48:36 -0500

Enrico,

I remember reading your draft when it first came out, and I thought I 
commented on it. But I cannot find any record of actually sending 
comments. :-(

I'm not taking time to read it carefully again now. But based on a 
glance, it appears to be consistent with my reaction to the 329 state 
FSM: this thing needs to be factored. The obvious factoring is into an 
offer/answer fsm, an invite-dialog-usage fsm, and a transaction fsm. 
There is also need for a dialog state machine, but it isn't an fsm 
because it requires counting, and it is pretty trivial.

I would also observe that the 329 state fsm is incomplete because it 
doesn't support early-session. (At least I don't think so.) It is in 
theory possible to have an offer/answer fsm for session and an 
offer/answer fsm for early-session in progress, and in different states, 
attached to the same invite-dialog-usage fsm.

	Paul

Enrico Marocco wrote:
> This message and its attachments are addressed solely to the persons
> above and may contain confidential information. If you have received
> the message in error, be informed that any use of the content hereof
> is prohibited. Please return it immediately to the sender and delete
> the message. Should you have any questions, please contact us by
> replying to [email-masked] <mailto:[email-masked]>.
>         Thank you
>                                         www.telecomitalia.it 
> <http://www.telecomitalia.it>
> ------------------------------------------------------------------------
>

---

From: "Enrico Marocco" <[email-masked]>
Date: Thu, 23 Mar 2006 17:56:48 -0600

> commented on it. But I cannot find any record of actually sending

Actually we haven't received any.

> offer/answer fsm, an invite-dialog-usage fsm, and a transaction fsm.

That's basically our approach.  We've come to it in the effort of
reducing the mess introduced in our stack by adding support for the
insane 3gpp handshake; that's why it is much (maybe too) "implementation
oriented".

Enrico

CONFIDENTIALITY NOTICE

        Thank you

                                        www.telecomitalia.it