Login | Register

Documentation

Documentation -> Development Manual -> Transformations API

This page has been visited 187 times.



Transformations API

Transformations are functions which can operate directly on any OpenSIPS pseudo-variable. A transformation takes as input the value of the pseudo-variable and processes it, outputting a transformed version.
Some transformation examples:

  • the "uri" transformations (which work on SIP URIs, and they allow extracting various useful information, such as the URI's username or domain parts, various parameters, etc.)
  • the "s" class of transformations (which work on generic strings, and provide various useful methods as fetching the length of the string, searching the first occurrence of a character inside the string, etc.)
  • ... many others! – see http://www.opensips.org/Documentation/Script-Tran-3-5


# example of usage
$var(tutorial)  = “OpenSIPSDevel”;
xlog("Our variable has $(var(tutorial){s.len}) characters\n");
# ... which will print "Our variable has 13 characters\n"

Note that transformations can be chained together, so make sure to take this into account when implementing new ones!


$var(our_uri) = “sip:vlad@opensips.org;
xlog("The username of our URI has $(var(our_uri){uri.user}{s.len}) characters\n");

In our examples, uri and s are the so called classes of transformations, while user and len are the actual operations within the class.
We will further follow the implementation of the uri class of transformation, and then focus on the user function.
Adding new classes of transformations is done in transformations.c, by extending the core_trans[] array:

static trans_export_t core_trans[] = {
...
    {str_init("uri"), tr_parse_uri, tr_eval_uri},
...

Notice that we supply a parsing function and an evaluation function.
The parsing function will be invoked with the full name of the transformation, so you can parse it and establish the actual function (transformation) to be invoked:

int tr_parse_uri(str* in, trans_t *t)
{
    char *p;
    str name;
    tr_param_t *tp = NULL;

    if(in==NULL || in->s==NULL || t==NULL)
        return -1;
    p = in->s;
    name.s = in->s;
...


After we've decided what actually needs to be done and did all the parsing, the evaluation function, tr_eval_uri() will do all the weightlifting at runtime, as it will evaluate our transformation and return the new transformation output.
In our case, the function parses the provided string into a SIP URI, and then populates the output pv_value_t accordingly to the subtype provided :

/* make a PKG copy of the input */
_tr_uri.s = (char*)pkg_malloc((val->rs.len+1)*sizeof(char));
...
memcpy(_tr_uri.s, val->rs.s, val->rs.len);
_tr_uri.s[_tr_uri.len] = '\0';
...
/* parse uri -- params only when requested */
        if(parse_uri(_tr_uri.s, _tr_uri.len, &_tr_parsed_uri)!=0)
        {
            LM_ERR("invalid uri [%.*s]\n", val->rs.len,
                    val->rs.s);
...
/* zero out the output val */
memset(val, 0, sizeof(pv_value_t));
/* the output pvar will be a string */
val->flags = PV_VAL_STR;

switch(subtype) {
      case TR_URI_USER:
            val->rs = (_tr_parsed_uri.user.s)?_tr_parsed_uri.user:_tr_empty;
            break;
...

Page last modified on May 31, 2024, at 09:54 AM