Browse code

sbc b/f: create hold request cleaner way

Václav Kubart authored on 07/11/2013 08:57:43
Showing 3 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)
... ...
@@ -317,6 +317,7 @@ bool AudioStreamData::initStream(PlayoutType playout_type,
317 317
 
318 318
   // TODO: try to init only in case there are some payloads which can't be relayed
319 319
   stream->forceSdpMediaIndex(media_idx);
320
+
320 321
   if (stream->init(local_sdp, remote_sdp, force_symmetric_rtp) == 0) {
321 322
     stream->setPlayoutType(playout_type);
322 323
     initialized = true;
... ...
@@ -326,7 +327,7 @@ bool AudioStreamData::initStream(PlayoutType playout_type,
326 327
     // there still can be payloads to be relayed (if all possible payloads are
327 328
     // to be relayed this needs not to be an error)
328 329
   }
329
-  stream->setOnHold(muted);
330
+  stream->setOnHold(muted); // FIXME: do not unmute if muted because of 0.0.0.0 remote IP
330 331
 
331 332
   return initialized;
332 333
 }
... ...
@@ -699,13 +700,12 @@ void AmB2BMedia::replaceConnectionAddress(AmSdp &parser_sdp, bool a_leg,
699 700
 					  const string& relay_address,
700 701
 					  const string& relay_public_address)
701 702
 {
702
-  static const string void_addr("0.0.0.0");
703 703
   AmLock lock(mutex);
704 704
 
705 705
   SdpConnection orig_conn = parser_sdp.conn; // needed for the 'quick workaround' for non-audio media
706 706
 
707 707
   // place relay_address in connection address
708
-  if (!parser_sdp.conn.address.empty() && (parser_sdp.conn.address != void_addr)) {
708
+  if (!parser_sdp.conn.address.empty() && (parser_sdp.conn.address != zero_ip)) {
709 709
     parser_sdp.conn.address = relay_public_address;
710 710
     DBG("new connection address: %s",parser_sdp.conn.address.c_str());
711 711
   }
... ...
@@ -731,7 +731,7 @@ void AmB2BMedia::replaceConnectionAddress(AmSdp &parser_sdp, bool a_leg,
731 731
       }
732 732
 
733 733
       if(it->port) { // if stream active
734
-	if (!it->conn.address.empty() && (parser_sdp.conn.address != void_addr)) {
734
+	if (!it->conn.address.empty() && (parser_sdp.conn.address != zero_ip)) {
735 735
 	  it->conn.address = relay_public_address;
736 736
 	  DBG("new stream connection address: %s",it->conn.address.c_str());
737 737
 	}
... ...
@@ -764,7 +764,7 @@ void AmB2BMedia::replaceConnectionAddress(AmSdp &parser_sdp, bool a_leg,
764 764
       }
765 765
 
766 766
       if(it->port) { // if stream active
767
-	if (!it->conn.address.empty() && (parser_sdp.conn.address != void_addr)) {
767
+	if (!it->conn.address.empty() && (parser_sdp.conn.address != zero_ip)) {
768 768
 	  it->conn.address = relay_public_address;
769 769
 	  DBG("new stream connection address: %s",it->conn.address.c_str());
770 770
 	}
... ...
@@ -1034,54 +1034,31 @@ void AmB2BMedia::onMediaProcessingTerminated()
1034 1034
   }
1035 1035
 }
1036 1036
 
1037
-bool AmB2BMedia::createHoldRequest(AmSdp &sdp, bool a_leg, bool zero_connection, bool sendonly)
1037
+bool AmB2BMedia::replaceOffer(AmSdp &sdp, bool a_leg)
1038 1038
 {
1039
-  AmB2BSession *session = (a_leg ? a : b);
1040
-
1041
-  // session is needed to fill all the stuff and to have the streams initialised correctly
1042
-  if (!session) return false;
1043
-
1044
-  sdp.clear();
1045
-
1046
-  // FIXME: use original origin and continue in versioning? (the one used in
1047
-  // previous SDPs if any)
1048
-  // stolen from AmSession
1049
-  sdp.version = 0;
1050
-  sdp.origin.user = "sems";
1051
-  //offer.origin.sessId = 1;
1052
-  //offer.origin.sessV = 1;
1053
-  sdp.sessionName = "sems";
1054
-  sdp.conn.network = NT_IN;
1055
-  sdp.conn.addrType = AT_V4;
1056
-  if (zero_connection) sdp.conn.address = zero_ip;
1057
-  else sdp.conn.address = session->advertisedIP();
1058
-
1059
-  // possible params:
1060
-  //  - use 0.0.0.0 connection address or sendonly stream
1061
-  // create hold request based on current streams
1039
+  TRACE("replacing offer with a local one\n");
1040
+  createStreams(sdp); // create missing streams
1041
+
1062 1042
   AmLock lock(mutex);
1063 1043
 
1064 1044
   try {
1065
-    if (audio.empty()) {
1066
-      // create one dummy stream to create valid SDP
1067
-      AudioStreamPair pair(a, b, 0);
1068
-      audio.push_back(pair);
1069
-    }
1070
-
1071
-    for (AudioStreamIterator i = audio.begin(); i != audio.end(); ++i) {
1072
-      // TODO: put disabled media stream for non-audio media? (we would need to
1073
-      // remember what type of media was it etc.)
1074
-
1075
-      TRACE("generating SDP offer from stream %d\n", i->media_idx);
1076
-      sdp.media.push_back(SdpMedia());
1077
-      SdpMedia &m = sdp.media.back();
1078
-      m.type = MT_AUDIO;
1079
-      if (a_leg) i->a.getSdpOffer(i->media_idx, m);
1080
-      else i->b.getSdpOffer(i->media_idx, m);
1081 1045
 
1082
-      m.send = true; // always? (what if there is no 'hold music' to play?
1083
-      if (sendonly) m.recv = false;
1046
+    AudioStreamIterator as = audio.begin();
1047
+    for (vector<SdpMedia>::iterator m = sdp.media.begin(); m != sdp.media.end(); ++m) {
1048
+      if (m->type == MT_AUDIO && as != audio.end()) {
1049
+        // generate our local offer
1050
+        TRACE("... making audio stream offer\n");
1051
+        if (a_leg) as->a.getSdpOffer(as->media_idx, *m);
1052
+        else as->b.getSdpOffer(as->media_idx, *m);
1053
+        ++as;
1054
+      }
1055
+      else {
1056
+        TRACE("... making non-audio/uninitialised stream inactive\n");
1057
+        m->send = false;
1058
+        m->recv = false;
1059
+      }
1084 1060
     }
1061
+
1085 1062
   }
1086 1063
   catch (...) {
1087 1064
     TRACE("hold SDP offer creation failed\n");
... ...
@@ -371,6 +371,10 @@ class AmB2BMedia: public AmMediaSession
371 371
 				  const string& relay_address,
372 372
 				  const string& relay_public_address);
373 373
 
374
+    /** replace offer inside given SDP with locally generated one (media streams
375
+     * etc must be initialised like in case replaceConnectionAddress) */
376
+    bool replaceOffer(AmSdp &sdp, bool a_leg);
377
+
374 378
     /** Store remote SDP for given leg and update media session appropriately. */
375 379
     void updateRemoteSdp(bool a_leg, const AmSdp &remote_sdp, RelayController *ctrl);
376 380
     
... ...
@@ -426,7 +430,6 @@ class AmB2BMedia: public AmMediaSession
426 430
 
427 431
     bool isOnHold(bool a_leg) { if (a_leg) return a_leg_on_hold; else return b_leg_on_hold; }
428 432
     void setHoldFlag(bool a_leg, bool hold) { if (a_leg) a_leg_on_hold = hold; else b_leg_on_hold = hold; }
429
-    bool createHoldRequest(AmSdp &sdp, bool a_leg, bool zero_connection, bool sendonly);
430 433
 
431 434
     void mute(bool a_leg) { setMuteFlag(a_leg, true); }
432 435
     void unmute(bool a_leg) { setMuteFlag(a_leg, false); }