diff --git a/modules/sca/Makefile b/modules/sca/Makefile index 808f16f71fc..bad03750a00 100644 --- a/modules/sca/Makefile +++ b/modules/sca/Makefile @@ -9,7 +9,7 @@ auto_gen= NAME=sca.so LIBS= -DEFS+=-DSER_MOD_INTERFACE +DEFS+=-DKAMAILIO_MOD_INTERFACE SERLIBPATH=../../lib SER_LIBS+=$(SERLIBPATH)/kcore/kcore diff --git a/modules/sca/doc/sca_admin.xml b/modules/sca/doc/sca_admin.xml index a4b5210be04..b422dc53c01 100644 --- a/modules/sca/doc/sca_admin.xml +++ b/modules/sca/doc/sca_admin.xml @@ -342,7 +342,7 @@ if ( is_method( "SUBSCRIBE" )) {
- <function moreinfo="none">sca_call_info_update([mask])</function> + <function moreinfo="none">sca_call_info_update([mask, to, from])</function> @@ -355,6 +355,14 @@ if ( is_method( "SUBSCRIBE" )) { 2 - SCA_CALL_INFO_SHARED_CALLEE + + to - string (optional) + string to use as To and skip parsing To header from the message. The parameter allows pseudo-variables usage + + + from - string (optional) + string to use as From and skip parsing From header from the message. The parameter allows pseudo-variables usage + @@ -400,7 +408,7 @@ if ( is_method( "SUBSCRIBE" )) { route { ... - sca_call_info_update(); + sca_call_info_update(0, "$var(to)", "$var(from)@$var(domain)"); ... } diff --git a/modules/sca/sca.c b/modules/sca/sca.c index cca8b810e77..62a6db971e0 100644 --- a/modules/sca/sca.c +++ b/modules/sca/sca.c @@ -40,6 +40,7 @@ #include "../../timer.h" #include "../../timer_proc.h" +#include "../../mod_fix.h" #include "sca.h" #include "sca_appearance.h" @@ -69,18 +70,24 @@ static int sca_mod_init(void); static int sca_child_init(int); static void sca_mod_destroy(void); static int sca_set_config(sca_mod *); +int fixup_ciu(void **, int); +int fixup_free_ciu(void **param, int param_no); /* * EXPORTED COMMANDS */ static cmd_export_t cmds[] = { - {"sca_handle_subscribe", sca_handle_subscribe, 0, NULL, + {"sca_handle_subscribe", (cmd_function)sca_handle_subscribe, 0, NULL, 0, REQUEST_ROUTE}, - {"sca_call_info_update", sca_call_info_update, 0, NULL, + {"sca_call_info_update", (cmd_function)sca_call_info_update, 0, NULL, 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, - {"sca_call_info_update", sca_call_info_update, 1, fixup_var_int_1, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, - {NULL, NULL, -1, 0, 0}, + {"sca_call_info_update", (cmd_function)sca_call_info_update, 1, + fixup_ciu, fixup_free_ciu, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, + {"sca_call_info_update", (cmd_function)sca_call_info_update, 2, + fixup_ciu, fixup_free_ciu, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, + {"sca_call_info_update", (cmd_function)sca_call_info_update, 3, + fixup_ciu, fixup_free_ciu, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, + { 0, 0, 0, 0, 0, 0 } }; /* @@ -144,16 +151,19 @@ static param_export_t params[] = { /* * MODULE EXPORTS */ -struct module_exports exports = { - "sca", // module name - cmds, // exported functions - NULL, // RPC methods - params, // exported parameters - sca_mod_init, // module initialization function - NULL, // response handling function - sca_mod_destroy, // destructor function - NULL, // oncancel function - sca_child_init, // per-child initialization function +struct module_exports exports= { + "sca", + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, + params, + 0, /* exported statistics */ + 0, /* exported MI functions */ + 0, /* exported pseudo-variables */ + 0, /* extra processes */ + sca_mod_init, + 0, + sca_mod_destroy, + sca_child_init /* per-child init function */ }; static int sca_bind_sl(sca_mod *scam, sl_api_t *sl_api) @@ -397,3 +407,29 @@ void sca_mod_destroy(void) sca_db_disconnect(); } + +int fixup_ciu(void **param, int param_no) +{ + switch (param_no) { + case 1: + return fixup_var_int_1(param, param_no); + case 2: + case 3: + return fixup_spve_null(param, 1); + default: + return E_UNSPEC; + } +} + +int fixup_free_ciu(void **param, int param_no) +{ + switch (param_no) { + case 1: + return 0; + case 2: + case 3: + return fixup_free_spve_null(param, 1); + default: + return E_UNSPEC; + } +} diff --git a/modules/sca/sca_call_info.c b/modules/sca/sca_call_info.c index eaff33220cc..8f8ca7e912e 100644 --- a/modules/sca/sca_call_info.c +++ b/modules/sca/sca_call_info.c @@ -1816,7 +1816,7 @@ struct sca_call_info_dispatch call_info_dispatch[] = { #define SCA_CALL_INFO_UPDATE_FLAG_FROM_ALLOC (1 << 0) #define SCA_CALL_INFO_UPDATE_FLAG_TO_ALLOC (1 << 1) -int sca_call_info_update(sip_msg_t *msg, char *p1, char *p2) +int sca_call_info_update(sip_msg_t *msg, char *p1, char *p2, char *p3) { sca_call_info call_info; hdr_field_t *call_info_hdr; @@ -1886,11 +1886,23 @@ int sca_call_info_update(sip_msg_t *msg, char *p1, char *p2) } } - if (sca_get_msg_from_header(msg, &from) < 0) { + if (p3 != NULL) { + if (sca_get_pv_from_header(msg, &from, (pv_spec_t *) p3) < 0) { + LM_ERR("Bad From pvar\n"); + return (-1); + } + } + else if (sca_get_msg_from_header(msg, &from) < 0) { LM_ERR("Bad From header\n"); return (-1); } - if (sca_get_msg_to_header(msg, &to) < 0) { + if (p2 != NULL) { + if (sca_get_pv_to_header(msg, &to, (pv_spec_t *) p2) < 0) { + LM_ERR("Bad To pvar\n"); + return (-1); + } + } + else if (sca_get_msg_to_header(msg, &to) < 0) { LM_ERR("Bad To header\n"); return (-1); } diff --git a/modules/sca/sca_call_info.h b/modules/sca/sca_call_info.h index 5dde1d5c908..2859c56654e 100644 --- a/modules/sca/sca_call_info.h +++ b/modules/sca/sca_call_info.h @@ -59,7 +59,7 @@ typedef struct _sca_call_info sca_call_info; extern const str SCA_CALL_INFO_HEADER_STR; -int sca_call_info_update(sip_msg_t *, char *, char *); +int sca_call_info_update(sip_msg_t *, char *, char *, char *); void sca_call_info_sl_reply_cb(void *); void sca_call_info_ack_cb(struct cell *, int, struct tmcb_params *); diff --git a/modules/sca/sca_util.c b/modules/sca/sca_util.c index 9b2331eda13..be619ff166c 100644 --- a/modules/sca/sca_util.c +++ b/modules/sca/sca_util.c @@ -178,6 +178,62 @@ int sca_get_msg_to_header(sip_msg_t *msg, struct to_body **to) return (0); } +int sca_get_pv_from_header(sip_msg_t *msg, struct to_body **from, pv_spec_t *sp) +{ + struct to_body parsed_from; + pv_value_t pv_val; + + assert(msg != NULL); + assert(from != NULL); + assert(sp != NULL); + + if (pv_get_spec_value(msg, sp, &pv_val) < 0) { + LM_ERR("can't get value from to_pvar\n"); + return (-1); + } + if (pv_val.flags & PV_VAL_STR) { + parse_to(pv_val.rs.s, pv_val.rs.s + pv_val.rs.len + 1, &parsed_from); + if (parsed_from.error != PARSE_OK) { + LM_ERR("Bad From value from from_pvar\n"); + return (-1); + } + *from = &parsed_from; + return (0); + } + else { + LM_ERR("value from from_pvar is not a string\n"); + } + return (-1); +} + +int sca_get_pv_to_header(sip_msg_t *msg, struct to_body **to, pv_spec_t *sp) +{ + struct to_body parsed_to; + pv_value_t pv_val; + + assert(msg != NULL); + assert(to != NULL); + assert(sp != NULL); + + if (pv_get_spec_value(msg, sp, &pv_val) < 0) { + LM_ERR("can't get value from to_pvar\n"); + return (-1); + } + if (pv_val.flags & PV_VAL_STR) { + parse_to(pv_val.rs.s, pv_val.rs.s + pv_val.rs.len + 1, &parsed_to); + if (parsed_to.error != PARSE_OK) { + LM_ERR("Bad To value from to_pvar\n"); + return (-1); + } + *to = &parsed_to; + return (0); + } + else { + LM_ERR("value from to_pvar is not a string\n"); + } + return (-1); +} + /* * count characters requiring escape as defined by escape_common */ diff --git a/modules/sca/sca_util.h b/modules/sca/sca_util.h index e17b412fda2..31d9ca3e941 100644 --- a/modules/sca/sca_util.h +++ b/modules/sca/sca_util.h @@ -46,6 +46,9 @@ int sca_get_msg_from_header(sip_msg_t *, struct to_body **); // convenient To header parsing and extraction int sca_get_msg_to_header(sip_msg_t *, struct to_body **); +int sca_get_pv_from_header(sip_msg_t *, struct to_body **, pv_spec_t *); +int sca_get_pv_to_header(sip_msg_t *, struct to_body **, pv_spec_t *); + // count number of characters requiring escape as defined by escape_common int sca_uri_display_escapes_count(str *);