sl: new pv $ltt(key) - return local generated to tag
authorDaniel-Constantin Mierla <miconda@gmail.com>
Tue, 4 Dec 2018 08:21:38 +0000 (09:21 +0100)
committerDaniel-Constantin Mierla <miconda@gmail.com>
Tue, 4 Dec 2018 08:21:38 +0000 (09:21 +0100)
- the to-tag used when kamailio sends a reply
- $ltt(s) - the to-tag used in stateless replies
- $ltt(t) - the to-tag used in transaction stateful replies (transaction
has to be created at that time, eg., by t_newtran() or in a
branch/failure route, otherwise it returns $null)
- $ltt(x) - $ltt(t) if the transaction was created already, otherwise
$ltt(s)

src/modules/sl/sl.c

index 96c3fdf..36c8a8e 100644 (file)
@@ -78,6 +78,17 @@ static int child_init(int rank);
 static void mod_destroy();
 static int fixup_sl_reply(void** param, int param_no);
 
+static int pv_get_ltt(sip_msg_t *msg, pv_param_t *param, pv_value_t *res);
+static int pv_parse_ltt_name(pv_spec_p sp, str *in);
+
+
+static pv_export_t mod_pvs[] = {
+       { {"ltt", (sizeof("ltt")-1)}, PVT_OTHER, pv_get_ltt, 0,
+               pv_parse_ltt_name, 0, 0, 0 },
+
+       { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
+};
+
 static cmd_export_t cmds[]={
        {"sl_send_reply",  w_sl_send_reply,             2, fixup_sl_reply, 0,
                REQUEST_ROUTE},
@@ -120,7 +131,7 @@ struct module_exports exports= {
        cmds,                           /* cmd (cfg function) exports */
        params,                     /* param exports */
        sl_rpc,                     /* RPC method exports */
-       0,                                      /* pv exports */
+       mod_pvs,                        /* pv exports */
        0,                                      /* response handling function */
        mod_init,                       /* module init function */
        child_init,                     /* per-child init function */
@@ -486,6 +497,83 @@ static int w_sl_forward_reply2(sip_msg_t* msg, char* str1, char* str2)
 }
 
 /**
+ *
+ */
+static int pv_get_ltt(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
+{
+       str ttag = STR_NULL;
+       tm_cell_t *t = NULL;
+
+       if(msg==NULL)
+               return pv_get_null(msg, param, res);
+
+       if(param==NULL)
+               return pv_get_null(msg, param, res);
+
+       switch(param->pvn.u.isname.name.n) {
+               case 0: /* mixed */
+                       if(get_reply_totag(msg, &ttag)<0) {
+                               return pv_get_null(msg, param, res);
+                       }
+                       return pv_get_strval(msg, param, res, &ttag);
+               case 1: /* stateless */
+                       if(sl_get_reply_totag(msg, &ttag)<0) {
+                               return pv_get_null(msg, param, res);
+                       }
+                       return pv_get_strval(msg, param, res, &ttag);
+               case 2: /* transaction stateful */
+                       if(sl_bind_tm==0 || tmb.t_gett==0) {
+                               return pv_get_null(msg, param, res);
+                       }
+
+                       t = tmb.t_gett();
+                       if(t== NULL || t==T_UNDEFINED) {
+                               return pv_get_null(msg, param, res);
+                       }
+                       if(tmb.t_get_reply_totag(msg, &ttag)<0) {
+                               return pv_get_null(msg, param, res);
+                       }
+                       return pv_get_strval(msg, param, res, &ttag);
+               default:
+                       return pv_get_null(msg, param, res);
+       }
+}
+
+/**
+ *
+ */
+static int pv_parse_ltt_name(pv_spec_p sp, str *in)
+{
+       if(sp==NULL || in==NULL || in->len<=0)
+               return -1;
+
+       switch(in->len) {
+               case 1:
+                       if(strncmp(in->s, "x", 1)==0) {
+                               sp->pvp.pvn.u.isname.name.n = 0;
+                       } else if(strncmp(in->s, "s", 1)==0) {
+                               sp->pvp.pvn.u.isname.name.n = 1;
+                       } else if(strncmp(in->s, "t", 1)==0) {
+                               sp->pvp.pvn.u.isname.name.n = 2;
+                       } else {
+                               goto error;
+                       }
+               break;
+               default:
+                       goto error;
+       }
+       sp->pvp.pvn.type = PV_NAME_INTSTR;
+       sp->pvp.pvn.u.isname.type = 0;
+
+       return 0;
+
+error:
+       LM_ERR("unknown PV ltt key: %.*s\n", in->len, in->s);
+       return -1;
+}
+
+
+/**
  * @brief bind functions to SL API structure
  */
 static int bind_sl(sl_api_t* api)