@@ -175,15 +175,23 @@ impl Transaction {
175175 endpoint_inner : EndpointInnerRef ,
176176 ) -> Self {
177177 let ( tu_sender, tu_receiver) = unbounded_channel ( ) ;
178- info ! ( %key, "transaction created" ) ;
178+ let state = if matches ! (
179+ transaction_type,
180+ TransactionType :: ServerInvite | TransactionType :: ServerNonInvite
181+ ) {
182+ TransactionState :: Calling
183+ } else {
184+ TransactionState :: Nothing
185+ } ;
186+ info ! ( %key, %state, "transaction created" ) ;
179187 let tx = Self {
180188 transaction_type,
181189 endpoint_inner,
182190 connection,
183191 key,
184192 original,
185193 destination : None ,
186- state : TransactionState :: Calling ,
194+ state,
187195 last_response : None ,
188196 last_ack : None ,
189197 timer_a : None ,
@@ -270,7 +278,7 @@ impl Transaction {
270278 } ;
271279
272280 connection. send ( message, self . destination . as_ref ( ) ) . await ?;
273- self . transition ( TransactionState :: Trying ) . map ( |_| ( ) )
281+ self . transition ( TransactionState :: Calling ) . map ( |_| ( ) )
274282 }
275283
276284 pub async fn reply_with (
@@ -348,7 +356,11 @@ impl Transaction {
348356
349357 fn can_transition ( & self , target : & TransactionState ) -> Result < ( ) > {
350358 match ( & self . state , target) {
351- ( & TransactionState :: Calling , & TransactionState :: Trying )
359+ ( & TransactionState :: Nothing , & TransactionState :: Calling )
360+ | ( & TransactionState :: Nothing , & TransactionState :: Trying )
361+ | ( & TransactionState :: Nothing , & TransactionState :: Proceeding )
362+ | ( & TransactionState :: Nothing , & TransactionState :: Terminated )
363+ | ( & TransactionState :: Calling , & TransactionState :: Trying )
352364 | ( & TransactionState :: Calling , & TransactionState :: Proceeding )
353365 | ( & TransactionState :: Calling , & TransactionState :: Completed )
354366 | ( & TransactionState :: Calling , & TransactionState :: Terminated )
@@ -615,7 +627,7 @@ impl Transaction {
615627
616628 async fn on_timer ( & mut self , timer : TransactionTimer ) -> Result < ( ) > {
617629 match self . state {
618- TransactionState :: Trying => {
630+ TransactionState :: Calling | TransactionState :: Trying => {
619631 if matches ! (
620632 self . transaction_type,
621633 TransactionType :: ClientInvite | TransactionType :: ClientNonInvite
@@ -704,8 +716,28 @@ impl Transaction {
704716 return Ok ( self . state . clone ( ) ) ;
705717 }
706718 match state {
719+ TransactionState :: Nothing => { }
707720 TransactionState :: Calling => {
708- // not state can transition to Calling
721+ let connection = self . connection . as_ref ( ) . ok_or ( Error :: TransactionError (
722+ "no connection found" . to_string ( ) ,
723+ self . key . clone ( ) ,
724+ ) ) ?;
725+
726+ if matches ! (
727+ self . transaction_type,
728+ TransactionType :: ClientInvite | TransactionType :: ClientNonInvite
729+ ) {
730+ if !connection. is_reliable ( ) {
731+ let timer_a = self . endpoint_inner . timers . timeout (
732+ self . endpoint_inner . option . t1 ,
733+ TransactionTimer :: TimerA (
734+ self . key . clone ( ) ,
735+ self . endpoint_inner . option . t1 ,
736+ ) ,
737+ ) ;
738+ self . timer_a . replace ( timer_a) ;
739+ }
740+ }
709741 }
710742 TransactionState :: Trying => {
711743 let connection = self . connection . as_ref ( ) . ok_or ( Error :: TransactionError (
0 commit comments