> For the complete documentation index, see [llms.txt](https://prosbcdocs.telcobridges.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://prosbcdocs.telcobridges.com/telecom-references/apis-and-integration/caf-ctbcmctimer.md).

# CAF: CTBCMCTimer

#### Recommended timer API within CTBCAFCallFlow or CTBCAFCallBehavior

Before you read information about CTBCMCTimer below, please note that Toolpack 2.9 and above provide a much simplified mechanism for managing timers in CAF call flow or behaviors.

With these simplified timers, it is no longer necessary to "manually" deal with timer allocation and de-allocation, and it is not dangerous to leak memory or timers, and cause crashes if timers are not properly canceled upon leg termination. For these reasons, we highly encourage developers to use this "simplified" timer API.

Here are the "simplified" timer functions.

**StartCallTimer**

This method allows to start a call flow timer, either attached to a given leg (timer is automatically canceled when the leg is terminated), or to the call flow in general (timer will remain valid until the last leg of the call flow is terminated).

The timer can also be periodic (will be called multiple times until it's canceled)

**FindCallTimer**

Find a previously started timer

**CancelCallTimer**

Cancel a timer

**Timer expiration**

When the timer reaches the expiration delay, **OnLegEvent** is called with event type **TBCMC\_EVENT\_TYPE\_TIMEOUT** and the cause specified through **StartCallTimer**.

#### CTBCMCTimer class

The *CTBCMCTimer* class is used to spawn timers attached to call legs. CTBCMCTimer( TBCMC\_LEG\_ID in\_LegId ) This constructor creates a new timer object bound to a call leg, but that's not yet kicked (doing nothing for now).

```
CTBCMCTimer( TBCMC_LEG_ID in_LegId, TBX_UINT32 in_un32TimeoutMs, TBX_UINT32 in_un32TimeoutEventCause )
This constructor creates a new timer object bound to a call leg,
and immediately "kicks" that timer so it expire in "in_un32TimeoutMs" milliseconds with cause in_un32TimeoutEventCause.

Kick( TBX_UINT32 in_un32TimeoutMs, TBX_UINT32 in_un32TimeoutEventCause )
This function will cancel previously kicked timer,
then "kicks" that timer so it expire in "in_un32TimeoutMs" milliseconds with cause in_un32TimeoutEventCause.

Cancel()
This function cancels a timer that had previously been kicked
```

#### Using the timer within a *CTBCAFCallFlow* or *CTBCAFCallBehavior* object

The *CTBCMCTimer* is bound to a call leg. When it expires, it will cause *OnLegEvent* to be called on the *CTBCAFCallFlow* that owns that call leg, and also on all behaviors attached to that call flow. The event will be of type *TBCMC\_LEG\_EVENT\_TYPE\_TIMEOUT*, and the event cause will be equal to the value of *in\_un32TimeoutEventCause* passed when the timer was kicked.

#### Destroying the timer object

The timer object must be destroyed (or at least canceled) at most upon *OnLegFreed*. In fact, if not canceled at that point, it will cause error traces in the CAF library due to timer expiring for unknown call leg.

#### Example code

Define a unique timer cause:

1. define MY\_CTBCMC\_TIMER\_CAUSE CTBCAF\_MSG\_ID\_GEN(TBX\_ID\_CLASS\_TBCMC\_TIMER\_ID\_USER\_APP, 0x01)
2. define MY\_OTHER\_CTBCMC\_TIMER\_CAUSE CTBCAF\_MSG\_ID\_GEN(TBX\_ID\_CLASS\_TBCMC\_TIMER\_ID\_USER\_APP, 0x02)

Creating and kicking the timer: mpExampleTimer = tbnew CTBCMCTimer ( in\_pCallLeg->GetLegId(), 15000, /\* Timeout in 15 seconds \*/ MY\_CTBCMC\_TIMER\_CAUSE );

Destroying the timer, upon leg destruction, in case it did not timeout: TBX\_RESULT MyCallFlowOrBehavior::OnLegFreed( PCTBCAFCallLeg in\_pCallLeg, PITBCAFCallFlow\* io\_ppThis ) ( IN PCTBCAFCallLeg in\_pCallLeg, IN\_OUT PITBCAFCallFlow\* io\_ppThis ) { if( mpExampleTimer ) { delete mpExampleTimer; mpExampleTimer = NULL; } // Call default leg terminated implementation (mandatory) return CTBCAFCallBehavior::OnLegFreed(in\_pCallLeg, io\_ppThis); }

Handling expired timer: TBX\_RESULT MyCallFlowOrBehavior::OnLegEvent( PCTBCAFCallLeg in\_pCallLeg, PITBCMCLegEvent in\_pEvent ) { TBX\_BOOL fConsumed = TBX\_FALSE; if( in\_pEvent->GetType() == TBCMC\_LEG\_EVENT\_TYPE\_TIMEOUT ) { if( in\_pEvent->GetCause() != MY\_CTBCMC\_TIMER\_CAUSE ) { // My timer expired, do something DoSomething(); // Destroy the timer (in this example we don't need to kick it anymore) if( mpExampleTimer ) { delete mpExampleTimer; mpExampleTimer = NULL; } fConsumed = TBX\_TRUE; } } if( !fConsumed ) { // Event was not for us, forward to next behavior in the chain return mpCallInterface->OnLegEvent( in\_pCallLeg, in\_pEvent ); } }


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://prosbcdocs.telcobridges.com/telecom-references/apis-and-integration/caf-ctbcmctimer.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
