# TM Module API

There are applications which would like to generate SIP transactions without too big involvement in SIP stack, transaction management, etc. An example of such an application is sending instant messages from a website. To address needs of such apps, SIP-router accepts requests for new transactions via the management interface. If you want to enable this feature, start the management interface server by configuring the proper modules.

An application can easily launch a new transaction by writing a transaction request to this interface. The request must follow very simple format, which for the basic FIFO interface is

     :t_uac_from:[<file_name>]\n
     <method>\n
     <sender's uri>\n
     <dst uri>\n
     <CR_separated_headers>\n
     <body>\n
     .\n
     \n

(Filename is to where a report will be dumped. ser assumes /tmp as file's directory.)

Note the request write must be atomic, otherwise it might get intermixed with writes from other writers. You can easily use it via Unix command-line tools, see the following example:

    [jiri@bat jiri]$ cat > /tmp/ser_fifo
    :t_uac_from:xxx
    MESSAGE
    sip:sender@iptel.org
    sip:mrx@iptel.org
    header:value
    foo:bar
    bznk:hjhjk
    p_header: p_value

    body body body
    yet body
    end of body
    .

or cat test/transaction.fifo > /tmp/ser_fifo

## Defines

- ACK_TAG enables stricter matching of acknowledgments including to-tags. Without it, to-tags are ignored. It is disabled by default for two reasons:

  - It eliminates an unlikely race condition in which transaction's to-tag is being rewritten by a 200 OK whereas an ACK is being looked up by to-tag.

  - It makes UACs happy who set wrong to-tags.

  It should not make a difference, as there may be only one negative reply sent upstream and 200/ACKs are not matched as they constitute another transaction. It will make no difference at all when the new magic cookie matching is enabled anyway.

- CANCEL_TAG similarly enables strict matching of CANCELs including to-tags--act of mercy to UACs, who screw up the to-tags (however, it still depends on how forgiving the downstream UAS is). Like with ACK_TAG, all this complex transactions matching goes with RFC3261's magic cookie away anyway.

## Functions

### `register_tmcb(cb_type, cb_func)`

For programmatic use only--register a function to be called back on an event. See t_hooks.h for more details.

Meaning of the parameters is as follows:

- cb_type - Callback type.

- cb_func - Callback function.

### `load_tm(*import_structure)`

For programmatic use only--import exported TM functions. See the acc module for an example of use.

Meaning of the parameters is as follows:

- import_structure - Pointer to the import structure.

### `int t_suspend(struct sip_msg *msg, unsigned int *hash_index, unsigned int *label)`

For programmatic use only. This function together with t_continue() can be used to implement asynchronous actions: t_suspend() saves the transaction, returns its identifiers, and t_continue() continues the SIP request/response processing. (The request/response processing does not continue from the same point in the script, a separate route block defined by the parameter of t_continue() is executed instead. The reply lock is held during the route block execution.) FR timer is ticking while the transaction is suspended, and the transaction's failure route is executed if t_continue() is not called in time.

Missing: message lumps are saved by t_suspend() and are not updated by the subsequent t_relay(). This means that the modifications made between them are lost.

Meaning of the parameters is as follows:

- msg - SIP message pointer.

- hash_index - transaction identifier.

- label - transaction identifier.

Return value: 0 - success, <0 - error.

Usage: Allocate a memory block for storing the transaction identifiers (hash_index and label), and for storing also any variable related to the async query. Before calling t_suspend(), register for the following callbacks, and pass the pointer to the allocated shared memory as a parameter: TMCB_ON_FAILURE, TMCB_DESTROY, and TMCB_E2ECANCEL_IN (in case of INVITE transaction). The async operation can be cancelled, if it is still pending, when TMCB_ON_FAILURE or TMCB_E2ECANCEL_IN is called. TMCB_DESTROY is suitable to free the shared memory allocated for the async and SIP transaction identifiers. Once the async query result is available call t_continue(), see below. The SIP transaction must exist before calling t_suspend(), and the module function calling t_suspend() should return 0 to make sure that the script processing does not continue.

### `int t_continue(unsigned int hash_index, unsigned int label, struct action *route)`

For programmatic use only. This function is the pair of t_suspend(), and is supposed to be called when the asynchronous query result is available. The function executes a route block with the saved SIP message. It is possible to add more branches to the transaction, or send a reply from the route block.

Meaning of the parameters is as follows:

- hash_index - transaction identifier.

- label - transaction identifier.

- route - route block to execute.

Return value: 0 - success, <0 - error.

### `int t_cancel_suspend(unsigned int hash_index, unsigned int label)`

For programmatic use only. This function is for revoking t_suspend() from the same process as it was executed before. t_cancel_suspend() can be used when something fails after t_suspend() has already been executed and it turns out that the transaction should not have been suspended. The function cancels the FR timer of the transaction.

The message lumps are saved by t_suspend() which cannot be restored.

Meaning of the parameters is as follows:

- hash_index - transaction identifier.

- label - transaction identifier.

Return value: 0 - success, <0 - error.