Module: sip-router Branch: master Commit: 4223ed2097efaba0305c8d8768c34b2d25ff407e URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=4223ed20...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: Wed Apr 21 12:46:20 2010 +0200
pv: implemented assignment for branch pvs
- branch attributes can be individually changed via $(branch(attr)[index]) - if index is missing, first branch structure is taken - if index is -1, last branch is missing - adding a new branch is possible via km_append_branch("uri") or append_branch() functions - $(branch(uri)[index]) = $null; will drop the branch. Note that the next branches after dropped one will be shifted one possiotn back - for the rest of attributes, $null assignment means reseting the value of the attribute to null (uri is mandatory to have the branch valid) - completed FS#8
---
modules_k/pv/pv_branch.c | 185 +++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 184 insertions(+), 1 deletions(-)
diff --git a/modules_k/pv/pv_branch.c b/modules_k/pv/pv_branch.c index 5fa399e..e162104 100644 --- a/modules_k/pv/pv_branch.c +++ b/modules_k/pv/pv_branch.c @@ -24,6 +24,7 @@ #include "../../parser/parse_uri.h" #include "../../dset.h" #include "../../onsend.h" +#include "../../socket_info.h"
#include "pv_core.h" #include "pv_branch.h" @@ -88,7 +89,189 @@ int pv_get_branchx(struct sip_msg *msg, pv_param_t *param, int pv_set_branchx(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val) { - /* tbd */ + int idx = 0; + int idxf = 0; + branch_t *br; + struct socket_info *si; + int port, proto; + str host; + char backup; + + if(msg==NULL || param==NULL) + { + LM_ERR("bad parameters\n"); + return -1; + } + + /* get the index */ + if(pv_get_spec_index(msg, param, &idx, &idxf)!=0) + { + LM_ERR("invalid index\n"); + return -1; + } + + br = get_sip_branch(idx); + + if(br==NULL) + { + LM_DBG("no branch to operate on\n"); + return -1; + } + + switch(param->pvn.u.isname.name.n) + { + case 1: /* dst uri */ + if(val==NULL || (val->flags&PV_VAL_NULL)) + { + br->dst_uri[0] = '\0'; + br->dst_uri_len = 0; + break; + } + if(!(val->flags&PV_VAL_STR)) + { + LM_ERR("str value required to set branch dst uri\n"); + return -1; + } + if(val->rs.len<=0) + { + br->dst_uri[0] = '\0'; + br->dst_uri_len = 0; + break; + } + + if (unlikely(val->rs.len > MAX_URI_SIZE - 1)) + { + LM_ERR("too long dst uri: %.*s\n", + val->rs.len, val->rs.s); + return -1; + } + memcpy(br->dst_uri, val->rs.s, val->rs.len); + br->dst_uri[val->rs.len] = 0; + br->dst_uri_len = val->rs.len; + break; + case 2: /* path */ + if(val==NULL || (val->flags&PV_VAL_NULL)) + { + br->path[0] = '\0'; + br->path_len = 0; + break; + } + if(!(val->flags&PV_VAL_STR)) + { + LM_ERR("str value required to set branch path\n"); + return -1; + } + if(val->rs.len<=0) + { + br->path[0] = '\0'; + br->path_len = 0; + break; + } + + if (unlikely(val->rs.len > MAX_PATH_SIZE - 1)) + { + LM_ERR("path too long: %.*s\n", + val->rs.len, val->rs.s); + return -1; + } + memcpy(br->path, val->rs.s, val->rs.len); + br->path[val->rs.len] = 0; + br->path_len = val->rs.len; + break; + case 3: /* Q */ + if(val==NULL || (val->flags&PV_VAL_NULL)) + { + br->q = Q_UNSPECIFIED; + break; + } + if(!(val->flags&PV_VAL_INT)) + { + LM_ERR("int value required to set branch q\n"); + return -1; + } + br->q = val->ri; + break; + case 4: /* send socket */ + if(val==NULL || (val->flags&PV_VAL_NULL)) + { + br->force_send_socket = NULL; + break; + } + if(!(val->flags&PV_VAL_STR)) + { + LM_ERR("str value required to set branch send sock\n"); + return -1; + } + if(val->rs.len<=0) + { + br->force_send_socket = NULL; + break; + } + backup = val->rs.s[val->rs.len]; + val->rs.s[val->rs.len] = '\0'; + if (parse_phostport(val->rs.s, &host.s, &host.len, &port, + &proto) < 0) + { + LM_ERR("invalid socket specification\n"); + val->rs.s[val->rs.len] = backup; + return -1; + } + val->rs.s[val->rs.len] = backup; + si = grep_sock_info(&host, (unsigned short)port, + (unsigned short)proto); + if (si!=NULL) + { + br->force_send_socket = si; + } else { + LM_WARN("no socket found to match [%.*s]\n", + val->rs.len, val->rs.s); + br->force_send_socket = NULL; + } + break; + case 5: /* count */ + /* do nothing - cannot set the branch counter */ + break; + case 6: /* flags */ + if(val==NULL || (val->flags&PV_VAL_NULL)) + { + br->flags = 0; + break; + } + if(!(val->flags&PV_VAL_INT)) + { + LM_ERR("int value required to set branch flags\n"); + return -1; + } + br->flags = val->ri; + break; + default: + /* 0 - uri */ + if(val==NULL || (val->flags&PV_VAL_NULL)) + { + drop_sip_branch(idx); + } else { + if(!(val->flags&PV_VAL_STR)) + { + LM_ERR("str value required to set branch uri\n"); + return -1; + } + if(val->rs.len<=0) + { + drop_sip_branch(idx); + } else { + if (unlikely(val->rs.len > MAX_URI_SIZE - 1)) + { + LM_ERR("too long r-uri: %.*s\n", + val->rs.len, val->rs.s); + return -1; + } + memcpy(br->uri, val->rs.s, val->rs.len); + br->uri[val->rs.len] = 0; + br->len = val->rs.len; + } + } + } + return 0; }