diff --git a/Makefile b/Makefile index 44f5a68b8..66b64bebc 100644 --- a/Makefile +++ b/Makefile @@ -170,7 +170,7 @@ module_group_postgres=$(module_group_postgres_driver) $(module_group_db) # For radius module_group_radius=acc_radius auth_radius misc_radius avp_radius uri_radius \ - peering + peering pcem # For presence # kamailio modules @@ -226,7 +226,7 @@ module_group_kpostgres=db_postgres module_group_kcpl=cpl-c # K radius modules -module_group_kradius=acc_radius auth_radius misc_radius peering +module_group_kradius=acc_radius auth_radius misc_radius peering pcem # K unixodbc module module_group_kunixodbc=db_unixodbc @@ -309,7 +309,7 @@ else db_sqlite db_unixodbc db_cassandra memcached mi_xmlrpc \ perl perlvdb purple \ snmpstats xmpp \ - carrierroute peering \ + carrierroute peering pcem \ dialplan lcr utils presence presence_mwi \ presence_dialoginfo presence_xml pua pua_bla \ pua_dialoginfo pua_usrloc pua_xmpp \ @@ -884,7 +884,7 @@ sunpkg: .PHONY: install install: mk_params="compile_for_install=yes" -install: install-bin install-every-module install-cfg \ +install: install-bin install-every-module \ install-doc install-man install-utils install-share .PHONY: dbinstall diff --git a/modules/dialplan/dialplan.c b/modules/dialplan/dialplan.c index ec8c0e510..5206a087e 100644 --- a/modules/dialplan/dialplan.c +++ b/modules/dialplan/dialplan.c @@ -280,7 +280,7 @@ static int dp_update(struct sip_msg * msg, pv_spec_t * src, pv_spec_t * dest, memset(&val, 0, sizeof(pv_value_t)); val.flags = PV_VAL_STR; - no_change = (dest->type == PVT_NONE) || (!repl->s) || (!repl->len); + no_change = (dest->type == PVT_NONE) || (!repl->s); if (no_change) goto set_attr_pvar; diff --git a/modules/dialplan/dp_repl.c b/modules/dialplan/dp_repl.c index ec2e5bb44..63cf7d5d5 100644 --- a/modules/dialplan/dp_repl.c +++ b/modules/dialplan/dp_repl.c @@ -147,41 +147,9 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule, subst_comp = rule->subst_comp; repl_comp = rule->repl_comp; - if(!repl_comp){ - LM_DBG("null replacement\n"); - return 0; - } - - if(subst_comp){ - /*just in case something went wrong at load time*/ - rc = pcre_fullinfo(subst_comp, NULL, PCRE_INFO_CAPTURECOUNT, - &cap_cnt); - if (rc != 0) { - LM_ERR("pcre_fullinfo on compiled pattern yielded error: %d\n", - rc); - return -1;; - } - if(repl_comp->max_pmatch > cap_cnt){ - LM_ERR("illegal access to the %i-th subexpr of the subst expr\n", - repl_comp->max_pmatch); - return -1; - } - - /*search for the pattern from the compiled subst_exp*/ - if (pcre_exec(rule->subst_comp, NULL, string.s, string.len, - 0, 0, ovector, 3 * (MAX_REPLACE_WITH + 1)) <= 0) { - LM_ERR("the string %.*s matched " - "the match_exp %.*s but not the subst_exp %.*s!\n", - string.len, string.s, - rule->match_exp.len, rule->match_exp.s, - rule->subst_exp.len, rule->subst_exp.s); - return -1; - } - } - - /*simply copy from the replacing string*/ - if(!subst_comp || (repl_comp->n_escapes <=0)){ - if(!repl_comp->replacement.s || repl_comp->replacement.len == 0){ + if (!subst_comp) { + /*simply copy from the replacing string*/ + if(!repl_comp || !repl_comp->replacement.s || repl_comp->replacement.len == 0){ LM_ERR("invalid replacing string\n"); goto error; } @@ -194,108 +162,156 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule, return 0; } - /* offset- offset in the replacement string */ - result->len = repl_nb = offset = 0; - p=repl_comp->replacement.s; - - while( repl_nb < repl_comp->n_escapes){ + /*just in case something went wrong at load time*/ + rc = pcre_fullinfo(subst_comp, NULL, PCRE_INFO_CAPTURECOUNT, + &cap_cnt); + if (rc != 0) { + LM_ERR("pcre_fullinfo on compiled pattern yielded error: %d\n", + rc); + return -1;; + } + if(repl_comp && repl_comp->max_pmatch > cap_cnt){ + LM_ERR("illegal access to the %i-th subexpr of the subst expr\n", + repl_comp->max_pmatch); + return -1; + } - token = repl_comp->replace[repl_nb]; + /*search for the pattern from the compiled subst_exp*/ + if (pcre_exec(rule->subst_comp, NULL, string.s, string.len, + 0, 0, ovector, 3 * (MAX_REPLACE_WITH + 1)) <= 0) { + LM_ERR("the string %.*s matched " + "the match_exp %.*s but not the subst_exp %.*s!\n", + string.len, string.s, + rule->match_exp.len, rule->match_exp.s, + rule->subst_exp.len, rule->subst_exp.s); + return -1; + } - if(offset< token.offset){ - if((repl_comp->replacement.len < offset)|| - (result->len + token.offset -offset >= MAX_PHONE_NB_DIGITS)){ - LM_ERR("invalid length\n"); - goto error; - } - /*copy from the replacing string*/ - size = token.offset - offset; - memcpy(result->s + result->len, p + offset, size); - LM_DBG("copying <%.*s> from replacing string\n", - size, p + offset); - result->len += size; - offset = token.offset; + /* copy non-matched prefix of string to output */ + if (ovector[0] > 0) { + if (ovector[0] >= MAX_PHONE_NB_DIGITS) { + LM_ERR("overflow\n"); + goto error; } + memcpy(result->s, string.s, ovector[0]); + result->len += ovector[0]; + } + + if (repl_comp) { + /* offset- offset in the replacement string */ + repl_nb = offset = 0; + p=repl_comp->replacement.s; - switch(token.type) { - case REPLACE_NMATCH: - /*copy from the match subexpression*/ - match_nb = token.u.nmatch * 2; - match.s = string.s + ovector[match_nb]; - match.len = ovector[match_nb + 1] - ovector[match_nb]; - if(result->len + match.len >= MAX_PHONE_NB_DIGITS){ - LM_ERR("overflow\n"); + while( repl_nb < repl_comp->n_escapes){ + + token = repl_comp->replace[repl_nb]; + + if(offset< token.offset){ + if((repl_comp->replacement.len < offset)|| + (result->len + token.offset -offset >= MAX_PHONE_NB_DIGITS)){ + LM_ERR("invalid length\n"); goto error; } + /*copy from the replacing string*/ + size = token.offset - offset; + memcpy(result->s + result->len, p + offset, size); + LM_DBG("copying <%.*s> from replacing string\n", + size, p + offset); + result->len += size; + offset = token.offset; + } - memcpy(result->s + result->len, match.s, match.len); - LM_DBG("copying match <%.*s> token size %d\n", - match.len, match.s, token.size); - result->len += match.len; - offset += token.size; + switch(token.type) { + case REPLACE_NMATCH: + /*copy from the match subexpression*/ + match_nb = token.u.nmatch * 2; + match.s = string.s + ovector[match_nb]; + match.len = ovector[match_nb + 1] - ovector[match_nb]; + if(result->len + match.len >= MAX_PHONE_NB_DIGITS){ + LM_ERR("overflow\n"); + goto error; + } + + memcpy(result->s + result->len, match.s, match.len); + LM_DBG("copying match <%.*s> token size %d\n", + match.len, match.s, token.size); + result->len += match.len; + offset += token.size; break; - case REPLACE_CHAR: - if(result->len + 1>= MAX_PHONE_NB_DIGITS){ - LM_ERR("overflow\n"); - goto error; - } - *(result->s + result->len) = token.u.c; - LM_DBG("copying char <%c> token size %d\n", + case REPLACE_CHAR: + if(result->len + 1>= MAX_PHONE_NB_DIGITS){ + LM_ERR("overflow\n"); + goto error; + } + *(result->s + result->len) = token.u.c; + LM_DBG("copying char <%c> token size %d\n", token.u.c, token.size); - result->len++; - offset += token.size; + result->len++; + offset += token.size; break; - case REPLACE_URI: - if ( msg== NULL || msg->first_line.type!=SIP_REQUEST){ - LM_CRIT("uri substitution attempt on no request" + case REPLACE_URI: + if ( msg== NULL || msg->first_line.type!=SIP_REQUEST){ + LM_CRIT("uri substitution attempt on no request" " message\n"); - break; /* ignore, we can continue */ - } - uri= (msg->new_uri.s)?(&msg->new_uri): - (&msg->first_line.u.request.uri); - if(result->len+uri->len>=MAX_PHONE_NB_DIGITS){ - LM_ERR("overflow\n"); - goto error; - } - memcpy(result->s + result->len, uri->s, uri->len); - LM_DBG("copying uri <%.*s> token size %d\n", + break; /* ignore, we can continue */ + } + uri= (msg->new_uri.s)?(&msg->new_uri): + (&msg->first_line.u.request.uri); + if(result->len+uri->len>=MAX_PHONE_NB_DIGITS){ + LM_ERR("overflow\n"); + goto error; + } + memcpy(result->s + result->len, uri->s, uri->len); + LM_DBG("copying uri <%.*s> token size %d\n", uri->len, uri->s, token.size); - result->len+=uri->len; - offset += token.size; + result->len+=uri->len; + offset += token.size; break; - case REPLACE_SPEC: - if (msg== NULL) { - LM_DBG("replace spec attempted on no message\n"); - break; - } - if (pv_get_spec_value(msg, &token.u.spec, &sv) != 0) { - LM_CRIT("item substitution returned error\n"); - break; /* ignore, we can continue */ - } - if(result->len+sv.rs.len>=MAX_PHONE_NB_DIGITS){ - LM_ERR("rule_translate: overflow\n"); - goto error; - } - memcpy(result->s + result->len, sv.rs.s, - sv.rs.len); - LM_DBG("copying pvar value <%.*s> token size %d\n", + case REPLACE_SPEC: + if (msg== NULL) { + LM_DBG("replace spec attempted on no message\n"); + break; + } + if (pv_get_spec_value(msg, &token.u.spec, &sv) != 0) { + LM_CRIT("item substitution returned error\n"); + break; /* ignore, we can continue */ + } + if(result->len+sv.rs.len>=MAX_PHONE_NB_DIGITS){ + LM_ERR("rule_translate: overflow\n"); + goto error; + } + memcpy(result->s + result->len, sv.rs.s, + sv.rs.len); + LM_DBG("copying pvar value <%.*s> token size %d\n", sv.rs.len, sv.rs.s, token.size); - result->len+=sv.rs.len; - offset += token.size; + result->len+=sv.rs.len; + offset += token.size; break; - default: - LM_CRIT("unknown type %d\n", repl_comp->replace[repl_nb].type); - /* ignore it */ + default: + LM_CRIT("unknown type %d\n", repl_comp->replace[repl_nb].type); + /* ignore it */ + } + repl_nb++; } - repl_nb++; - } - /* anything left? */ - if( repl_nb && offset < repl_comp->replacement.len){ - /*copy from the replacing string*/ - size = repl_comp->replacement.len - offset; - memcpy(result->s + result->len, p + offset, size); - LM_DBG("copying leftover <%.*s> from replacing string\n", + /* anything left? */ + if(offset < repl_comp->replacement.len){ + /*copy from the replacing string*/ + size = repl_comp->replacement.len - offset; + memcpy(result->s + result->len, p + offset, size); + LM_DBG("copying leftover <%.*s> from replacing string\n", size, p + offset); + result->len += size; + } + } + + /* copy non-matched suffix of string to output */ + size = string.len - ovector[1]; + if (size > 0) { + if (result->len + size >= MAX_PHONE_NB_DIGITS) { + LM_ERR("overflow\n"); + goto error; + } + memcpy(result->s + result->len, string.s + ovector[1], size); result->len += size; } diff --git a/modules/rtpproxy/rtpproxy.c b/modules/rtpproxy/rtpproxy.c index b50b2d1ec..03b47724c 100644 --- a/modules/rtpproxy/rtpproxy.c +++ b/modules/rtpproxy/rtpproxy.c @@ -283,7 +283,8 @@ static int alter_mediaport(struct sip_msg *, str *, str *, str *, int); static int alter_rtcp(struct sip_msg *msg, str *body, str *oldport, str *newport); static char *gencookie(); static int rtpp_test(struct rtpp_node*, int, int); -static int unforce_rtp_proxy_f(struct sip_msg *, char *, char *); +static int unforce_rtp_proxy0_f(struct sip_msg *, char *, char *); +static int unforce_rtp_proxy1_f(struct sip_msg *, char *, char *); static int force_rtp_proxy(struct sip_msg *, char *, char *, int, int); static int start_recording_f(struct sip_msg *, char *, char *); static int rtpproxy_answer1_f(struct sip_msg *, char *, char *); @@ -349,10 +350,16 @@ static cmd_export_t cmds[] = { {"set_rtp_proxy_set", (cmd_function)set_rtp_proxy_set_f, 1, fixup_set_id, 0, ANY_ROUTE}, - {"unforce_rtp_proxy", (cmd_function)unforce_rtp_proxy_f, 0, + {"unforce_rtp_proxy", (cmd_function)unforce_rtp_proxy0_f, 0, 0, 0, ANY_ROUTE}, - {"rtpproxy_destroy", (cmd_function)unforce_rtp_proxy_f, 0, + {"unforce_rtp_proxy", (cmd_function)unforce_rtp_proxy1_f, 1, + 0, 0, + ANY_ROUTE}, + {"rtpproxy_destroy", (cmd_function)unforce_rtp_proxy0_f, 0, + 0, 0, + ANY_ROUTE}, + {"rtpproxy_destroy", (cmd_function)unforce_rtp_proxy1_f, 1, 0, 0, ANY_ROUTE}, {"start_recording", (cmd_function)start_recording_f, 0, @@ -1638,7 +1645,14 @@ found: } static int -unforce_rtp_proxy_f(struct sip_msg* msg, char* str1, char* str2) +unforce_rtp_proxy0_f(struct sip_msg* msg, char* str1, char* str2) +{ + char arg[1] = {'\0'}; + return unforce_rtp_proxy1_f(msg, arg, str2); +} + +static int +unforce_rtp_proxy1_f(struct sip_msg* msg, char* str1, char* str2) { str callid, from_tag, to_tag, viabranch; char *cp; @@ -1740,7 +1754,7 @@ rtpproxy_manage(struct sip_msg *msg, char *flags, char *ip) return -1; if(method==METHOD_CANCEL || method==METHOD_BYE) - return unforce_rtp_proxy_f(msg, 0, 0); + return unforce_rtp_proxy0_f(msg, 0, 0); if(ip==NULL) { @@ -1766,13 +1780,13 @@ rtpproxy_manage(struct sip_msg *msg, char *flags, char *ip) && tmb.t_gett()!=T_UNDEFINED) tmb.t_gett()->uas.request->msg_flags |= FL_SDP_BODY; if(route_type==FAILURE_ROUTE) - return unforce_rtp_proxy_f(msg, 0, 0); + return unforce_rtp_proxy0_f(msg, 0, 0); return force_rtp_proxy(msg, flags, (cp!=NULL)?newip:ip, 1, (ip!=NULL)?1:0); } } else if(msg->first_line.type == SIP_REPLY) { if(msg->first_line.u.reply.statuscode>=300) - return unforce_rtp_proxy_f(msg, 0, 0); + return unforce_rtp_proxy0_f(msg, 0, 0); if(nosdp==0) { if(method==METHOD_UPDATE) return force_rtp_proxy(msg, flags, (cp!=NULL)?newip:ip, 0, diff --git a/modules_k/acc/acc.c b/modules_k/acc/acc.c index d4fd89c27..e322ba1b7 100644 --- a/modules_k/acc/acc.c +++ b/modules_k/acc/acc.c @@ -125,6 +125,14 @@ int core2strar(struct sip_msg *req, str *c_vals, int *i_vals, char *t_vals) struct hdr_field *from; struct hdr_field *to; + struct timeval tv; + struct timezone tz; + struct tm *tm; + uint64_t time_hires; + + gettimeofday(&tv, &tz); + tm = localtime(&tv.tv_sec); + /* method : request/reply - cseq parsed in acc_preparse_req() */ c_vals[0] = get_cseq(req)->method; t_vals[0] = TYPE_STR; @@ -174,6 +182,10 @@ int core2strar(struct sip_msg *req, str *c_vals, int *i_vals, char *t_vals) t_vals[5] = TYPE_STR; acc_env.ts = time(NULL); + + time_hires = (tv.tv_sec * 1000) + tv.tv_usec / 1000; + acc_env.time_hires = time_hires; + return ACC_CORE_LEN; } @@ -306,7 +318,8 @@ static void acc_db_init_keys(void) db_keys[n++] = &acc_sipcode_col; db_keys[n++] = &acc_sipreason_col; db_keys[n++] = &acc_time_col; - time_idx = n-1; + db_keys[n++] = &acc_time_hires_col; + time_idx = n-2; /* init the extra db keys */ for(extra=db_extra; extra ; extra=extra->next) @@ -322,6 +335,7 @@ static void acc_db_init_keys(void) VAL_NULL(db_vals+i)=0; } VAL_TYPE(db_vals+time_idx)=DB1_DATETIME; + VAL_TYPE(db_vals+time_idx+1)=DB1_DOUBLE; } @@ -380,7 +394,8 @@ int acc_db_request( struct sip_msg *rq) VAL_STR(db_vals+i) = val_arr[i]; /* time value */ VAL_TIME(db_vals+(m++)) = acc_env.ts; - + VAL_DOUBLE(db_vals+(m++)) = ((double) acc_env.time_hires) / 1000; + i = m; /* extra columns */ m += extra2strar( db_extra, rq, val_arr+m, int_arr+m, type_arr+m); diff --git a/modules_k/acc/acc_api.h b/modules_k/acc/acc_api.h index bc52eee0f..61bbb51d2 100644 --- a/modules_k/acc/acc_api.h +++ b/modules_k/acc/acc_api.h @@ -57,6 +57,7 @@ typedef struct acc_enviroment { struct hdr_field *to; str text; time_t ts; + uint64_t time_hires; } acc_enviroment_t; /* acc extra parameter */ diff --git a/modules_k/acc/acc_mod.c b/modules_k/acc/acc_mod.c index 9f40e14d6..f8124d52f 100644 --- a/modules_k/acc/acc_mod.c +++ b/modules_k/acc/acc_mod.c @@ -195,6 +195,7 @@ str acc_callid_col = str_init("callid"); str acc_sipcode_col = str_init("sip_code"); str acc_sipreason_col = str_init("sip_reason"); str acc_time_col = str_init("time"); +str acc_time_hires_col = str_init("time_hires"); int acc_db_insert_mode = 0; #endif @@ -289,6 +290,7 @@ static param_export_t params[] = { {"acc_sip_code_column", STR_PARAM, &acc_sipcode_col.s }, {"acc_sip_reason_column",STR_PARAM, &acc_sipreason_col.s }, {"acc_time_column", STR_PARAM, &acc_time_col.s }, + {"acc_time_hires_column", STR_PARAM, &acc_time_hires_col.s }, {"db_insert_mode", INT_PARAM, &acc_db_insert_mode }, #endif {0,0,0} @@ -453,6 +455,7 @@ static int mod_init( void ) acc_sipcode_col.len = strlen(acc_sipcode_col.s); acc_sipreason_col.len = strlen(acc_sipreason_col.s); acc_time_col.len = strlen(acc_time_col.s); + acc_time_hires_col.len = strlen(acc_time_hires_col.s); #endif if (log_facility_str) { diff --git a/modules_k/acc/acc_mod.h b/modules_k/acc/acc_mod.h index 5e7792a8a..6494a30a0 100644 --- a/modules_k/acc/acc_mod.h +++ b/modules_k/acc/acc_mod.h @@ -92,6 +92,7 @@ extern str acc_cseqno_col; extern str acc_sipcode_col; extern str acc_sipreason_col; extern str acc_time_col; +extern str acc_time_hires_col; #endif /* SQL_ACC */ diff --git a/modules_k/pcem/Makefile b/modules_k/pcem/Makefile index 3ab8f8f01..2f2958647 100644 --- a/modules_k/pcem/Makefile +++ b/modules_k/pcem/Makefile @@ -16,3 +16,21 @@ SERLIBPATH=../../lib SER_LIBS+=$(SERLIBPATH)/srdb1/srdb1 $(SERLIBPATH)/kcore/kcore include ../../Makefile.modules +# $Id$ +# +# pcem module makefile +# +# +# WARNING: do not run this directly, it should be run by the master Makefile + +include ../../Makefile.defs +auto_gen= +NAME=pcem.so +LIBS= + +DEFS+=-DOPENSER_MOD_INTERFACE + +SERLIBPATH=../../lib +SER_LIBS+=$(SERLIBPATH)/srdb1/srdb1 $(SERLIBPATH)/kcore/kcore + +include ../../Makefile.modules diff --git a/modules_k/pcem/pcem_logic.c b/modules_k/pcem/pcem_logic.c index 1d7607aca..15e970e98 100644 --- a/modules_k/pcem/pcem_logic.c +++ b/modules_k/pcem/pcem_logic.c @@ -128,3 +128,133 @@ static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps ) } } +/* + * $Id$ + * + * PacketCable Event Messages module + * + * Copyright (C) 2012 Sipwise GmbH + * + * This file is part of Kamailio, a free SIP server. + * + * Kamailio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version + * + * Kamailio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include + +#include "../../dprint.h" +#include "../../parser/parse_from.h" +#include "../../parser/parse_content.h" +#include "../../modules/tm/tm_load.h" +#include "../rr/api.h" +#include "../../flags.h" +#include "pcem_mod.h" +#include "pcem_logic.h" + +extern struct tm_binds tmb; +extern struct rr_binds rrb; + +#define is_pcem_flag_set(_rq,_flag) (((_flag) != -1) && (isflagset((_rq), (_flag)) == 1)) +#define reset_pcem_flag(_rq,_flag) (resetflag((_rq), (_flag))) + +#define is_all_on(_rq) is_pcem_flag_set(_rq,pcem_all_flag) +#define is_qos_on(_rq) is_pcem_flag_set(_rq,pcem_qos_flag) + +static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps ); + +static inline int pcem_preparse_req(struct sip_msg *req) +{ +/* + if((parse_headers(req,HDR_CALLID_F|HDR_CSEQ_F|HDR_FROM_F|HDR_TO_F,0)<0) + || (parse_from_header(req)<0 ) ) { + LM_ERR("failed to preparse request\n"); + return -1; + } +*/ + return 0; +} + +void pcem_onreq( struct cell* t, int type, struct tmcb_params *ps ) +{ + int tmcb_types; + int is_invite; + + LM_ERR("pcem_onreq called for t(%p) event type %d\n", t, type); + + if(ps->req && (is_all_on(ps->req) || is_qos_on(ps->req))) { + LM_ERR("it's a request, is_all_on=%d, is_qos_on=%d, processing request\n", + is_all_on(ps->req), is_qos_on(ps->req)); + + if (pcem_preparse_req(ps->req)<0) + return; + + is_invite = (ps->req->REQ_METHOD==METHOD_INVITE)?1:0; + + tmcb_types = + /* get completed transactions */ + TMCB_RESPONSE_OUT | + /* get incoming replies ready for processing */ + TMCB_RESPONSE_IN | + /* get failed transactions */ + (is_invite?TMCB_ON_FAILURE:0); + + if (tmb.register_tmcb( 0, t, tmcb_types, tmcb_func, 0, 0 ) <= 0) { + LM_ERR("cannot register additional callbacks\n"); + return; + } + + /* + if(!rrb.is_direction(ps->req,RR_FLOW_UPSTREAM) ) { + LM_DBG("detected an UPSTREAM req -> flaging it\n"); + ps->req->msg_flags |= FL_REQ_UPSTREAM; + } + */ + } +} + + +static inline void pcem_onreply_in(struct cell *t, struct sip_msg *req, + struct sip_msg *reply, int code) +{ + LM_ERR("got a reply_in, code=%d\n", code); +} + +static inline void pcem_onreply(struct cell *t, struct sip_msg *req, + struct sip_msg *reply, int code) +{ + LM_ERR("got a reply, code=%d\n", code); +} + +static inline void pcem_onfailure(struct cell *t, struct sip_msg *req, + struct sip_msg *reply, int code) +{ + LM_ERR("got a failure\n"); +} + +static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps ) +{ + LM_ERR("pcem callback called for t(%p) event type %d, reply code %d\n", + t, type, ps->code); + if (type&TMCB_RESPONSE_OUT) { + pcem_onreply( t, ps->req, ps->rpl, ps->code); + } else if (type&TMCB_ON_FAILURE) { + pcem_onfailure( t, ps->req, ps->rpl, ps->code); + } else if (type&TMCB_RESPONSE_IN) { + pcem_onreply_in( t, ps->req, ps->rpl, ps->code); + } +} + diff --git a/modules_k/pcem/pcem_logic.h b/modules_k/pcem/pcem_logic.h index 9f6a97a1a..869a8017a 100644 --- a/modules_k/pcem/pcem_logic.h +++ b/modules_k/pcem/pcem_logic.h @@ -32,3 +32,37 @@ void pcem_onreq( struct cell* t, int type, struct tmcb_params *ps ); #endif +/* + * $Id$ + * + * PacketCable Event Messages module + * + * Copyright (C) 2012 Sipwise GmbH + * + * This file is part of Kamailio, a free SIP server. + * + * Kamailio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version + * + * Kamailio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _PCEM_LOGIC_H +#define _PCEM_LOGIC_H + +#include "../../str.h" +#include "../../modules/tm/t_hooks.h" + +void pcem_onreq( struct cell* t, int type, struct tmcb_params *ps ); + +#endif diff --git a/modules_k/pcem/pcem_mod.c b/modules_k/pcem/pcem_mod.c index 0d0ea2c44..41b6bdf22 100644 --- a/modules_k/pcem/pcem_mod.c +++ b/modules_k/pcem/pcem_mod.c @@ -72,6 +72,159 @@ static cmd_export_t cmds[] = { +static param_export_t params[] = { + /*{"test_str", INT_PARAM, &test_str.s },*/ + {"qos_flag", INT_PARAM, &pcem_qos_flag }, + {"all_flag", INT_PARAM, &pcem_all_flag }, + {0,0,0} +}; + + +struct module_exports exports= { + "pcem", + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported functions */ + params, /* exported params */ + 0, /* exported statistics */ + 0, /* exported MI functions */ + 0, /* exported pseudo-variables */ + 0, /* extra processes */ + mod_init, /* initialization module */ + 0, /* response function */ + destroy, /* destroy function */ + child_init /* per-child init function */ +}; + + +static int mod_init( void ) +{ + if ((pcem_qos_flag != -1) && + !flag_in_range(pcem_qos_flag)) { + LM_ERR("pcem_qos_flag set to invalid value\n"); + return -1; + } + if ((pcem_all_flag != -1) && + !flag_in_range(pcem_all_flag)) { + LM_ERR("pcem_all_flag set to invalid value\n"); + return -1; + } + + /* load the TM API */ + if (load_tm_api(&tmb)!=0) { + LM_ERR("can't load TM API\n"); + return -1; + } + + /* load the RR API */ + if (load_rr_api(&rrb)!=0) { + LM_ERR("can't load RR API\n"); + return -1; + } + /* we need the append_fromtag on in RR */ + if (!rrb.append_fromtag) { + LM_ERR("'append_fromtag' RR param is not enabled\n"); + return -1; + } + + /* listen for all incoming requests */ + if ( tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, pcem_onreq, 0, 0 ) <=0 ) { + LM_ERR("cannot register TMCB_REQUEST_IN callback\n"); + return -1; + } + + _pcem_module_initialized = 1; + + return 0; +} + + +static int child_init(int rank) +{ + if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN) + return 0; /* do nothing for the main process */ + + return 0; +} + + +static void destroy(void) +{ +} + +/* + * $Id$ + * + * PacketCable Event Messages module + * + * Copyright (C) 2012 Sipwise GmbH + * + * This file is part of Kamailio, a free SIP server. + * + * Kamailio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version + * + * Kamailio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include + +#include "../../sr_module.h" +#include "../../dprint.h" +#include "../../mem/mem.h" +#include "../../modules/tm/tm_load.h" +#include "../../str.h" +#include "../rr/api.h" +#include "pcem_mod.h" +#include "pcem_logic.h" + +MODULE_VERSION + +struct tm_binds tmb; +struct rr_binds rrb; + +static int mod_init(void); +static void destroy(void); +static int child_init(int rank); + +int pcem_qos_flag = -1; /* don't send qos messages by default */ +int pcem_all_flag = -1; /* don't send any messages by default */ + +/* +static int bind_acc(acc_api_t* api); +static int acc_register_engine(acc_engine_t *eng); +static int acc_init_engines(void); +static acc_engine_t *_acc_engines=NULL; +*/ +static int _pcem_module_initialized = 0; + +/* +static int acc_fixup(void** param, int param_no); +static int free_acc_fixup(void** param, int param_no); +*/ + + +static cmd_export_t cmds[] = { +/* + {"pcem_test", (cmd_function)w_pkg_em_test, 1, + acc_fixup, free_acc_fixup, + ANY_ROUTE}, +*/ + {0, 0, 0, 0, 0, 0} +}; + + + static param_export_t params[] = { /*{"test_str", INT_PARAM, &test_str.s },*/ {"qos_flag", INT_PARAM, &pcem_qos_flag }, diff --git a/modules_k/pcem/pcem_mod.h b/modules_k/pcem/pcem_mod.h index 167fd30b4..d5a5739e7 100644 --- a/modules_k/pcem/pcem_mod.h +++ b/modules_k/pcem/pcem_mod.h @@ -31,3 +31,36 @@ extern int pcem_qos_flag; extern int pcem_all_flag; #endif +/* + * $Id$ + * + * PacketCable Event Messages module + * + * Copyright (C) 2012 Sipwise GmbH + * + * This file is part of Kamailio, a free SIP server. + * + * Kamailio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version + * + * Kamailio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _PCEM_MOD_H +#define _PCEM_MOD_H + +/* module parameter declaration */ +extern int pcem_qos_flag; +extern int pcem_all_flag; + +#endif diff --git a/modules_k/usrloc/ul_mi.c b/modules_k/usrloc/ul_mi.c index ca7c71a11..d6b94c338 100644 --- a/modules_k/usrloc/ul_mi.c +++ b/modules_k/usrloc/ul_mi.c @@ -525,8 +525,10 @@ struct mi_root* mi_usrloc_add(struct mi_root *cmd, void *param) if (str2q( &ci.q, node->value.s, node->value.len) < 0) goto bad_syntax; - /* unused value (param 6) FIXME */ + /* path value (param 6) */ node = node->next; + if(strncmp(node->value.s, "0", 1) != 0 && node->value.len > 1) + ci.path = &node->value; /* flags value (param 7) */ node = node->next; diff --git a/utils/kamctl/Makefile b/utils/kamctl/Makefile index ba3d67a31..9d374b093 100644 --- a/utils/kamctl/Makefile +++ b/utils/kamctl/Makefile @@ -8,7 +8,7 @@ all: install-if-newer: install -install: install-cfg install-bin install-man install-modules +install: install-bin install-man install-modules install-cfg: $(cfg_prefix)/$(cfg_dir) # kamctl config diff --git a/utils/kamctl/kamctl b/utils/kamctl/kamctl index 2cfb9511d..23c87d220 100755 --- a/utils/kamctl/kamctl +++ b/utils/kamctl/kamctl @@ -2201,10 +2201,17 @@ usrloc() { UL_EXPIRES=0 UL_FLAGS=0 BR_FLAGS=0 + UL_PATH=0 elif [ $# -eq 4 ] ; then UL_EXPIRES=$4 UL_FLAGS=0 BR_FLAGS=0 + UL_PATH=0 + elif [ $# -eq 5 ] ; then + UL_EXPIRES=$4 + UL_FLAGS=0 + BR_FLAGS=0 + UL_PATH="$5" else usage_usrloc exit 1 @@ -2237,7 +2244,7 @@ usrloc() { fi $CTLCMD ul_add "$USRLOC_TABLE" "$OSERUSER@$OSERDOMAIN" "$2" \ -"$UL_EXPIRES" "1.00" "0" "$UL_FLAGS" "$BR_FLAGS" "$ALL_METHODS" +"$UL_EXPIRES" "1.00" "$UL_PATH" "$UL_FLAGS" "$BR_FLAGS" "$ALL_METHODS" exit $? ;; rm)