# &adminguide;

## Overview

This module allows the execution of assemblies of managed code, among the most popular of which is C# (.NET). It uses the Mono project (http://www.mono-project.com/) to embed the managed code interpreter inside the SIP server, providing fast execution.

Besides C#, other languages can be used to build managed assemblies, such as: Java, Python, VisualBasic.NET, JavaScript. For more details on what kind of languages can be used to build managed assemblies, see: http://www.mono-project.com/Languages

A managed assembly can get access to any &kamailio; config variables and set them. It can also perform many other functions implemented inside &kamailio; itself, allowing easier handling of SIP from managed code.

There are two ways to execute managed code assemblies: load the code at startup and only execute at runtime, or load and execute at runtime. Only one mode at a time may be used. The mode is determined by the 'load' parameter and the function used to execute the code.

## Dependencies

### &kamailio; Modules

The following modules must be loaded before this module:

- none.

### External Libraries or Applications

The following libraries or applications must be installed before running &kamailio; with this module loaded:

- mono-devel - Mono devel toolkit.

## Parameters

### `load` (string)

Set the path to the Mono assembly to be loaded at startup. You can use mono_run(param) to execute the assembly at runtime.

Default value is null.

#### Set `load` parameter

    ...
    modparam("app_mono", "load", "/usr/local/etc/kamailio/mono/myscript.exe")
    ...

## Functions

### `mono_exec(path [, param])`

Execute the managed code assembly stored in 'path'. The path can be a string with pseudo-variables evaluated at runtime. A second parameter can optionally be provided; it will be passed to the assembly.

Note that the assembly is loaded every time from the file, so any change to it is immediately live. This function cannot be used if 'load' parameter is set.

#### `mono_exec` usage

    ...
    mono_exec("/usr/local/etc/kamailio/mono/myscript.exe");
    ...

### `mono_run([param])`

Execute the assembly specified by 'load' module parameter. The assembly is loaded at startup, so changes to it will be effective only after &kamailio; restart.

An optional parameter can be given and it will be passed over to the assembly. It can be a string with pseudo-variables; these will be evaluated at runtime.

#### `mono_run` usage

    ...
    if(!mono_run("myparam"))
    {
        xdbg("SCRIPT: failed to execute mono assembly!\n");
    }
    ...

## Usage

First, create a library from the 'SR.cs' file provided in the folder 'modules/app_mono/lib/'. The examples uses the folder /usr/local/etc/kamailio/mono/ to store the Mono-specific assemblies to be used by &kamailio;.

    ...
    mkdir -p /usr/local/etc/kamailio/mono/
    cp modules/app_mono/lib/SR.cs /usr/local/etc/kamailio/mono/
    gmcs -t:library SR.cs
    ...

You should see the 'SR.dll' file generated.

Create your application in C#/.NET and save it in the same folder with SR.dll. You have to use the SR package in your managed source code file -- say you named MySRTest.cs. Also, be aware that the Main() function from the managed assembly is executed; thus, be sure that you have it defined.

    ...
    using SR;

    namespace MySRTest {
    	class Test {
    		static int Main(string[] args) {
    			SR.Core.Log(1, "Kamailio API Version: " + SR.Core.APIVersion() + "\n");
    			if (args.Length == 1) {
    				SR.Core.Log(1, "Parameter from Kamailio config: "
    					+ args[0] + "\n");
    			}
    			SR.Core.Dbg("Request URI is: " + SR.PV.GetS("$ru") + "\n");
    			SR.PV.SetS("$rU", "123");
    			SR.HDR.AppendToReply("My-Mono-Hdr: ok\r\n");
    			SR.Core.ModF("sl_reply_error");
    			return 1;
    		}
    	}
    }
    ...

You have to compile the 'SR.dll' file generated.

    ...
    $ gmcs -r:SR.dll MySRTest.cs
    ...

You should see the file 'MySRTest.exe' generated in the folder.

In the &kamailio; config file, load the app_mono.so module and use its functions inside the routing blocks.

    ...
    loadmodule "app_mono.so"
    ...
    route {
        ...
        mono_exec("/usr/local/etc/kamailio/mono/MySRTest.exe");
        ...
    }
    ...

The API exported by the SR package to Mono applications is documented on the &kamailio; wiki site. Also, it is easy to figure out by looking in the source code tree inside the file modules/app_mono/lib/SR.cs.