Browse code

b/f: fix SDP media attribute without value parsing, changed log

Stefan Sayer authored on 07/02/2012 18:38:48
Showing 2 changed files
... ...
@@ -95,6 +95,21 @@ inline string transport_p_2_str(int tp)
95 95
   }
96 96
 }
97 97
 
98
+string SdpConnection::debugPrint() const {
99
+  return addr_t_2_str(addrType) + " " + address;
100
+}
101
+
102
+string SdpMedia::debugPrint() const {
103
+  string payload_list;
104
+  for(std::vector<SdpPayload>::const_iterator it=
105
+	payloads.begin(); it!= payloads.end(); it++) {
106
+    if (it != payloads.begin())
107
+      payload_list+=" ";
108
+    payload_list+=int2str(it->payload_type);
109
+  }
110
+  return "port "+int2str(port) + ", payloads: "+payload_list;
111
+}
112
+
98 113
 bool SdpPayload::operator == (int r)
99 114
 {
100 115
   DBG("pl == r: payload_type = %i; r = %i\n", payload_type, r);
... ...
@@ -349,7 +364,7 @@ static bool parse_sdp_line_ex(AmSdp* sdp_msg, char*& s)
349 364
   register parse_st state;
350 365
   //default state
351 366
   state=SDP_DESCR;
352
-  DBG("parse_sdp_line_ex: parsing sdp message\n");
367
+  DBG("parsing SDP message...\n");
353 368
 
354 369
   while(*s != '\0'){
355 370
     switch(state){
... ...
@@ -568,11 +583,13 @@ static void parse_sdp_connection(AmSdp* sdp_msg, char* s, char t)
568 583
       }
569 584
     }
570 585
   }
571
-  if(t == 'd')
586
+  if(t == 'd') {
572 587
     sdp_msg->conn = c;
573
-  if(t == 'm'){
588
+    DBG("SDP: got session level connection: %s\n", c.debugPrint().c_str());
589
+  } else if(t == 'm'){
574 590
     SdpMedia& media = sdp_msg->media.back();
575 591
     media.conn = c;
592
+    DBG("SDP: got media level connection: %s\n", c.debugPrint().c_str());
576 593
   }
577 594
 
578 595
   //DBG("parse_sdp_line_ex: parse_sdp_connection: done parsing sdp connection\n");
... ...
@@ -703,10 +720,12 @@ static void parse_sdp_media(AmSdp* sdp_msg, char* s)
703 720
   }
704 721
   sdp_msg->media.push_back(m);
705 722
 
723
+  DBG("SDP: got media: %s\n", m.debugPrint().c_str());
706 724
   //DBG("parse_sdp_line_ex: parse_sdp_media: done parsing media description \n");
707 725
   return;
708 726
 }
709 727
 
