Browse code

core:zrtp: disable ZRTP for sbc app

Stefan Sayer authored on 03/11/2014 13:51:49
Showing 1 changed files
... ...
@@ -128,6 +128,9 @@ SBCCallLeg::SBCCallLeg(const SBCCallProfile& call_profile, AmSipDialog* p_dlg,
128 128
     cc_started(false),
129 129
     logger(NULL)
130 130
 {
131
+#ifdef WITH_ZRTP
132
+  enable_zrtp = false;
133
+#endif
131 134
   set_sip_relay_only(false);
132 135
   dlg->setRel100State(Am100rel::REL100_IGNORED);
133 136
 
... ...
@@ -155,6 +158,10 @@ SBCCallLeg::SBCCallLeg(SBCCallLeg* caller, AmSipDialog* p_dlg,
155 158
     cc_started(false),
156 159
     logger(NULL)
157 160
 {
161
+#ifdef WITH_ZRTP
162
+  enable_zrtp = false;
163
+#endif
164
+
158 165
   // FIXME: do we want to inherit cc_vars from caller?
159 166
   // Can be pretty dangerous when caller stored pointer to object - we should
160 167
   // not probably operate on it! But on other hand it could be handy for
... ...
@@ -202,6 +209,10 @@ SBCCallLeg::SBCCallLeg(AmSipDialog* p_dlg, AmSipSubscription* p_subs)
202 209
     cc_started(false),
203 210
     logger(NULL)
204 211
 {
212
+#ifdef WITH_ZRTP
213
+  enable_zrtp = false;
214
+#endif
215
+
205 216
   memset(&call_start_ts, 0, sizeof(struct timeval));
206 217
   memset(&call_connect_ts, 0, sizeof(struct timeval));
207 218
   memset(&call_end_ts, 0, sizeof(struct timeval));
Browse code

sbc: b/f: lower case before searching in message filter

Raphael Coeffic authored on 13/05/2014 09:30:35
Showing 1 changed files
... ...
@@ -516,8 +516,11 @@ void SBCCallLeg::onSipRequest(const AmSipRequest& req) {
516 516
 	 it != call_profile.messagefilter.end(); it++) {
517 517
 
518 518
       if (isActiveFilter(it->filter_type)) {
519
+	string method = req.method;
520
+	std::transform(method.begin(), method.end(), method.begin(), ::tolower);
521
+
519 522
 	bool is_filtered = (it->filter_type == Whitelist) ^ 
520
-	  (it->filter_list.find(req.method) != it->filter_list.end());
523
+	  (it->filter_list.find(method) != it->filter_list.end());
521 524
 	if (is_filtered) {
522 525
 	  DBG("replying 405 to filtered message '%s'\n", req.method.c_str());
523 526
 	  dlg->reply(req, 405, "Method Not Allowed", NULL, "", SIP_FLAGS_VERBATIM);
Browse code

sbc: make rtprelay_enabled controllable via msg/hdrs/replacement

Stefan Sayer authored on 17/04/2014 00:14:02
Showing 1 changed files
... ...
@@ -227,7 +227,7 @@ void SBCCallLeg::applyAProfile()
227 227
   // apply A leg configuration (but most of the configuration is applied in
228 228
   // SBCFactory::onInvite)
229 229
 
230
-  if (call_profile.rtprelay_enabled || call_profile.transcoder.isActive()) {
230
+  if (call_profile.rtprelay_enabled_value || call_profile.transcoder.isActive()) {
231 231
     DBG("Enabling RTP relay mode for SBC call\n");
232 232
 
233 233
     setRtpRelayForceSymmetricRtp(call_profile.aleg_force_symmetric_rtp_value);
... ...
@@ -371,7 +371,7 @@ void SBCCallLeg::applyBProfile()
371 371
     dlg->setOutboundInterface(call_profile.outbound_interface_value);
372 372
 
373 373
   // was read from caller but reading directly from profile now
374
-  if (call_profile.rtprelay_enabled || call_profile.transcoder.isActive()) {
374
+  if (call_profile.rtprelay_enabled_value || call_profile.transcoder.isActive()) {
375 375
 
376 376
     if (call_profile.rtprelay_interface_value >= 0)
377 377
       setRtpInterface(call_profile.rtprelay_interface_value);
Browse code

sbc: SIP UAS authentication for B leg (uas_auth_bleg_enabled)

Notes:
- All of those profile options must be set
uas_auth_bleg_realm
uas_auth_bleg_user
uas_auth_bleg_pwd

- On realm mismatch, it is not authenticated

- URI is not checked against the Authorization URI

Conflicts:

apps/sbc/SBC.cpp
apps/sbc/SBC.h
apps/sbc/SBCCallProfile.cpp
apps/sbc/SBCCallProfile.h
apps/sbc/etc/transparent.sbcprofile.conf

Conflicts:

apps/sbc/SBC.cpp
apps/sbc/SBC.h
apps/sbc/SBCCallProfile.cpp
apps/sbc/SBCCallProfile.h
apps/sbc/etc/transparent.sbcprofile.conf

Stefan Sayer authored on 01/08/2013 17:10:46
Showing 1 changed files
... ...
@@ -121,7 +121,7 @@ SBCCallLeg::SBCCallLeg(const SBCCallProfile& call_profile, AmSipDialog* p_dlg,
121 121
 		       AmSipSubscription* p_subs)
122 122
   : CallLeg(p_dlg,p_subs),
123 123
     m_state(BB_Init),
124
-    auth(NULL),
124
+    auth(NULL), auth_di(NULL),
125 125
     call_profile(call_profile),
126 126
     cc_timer_id(SBC_TIMER_ID_CALL_TIMERS_START),
127 127
     ext_cc_timer_id(SBC_TIMER_ID_CALL_TIMERS_END + 1),
... ...
@@ -148,7 +148,7 @@ SBCCallLeg::SBCCallLeg(const SBCCallProfile& call_profile, AmSipDialog* p_dlg,
148 148
 // B leg constructor (from SBCCalleeSession)
149 149
 SBCCallLeg::SBCCallLeg(SBCCallLeg* caller, AmSipDialog* p_dlg,
150 150
 		       AmSipSubscription* p_subs)
151
-  : auth(NULL),
151
+  : auth(NULL), auth_di(NULL),
152 152
     call_profile(caller->getCallProfile()),
153 153
     CallLeg(caller,p_dlg,p_subs),
154 154
     ext_cc_timer_id(SBC_TIMER_ID_CALL_TIMERS_END + 1),
... ...
@@ -197,7 +197,7 @@ SBCCallLeg::SBCCallLeg(SBCCallLeg* caller, AmSipDialog* p_dlg,
197 197
 SBCCallLeg::SBCCallLeg(AmSipDialog* p_dlg, AmSipSubscription* p_subs)
198 198
   : CallLeg(p_dlg,p_subs),
199 199
     m_state(BB_Init),
200
-    auth(NULL),
200
+    auth(NULL),  auth_di(NULL),
201 201
     cc_timer_id(SBC_TIMER_ID_CALL_TIMERS_START),
202 202
     cc_started(false),
203 203
     logger(NULL)
... ...
@@ -331,6 +331,18 @@ void SBCCallLeg::applyBProfile()
331 331
     }
332 332
   }
333 333
 
334
+  if (call_profile.uas_auth_bleg_enabled) {
335
+    AmDynInvokeFactory* fact = AmPlugIn::instance()->getFactory4Di("uac_auth");
336
+    if (NULL != fact) {
337
+      AmDynInvoke* di_inst = fact->getInstance();
338
+      if(NULL != di_inst) {
339
+	setAuthDI(di_inst);
340
+      }
341
+    } else {
342
+      ERROR("B-leg UAS auth enabled (uas_auth_bleg_enabled), but uac_auth module not loaded!\n");
343
+    }
344
+  }
345
+
334 346
   if (call_profile.sst_enabled_value) {
335 347
     if(applySSTCfg(call_profile.sst_b_cfg,NULL) < 0) {
336 348
        throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);
... ...
@@ -519,6 +531,48 @@ void SBCCallLeg::onSipRequest(const AmSipRequest& req) {
519 531
     if ((*i)->onInDialogRequest(this, req) == StopProcessing) return;
520 532
   }
521 533
 
534
+  if (call_profile.uas_auth_bleg_enabled && NULL != auth_di) {
535
+    AmArg di_args, di_ret;
536
+    try {
537
+      DBG("Auth: checking authentication\n");
538
+      di_args.push((AmObject*)&req);
539
+      di_args.push(call_profile.uas_auth_bleg_credentials.realm);
540
+      di_args.push(call_profile.uas_auth_bleg_credentials.user);
541
+      di_args.push(call_profile.uas_auth_bleg_credentials.pwd);
542
+      auth_di->invoke("checkAuth", di_args, di_ret);
543
+
544
+      if (di_ret.size() >= 3) {
545
+	if (di_ret[0].asInt() != 200) {
546
+	  DBG("Auth: replying %u %s - hdrs: '%s'\n",
547
+	      di_ret[0].asInt(), di_ret[1].asCStr(), di_ret[2].asCStr());
548
+	  dlg->reply(req, di_ret[0].asInt(), di_ret[1].asCStr(), NULL, di_ret[2].asCStr());
549
+	  return;
550
+	} else {
551
+	  DBG("Successfully authenticated request.\n");
552
+	}
553
+      } else {
554
+	ERROR("internal: no proper result from checkAuth: '%s'\n", AmArg::print(di_ret).c_str());
555
+      }
556
+
557
+    } catch (const AmDynInvoke::NotImplemented& ni) {
558
+      ERROR("not implemented DI function 'checkAuth'\n");
559
+      dlg->reply(req, 500, SIP_REPLY_SERVER_INTERNAL_ERROR, NULL, "", SIP_FLAGS_VERBATIM);
560
+      return;
561
+    } catch (const AmArg::OutOfBoundsException& oob) {
562
+      ERROR("out of bounds in  DI call 'checkAuth'\n");
563
+      dlg->reply(req, 500, SIP_REPLY_SERVER_INTERNAL_ERROR, NULL, "", SIP_FLAGS_VERBATIM);
564
+      return;
565
+    } catch (const AmArg::TypeMismatchException& oob) {
566
+      ERROR("type mismatch  in  DI call checkAuth\n");
567
+      dlg->reply(req, 500, SIP_REPLY_SERVER_INTERNAL_ERROR, NULL, "", SIP_FLAGS_VERBATIM);
568
+      return;
569
+    } catch (...) {
570
+      ERROR("unexpected Exception  in  DI call checkAuth\n");
571
+      dlg->reply(req, 500, SIP_REPLY_SERVER_INTERNAL_ERROR, NULL, "", SIP_FLAGS_VERBATIM);
572
+      return;
573
+    }
574
+  }
575
+
522 576
   if (fwd && req.method == SIP_METH_INVITE) {
523 577
     DBG("replying 100 Trying to INVITE to be fwd'ed\n");
524 578
     dlg->reply(req, 100, SIP_REPLY_TRYING);
Browse code

sbc: fix call transfers with Replaces through SBC

Replaces header is fixed in either Replaces of INVITE or of REFER
messages. New sbc profile options:
fix_replaces_inv=[yes|no]
fix_replaces_ref=[yes|no]

Conflicts:

apps/sbc/SBC.cpp
apps/sbc/SBCCallProfile.cpp
apps/sbc/SBCCallProfile.h
core/AmSipHeaders.h
core/tests/Makefile
core/tests/sems_tests.cpp

Stefan Sayer authored on 16/08/2013 14:32:30
Showing 1 changed files
... ...
@@ -45,6 +45,7 @@
45 45
 #include "sip/sip_trans.h"
46 46
 
47 47
 #include "HeaderFilter.h"
48
+#include "ReplacesMapper.h"
48 49
 #include "ParamReplacer.h"
49 50
 #include "SDPFilter.h"
50 51
 #include "SBCEventLog.h"
... ...
@@ -405,6 +406,11 @@ int SBCCallLeg::relayEvent(AmEvent* ev)
405 406
             inplaceHeaderFilter(req_ev->req.hdrs, call_profile.headerfilter);
406 407
           }
407 408
 
409
+	  if (req_ev->req.method == SIP_METH_REFER &&
410
+	      call_profile.fix_replaces_ref == "yes") {
411
+	    fixReplaces(req_ev->req.hdrs, false);
412
+	  }
413
+
408 414
           DBG("filtering body for request '%s' (c/t '%s')\n",
409 415
               req_ev->req.method.c_str(), req_ev->req.body.getCTStr().c_str());
410 416
           // todo: handle filtering errors
... ...
@@ -871,6 +877,10 @@ void SBCCallLeg::onInvite(const AmSipRequest& req)
871 877
 
872 878
   inplaceHeaderFilter(invite_req.hdrs, call_profile.headerfilter);
873 879
 
880
+  if (call_profile.fix_replaces_inv == "yes") {
881
+    fixReplaces(invite_req.hdrs, true);
882
+  }
883
+
874 884
   if (call_profile.append_headers.size() > 2) {
875 885
     string append_headers = call_profile.append_headers;
876 886
     assertEndCRLF(append_headers);
Browse code

sbc b/f: allow to disable session timers in A leg

thanks Herve Couplet for reporting and providing the fix

Václav Kubart authored on 09/04/2014 08:18:18
Showing 1 changed files
... ...
@@ -794,7 +794,7 @@ void SBCCallLeg::onInvite(const AmSipRequest& req)
794 794
   call_profile.sst_enabled = ctx.replaceParameters(call_profile.sst_enabled, 
795 795
 						   "enable_session_timer", req);
796 796
 
797
-  if ((call_profile.sst_aleg_enabled == "yes") ||
797
+  if ((call_profile.sst_aleg_enabled == "yes") &&
798 798
       (call_profile.sst_enabled == "yes")) {
799 799
 
800 800
     call_profile.eval_sst_config(ctx,req,call_profile.sst_a_cfg);
Browse code

sbc: b/f: fixed use of setting for unsolicited NOTIFY forwarding

Raphael Coeffic authored on 23/12/2013 13:07:24 • Stefan Sayer committed on 24/03/2014 16:40:52
Showing 1 changed files
... ...
@@ -142,8 +142,6 @@ SBCCallLeg::SBCCallLeg(const SBCCallProfile& call_profile, AmSipDialog* p_dlg,
142 142
 				     1000);
143 143
     rtp_relay_rate_limit.reset(limit);
144 144
   }
145
-
146
-  subs->allowUnsolicitedNotify(call_profile.allow_subless_notify);
147 145
 }
148 146
 
149 147
 // B leg constructor (from SBCCalleeSession)
Browse code

core/sbc: added support for subscription-less NOTIFY forwarding

For the moment, it is only implemented for NOTIFY requests within a dialog.
Conflicts:

apps/sbc/SBCCallProfile.h
core/AmSipSubscription.h

Raphael Coeffic authored on 20/12/2013 14:36:31 • Stefan Sayer committed on 24/03/2014 16:33:39
Showing 1 changed files
... ...
@@ -142,6 +142,8 @@ SBCCallLeg::SBCCallLeg(const SBCCallProfile& call_profile, AmSipDialog* p_dlg,
142 142
 				     1000);
143 143
     rtp_relay_rate_limit.reset(limit);
144 144
   }
145
+
146
+  subs->allowUnsolicitedNotify(call_profile.allow_subless_notify);
145 147
 }
146 148
 
147 149
 // B leg constructor (from SBCCalleeSession)
Browse code

Merge remote-tracking branch 'frafos/1.6-dev' into 1.6-dev-ccdsm

* frafos/1.6-dev:
sbc: b/f: fixed use of setting for unsolicited NOTIFY forwarding
core: made allowUnsolicitedNotify() virtual
core: move str2bool() to AmUtils
core/sbc: added support for subscription-less NOTIFY forwarding

Conflicts:
apps/sbc/SBCCallProfile.h
core/AmUtils.cpp
core/AmUtils.h

Stefan Sayer authored on 20/01/2014 15:57:20
Showing 0 changed files
Browse code

Merge remote-tracking branch 'frafos/tcp-trsp' into 1.6-dev-ccdsm

* frafos/tcp-trsp: (55 commits)
sip: b/f: fix segfault in try_next_ip()
sip: fns: solved some memory management issues
sip: b/f: fix case-sensitivity issue for transport parameter
sip: b/f: added Content-Length-HF to non-200 ACK
sip: b/f: return immediately from parse_headers() if the input string is empty
sbc: b/f: correct fix for nat_handling flag support
Revert "b/f:core:dlg: reevaluate nat_handling flag after onSipRequest/onInvite"
sip: initialise sip_destination correctly
sip: b/f: avoid checking header type more than once in parse_headers()
b/f:core:dlg: reevaluate nat_handling flag after onSipRequest/onInvite
sip: c/f: fixed copy-paste error
sip: insert into blacklist only if default_bl_ttl != 0
sip: try next target on TCP immediate errors
sip: moved resolve_targets() to resolver
sip: moved sip_target_set to resolver
sip: patch temporary Contact-HFs instead of the given ones
core: fixed small issue when sending BYE on 2xx w/o to-tag
sip: tcp: small fixes to avoid libevent errors
core: set transport when updating next-hop
sip: tcp: hash only the sin[6]_addr to compute the tcp worker thread
...

Conflicts:
core/sip/resolver.cpp
core/sip/resolver.h
core/sip/sip_parser.h
core/sip/trans_layer.cpp
core/sip/trans_layer.h

Stefan Sayer authored on 20/01/2014 10:01:13
Showing 0 changed files
Browse code

b/f:sbc:apply rtprelay_dtmf_filtering and rtprelay_dtmf_detection also on B leg

Stefan Sayer authored on 03/01/2014 16:15:55
Showing 1 changed files
... ...
@@ -368,6 +368,8 @@ void SBCCallLeg::applyBProfile()
368 368
 
369 369
     setRtpRelayTransparentSeqno(call_profile.rtprelay_transparent_seqno);
370 370
     setRtpRelayTransparentSSRC(call_profile.rtprelay_transparent_ssrc);
371
+    setEnableDtmfRtpFiltering(call_profile.rtprelay_dtmf_filtering);
372
+    setEnableDtmfRtpDetection(call_profile.rtprelay_dtmf_detection);
371 373
 
372 374
     // copy stats counters
373 375
     rtp_pegs = call_profile.bleg_rtp_counters;
Browse code

sbc: b/f: fixed use of setting for unsolicited NOTIFY forwarding

Raphael Coeffic authored on 23/12/2013 13:07:24
Showing 1 changed files
... ...
@@ -119,8 +119,6 @@ SBCCallLeg::SBCCallLeg(const SBCCallProfile& call_profile, AmSipDialog* p_dlg,
119 119
 				     1000);
120 120
     rtp_relay_rate_limit.reset(limit);
121 121
   }
122
-
123
-  subs->allowUnsolicitedNotify(call_profile.allow_subless_notify);
124 122
 }
125 123
 
126 124
 // B leg constructor (from SBCCalleeSession)
... ...
@@ -862,6 +860,8 @@ void SBCCallLeg::onInvite(const AmSipRequest& req)
862 860
   if(a_leg && call_profile.keep_vias)
863 861
     invite_req.hdrs = invite_req.vias + invite_req.hdrs;
864 862
 
863
+  subs->allowUnsolicitedNotify(call_profile.allow_subless_notify);
864
+
865 865
   // call extend call controls
866 866
   InitialInviteHandlerParams params(to, ruri, from, &req, &invite_req);
867 867
   for (vector<ExtendedCCInterface*>::iterator i = cc_ext.begin(); i != cc_ext.end(); ++i) {
Browse code

core/sbc: added support for subscription-less NOTIFY forwarding

For the moment, it is only implemented for NOTIFY requests within a dialog.

Raphael Coeffic authored on 20/12/2013 14:36:31
Showing 1 changed files
... ...
@@ -119,6 +119,8 @@ SBCCallLeg::SBCCallLeg(const SBCCallProfile& call_profile, AmSipDialog* p_dlg,
119 119
 				     1000);
120 120
     rtp_relay_rate_limit.reset(limit);
121 121
   }
122
+
123
+  subs->allowUnsolicitedNotify(call_profile.allow_subless_notify);
122 124
 }
123 125
 
124 126
 // B leg constructor (from SBCCalleeSession)
... ...
@@ -164,6 +166,8 @@ SBCCallLeg::SBCCallLeg(SBCCallLeg* caller, AmSipDialog* p_dlg,
164 166
   initCCExtModules();
165 167
 
166 168
   setLogger(caller->getLogger());
169
+
170
+  subs->allowUnsolicitedNotify(call_profile.allow_subless_notify);
167 171
 }
168 172
 
169 173
 SBCCallLeg::SBCCallLeg(AmSipDialog* p_dlg, AmSipSubscription* p_subs)
Browse code

Merge remote-tracking branch 'frafos/b2b_use_oa' into 1.6-dev-ccdsm

* frafos/b2b_use_oa: (24 commits)
b2b calls q/f: handle OA locally only if the local RTP stream is initialized
b2b calls: use dialog's OA to update media streams
b2b media q/f: do correct mute detection from SDP
OA: store local sdp sent in reply
OA: ignore repeated SDP in sent 2xx replies to INVITE
core: AmRtpStream: do not report unknown codecs as error
b2b media: code cleanup
OA: ignore repeated SDP in sent 1xx replies to INVITE
b2b media: re-initialize streams on every SDP change
sbc b/f: use dialog for offer-answer detection
SIP dialog: allow access to oa's SDPs
sbc: do not change OA mode in SBCCallLeg
b2b media q/f: SDP changes need to be handled independently for each call leg
sbc b/f: debug info fixed
b2b media: debug OA exchange
sbc: debug OA exchange
sbc: added method for call leg debugging
b2b media: debugging improved a bit
core: AmRtpStream: added method for debugging
b2b media q/f: do not mix input with relayed data
...

Stefan Sayer authored on 03/12/2013 12:49:44
Showing 0 changed files
Browse code

sbc:ext-cc: possibility to add ext-cc interfaces from cc-interfaces' init function - possible in init and onInitialInvite - only call legs (SBCCallLeg), not supported in SimpleRelay (non-call messages)

Stefan Sayer authored on 02/12/2013 18:04:31
Showing 1 changed files
... ...
@@ -1,5 +1,5 @@
1 1
 /*
2
- * Copyright (C) 2010-2011 Stefan Sayer
2
+ * Copyright (C) 2010-2013 Stefan Sayer
3 3
  * Copyright (C) 2012-2013 FRAFOS GmbH
4 4
  *
5 5
  * This file is part of SEMS, a free SIP media server.
... ...
@@ -48,6 +48,7 @@
48 48
 #include "ParamReplacer.h"
49 49
 #include "SDPFilter.h"
50 50
 #include "SBCEventLog.h"
51
+#include "SBC.h"
51 52
 
52 53
 #include <algorithm>
53 54
 
... ...
@@ -187,7 +188,7 @@ SBCCallLeg::SBCCallLeg(SBCCallLeg* caller, AmSipDialog* p_dlg,
187 188
     throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);
188 189
   }
189 190
 
190
-  if (!initCCExtModules()) {
191
+  if (!initCCExtModules(call_profile.cc_interfaces, cc_modules)) {
191 192
     ERROR("initializing extended call control modules\n");
192 193
     throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);
193 194
   }
... ...
@@ -817,7 +818,7 @@ void SBCCallLeg::onInvite(const AmSipRequest& req)
817 818
     throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);
818 819
   }
819 820
 
820
-  if (!initCCExtModules()) {
821
+  if (!initCCExtModules(call_profile.cc_interfaces, cc_modules)) {
821 822
     ERROR("initializing extended call control modules\n");
822 823
     throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);    
823 824
   }
... ...
@@ -907,6 +908,8 @@ void SBCCallLeg::onInvite(const AmSipRequest& req)
907 908
   InitialInviteHandlerParams params(to, ruri, from, &req, &invite_req);
908 909
   for (vector<ExtendedCCInterface*>::iterator i = cc_ext.begin(); i != cc_ext.end(); ++i) {
909 910
     (*i)->onInitialInvite(this, params);
911
+    // initialize possibily added modules
912
+    initPendingCCExtModules();
910 913
   }
911 914
 
912 915
   if (getCallStatus() == Disconnected) {
... ...
@@ -1548,15 +1551,19 @@ bool SBCCallLeg::reinvite(const AmSdp &sdp, unsigned &request_cseq)
1548 1551
   return true;
1549 1552
 }
1550 1553
 
1551
-bool SBCCallLeg::initCCExtModules()
1554
+/**
1555
+ * initialize modules from @arg cc_module_list with DI interface instances from @arg cc_module_di
1556
+ * add sucessfull ext-API call control instances to cc_ext
1557
+ * @return true on success (all modules properly initialized)
1558
+*/
1559
+bool SBCCallLeg::initCCExtModules(const CCInterfaceListT& cc_module_list, const vector<AmDynInvoke*>& cc_module_di)
1552 1560
 {
1553 1561
   // init extended call control modules
1554
-  vector<AmDynInvoke*>::iterator cc_mod = cc_modules.begin();
1555
-  for (CCInterfaceListIteratorT cc_it=call_profile.cc_interfaces.begin();
1556
-       cc_it != call_profile.cc_interfaces.end(); cc_it++)
1562
+  vector<AmDynInvoke*>::const_iterator cc_mod = cc_module_di.begin();
1563
+  for (CCInterfaceListConstIteratorT cc_it = cc_module_list.begin(); cc_it != cc_module_list.end(); cc_it++)
1557 1564
   {
1558
-    CCInterface& cc_if = *cc_it;
1559
-    string& cc_module = cc_it->cc_module;
1565
+    const CCInterface& cc_if = *cc_it;
1566
+    const string& cc_module = cc_it->cc_module;
1560 1567
 
1561 1568
     // get extended CC interface
1562 1569
     try {
... ...
@@ -1567,7 +1574,7 @@ bool SBCCallLeg::initCCExtModules()
1567 1574
         DBG("extended CC interface offered by cc_module '%s'\n", cc_module.c_str());
1568 1575
         // module initialization
1569 1576
         if (!iface->init(this, cc_if.cc_values)) {
1570
-	  ERROR("initializing extended call control interface\n");
1577
+	  ERROR("initializing extended call control interface '%s'\n", cc_module.c_str());
1571 1578
 	  return false;
1572 1579
 	}
1573 1580
 
... ...
@@ -1586,9 +1593,42 @@ bool SBCCallLeg::initCCExtModules()
1586 1593
 
1587 1594
     ++cc_mod;
1588 1595
   }
1596
+
1597
+  if (!initPendingCCExtModules()) {
1598
+    return false;
1599
+  }
1600
+
1589 1601
   return true; // success
1590 1602
 }
1591 1603
 
1604
+/** init pending modules until queue is empty */
1605
+bool SBCCallLeg::initPendingCCExtModules() {
1606
+  while (cc_module_queue.size()) {
1607
+    // local copy
1608
+    CCInterfaceListT _cc_mod_queue = cc_module_queue;
1609
+    cc_module_queue.clear();
1610
+    vector<AmDynInvoke*> _cc_mod_ifs;
1611
+
1612
+    // get corresponding DI interfaces
1613
+    if (!::getCCInterfaces(_cc_mod_queue, _cc_mod_ifs))
1614
+      return false;
1615
+
1616
+    // add to call leg
1617
+    if (!initCCExtModules(_cc_mod_queue, _cc_mod_ifs)) {
1618
+      return false;
1619
+    }
1620
+  }
1621
+  return true;
1622
+}
1623
+
1624
+void SBCCallLeg::addPendingCCExtModule(const string& cc_name, const string& cc_module, const map<string, string>& cc_values) {
1625
+  cc_module_queue.push_back(CCInterface(cc_name));
1626
+  cc_module_queue.back().cc_module = cc_module;
1627
+  cc_module_queue.back().cc_values = cc_values;
1628
+  DBG("added module '%s' from module '%s' to pending CC Ext modules\n",
1629
+      cc_name.c_str(), cc_module.c_str());
1630
+}
1631
+
1592 1632
 #define CALL_EXT_CC_MODULES(method) \
1593 1633
   do { \
1594 1634
     for (vector<ExtendedCCInterface*>::iterator i = cc_ext.begin(); i != cc_ext.end(); ++i) { \
Browse code

sbc:added missing (C) notices

Stefan Sayer authored on 02/12/2013 16:37:12
Showing 1 changed files
... ...
@@ -1,3 +1,29 @@
1
+/*
2
+ * Copyright (C) 2010-2011 Stefan Sayer
3
+ * Copyright (C) 2012-2013 FRAFOS GmbH
4
+ *
5
+ * This file is part of SEMS, a free SIP media server.
6
+ *
7
+ * SEMS is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * For a license to use the SEMS software under conditions
13
+ * other than those described here, or to purchase support for this
14
+ * software, please contact iptel.org by e-mail at the following addresses:
15
+ *    info@iptel.org
16
+ *
17
+ * SEMS is distributed in the hope that it will be useful,
18
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
+ * GNU General Public License for more details.
21
+ *
22
+ * You should have received a copy of the GNU General Public License
23
+ * along with this program; if not, write to the Free Software
24
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
+ */
26
+
1 27
 #include "SBCCallLeg.h"
2 28
 
3 29
 #include "SBCCallControlAPI.h"
Browse code

sbc: b/f: fix retarget

Raphael Coeffic authored on 29/11/2013 13:54:35
Showing 1 changed files
... ...
@@ -793,7 +793,7 @@ void SBCCallLeg::onInvite(const AmSipRequest& req)
793 793
   }
794 794
   else if(call_profile.reg_caching) {
795 795
     // REG-Cache lookup
796
-    uac_req.r_uri = call_profile.retarget(req.user,*dlg);
796
+    uac_req.r_uri = call_profile.retarget(req.user);
797 797
   }
798 798
 
799 799
   ruri = call_profile.ruri.empty() ? uac_req.r_uri : call_profile.ruri;
Browse code

sbc: do not change OA mode in SBCCallLeg

Václav Kubart authored on 27/11/2013 12:55:32
Showing 1 changed files
... ...
@@ -103,10 +103,6 @@ SBCCallLeg::SBCCallLeg(const SBCCallProfile& call_profile, AmSipDialog* p_dlg,
103 103
   set_sip_relay_only(false);
104 104
   dlg->setRel100State(Am100rel::REL100_IGNORED);
105 105
 
106
-  // better here than in onInvite
107
-  // or do we really want to start with OA when handling initial INVITE?
108
-  dlg->setOAEnabled(false);
109
-
110 106
   memset(&call_start_ts, 0, sizeof(struct timeval));
111 107
   memset(&call_connect_ts, 0, sizeof(struct timeval));
112 108
   memset(&call_end_ts, 0, sizeof(struct timeval));
... ...
@@ -138,7 +134,6 @@ SBCCallLeg::SBCCallLeg(SBCCallLeg* caller, AmSipDialog* p_dlg,
138 134
   // call_profile.cc_vars.clear();
139 135
 
140 136
   dlg->setRel100State(Am100rel::REL100_IGNORED);
141
-  dlg->setOAEnabled(false);
142 137
 
143 138
   // we need to apply it here instead of in applyBProfile because we have caller
144 139
   // here (FIXME: do it on better place and better way than accessing internals
... ...
@@ -624,11 +619,6 @@ void SBCCallLeg::updateLocalSdp(AmSdp &sdp)
624 619
   CallLeg::updateLocalSdp(sdp);
625 620
 }
626 621
 
627
-void SBCCallLeg::updateRemoteSdp(AmSdp &sdp)
628
-{
629
-  CallLeg::updateRemoteSdp(sdp);
630
-}
631
-
632 622
 void SBCCallLeg::onControlCmd(string& cmd, AmArg& params) {
633 623
   if (cmd == "teardown") {
634 624
     if (a_leg) {
Browse code

b/f:sbc: really apply next_hop_fixed to call

Stefan Sayer authored on 22/11/2013 21:25:19
Showing 1 changed files
... ...
@@ -318,8 +318,12 @@ void SBCCallLeg::applyBProfile()
318 318
   }
319 319
 
320 320
   if (!call_profile.next_hop.empty()) {
321
+    DBG("set next hop to '%s' (1st_req=%s,fixed=%s)\n",
322
+	call_profile.next_hop.c_str(), call_profile.next_hop_1st_req?"true":"false",
323
+	call_profile.next_hop_fixed?"true":"false");
321 324
     dlg->setNextHop(call_profile.next_hop);
322 325
     dlg->setNextHop1stReq(call_profile.next_hop_1st_req);
326
+    dlg->setNextHopFixed(call_profile.next_hop_fixed);
323 327
   }
324 328
 
325 329
   DBG("patch_ruri_next_hop = %i",call_profile.patch_ruri_next_hop);
Browse code

b/f:b2b:transparent dlg IDs: don't overwrite extLocalTag if dlg already connected

Stefan Sayer authored on 22/11/2013 09:27:04
Showing 1 changed files
... ...
@@ -502,7 +502,8 @@ void SBCCallLeg::setOtherId(const AmSipReply& reply)
502 502
 
503 503
 void SBCCallLeg::onInitialReply(B2BSipReplyEvent *e)
504 504
 {
505
-  if (call_profile.transparent_dlg_id && !e->reply.to_tag.empty()) {
505
+  if (call_profile.transparent_dlg_id && !e->reply.to_tag.empty()
506
+      && dlg->getStatus() != AmBasicSipDialog::Connected) {
506 507
     dlg->setExtLocalTag(e->reply.to_tag);
507 508
   }
508 509
   CallLeg::onInitialReply(e);
Browse code

b/f: fix onDtmf ext-cc module processing

Stefan Sayer authored on 20/11/2013 12:05:20
Showing 1 changed files
... ...
@@ -597,8 +597,8 @@ void SBCCallLeg::onDtmf(int event, int duration)
597 597
   DBG("received DTMF on %c-leg (%i;%i)\n", a_leg ? 'A': 'B', event, duration);
598 598
 
599 599
   for (vector<ExtendedCCInterface*>::iterator i = cc_ext.begin(); i != cc_ext.end(); ++i) {
600
-    if ((*i)->onDtmf(this, event, duration)  == StopProcessing);
601
-    return;
600
+    if ((*i)->onDtmf(this, event, duration)  == StopProcessing)
601
+      return;
602 602
   }
603 603
 
604 604
   AmB2BMedia *ms = getMediaSession();
Browse code

sbc b/f: alter locally generated hold request after b2b media class creates it

Václav Kubart authored on 14/11/2013 14:23:01 • Stefan Sayer committed on 19/11/2013 14:44:13
Showing 1 changed files
... ...
@@ -1690,10 +1690,10 @@ void SBCCallLeg::createHoldRequest(AmSdp &sdp)
1690 1690
     m.payloads.push_back(SdpPayload(0));
1691 1691
   }
1692 1692
 
1693
-  alterHoldRequestImpl(sdp);
1694
-
1695 1693
   AmB2BMedia *ms = getMediaSession();
1696 1694
   if (ms) ms->replaceOffer(sdp, a_leg);
1695
+
1696
+  alterHoldRequestImpl(sdp);
1697 1697
 }
1698 1698
 
1699 1699
 void SBCCallLeg::setMediaSession(AmB2BMedia *new_session)
Browse code

sbc: strict control over hold offer

Conflicts:

apps/sbc/SBCCallProfile.h

Václav Kubart authored on 13/11/2013 09:29:14 • Stefan Sayer committed on 19/11/2013 13:38:03
Showing 1 changed files
... ...
@@ -1607,39 +1607,60 @@ void SBCCallLeg::resumeRejected()
1607 1607
   CallLeg::resumeRejected();
1608 1608
 }
1609 1609
 
1610
-static void zero_connection(SdpConnection &c)
1610
+static void replace_address(SdpConnection &c, const string &ip)
1611 1611
 {
1612 1612
   if (!c.address.empty()) {
1613
-    if (c.network == NT_IN) {
1614
-      if (c.addrType == AT_V4) {
1615
-        c.address = "0.0.0.0";
1616
-        return;
1617
-      }
1618
-      // TODO: IPv6?
1613
+    if (c.addrType == AT_V4) {
1614
+      c.address = ip;
1615
+      return;
1619 1616
     }
1617
+    // TODO: IPv6?
1618
+    DBG("unsupported address type for replacing IP");
1620 1619
   }
1621
-
1622
-  DBG("unsupported connection type for marking with 0.0.0.0");
1623 1620
 }
1624 1621
 
1625
-static void alterHoldRequest(AmSdp &sdp, bool mark_zero_con, bool enable_recv)
1622
+static void alterHoldRequest(AmSdp &sdp, SBCCallProfile::HoldSettings::Activity a, const string &ip)
1626 1623
 {
1627
-  if (mark_zero_con) zero_connection(sdp.conn);
1624
+  if (!ip.empty()) replace_address(sdp.conn, ip);
1628 1625
   for (vector<SdpMedia>::iterator m = sdp.media.begin(); m != sdp.media.end(); ++m) {
1629
-    if (mark_zero_con) zero_connection(m->conn);
1630
-    m->recv = enable_recv;
1626
+    if (!ip.empty()) replace_address(m->conn, ip);
1627
+    m->recv = (a == SBCCallProfile::HoldSettings::sendrecv || a == SBCCallProfile::HoldSettings::recvonly);
1628
+    m->send = (a == SBCCallProfile::HoldSettings::sendrecv || a == SBCCallProfile::HoldSettings::sendonly);
1629
+  }
1630
+}
1631
+
1632
+void SBCCallLeg::alterHoldRequestImpl(AmSdp &sdp)
1633
+{
1634
+  if (call_profile.hold_settings.mark_zero_connection(a_leg)) {
1635
+    static const string zero("0.0.0.0");
1636
+    ::alterHoldRequest(sdp, call_profile.hold_settings.activity(a_leg), zero);
1637
+  }
1638
+  else {
1639
+    if (getRtpRelayMode() == RTP_Direct) {
1640
+      // we can not put our IP there if not relaying, using empty not to
1641
+      // overwrite existing addresses
1642
+      static const string empty;
1643
+      ::alterHoldRequest(sdp, call_profile.hold_settings.activity(a_leg), empty);
1644
+    }
1645
+    else {
1646
+      // use public IP to be put into connection addresses (overwrite 0.0.0.0
1647
+      // there)
1648
+      ::alterHoldRequest(sdp, call_profile.hold_settings.activity(a_leg), advertisedIP());
1649
+    }
1631 1650
   }
1632 1651
 }
1633 1652
 
1634 1653
 void SBCCallLeg::alterHoldRequest(AmSdp &sdp)
1635 1654
 {
1636
-  TRACE("altering B2B hold request\n");
1655
+  TRACE("altering B2B hold request(%s, %s, %s)\n",
1656
+      call_profile.hold_settings.alter_b2b(a_leg) ? "alter B2B" : "do not alter B2B",
1657
+      call_profile.hold_settings.mark_zero_connection(a_leg) ? "0.0.0.0" : "own IP",
1658
+      call_profile.hold_settings.activity_str(a_leg).c_str()
1659
+      );
1637 1660
 
1638 1661
   if (!call_profile.hold_settings.alter_b2b(a_leg)) return;
1639 1662
 
1640
-  ::alterHoldRequest(sdp,
1641
-      call_profile.hold_settings.mark_zero_connection(a_leg),
1642
-      call_profile.hold_settings.recv(a_leg));
1663
+  alterHoldRequestImpl(sdp);
1643 1664
 }
1644 1665
 
1645 1666
 void SBCCallLeg::createHoldRequest(AmSdp &sdp)
... ...
@@ -1669,9 +1690,7 @@ void SBCCallLeg::createHoldRequest(AmSdp &sdp)
1669 1690
     m.payloads.push_back(SdpPayload(0));
1670 1691
   }
1671 1692
 
1672
-  ::alterHoldRequest(sdp,
1673
-      call_profile.hold_settings.mark_zero_connection(a_leg),
1674
-      call_profile.hold_settings.recv(a_leg));
1693
+  alterHoldRequestImpl(sdp);
1675 1694
 
1676 1695
   AmB2BMedia *ms = getMediaSession();
1677 1696
   if (ms) ms->replaceOffer(sdp, a_leg);
Browse code

Merge remote-tracking branch 'frafos/1.6-dev' into 1.6-dev-ccdsm

* frafos/1.6-dev: (27 commits)
b2b calls quick hack: make RelayController accessible from derrived classes
sbc: keep original CSeq to support authentication case with Asterisk
sbc: allow to preserve media session when disconnecting
core: disable blacklist for in-dialog requests
sip: disable blacklist lookup if TR_FLAG_DISABLE_BL flag is set
sip: do not insert into blacklist if duration == 0
sbc: added active registration counter
b2b media b/f: do not try to set relay with empty remote address
AmRtpStream b/f: do not set mute together with hold
core: CPS limiter Calls-per-sec limiting capability, similar to the maximum number of calls limiter. There is a "soft limit" that is intended to use by the applications: if the app uses async processing and detects that the incoming workload is too much for the currenti capacity (which can depend on for example the remote DB engine's load), it can slewi it back to some percent of the current CPS; then when the circumstances are restored it can switch the CPS limit back to the configuration (or XMLRPC/stats interface) mandated value.
sbc: use non-hold SDP if possible when adding new callee
sbc: new event for asynchronous held call resume
b2b media cleanup: remove unused methods
sbc b/f: create hold request cleaner way
sbc b/f: signalize hold/resume request before creating the hold/resume request itself
webconference: add lonely_user_timer option
sbc b/f: apply remote SDP again if RTP mode changed during OA exchange
b2b media b/f: do not clear audio when removed from media processor
core: b/f: make get_header_keyvalue_single() case-insensitive as specified in RFC3261 7.3.1
sbc: improved hold handling
...

Conflicts:
apps/sbc/CallLeg.cpp
core/AmB2BMedia.h

Stefan Sayer authored on 13/11/2013 16:02:45
Showing 0 changed files
Browse code

sbc: keep original CSeq to support authentication case with Asterisk

Raphael Coeffic authored on 12/11/2013 12:13:12
Showing 1 changed files
... ...
@@ -146,6 +146,7 @@ SBCCallLeg::SBCCallLeg(SBCCallLeg* caller, AmSipDialog* p_dlg,
146 146
   if (call_profile.transparent_dlg_id && caller) {
147 147
     dlg->setCallid(caller->dlg->getCallid());
148 148
     dlg->setExtLocalTag(caller->dlg->getRemoteTag());
149
+    dlg->cseq = caller->dlg->r_cseq;
149 150
   }
150 151
 
151 152
   // copy RTP rate limit from caller leg
Browse code

sbc b/f: create hold request cleaner way

Václav Kubart authored on 07/11/2013 08:57:43
Showing 1 changed files
... ...
@@ -1598,49 +1598,44 @@ static void zero_connection(SdpConnection &c)
1598 1598
   DBG("unsupported connection type for marking with 0.0.0.0");
1599 1599
 }
1600 1600
 
1601
+static void alterHoldRequest(AmSdp &sdp, bool mark_zero_con, bool enable_recv)
1602
+{
1603
+  if (mark_zero_con) zero_connection(sdp.conn);
1604
+  for (vector<SdpMedia>::iterator m = sdp.media.begin(); m != sdp.media.end(); ++m) {
1605
+    if (mark_zero_con) zero_connection(m->conn);
1606
+    m->recv = enable_recv;
1607
+  }
1608
+}
1609
+
1601 1610
 void SBCCallLeg::alterHoldRequest(AmSdp &sdp)
1602 1611
 {
1603 1612
   TRACE("altering B2B hold request\n");
1604 1613
 
1605 1614
   if (!call_profile.hold_settings.alter_b2b(a_leg)) return;
1606 1615
 
1607
-  bool zero = call_profile.hold_settings.mark_zero_connection(a_leg);
1608
-  bool recv = call_profile.hold_settings.recv(a_leg);
1609
-
1610
-  if (zero) zero_connection(sdp.conn);
1611
-  for (vector<SdpMedia>::iterator m = sdp.media.begin(); m != sdp.media.end(); ++m) {
1612
-    if (zero) zero_connection(m->conn);
1613
-    m->recv = recv;
1614
-  }
1616
+  ::alterHoldRequest(sdp,
1617
+      call_profile.hold_settings.mark_zero_connection(a_leg),
1618
+      call_profile.hold_settings.recv(a_leg));
1615 1619
 }
1616 1620
 
1617 1621
 void SBCCallLeg::createHoldRequest(AmSdp &sdp)
1618 1622
 {
1619
-  // FIXME: hold SDP must be based on sdp if possible (updates existing session)
1620 1623
   // hack: we need to have other side SDP (if the stream is hold already
1621 1624
   // it should be marked as inactive)
1625
+  // FIXME: fix SDP versioning! (remember generated versions and increase the
1626
+  // version number in every SDP passing through?)
1622 1627
 
1623
-  AmB2BMedia *ms = getMediaSession();
1624
-  if (ms) {
1625
-    ms->mute(a_leg);
1626
-    ms->createHoldRequest(sdp, a_leg,
1627
-        call_profile.hold_settings.mark_zero_connection(a_leg),
1628
-        !call_profile.hold_settings.recv(a_leg));
1629
-  }
1630
-  else {
1631
-    sdp.clear();
1632
-
1633
-    // FIXME: versioning
1628
+  AmMimeBody *s = established_body.hasContentType(SIP_APPLICATION_SDP);
1629
+  if (s) sdp.parse((const char*)s->getPayload());
1630
+  if (sdp.media.empty()) {
1631
+    // established SDP is not valid! generate complete fake
1634 1632
     sdp.version = 0;
1635 1633
     sdp.origin.user = "sems";
1636
-    //offer.origin.sessId = 1;
1637
-    //offer.origin.sessV = 1;
1638 1634
     sdp.sessionName = "sems";
1639 1635
     sdp.conn.network = NT_IN;
1640 1636
     sdp.conn.addrType = AT_V4;
1641
-    sdp.conn.address = "0.0.0.0"; // we have no socket for RTP/RTCP on our side so we must do this
1637
+    sdp.conn.address = "0.0.0.0";
1642 1638
 
1643
-    // FIXME: use media line from stored body?
1644 1639
     sdp.media.push_back(SdpMedia());
1645 1640
     SdpMedia &m = sdp.media.back();
1646 1641
     m.type = MT_AUDIO;
... ...
@@ -1649,6 +1644,13 @@ void SBCCallLeg::createHoldRequest(AmSdp &sdp)
1649 1644
     m.recv = false;
1650 1645
     m.payloads.push_back(SdpPayload(0));
1651 1646
   }
1647
+
1648
+  ::alterHoldRequest(sdp,
1649
+      call_profile.hold_settings.mark_zero_connection(a_leg),
1650
+      call_profile.hold_settings.recv(a_leg));
1651
+
1652
+  AmB2BMedia *ms = getMediaSession();
1653
+  if (ms) ms->replaceOffer(sdp, a_leg);
1652 1654
 }
1653 1655
 
1654 1656
 void SBCCallLeg::setMediaSession(AmB2BMedia *new_session)
Browse code

sbc:rtprelay_dtmf_filtering and rtprelay_dtmf_detection options

With the option rtprelay_dtmf_filtering=yes the SBC filters out RTP DTMF
(RFC2833 / RFC4733) packets in relayed streams.

If rtprelay_dtmf_detection=yes is set, DTMF from RTP packets is detected
and can be used to control applications, e.g. special call flows, implemented with
the extended call control API. Note that the call needs to be added to
the media processor in order for DTMF events to be processed.

Internally, if the flag force_dtmf_receiving is set for the RTP stream,
also in relay mode the DTMF packets are sent to the DTMF detection queue.

The ext cc api is extended with the onDtmf function.

Stefan Sayer authored on 05/11/2013 23:55:52
Showing 1 changed files
... ...
@@ -279,6 +279,8 @@ void SBCCallLeg::applyAProfile()
279 279
 
280 280
     setRtpRelayTransparentSeqno(call_profile.rtprelay_transparent_seqno);
281 281
     setRtpRelayTransparentSSRC(call_profile.rtprelay_transparent_ssrc);
282
+    setEnableDtmfRtpFiltering(call_profile.rtprelay_dtmf_filtering);
283
+    setEnableDtmfRtpDetection(call_profile.rtprelay_dtmf_detection);
282 284
 
283 285
     if(call_profile.transcoder.isActive()) {
284 286
       setRtpRelayMode(RTP_Transcoding);
... ...
@@ -654,10 +656,16 @@ void SBCCallLeg::onOtherBye(const AmSipRequest& req)
654 656
 
655 657
 void SBCCallLeg::onDtmf(int event, int duration)
656 658
 {
659
+  DBG("received DTMF on %c-leg (%i;%i)\n", a_leg ? 'A': 'B', event, duration);
660
+
661
+  for (vector<ExtendedCCInterface*>::iterator i = cc_ext.begin(); i != cc_ext.end(); ++i) {
662
+    if ((*i)->onDtmf(this, event, duration)  == StopProcessing);
663
+    return;
664
+  }
665
+
657 666
   AmB2BMedia *ms = getMediaSession();
658 667
   if(ms) {
659
-    DBG("received DTMF on %c-leg (%i;%i)\n",
660
-	a_leg ? 'A': 'B', event, duration);
668
+    DBG("sending DTMF (%i;%i)\n", event, duration);
661 669
     ms->sendDtmf(!a_leg,event,duration);
662 670
   }
663 671
 }
Browse code

b/f:sbc: ext_cc: fix 891a8e0e if ext cc init(...) fails, stop call with 500...

onDestroyLeg is already called from onBeforeDestroy for the already
initialized call control modules.

Stefan Sayer authored on 05/11/2013 11:12:04
Showing 1 changed files
... ...
@@ -1599,10 +1599,6 @@ bool SBCCallLeg::initCCExtModules()
1599 1599
         // module initialization
1600 1600
         if (!iface->init(this, cc_if.cc_values)) {
1601 1601
 	  ERROR("initializing extended call control interface\n");
1602
-	  // call onDestroyLeg to clean up on call not going forward
1603
-	  for (vector<ExtendedCCInterface*>::iterator i = cc_ext.begin(); i != cc_ext.end(); ++i) {
1604
-	    (*i)->onDestroyLeg(this);
1605
-	  }
1606 1602
 	  return false;
1607 1603
 	}
1608 1604
 
Browse code

sbc: improved hold handling

Václav Kubart authored on 05/11/2013 08:47:30
Showing 1 changed files
... ...
@@ -1534,36 +1534,121 @@ void SBCCallLeg::initCCExtModules()
1534 1534
   }
1535 1535
 }
1536 1536
 
1537
-void SBCCallLeg::putOnHold()
1537
+#define CALL_EXT_CC_MODULES(method) \
1538
+  do { \
1539
+    for (vector<ExtendedCCInterface*>::iterator i = cc_ext.begin(); i != cc_ext.end(); ++i) { \
1540
+      (*i)->method(this); \
1541
+    } \
1542
+  } while (0)
1543
+
1544
+void SBCCallLeg::holdRequested()
1538 1545
 {
1539
-  for (vector<ExtendedCCInterface*>::iterator i = cc_ext.begin(); i != cc_ext.end(); ++i) {
1540
-    if ((*i)->putOnHold(this) == StopProcessing) return;
1541
-  }
1542
-  CallLeg::putOnHold();
1546
+  TRACE("%s: hold requested\n", getLocalTag().c_str());
1547
+  CALL_EXT_CC_MODULES(holdRequested);
1548
+  CallLeg::holdRequested();
1543 1549
 }
1544 1550
 
1545
-void SBCCallLeg::resumeHeld(bool send_reinvite)
1551
+void SBCCallLeg::holdAccepted()
1546 1552
 {
1547
-  for (vector<ExtendedCCInterface*>::iterator i = cc_ext.begin(); i != cc_ext.end(); ++i) {
1548
-    if ((*i)->resumeHeld(this, send_reinvite) == StopProcessing) return;
1553
+  TRACE("%s: hold accepted\n", getLocalTag().c_str());
1554
+  CALL_EXT_CC_MODULES(holdAccepted);
1555
+  CallLeg::holdAccepted();
1556
+}
1557
+
1558
+void SBCCallLeg::holdRejected()
1559
+{
1560
+  TRACE("%s: hold rejected\n", getLocalTag().c_str());
1561
+  CALL_EXT_CC_MODULES(holdRejected);
1562
+  CallLeg::holdRejected();
1563
+}
1564
+
1565
+void SBCCallLeg::resumeRequested()
1566
+{
1567
+  TRACE("%s: resume requested\n", getLocalTag().c_str());
1568
+  CALL_EXT_CC_MODULES(resumeRequested);
1569
+  CallLeg::resumeRequested();
1570
+}
1571
+
1572
+void SBCCallLeg::resumeAccepted()
1573
+{
1574
+  TRACE("%s: resume accepted\n", getLocalTag().c_str());
1575
+  CALL_EXT_CC_MODULES(resumeAccepted);
1576
+  CallLeg::resumeAccepted();
1577
+}
1578
+
1579
+void SBCCallLeg::resumeRejected()
1580
+{
1581
+  TRACE("%s: resume rejected\n", getLocalTag().c_str());
1582
+  CALL_EXT_CC_MODULES(resumeRejected);
1583
+  CallLeg::resumeRejected();
1584
+}
1585
+
1586
+static void zero_connection(SdpConnection &c)
1587
+{
1588
+  if (!c.address.empty()) {
1589
+    if (c.network == NT_IN) {
1590
+      if (c.addrType == AT_V4) {
1591
+        c.address = "0.0.0.0";
1592
+        return;
1593
+      }
1594
+      // TODO: IPv6?
1595
+    }
1549 1596
   }
1550
-  CallLeg::resumeHeld(send_reinvite);
1597
+
1598
+  DBG("unsupported connection type for marking with 0.0.0.0");
1551 1599
 }
1552 1600
 
1553
-void SBCCallLeg::handleHoldReply(bool succeeded)
1601
+void SBCCallLeg::alterHoldRequest(AmSdp &sdp)
1554 1602
 {
1555
-  for (vector<ExtendedCCInterface*>::iterator i = cc_ext.begin(); i != cc_ext.end(); ++i) {
1556
-    if ((*i)->handleHoldReply(this, succeeded) == StopProcessing) return;
1603
+  TRACE("altering B2B hold request\n");
1604
+
1605
+  if (!call_profile.hold_settings.alter_b2b(a_leg)) return;
1606
+
1607
+  bool zero = call_profile.hold_settings.mark_zero_connection(a_leg);
1608
+  bool recv = call_profile.hold_settings.recv(a_leg);
1609
+
1610
+  if (zero) zero_connection(sdp.conn);
1611
+  for (vector<SdpMedia>::iterator m = sdp.media.begin(); m != sdp.media.end(); ++m) {
1612
+    if (zero) zero_connection(m->conn);
1613
+    m->recv = recv;
1557 1614
   }
1558
-  CallLeg::handleHoldReply(succeeded);
1559 1615
 }
1560 1616
 
1561 1617
 void SBCCallLeg::createHoldRequest(AmSdp &sdp)
1562 1618
 {
1563
-  for (vector<ExtendedCCInterface*>::iterator i = cc_ext.begin(); i != cc_ext.end(); ++i) {
1564
-    if ((*i)->createHoldRequest(this, sdp) == StopProcessing) return;
1619
+  // FIXME: hold SDP must be based on sdp if possible (updates existing session)
1620
+  // hack: we need to have other side SDP (if the stream is hold already
1621
+  // it should be marked as inactive)
1622
+
1623
+  AmB2BMedia *ms = getMediaSession();
1624
+  if (ms) {
1625
+    ms->mute(a_leg);
1626
+    ms->createHoldRequest(sdp, a_leg,
1627
+        call_profile.hold_settings.mark_zero_connection(a_leg),
1628
+        !call_profile.hold_settings.recv(a_leg));
1629
+  }
1630
+  else {
1631
+    sdp.clear();
1632
+
1633
+    // FIXME: versioning
1634
+    sdp.version = 0;
1635
+    sdp.origin.user = "sems";
1636
+    //offer.origin.sessId = 1;
1637
+    //offer.origin.sessV = 1;
1638
+    sdp.sessionName = "sems";
1639
+    sdp.conn.network = NT_IN;
1640
+    sdp.conn.addrType = AT_V4;
1641
+    sdp.conn.address = "0.0.0.0"; // we have no socket for RTP/RTCP on our side so we must do this
1642
+
1643
+    // FIXME: use media line from stored body?
1644
+    sdp.media.push_back(SdpMedia());
1645
+    SdpMedia &m = sdp.media.back();
1646
+    m.type = MT_AUDIO;
1647
+    m.transport = TP_RTPAVP;
1648
+    m.send = false;
1649
+    m.recv = false;
1650
+    m.payloads.push_back(SdpPayload(0));
1565 1651
   }
1566
-  CallLeg::createHoldRequest(sdp);
1567 1652
 }
1568 1653
 
1569 1654
 void SBCCallLeg::setMediaSession(AmB2BMedia *new_session)
Browse code

sbc: ext_cc: if ext cc init(...) fails, stop call with 500 Server Internal Error

Stefan Sayer authored on 04/11/2013 15:42:43
Showing 1 changed files
... ...
@@ -223,7 +223,10 @@ SBCCallLeg::SBCCallLeg(SBCCallLeg* caller, AmSipDialog* p_dlg,
223 223
     throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);
224 224
   }
225 225
 
226
-  initCCExtModules();
226
+  if (!initCCExtModules()) {
227
+    ERROR("initializing extended call control modules\n");
228
+    throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);
229
+  }
227 230
 
228 231
   setLogger(caller->getLogger());
229 232
 }
... ...
@@ -845,7 +848,10 @@ void SBCCallLeg::onInvite(const AmSipRequest& req)
845 848
     throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);
846 849
   }
847 850
 
848
-  initCCExtModules();
851
+  if (!initCCExtModules()) {
852
+    ERROR("initializing extended call control modules\n");