Browse code

sbc: added call-variable replacement

Raphael Coeffic authored on 30/05/2013 07:55:26
Showing 7 changed files
... ...
@@ -69,6 +69,7 @@ char *url_encode(const char *str);
69 69
 string replaceParameters(const string& s,
70 70
 			 const char* r_type,
71 71
 			 const AmSipRequest& req,
72
+			 const SBCCallProfile* call_profile,
72 73
 			 const string& app_param,
73 74
 			 AmUriParser& ruri_parser, 
74 75
 			 AmUriParser& from_parser,
... ...
@@ -286,6 +287,63 @@ string replaceParameters(const string& s,
286 287
 	  skip_chars = skip_p-p;
287 288
 	} break;
288 289
 
290
+	case 'V': { // variable
291
+	  if (s[p+1] != '(') {
292
+	    WARN("Error parsing V variable replacement (missing '(')\n");
293
+	    break;
294
+	  }
295
+	  if (s.length()<p+3) {
296
+	    WARN("Error parsing V param replacement (short string)\n");
297
+	    break;
298
+	  }
299
+
300
+	  size_t skip_p = p+2;
301
+	  for (;skip_p<s.length() && s[skip_p] != ')';skip_p++) { }
302
+	  if (skip_p==s.length()) {
303
+	    WARN("Error parsing V param replacement (unclosed brackets)\n");
304
+	    break;
305
+	  }
306
+	  string var_name = s.substr(p+2, skip_p-p-2);
307
+	  // DBG("param_name = '%s' (skip-p - p = %d)\n", param_name.c_str(), skip_p-p);
308
+	  if (!call_profile) {
309
+	    WARN("no call_profile object when replacing variable '%s'\n", var_name.c_str());
310
+	  } else {
311
+	    const AmArg* val = NULL;
312
+	    size_t dotpos = var_name.find('.');
313
+	    string vn;
314
+	    if (dotpos != string::npos) {
315
+	      vn = var_name.substr(dotpos+1);
316
+	      var_name = var_name.substr(0, dotpos);
317
+	    }
318
+	    SBCVarMapConstIteratorT it = call_profile->cc_vars.find(var_name);
319
+	    if (it != call_profile->cc_vars.end()) {
320
+	      if (vn.empty()) {
321
+		val = &it->second;
322
+	      } else {
323
+		if (isArgStruct(it->second)) {
324
+		  // recursive replacement for call variable name (defined via GUI)
325
+		  if (vn.find('$') != string::npos)
326
+		    vn = replaceParameters(vn, "CallVar Subname", req, call_profile, app_param, ruri_parser, from_parser, to_parser);
327
+		  val = &it->second[vn];
328
+		} else {
329
+		  DBG("CC variable '%s' has wrong type: '%s'\n",
330
+		      vn.c_str(), AmArg::print(it->second).c_str());
331
+		}
332
+	      }
333
+	      if (val != NULL) {
334
+		if (val->getType() == AmArg::CStr)
335
+		  res += val->asCStr();
336
+		else
337
+		  res += AmArg::print(*val);
338
+	      }
339
+	    } else {
340
+	      DBG("CC variable '%s' does not exist\n", var_name.c_str());
341
+	    }
342
+	  }
343
+
344
+	  skip_chars = skip_p-p;
345
+	} break;
346
+
289 347
 	case 'H': { // header
290 348
 	  size_t name_offset = 2;
291 349
 	  if (s[p+1] != '(') {
... ...
@@ -360,8 +418,10 @@ string replaceParameters(const string& s,
360 418
 	  }
361 419
 
362 420
 	  string map_val = map_str.substr(0, spos);
363
-	  string map_val_replaced = replaceParameters(map_val, r_type, req, app_param,
364
-						      ruri_parser, from_parser, to_parser);
421
+	  string map_val_replaced = replaceParameters(map_val, r_type, req, 
422
+						      call_profile, app_param,
423
+						      ruri_parser, from_parser, 
424
+						      to_parser);
365 425
 	  string mapping_name = map_str.substr(spos+2);
366 426
 
367 427
 	  string map_res; 
... ...
@@ -407,8 +467,9 @@ string replaceParameters(const string& s,
407 467
 
408 468
 	  string br_str = s.substr(p+3, skip_p-p-3);
409 469
 	  string br_str_replaced = replaceParameters(br_str, "$_*(...)",
410
-						     req, app_param,
411
-						     ruri_parser, from_parser, to_parser);
470
+						     req, call_profile, app_param,
471
+						     ruri_parser, from_parser, 
472
+						     to_parser);
412 473
 	  br_str = br_str_replaced;
413 474
 	  switch(operation) {
414 475
 	  case 'u': // uppercase
... ...
@@ -460,8 +521,9 @@ string replaceParameters(const string& s,
460 521
 
461 522
 	  string expr_str = s.substr(p+2, skip_p-p-2);
462 523
 	  string expr_replaced = replaceParameters(expr_str, r_type, req,
463
-						   app_param, ruri_parser, 
464
-						   from_parser, to_parser);
524
+						   call_profile, app_param, 
525
+						   ruri_parser, from_parser,
526
+						   to_parser);
465 527
 	  char* val_escaped = url_encode(expr_replaced.c_str());
466 528
 	  res += string(val_escaped);
467 529
 	  free(val_escaped);
... ...
@@ -32,10 +32,13 @@ using std::string;
32 32
 #include "AmSipMsg.h"
33 33
 #include "AmUriParser.h"
34 34
 
35
+struct SBCCallProfile;
36
+
35 37
 // $xy parameters replacement
36 38
 string replaceParameters(const string& s,
37 39
 			 const char* r_type,
38 40
 			 const AmSipRequest& req,
41
+			 const SBCCallProfile* call_profile,
39 42
 			 const string& app_param,
40 43
 			 AmUriParser& ruri_parser,
41 44
 			 AmUriParser& from_parser,
... ...
@@ -52,10 +55,13 @@ struct ParamReplacerCtx
52 55
   bool from_modified;
53 56
   bool to_modified;
54 57
 
55
-  ParamReplacerCtx()
58
+  const SBCCallProfile* call_profile;
59
+
60
+  ParamReplacerCtx(const SBCCallProfile* call_profile=NULL)
56 61
     : ruri_modified(false), 
57 62
       from_modified(false), 
58
-      to_modified(false)
63
+      to_modified(false),
64
+      call_profile(call_profile)
59 65
   {}
60 66
 
61 67
   string replaceParameters(const string& s,
... ...
@@ -63,6 +69,7 @@ struct ParamReplacerCtx
63 69
 			   const AmSipRequest& req) {
64 70
     
65 71
     return ::replaceParameters(s,r_type,req,
72
+			       call_profile,
66 73
 			       app_param,
67 74
 			       ruri_parser,
68 75
 			       from_parser,
... ...
@@ -1083,11 +1083,6 @@ bool _RegisterCache::saveSingleContact(RegisterCacheCtx& ctx,
1083 1083
 
1084 1084
   reg_expires += now.tv_sec;
1085 1085
 
1086
-  //TODO:
1087
-  // - query/save binding according to reg_expires / ua_expires
1088
-  // - ?check call-id, cseq?
1089
-  // - send 200 reply
1090
-
1091 1086
   AliasEntry alias_update;
1092 1087
   alias_update.aor = ctx.from_aor;
1093 1088
   alias_update.contact_uri = contact->uri_str();
... ...
@@ -267,7 +267,7 @@ int RegisterDialog::fixUacContacts(const AmSipRequest& req)
267 267
 void RegisterDialog::fixUacContactHosts(const AmSipRequest& req,
268 268
 					const SBCCallProfile& cp)
269 269
 {
270
-  ParamReplacerCtx ctx;
270
+  ParamReplacerCtx ctx(&cp);
271 271
   int oif = getOutboundIf();
272 272
   assert(oif >= 0);
273 273
   assert((size_t)outbound_interface < AmConfig::SIP_Ifs.size());
... ...
@@ -340,6 +340,7 @@ void SBCFactory::onOoDRequest(const AmSipRequest& req)
340 340
   SBCCallProfile call_profile(*p_call_profile);
341 341
   profiles_mut.unlock();
342 342
 
343
+  ctx.call_profile = &call_profile;
343 344
   call_profile.eval_cc_list(ctx,req);
344 345
 
345 346
   vector<AmDynInvoke*> cc_modules;
... ...
@@ -705,7 +706,7 @@ bool SBCFactory::CCRoute(const AmSipRequest& req,
705 706
 
706 707
     if (!logger && !call_profile.msg_logger_path.empty()) {
707 708
 
708
-      ParamReplacerCtx ctx;
709
+      ParamReplacerCtx ctx(&call_profile);
709 710
       call_profile.msg_logger_path = 
710 711
 	ctx.replaceParameters(call_profile.msg_logger_path,
711 712
 			      "msg_logger_path",req);
... ...
@@ -717,7 +717,7 @@ void SBCCallLeg::onInvite(const AmSipRequest& req)
717 717
 {
718 718
   DBG("processing initial INVITE %s\n", req.r_uri.c_str());
719 719
 
720
-  ParamReplacerCtx ctx;
720
+  ParamReplacerCtx ctx(&call_profile);
721 721
   ctx.app_param = getHeader(req.hdrs, PARAM_HDR, true);
722 722
 
723 723
   // process call control
... ...
@@ -1015,7 +1015,7 @@ bool SBCCallLeg::CCStart(const AmSipRequest& req) {
1015 1015
 
1016 1016
     if (!logger && !call_profile.msg_logger_path.empty()) {
1017 1017
       // open the logger if not already opened
1018
-      ParamReplacerCtx ctx;
1018
+      ParamReplacerCtx ctx(&call_profile);
1019 1019
       string log_path = ctx.replaceParameters(call_profile.msg_logger_path,
1020 1020
 					      "msg_logger_path",req);
1021 1021
       if (openLogger(log_path)) logRequest(req);
... ...
@@ -286,7 +286,7 @@ int SimpleRelayDialog::initUAC(const AmSipRequest& req,
286 286
     }
287 287
   }
288 288
 
289
-  ParamReplacerCtx ctx;
289
+  ParamReplacerCtx ctx(&cp);
290 290
   if((cp.apply_b_routing(ctx,n_req,*this) < 0) ||
291 291
      (cp.apply_common_fields(ctx,n_req) < 0) ) {
292 292
     reply_error(req,500,SIP_REPLY_SERVER_INTERNAL_ERROR);
... ...
@@ -323,7 +323,7 @@ int SimpleRelayDialog::initUAS(const AmSipRequest& req,
323 323
     return -1;
324 324
   }
325 325
 
326
-  ParamReplacerCtx ctx;
326
+  ParamReplacerCtx ctx(&cp);
327 327
   if(cp.apply_a_routing(ctx,req,*this) < 0)
328 328
     return -1;
329 329