728
+// session level attribute
710 729
 static void parse_session_attr(AmSdp* sdp_msg, char* s, char** next) {
711 730
   *next = get_next_line(s);
712 731
   if (*next == s) {
... ...
@@ -730,17 +749,17 @@ static void parse_session_attr(AmSdp* sdp_msg, char* s, char** next) {
730 749
   if (col == attr_end) {
731 750
     // property attribute
732 751
     sdp_msg->attributes.push_back(SdpAttribute(string(s, attr_end-s+1)));
733
-    DBG("got session attribute '%.*s\n", (int)(attr_end-s+1), s);
752
+    // DBG("got session attribute '%.*s\n", (int)(attr_end-s+1), s);
734 753
   } else {
735 754
     // value attribute
736 755
     sdp_msg->attributes.push_back(SdpAttribute(string(s, col-s-1),
737 756
 					       string(col, attr_end-col+1)));
738
-    DBG("got session attribute '%.*s:%.*s'\n", (int)(col-s-1), s, (int)(attr_end-col+1), col);
739
-
757
+    // DBG("got session attribute '%.*s:%.*s'\n", (int)(col-s-1), s, (int)(attr_end-col+1), col);
740 758
   }
741 759
 
742 760
 }
743 761
 
762
+// media level attribute
744 763
 static void parse_sdp_attr(AmSdp* sdp_msg, char* s)
745 764
 {
746 765
   if(sdp_msg->media.empty()){
... ...
@@ -765,197 +784,196 @@ static void parse_sdp_attr(AmSdp* sdp_msg, char* s)
765 784
   unsigned int payload_type, clock_rate, encoding_param = 0;
766 785
   string encoding_name, params;
767 786
 
768
-  if(contains(attr_line, line_end, ':')){
787
+  string attr;
788
+  if (!contains(attr_line, line_end, ':')) {
789
+    next = parse_until(attr_line, '\r');
790
+    if (next >= line_end) {
791
+      DBG("found attribute line '%s', which is not followed by cr\n", attr_line);
792
+      next = line_end;
793
+    }
794
+    attr = string(attr_line, int(next-attr_line)-1);
795
+    attr_check(attr);
796
+    parsing = 0;
797
+  } else {
769 798
     next = parse_until(attr_line, ':');
770
-    string attr(attr_line, int(next-attr_line)-1);
799
+    attr = string(attr_line, int(next-attr_line)-1);
771 800
     attr_line = next;
772
-    if(attr == "rtpmap"){
773
-      while(parsing){
774
-	switch(rtpmap_st){
775
-	case TYPE:
776
-	  {
777
-	    next = parse_until(attr_line, ' ');
778
-	    string type(attr_line, int(next-attr_line)-1);
779
-	    str2i(type,payload_type);
801
+  }
802
+
803
+  if(attr == "rtpmap"){
804
+    while(parsing){
805
+      switch(rtpmap_st){
806
+      case TYPE:
807
+	{
808
+	  next = parse_until(attr_line, ' ');
809
+	  string type(attr_line, int(next-attr_line)-1);
810
+	  str2i(type,payload_type);
811
+	  attr_line = next;
812
+	  rtpmap_st = ENC_NAME;
813
+	  break;
814
+	}
815
+      case ENC_NAME:
816
+	{
817
+	  if(contains(s, line_end, '/')){
818
+	    next = parse_until(attr_line, '/');
819
+	    string enc_name(attr_line, int(next-attr_line)-1);
820
+	    encoding_name = enc_name;
780 821
 	    attr_line = next;
781
-	    rtpmap_st = ENC_NAME;
822
+	    rtpmap_st = CLK_RATE;
823
+	    break;
824
+	  } else {
825
+	    rtpmap_st = ENC_PARAM;
782 826
 	    break;
783 827
 	  }
784
-	case ENC_NAME:
785
-	  {
786
-	    if(contains(s, line_end, '/')){
787
-	      next = parse_until(attr_line, '/');
788
-	      string enc_name(attr_line, int(next-attr_line)-1);
789
-	      encoding_name = enc_name;
790
-	      attr_line = next;
791
-	      rtpmap_st = CLK_RATE;
792
-	      break;
793
-	    }else{
794
-	      rtpmap_st = ENC_PARAM;
795
-	      break;
796
-	    }
828
+	}
829
+      case CLK_RATE:
830
+	{
831
+	  // check for posible encoding parameters after clock rate
832
+	  if(contains(attr_line, line_end, '/')){
833
+	    next = parse_until(attr_line, '/');
834
+	    string clk_rate(attr_line, int(next-attr_line)-1);
835
+	    str2i(clk_rate, clock_rate);
836
+	    attr_line = next;
837
+	    rtpmap_st = ENC_PARAM;
838
+	    //last line check
839
+	  }else if (*line_end == '\0') {
840
+	    string clk_rate(attr_line, int(line_end-attr_line));
841
+	    str2i(clk_rate, clock_rate);
842
+	    parsing = 0;
843
+	    //more lines to come
844
+	  }else{
845
+	    string clk_rate(attr_line, int(line_end-attr_line)-1);
846
+	    str2i(clk_rate, clock_rate);
847
+	    parsing=0;
797 848
 	  }
798
-	case CLK_RATE:
799
-	  {
800
-	    // check for posible encoding parameters after clock rate
801
-	    if(contains(attr_line, line_end, '/')){
802
-	      next = parse_until(attr_line, '/');
803
-	      string clk_rate(attr_line, int(next-attr_line)-1);
804
-	      str2i(clk_rate, clock_rate);
805
-	      attr_line = next;
806
-	      rtpmap_st = ENC_PARAM;
807
-	      //last line check
808
-	    }else if (*line_end == '\0') {
809
-	      string clk_rate(attr_line, int(line_end-attr_line));
810
-	      str2i(clk_rate, clock_rate);
811
-	      parsing = 0;
812
-	      //more lines to come
813
-	    }else{
814
-	      string clk_rate(attr_line, int(line_end-attr_line)-1);
815
-	      str2i(clk_rate, clock_rate);
816
-	      parsing=0;
817
-	    }
818 849
 	    
819
-	    break;
820
-	  }
821
-	case ENC_PARAM:
822
-	  {
823
-	    next = parse_until(attr_line, ' ');
824
-	    if(next < line_end){
825
-	      string value(attr_line, int(next-attr_line)-1);
826
-	      str2i(value, encoding_param);
827
-	      attr_line = next;
828
-	      rtpmap_st = ENC_PARAM;
829
-	    }else{
830
-	      string last_value(attr_line, int(line_end-attr_line)-1);
831
-	      str2i(last_value, encoding_param);
832
-	      parsing = 0;
833
-	    }
834
-	    break;
850
+	  break;
851
+	}
852
+      case ENC_PARAM:
853
+	{
854
+	  next = parse_until(attr_line, ' ');
855
+	  if(next < line_end){
856
+	    string value(attr_line, int(next-attr_line)-1);
857
+	    str2i(value, encoding_param);
858
+	    attr_line = next;
859
+	    rtpmap_st = ENC_PARAM;
860
+	  }else{
861
+	    string last_value(attr_line, int(line_end-attr_line)-1);
862
+	    str2i(last_value, encoding_param);
863
+	    parsing = 0;
835 864
 	  }
836 865
 	  break;
837 866
 	}
867
+	break;
838 868
       }
869
+    }
839 870
       
840
-      //DBG("found media attr 'rtpmap' type '%d'\n", payload_type);
841
-      
842
-      vector<SdpPayload>::iterator pl_it;
871
+    //DBG("found media attr 'rtpmap' type '%d'\n", payload_type);
843 872
       
844
-      for( pl_it=media.payloads.begin();
845
-	   (pl_it != media.payloads.end())
846
-	     && (pl_it->payload_type != int(payload_type));
847
-	   ++pl_it);
848
-
849
-      if(pl_it != media.payloads.end()){
850
-	*pl_it = SdpPayload( int(payload_type),
851
-			     encoding_name,
852
-			     int(clock_rate),
853
-			     int(encoding_param));
854
-      }
873
+    vector<SdpPayload>::iterator pl_it;
855 874
       
875
+    for( pl_it=media.payloads.begin();
876
+	 (pl_it != media.payloads.end())
877
+	   && (pl_it->payload_type != int(payload_type));
878
+	 ++pl_it);
879
+
880
+    if(pl_it != media.payloads.end()){
881
+      *pl_it = SdpPayload( int(payload_type),
882
+			   encoding_name,
883
+			   int(clock_rate),
884
+			   int(encoding_param));
885
+    }
856 886
 
857
-    } else if(attr == "fmtp"){
858
-      while(parsing){
859
-	switch(fmtp_st){
860
-	case FORMAT:
861
-	  {
862
-	    next = parse_until(attr_line, ' ');
863
-	    string fmtp_format(attr_line, int(next-attr_line)-1);
864
-	    str2i(fmtp_format, payload_type);
865
-	    attr_line = next;
866
-	    fmtp_st = FORMAT_PARAM;
867
-	    break;
868
-	  }
869
-	case FORMAT_PARAM:
870
-	  { 
887
+  } else if(attr == "fmtp"){
888
+    while(parsing){
889
+      switch(fmtp_st){
890
+      case FORMAT:
891
+	{
892
+	  next = parse_until(attr_line, ' ');
893
+	  string fmtp_format(attr_line, int(next-attr_line)-1);
894
+	  str2i(fmtp_format, payload_type);
895
+	  attr_line = next;
896
+	  fmtp_st = FORMAT_PARAM;
897
+	  break;
898
+	}
899
+      case FORMAT_PARAM:
900
+	{ 
901
+	  line_end--;
902
+	  while (is_wsp(*line_end))
871 903
 	    line_end--;
872
-	    while (is_wsp(*line_end))
873
-	      line_end--;
874 904
 
875
-	    params = string(attr_line, line_end-attr_line+1);
876
-	    parsing = 0;
877
-	  }
878
-	  break;
905
+	  params = string(attr_line, line_end-attr_line+1);
906
+	  parsing = 0;
879 907
 	}
908
+	break;
880 909
       }
910
+    }
881 911
 
882
-      //DBG("found media attr 'fmtp' for payload '%d': '%s'\n", 
883
-      //  payload_type, params.c_str());
912
+    //DBG("found media attr 'fmtp' for payload '%d': '%s'\n", 
913
+    //  payload_type, params.c_str());
884 914
 
885
-      vector<SdpPayload>::iterator pl_it;
915
+    vector<SdpPayload>::iterator pl_it;
886 916
       
887
-      for(pl_it=media.payloads.begin();
888
-	   (pl_it != media.payloads.end())
889
-	     && (pl_it->payload_type != int(payload_type));
890
-	   pl_it++);
917
+    for(pl_it=media.payloads.begin();
918
+	(pl_it != media.payloads.end())
919
+	  && (pl_it->payload_type != int(payload_type));
920
+	pl_it++);
891 921
 
892
-      if(pl_it != media.payloads.end())
893
-	pl_it->sdp_format_parameters = params;
922
+    if(pl_it != media.payloads.end())
923
+      pl_it->sdp_format_parameters = params;
894 924
 
895
-    } else if (attr == "direction") {
896
-	next = parse_until(attr_line, '\r');
897
-	if(next < line_end){
898
-	    string value(attr_line, int(next-attr_line)-1);
899
-	    if (value == "active") {
900
-		media.dir=SdpMedia::DirActive;
901
-		//DBG("found media attr 'direction' value '%s'\n",
902
-		//    (char*)value.c_str());
903
-	    } else if (value == "passive") {
904
-		media.dir=SdpMedia::DirPassive;
905
-		//DBG("found media attr 'direction' value '%s'\n",
906
-		//    (char*)value.c_str());
907
-	    } else if (attr == "both") {
908
-		media.dir=SdpMedia::DirBoth;
909
-		//DBG("found media attr 'direction' value '%s'\n",
910
-		//    (char*)value.c_str());
911
-	    } //else
912
-	      //DBG("found media attr 'direction' with unknown value '%s'\n",
913
-	      //    (char*)value.c_str());
914
-	} else {
915
-	    DBG("found media attr 'direction', but value is not"
916
-		" followed by cr\n");
917
-	}
918
-    } else if (attr == "sendrecv") {
919
-      media.send = true;
920
-      media.recv = true;
921
-    } else if (attr == "sendonly") {
922
-      media.send = true;
923
-      media.recv = false;
924
-    } else if (attr == "recvonly") {
925
-      media.send = false;
926
-      media.recv = true;
927
-    } else if (attr == "inactive") {
928
-      media.send = false;
929
-      media.recv = false;
930
-    } else {
931
-      attr_check(attr);
925
+  } else if (attr == "direction") {
926
+    if (parsing) {
932 927
       next = parse_until(attr_line, '\r');
933 928
       if(next < line_end){
934
-	  string value(attr_line, int(next-attr_line)-1);
935
-	  DBG("found media attr '%s' value '%s'\n",
936
-	      (char*)attr.c_str(), (char*)value.c_str());
937
-	  media.attributes.push_back(SdpAttribute(attr, value));
929
+	string value(attr_line, int(next-attr_line)-1);
930
+	if (value == "active") {
931
+	  media.dir=SdpMedia::DirActive;
932
+	  // DBG("found media attr 'direction' value '%s'\n", (char*)value.c_str());
933
+	} else if (value == "passive") {
934
+	  media.dir=SdpMedia::DirPassive;
935
+	  //DBG("found media attr 'direction' value '%s'\n", (char*)value.c_str());
936
+	} else if (attr == "both") {
937
+	  media.dir=SdpMedia::DirBoth;
938
+	  //DBG("found media attr 'direction' value '%s'\n", (char*)value.c_str());
939
+	} 
938 940
       } else {
939
-	  DBG("found media attr '%s', but value is not followed by cr\n",
940
-	      (char *)attr.c_str());
941
+	DBG("found media attribute 'direction', but value is not followed by cr\n");
941 942
       }
943
+    } else {
944
+      DBG("ignoring direction attribute without value\n");
942 945
     }
943
-
944
-
946
+  } else if (attr == "sendrecv") {
947
+    media.send = true;
948
+    media.recv = true;
949
+  } else if (attr == "sendonly") {
950
+    media.send = true;
951
+    media.recv = false;
952
+  } else if (attr == "recvonly") {
953
+    media.send = false;
954
+    media.recv = true;
955
+  } else if (attr == "inactive") {
956
+    media.send = false;
957
+    media.recv = false;
945 958
   } else {
959
+    attr_check(attr);
960
+    string value;
961
+    if (parsing) {
946 962
       next = parse_until(attr_line, '\r');
947
-      if(next < line_end){
948
-	  string attr(attr_line, int(next-attr_line)-1);
949
-	  attr_check(attr);
950
-	  DBG("found media attr '%s'\n", (char*)attr.c_str());
951
-	  media.attributes.push_back(SdpAttribute(attr));
952
-      } else {
953
-	  DBG("found media attr line '%s', which is not followed by cr\n",
954
-	      attr_line);
963
+      if(next >= line_end){
964
+	DBG("found media attribute '%s', but value is not followed by cr\n",
965
+	    (char *)attr.c_str());
955 966
       }
956
-  }
967
+      value = string (attr_line, int(next-attr_line)-1);
968
+    }
957 969
 
958
-  return;
970
+    // if (value.empty()) {
971
+    //   DBG("got media attribute '%s'\n", attr.c_str());
972
+    // } else {
973
+    //   DBG("got media attribute '%s':'%s'\n", attr.c_str(), value.c_str());
974
+    // }
975
+    media.attributes.push_back(SdpAttribute(attr, value));
976
+  }
959 977
 }
960 978
 
961 979
 static void parse_sdp_origin(AmSdp* sdp_msg, char* s)
... ...
@@ -1211,11 +1229,9 @@ static bool attr_check(std::string attr)
1211 1229
     return true;
1212 1230
   else if(attr == "passive")
1213 1231
     return true;
1214
-  else
1215
-    {
1216
-    DBG("sdp_parse_attr: Unknown attribute name used: %s, plz see RFC4566\n",
1217
-	(char*)attr.c_str());
1232
+  else {
1233
+    DBG("unknown attribute: %s\n", (char*)attr.c_str());
1218 1234
     return false;
1219
-    }
1235
+  }
1220 1236
 }
1221 1237
 
... ...
@@ -71,6 +71,9 @@ struct SdpConnection
71 71
   string address;
72 72
 
73 73
   SdpConnection() : address() {}
74
+
75
+  /** pretty print */
76
+  string debugPrint() const;
74 77
 };
75 78
 
76 79
 /** \brief o=... line in SDP */
... ...
@@ -151,6 +154,9 @@ struct SdpMedia
151 154
 
152 155
   SdpMedia() : conn(),send(true),recv(true) {}
153 156
 
157
+  /** pretty print */
158
+  string debugPrint() const;
159
+
154 160
   /**
155 161
    * Checks which payloads are compatible with the payload provider,
156 162
    * inserts them into the answer, compute send/recv attributes