... | ... |
@@ -33,14 +33,19 @@ using std::map; |
33 | 33 |
#include "strings.h" |
34 | 34 |
#endif |
35 | 35 |
|
36 |
+#define CR '\r' |
|
37 |
+#define LF '\n' |
|
38 |
+#define CRLF "\r\n" |
|
39 |
+ |
|
36 | 40 |
static void parse_session_attr(AmSdp* sdp_msg, char* s, char** next); |
37 | 41 |
static bool parse_sdp_line_ex(AmSdp* sdp_msg, char*& s); |
38 |
-static void parse_sdp_connection(AmSdp* sdp_msg, char* s, char t); |
|
42 |
+static char* parse_sdp_connection(AmSdp* sdp_msg, char* s, char t); |
|
39 | 43 |
static void parse_sdp_media(AmSdp* sdp_msg, char* s); |
40 |
-static void parse_sdp_attr(AmSdp* sdp_msg, char* s); |
|
44 |
+static char* parse_sdp_attr(AmSdp* sdp_msg, char* s); |
|
41 | 45 |
static void parse_sdp_origin(AmSdp* sdp_masg, char* s); |
42 | 46 |
|
43 | 47 |
inline char* get_next_line(char* s); |
48 |
+inline char* skip_till_next_line(char* s, size_t& line_len); |
|
44 | 49 |
static char* is_eql_next(char* s); |
45 | 50 |
static char* parse_until(char* s, char end); |
46 | 51 |
static char* parse_until(char* s, char* end, char c); |
... | ... |
@@ -555,7 +560,7 @@ static bool parse_sdp_line_ex(AmSdp* sdp_msg, char*& s) |
555 | 560 |
{ |
556 | 561 |
if (!s) return true; // SDP can't be empty, return error (true really used for failure?) |
557 | 562 |
|
558 |
- char* next=0; |
|
563 |
+ char* next=0; size_t line_len = 0; |
|
559 | 564 |
register parse_st state; |
560 | 565 |
//default state |
561 | 566 |
state=SDP_DESCR; |
... | ... |
@@ -568,11 +573,13 @@ static bool parse_sdp_line_ex(AmSdp* sdp_msg, char*& s) |
568 | 573 |
case 'v': |
569 | 574 |
{ |
570 | 575 |
s = is_eql_next(s); |
571 |
- next = get_next_line(s); |
|
572 |
- if (int(next-s)-2 >= 0) { |
|
573 |
- string version(s, int(next-s)-2); |
|
576 |
+ next = skip_till_next_line(s, line_len); |
|
577 |
+ if (line_len) { |
|
578 |
+ string version(s, line_len); |
|
574 | 579 |
str2i(version, sdp_msg->version); |
575 |
- //DBG("parse_sdp_line_ex: found version\n"); |
|
580 |
+ // DBG("parse_sdp_line_ex: found version '%s'\n", version.c_str()); |
|
581 |
+ } else { |
|
582 |
+ sdp_msg->version = 0; |
|
576 | 583 |
} |
577 | 584 |
s = next; |
578 | 585 |
state = SDP_DESCR; |
... | ... |
@@ -588,23 +595,24 @@ static bool parse_sdp_line_ex(AmSdp* sdp_msg, char*& s) |
588 | 595 |
break; |
589 | 596 |
case 's': |
590 | 597 |
{ |
591 |
- //DBG("parse_sdp_line_ex: found session\n"); |
|
592 | 598 |
s = is_eql_next(s); |
593 |
- next = get_next_line(s); |
|
594 |
- if (int(next-s)-2 >= 0) { |
|
595 |
- string sessionName(s, int(next-s)-2); |
|
596 |
- sdp_msg->sessionName = sessionName; |
|
599 |
+ next = skip_till_next_line(s, line_len); |
|
600 |
+ if (line_len) { |
|
601 |
+ sdp_msg->sessionName = string(s, line_len); |
|
602 |
+ } else { |
|
603 |
+ sdp_msg->sessionName.clear(); |
|
597 | 604 |
} |
598 | 605 |
s = next; |
599 | 606 |
break; |
600 | 607 |
} |
601 | 608 |
|
602 | 609 |
case 'u': { |
603 |
- //DBG("parse_sdp_line_ex: found uri\n"); |
|
604 | 610 |
s = is_eql_next(s); |
605 |
- next = get_next_line(s); |
|
606 |
- if (int(next-s)-2 >= 0) { |
|
607 |
- sdp_msg->uri = string(s, int(next-s)-2); |
|
611 |
+ next = skip_till_next_line(s, line_len); |
|
612 |
+ if (line_len) { |
|
613 |
+ sdp_msg->uri = string(s, line_len); |
|
614 |
+ } else { |
|
615 |
+ sdp_msg->uri.clear(); |
|
608 | 616 |
} |
609 | 617 |
s = next; |
610 | 618 |
} break; |
... | ... |
@@ -615,14 +623,11 @@ static bool parse_sdp_line_ex(AmSdp* sdp_msg, char*& s) |
615 | 623 |
case 'b': |
616 | 624 |
case 't': |
617 | 625 |
case 'k': |
618 |
- //DBG("parse_sdp_line_ex: found unknown line '%c'\n", *s); |
|
619 | 626 |
s = is_eql_next(s); |
620 |
- next = get_next_line(s); |
|
621 |
- s = next; |
|
627 |
+ s = skip_till_next_line(s, line_len); |
|
622 | 628 |
state = SDP_DESCR; |
623 | 629 |
break; |
624 | 630 |
case 'a': |
625 |
- //DBG("parse_sdp_line_ex: found attributes\n"); |
|
626 | 631 |
s = is_eql_next(s); |
627 | 632 |
parse_session_attr(sdp_msg, s, &next); |
628 | 633 |
// next = get_next_line(s); |
... | ... |
@@ -631,11 +636,9 @@ static bool parse_sdp_line_ex(AmSdp* sdp_msg, char*& s) |
631 | 636 |
state = SDP_DESCR; |
632 | 637 |
break; |
633 | 638 |
case 'c': |
634 |
- //DBG("parse_sdp_line_ex: found connection\n"); |
|
635 | 639 |
s = is_eql_next(s); |
636 |
- parse_sdp_connection(sdp_msg, s, 'd'); |
|
637 |
- s = get_next_line(s); |
|
638 |
- state = SDP_DESCR; |
|
640 |
+ s = parse_sdp_connection(sdp_msg, s, 'd'); |
|
641 |
+ state = SDP_DESCR; |
|
639 | 642 |
break; |
640 | 643 |
case 'm': |
641 | 644 |
//DBG("parse_sdp_line_ex: found media\n"); |
... | ... |
@@ -644,11 +647,17 @@ static bool parse_sdp_line_ex(AmSdp* sdp_msg, char*& s) |
644 | 647 |
|
645 | 648 |
default: |
646 | 649 |
{ |
647 |
- next = get_next_line(s); |
|
648 |
- if (int(next-s)-2 >= 0) { |
|
649 |
- string line(s, int(next-s)-2); |
|
650 |
+ next = skip_till_next_line(s, line_len); |
|
651 |
+ if (line_len) { |
|
652 |
+ sdp_msg->uri = string(s, line_len); |
|
653 |
+ } else { |
|
654 |
+ sdp_msg->uri.clear(); |
|
655 |
+ } |
|
656 |
+ |
|
657 |
+ next = skip_till_next_line(s, line_len); |
|
658 |
+ if (line_len) { |
|
650 | 659 |
DBG("parse_sdp_line: skipping unknown Session description %s=\n", |
651 |
- (char*)line.c_str()); |
|
660 |
+ string(s, line_len).c_str()); |
|
652 | 661 |
} |
653 | 662 |
s = next; |
654 | 663 |
break; |
... | ... |
@@ -661,45 +670,42 @@ static bool parse_sdp_line_ex(AmSdp* sdp_msg, char*& s) |
661 | 670 |
case 'm': |
662 | 671 |
s = is_eql_next(s); |
663 | 672 |
parse_sdp_media(sdp_msg, s); |
664 |
- s = get_next_line(s); |
|
673 |
+ s = skip_till_next_line(s, line_len); |
|
665 | 674 |
state = SDP_MEDIA; |
666 | 675 |
break; |
667 | 676 |
case 'i': |
668 | 677 |
s = is_eql_next(s); |
669 |
- s = get_next_line(s); |
|
678 |
+ s = skip_till_next_line(s, line_len); |
|
670 | 679 |
state = SDP_MEDIA; |
671 | 680 |
break; |
672 | 681 |
case 'c': |
673 | 682 |
s = is_eql_next(s); |
674 | 683 |
//DBG("parse_sdp_line: found media connection\n"); |
675 |
- parse_sdp_connection(sdp_msg, s, 'm'); |
|
676 |
- s = get_next_line(s); |
|
684 |
+ s = parse_sdp_connection(sdp_msg, s, 'm'); |
|
677 | 685 |
state = SDP_MEDIA; |
678 | 686 |
break; |
679 | 687 |
case 'b': |
680 | 688 |
s = is_eql_next(s); |
681 |
- s = get_next_line(s); |
|
689 |
+ s = skip_till_next_line(s, line_len); |
|
682 | 690 |
state = SDP_MEDIA; |
683 | 691 |
break; |
684 | 692 |
case 'k': |
685 | 693 |
s = is_eql_next(s); |
686 |
- s = get_next_line(s); |
|
694 |
+ s = skip_till_next_line(s, line_len); |
|
687 | 695 |
state = SDP_MEDIA; |
688 | 696 |
break; |
689 | 697 |
case 'a': |
690 | 698 |
s = is_eql_next(s); |
691 |
- parse_sdp_attr(sdp_msg, s); |
|
692 |
- s = get_next_line(s); |
|
699 |
+ s = parse_sdp_attr(sdp_msg, s); |
|
693 | 700 |
state = SDP_MEDIA; |
694 | 701 |
break; |
695 | 702 |
|
696 | 703 |
default : |
697 | 704 |
{ |
698 |
- next = get_next_line(s); |
|
699 |
- if (int(next-s)-2 >= 0) { |
|
700 |
- string line(s, int(next-s)-2); |
|
701 |
- DBG("parse_sdp_line: skipping unknown Media description '%s'\n", |
|
702 |
- (char*)line.c_str()); |
|
705 |
+ next = skip_till_next_line(s, line_len); |
|
706 |
+ if (line_len) { |
|
707 |
+ DBG("parse_sdp_line: skipping unknown Media description '%.*s'\n", |
|
708 |
+ (int)line_len, s); |
|
703 | 709 |
} |
704 | 710 |
s = next; |
705 | 711 |
break; |
... | ... |
@@ -713,17 +719,23 @@ static bool parse_sdp_line_ex(AmSdp* sdp_msg, char*& s) |
713 | 719 |
} |
714 | 720 |
|
715 | 721 |
|
716 |
-static void parse_sdp_connection(AmSdp* sdp_msg, char* s, char t) |
|
722 |
+static char* parse_sdp_connection(AmSdp* sdp_msg, char* s, char t) |
|
717 | 723 |
{ |
718 | 724 |
|
719 | 725 |
char* connection_line=s; |
720 | 726 |
char* next=0; |
721 |
- char* line_end=0; |
|
727 |
+ char* next_line=0; |
|
728 |
+ size_t line_len = 0; |
|
722 | 729 |
int parsing=1; |
723 | 730 |
|
724 | 731 |
SdpConnection c; |
725 | 732 |
|
726 |
- line_end = get_next_line(s); |
|
733 |
+ next_line = skip_till_next_line(s, line_len); |
|
734 |
+ if (line_len <= 7) { // should be at least c=IN IP4 ... |
|
735 |
+ DBG("short connection line '%.*s'\n", (int)line_len, s); |
|
736 |
+ return next_line; |
|
737 |
+ } |
|
738 |
+ |
|
727 | 739 |
register sdp_connection_st state; |
728 | 740 |
state = NET_TYPE; |
729 | 741 |
|
... | ... |
@@ -732,34 +744,35 @@ static void parse_sdp_connection(AmSdp* sdp_msg, char* s, char t) |
732 | 744 |
while(parsing){ |
733 | 745 |
switch(state){ |
734 | 746 |
case NET_TYPE: |
735 |
- //Ignore NET_TYPE since it is always IN |
|
736 |
- connection_line +=3; |
|
747 |
+ //Ignore NET_TYPE since it is always IN, fixme |
|
748 |
+ c.network = NT_IN; // fixme |
|
749 |
+ connection_line +=3; // fixme |
|
737 | 750 |
state = ADDR_TYPE; |
738 | 751 |
break; |
739 | 752 |
case ADDR_TYPE: |
740 | 753 |
{ |
741 | 754 |
string addr_type(connection_line,3); |
742 |
- connection_line +=4; |
|
755 |
+ connection_line +=4; // fixme |
|
743 | 756 |
if(addr_type == "IP4"){ |
744 |
- c.addrType = 1; |
|
757 |
+ c.addrType = AT_V4; |
|
745 | 758 |
state = IP4; |
746 | 759 |
}else if(addr_type == "IP6"){ |
747 |
- c.addrType = 2; |
|
760 |
+ c.addrType = AT_V6; |
|
748 | 761 |
state = IP6; |
749 | 762 |
}else{ |
750 |
- ERROR("parse_sdp_connection: Unknown addr_type in c=\n"); |
|
751 |
- c.addrType = 0; |
|
752 |
- parsing = 0; |
|
763 |
+ DBG("parse_sdp_connection: Unknown addr_type in c-line: '%s'\n", addr_type.c_str()); |
|
764 |
+ c.addrType = AT_NONE; |
|
765 |
+ parsing = 0; // ??? |
|
753 | 766 |
} |
754 | 767 |
break; |
755 | 768 |
} |
756 | 769 |
case IP4: |
757 | 770 |
{ |
758 |
- if(contains(connection_line, line_end, '/')){ |
|
771 |
+ if(contains(connection_line, next_line, '/')){ |
|
759 | 772 |
next = parse_until(s, '/'); |
760 | 773 |
c.address = string(connection_line,int(next-connection_line)-2); |
761 | 774 |
}else{ |
762 |
- c.address = string(connection_line, int(line_end-connection_line)-2); |
|
775 |
+ c.address = string(connection_line, line_len-7); |
|
763 | 776 |
} |
764 | 777 |
parsing = 0; |
765 | 778 |
break; |
... | ... |
@@ -767,11 +780,11 @@ static void parse_sdp_connection(AmSdp* sdp_msg, char* s, char t) |
767 | 780 |
|
768 | 781 |
case IP6: |
769 | 782 |
{ |
770 |
- if(contains(connection_line, line_end, '/')){ |
|
783 |
+ if(contains(connection_line, next_line, '/')){ |
|
771 | 784 |
next = parse_until(s, '/'); |
772 | 785 |
c.address = string(connection_line, int(next-connection_line)-2); |
773 | 786 |
}else{ |
774 |
- c.address = string(connection_line, int(line_end-connection_line)-2); |
|
787 |
+ c.address = string(connection_line, line_len-7); |
|
775 | 788 |
} |
776 | 789 |
parsing = 0; |
777 | 790 |
break; |
... | ... |
@@ -788,7 +801,7 @@ static void parse_sdp_connection(AmSdp* sdp_msg, char* s, char t) |
788 | 801 |
} |
789 | 802 |
|
790 | 803 |
//DBG("parse_sdp_line_ex: parse_sdp_connection: done parsing sdp connection\n"); |
791 |
- return; |
|
804 |
+ return next_line; |
|
792 | 805 |
} |
793 | 806 |
|
794 | 807 |
|
... | ... |
@@ -930,7 +943,8 @@ static void parse_sdp_media(AmSdp* sdp_msg, char* s) |
930 | 943 |
|
931 | 944 |
// session level attribute |
932 | 945 |
static void parse_session_attr(AmSdp* sdp_msg, char* s, char** next) { |
933 |
- *next = get_next_line(s); |
|
946 |
+ size_t line_len = 0; |
|
947 |
+ *next = skip_till_next_line(s, line_len); |
|
934 | 948 |
if (*next == s) { |
935 | 949 |
WARN("premature end of SDP in session attr\n"); |
936 | 950 |
while (**next != '\0') (*next)++; |
... | ... |
@@ -938,7 +952,7 @@ static void parse_session_attr(AmSdp* sdp_msg, char* s, char** next) { |
938 | 952 |
} |
939 | 953 |
char* attr_end = *next-1; |
940 | 954 |
while (attr_end >= s && |
941 |
- ((*attr_end == 10) || (*attr_end == 13))) |
|
955 |
+ ((*attr_end == LF) || (*attr_end == CR))) |
|
942 | 956 |
attr_end--; |
943 | 957 |
|
944 | 958 |
if (*attr_end == ':') { |
... | ... |
@@ -959,15 +973,14 @@ static void parse_session_attr(AmSdp* sdp_msg, char* s, char** next) { |
959 | 973 |
string(col, attr_end-col+1))); |
960 | 974 |
// DBG("got session attribute '%.*s:%.*s'\n", (int)(col-s-1), s, (int)(attr_end-col+1), col); |
961 | 975 |
} |
962 |
- |
|
963 | 976 |
} |
964 | 977 |
|
965 | 978 |
// media level attribute |
966 |
-static void parse_sdp_attr(AmSdp* sdp_msg, char* s) |
|
979 |
+static char* parse_sdp_attr(AmSdp* sdp_msg, char* s) |
|
967 | 980 |
{ |
968 | 981 |
if(sdp_msg->media.empty()){ |
969 | 982 |
ERROR("While parsing media options: no actual media !\n"); |
970 |
- return; |
|
983 |
+ return s; |
|
971 | 984 |
} |
972 | 985 |
|
973 | 986 |
SdpMedia& media = sdp_msg->media.back(); |
... | ... |
@@ -981,20 +994,16 @@ static void parse_sdp_attr(AmSdp* sdp_msg, char* s) |
981 | 994 |
char* attr_line=s; |
982 | 995 |
char* next=0; |
983 | 996 |
char* line_end=0; |
997 |
+ size_t line_len = 0; |
|
984 | 998 |
int parsing = 1; |
985 |
- line_end = get_next_line(attr_line); |
|
999 |
+ line_end = skip_till_next_line(attr_line, line_len); |
|
986 | 1000 |
|
987 | 1001 |
unsigned int payload_type, clock_rate, encoding_param = 0; |
988 | 1002 |
string encoding_name, params; |
989 | 1003 |
|
990 | 1004 |
string attr; |
991 | 1005 |
if (!contains(attr_line, line_end, ':')) { |
992 |
- next = parse_until(attr_line, '\r'); |
|
993 |
- if (next >= line_end) { |
|
994 |
- DBG("found attribute line '%s', which is not followed by cr\n", attr_line); |
|
995 |
- next = line_end; |
|
996 |
- } |
|
997 |
- attr = string(attr_line, int(next-attr_line)-1); |
|
1006 |
+ attr = string(attr_line, line_len); |
|
998 | 1007 |
attr_check(attr); |
999 | 1008 |
parsing = 0; |
1000 | 1009 |
} else { |
... | ... |
@@ -1089,10 +1098,10 @@ static void parse_sdp_attr(AmSdp* sdp_msg, char* s) |
1089 | 1098 |
|
1090 | 1099 |
} else if(attr == "fmtp"){ |
1091 | 1100 |
while(parsing){ |
1092 |
- switch(fmtp_st){ |
|
1101 |
+ switch(fmtp_st){ // fixme |
|
1093 | 1102 |
case FORMAT: |
1094 | 1103 |
{ |
1095 |
- next = parse_until(attr_line, ' '); |
|
1104 |
+ next = parse_until(attr_line, line_end, ' '); |
|
1096 | 1105 |
string fmtp_format(attr_line, int(next-attr_line)-1); |
1097 | 1106 |
str2i(fmtp_format, payload_type); |
1098 | 1107 |
attr_line = next; |
... | ... |
@@ -1100,12 +1109,12 @@ static void parse_sdp_attr(AmSdp* sdp_msg, char* s) |
1100 | 1109 |
break; |
1101 | 1110 |
} |
1102 | 1111 |
case FORMAT_PARAM: |
1103 |
- { |
|
1104 |
- line_end--; |
|
1105 |
- while (is_wsp(*line_end)) |
|
1106 |
- line_end--; |
|
1112 |
+ { |
|
1113 |
+ char* param_end = line_end-1; |
|
1114 |
+ while (is_wsp(*param_end)) |
|
1115 |
+ param_end--; |
|
1107 | 1116 |
|
1108 |
- params = string(attr_line, line_end-attr_line+1); |
|
1117 |
+ params = string(attr_line, param_end-attr_line+1); |
|
1109 | 1118 |
parsing = 0; |
1110 | 1119 |
} |
1111 | 1120 |
break; |
... | ... |
@@ -1127,21 +1136,20 @@ static void parse_sdp_attr(AmSdp* sdp_msg, char* s) |
1127 | 1136 |
|
1128 | 1137 |
} else if (attr == "direction") { |
1129 | 1138 |
if (parsing) { |
1130 |
- next = parse_until(attr_line, '\r'); |
|
1131 |
- if(next < line_end){ |
|
1132 |
- string value(attr_line, int(next-attr_line)-1); |
|
1133 |
- if (value == "active") { |
|
1134 |
- media.dir=SdpMedia::DirActive; |
|
1135 |
- // DBG("found media attr 'direction' value '%s'\n", (char*)value.c_str()); |
|
1136 |
- } else if (value == "passive") { |
|
1137 |
- media.dir=SdpMedia::DirPassive; |
|
1138 |
- //DBG("found media attr 'direction' value '%s'\n", (char*)value.c_str()); |
|
1139 |
- } else if (attr == "both") { |
|
1140 |
- media.dir=SdpMedia::DirBoth; |
|
1141 |
- //DBG("found media attr 'direction' value '%s'\n", (char*)value.c_str()); |
|
1142 |
- } |
|
1139 |
+ size_t dir_len = 0; |
|
1140 |
+ next = skip_till_next_line(attr_line, dir_len); |
|
1141 |
+ string value(attr_line, dir_len); |
|
1142 |
+ if (value == "active") { |
|
1143 |
+ media.dir=SdpMedia::DirActive; |
|
1144 |
+ // DBG("found media attr 'direction' value '%s'\n", (char*)value.c_str()); |
|
1145 |
+ } else if (value == "passive") { |
|
1146 |
+ media.dir=SdpMedia::DirPassive; |
|
1147 |
+ //DBG("found media attr 'direction' value '%s'\n", (char*)value.c_str()); |
|
1148 |
+ } else if (attr == "both") { |
|
1149 |
+ media.dir=SdpMedia::DirBoth; |
|
1150 |
+ //DBG("found media attr 'direction' value '%s'\n", (char*)value.c_str()); |
|
1143 | 1151 |
} else { |
1144 |
- DBG("found media attribute 'direction', but value is not followed by cr\n"); |
|
1152 |
+ DBG("found unknown value for media attribute 'direction'\n"); |
|
1145 | 1153 |
} |
1146 | 1154 |
} else { |
1147 | 1155 |
DBG("ignoring direction attribute without value\n"); |
... | ... |
@@ -1162,12 +1170,9 @@ static void parse_sdp_attr(AmSdp* sdp_msg, char* s) |
1162 | 1170 |
attr_check(attr); |
1163 | 1171 |
string value; |
1164 | 1172 |
if (parsing) { |
1165 |
- next = parse_until(attr_line, '\r'); |
|
1166 |
- if(next >= line_end){ |
|
1167 |
- DBG("found media attribute '%s', but value is not followed by cr\n", |
|
1168 |
- (char *)attr.c_str()); |
|
1169 |
- } |
|
1170 |
- value = string (attr_line, int(next-attr_line)-1); |
|
1173 |
+ size_t attr_len = 0; |
|
1174 |
+ next = skip_till_next_line(attr_line, attr_len); |
|
1175 |
+ value = string (attr_line, attr_len); |
|
1171 | 1176 |
} |
1172 | 1177 |
|
1173 | 1178 |
// if (value.empty()) { |
... | ... |
@@ -1177,6 +1182,7 @@ static void parse_sdp_attr(AmSdp* sdp_msg, char* s) |
1177 | 1182 |
// } |
1178 | 1183 |
media.attributes.push_back(SdpAttribute(attr, value)); |
1179 | 1184 |
} |
1185 |
+ return line_end; |
|
1180 | 1186 |
} |
1181 | 1187 |
|
1182 | 1188 |
static void parse_sdp_origin(AmSdp* sdp_msg, char* s) |
... | ... |
@@ -1184,7 +1190,8 @@ static void parse_sdp_origin(AmSdp* sdp_msg, char* s) |
1184 | 1190 |
char* origin_line = s; |
1185 | 1191 |
char* next=0; |
1186 | 1192 |
char* line_end=0; |
1187 |
- line_end = get_next_line(s); |
|
1193 |
+ size_t line_len=0; |
|
1194 |
+ line_end = skip_till_next_line(s, line_len); |
|
1188 | 1195 |
|
1189 | 1196 |
register sdp_origin_st origin_st; |
1190 | 1197 |
origin_st = USER; |
... | ... |
@@ -1248,6 +1255,7 @@ static void parse_sdp_origin(AmSdp* sdp_msg, char* s) |
1248 | 1255 |
break; |
1249 | 1256 |
} |
1250 | 1257 |
string net_type(origin_line, int(next-origin_line)-1); |
1258 |
+ origin.conn.network = NT_IN; // fixme |
|
1251 | 1259 |
origin_line = next; |
1252 | 1260 |
origin_st = ADDR; |
1253 | 1261 |
break; |
... | ... |
@@ -1260,7 +1268,17 @@ static void parse_sdp_origin(AmSdp* sdp_msg, char* s) |
1260 | 1268 |
origin_st = UNICAST_ADDR; |
1261 | 1269 |
break; |
1262 | 1270 |
} |
1271 |
+ |
|
1263 | 1272 |
string addr_type(origin_line, int(next-origin_line)-1); |
1273 |
+ if(addr_type == "IP4"){ |
|
1274 |
+ origin.conn.addrType = AT_V4; |
|
1275 |
+ }else if(addr_type == "IP6"){ |
|
1276 |
+ origin.conn.addrType = AT_V6; |
|
1277 |
+ }else{ |
|
1278 |
+ DBG("parse_sdp_connection: Unknown addr_type in o line: '%s'\n", addr_type.c_str()); |
|
1279 |
+ origin.conn.addrType = AT_NONE; |
|
1280 |
+ } |
|
1281 |
+ |
|
1264 | 1282 |
origin_line = next; |
1265 | 1283 |
origin_st = UNICAST_ADDR; |
1266 | 1284 |
break; |
... | ... |
@@ -1268,12 +1286,18 @@ static void parse_sdp_origin(AmSdp* sdp_msg, char* s) |
1268 | 1286 |
case UNICAST_ADDR: |
1269 | 1287 |
{ |
1270 | 1288 |
next = parse_until(origin_line, ' '); |
1271 |
- //check if line contains more values than allowed |
|
1272 |
- if(next > line_end){ |
|
1273 |
- origin.conn.address = string(origin_line, int(line_end-origin_line)-2); |
|
1274 |
- }else{ |
|
1275 |
- DBG("parse_sdp_origin: 'o=' contains more values than allowed; these values will be ignored\n"); |
|
1276 |
- origin.conn.address = string(origin_line, int(next-origin_line)-1); |
|
1289 |
+ if (next != origin_line) { |
|
1290 |
+ //check if line contains more values than allowed |
|
1291 |
+ if(next > line_end){ |
|
1292 |
+ size_t addr_len = 0; |
|
1293 |
+ skip_till_next_line(origin_line, addr_len); |
|
1294 |
+ origin.conn.address = string(origin_line, addr_len); |
|
1295 |
+ }else{ |
|
1296 |
+ DBG("parse_sdp_origin: 'o=' contains more values than allowed; these values will be ignored\n"); |
|
1297 |
+ origin.conn.address = string(origin_line, int(next-origin_line)-1); |
|
1298 |
+ } |
|
1299 |
+ } else { |
|
1300 |
+ origin.conn.address = ""; |
|
1277 | 1301 |
} |
1278 | 1302 |
parsing = 0; |
1279 | 1303 |
break; |
... | ... |
@@ -1328,6 +1352,28 @@ static char* parse_until(char* s, char* end, char c) |
1328 | 1352 |
return line; |
1329 | 1353 |
} |
1330 | 1354 |
|
1355 |
+static size_t len_till_eol(char* s, char* end) |
|
1356 |
+{ |
|
1357 |
+ size_t res=0; |
|
1358 |
+ char* line=s; |
|
1359 |
+ while(line<end && *line && *line != '\r' && *line != '\n'){ |
|
1360 |
+ line++; |
|
1361 |
+ res++; |
|
1362 |
+ } |
|
1363 |
+ return res; |
|
1364 |
+} |
|
1365 |
+ |
|
1366 |
+static size_t len_till_char_or_eol(char* s, char* end, char c) |
|
1367 |
+{ |
|
1368 |
+ size_t res=0; |
|
1369 |
+ char* line=s; |
|
1370 |
+ while(line<end && *line && *line != c && *line != '\r' && *line != '\n'){ |
|
1371 |
+ line++; |
|
1372 |
+ res++; |
|
1373 |
+ } |
|
1374 |
+ return res; |
|
1375 |
+} |
|
1376 |
+ |
|
1331 | 1377 |
static char* is_eql_next(char* s) |
1332 | 1378 |
{ |
1333 | 1379 |
char* current_line=s; |
... | ... |
@@ -1343,20 +1389,53 @@ inline char* get_next_line(char* s) |
1343 | 1389 |
char* next_line=s; |
1344 | 1390 |
//search for next line |
1345 | 1391 |
while( *next_line != '\0') { |
1346 |
- if(*next_line == 13){ |
|
1347 |
- next_line +=2; |
|
1392 |
+ if(*next_line == CR){ |
|
1393 |
+ next_line++; |
|
1394 |
+ if (*next_line == LF) { |
|
1395 |
+ next_line++; |
|
1396 |
+ break; |
|
1397 |
+ } else { |
|
1398 |
+ continue; |
|
1399 |
+ } |
|
1400 |
+ } else if (*next_line == LF){ |
|
1401 |
+ next_line++; |
|
1348 | 1402 |
break; |
1349 | 1403 |
} |
1350 |
- else if(*next_line == 10){ |
|
1351 |
- next_line +=1; |
|
1352 |
- break; |
|
1353 |
- } |
|
1354 | 1404 |
next_line++; |
1355 | 1405 |
} |
1356 | 1406 |
|
1357 | 1407 |
return next_line; |
1358 | 1408 |
} |
1359 | 1409 |
|
1410 |
+/* skip to 0, CRLF or LF; |
|
1411 |
+ @return line_len length of current line |
|
1412 |
+ @return start of next line |
|
1413 |
+*/ |
|
1414 |
+inline char* skip_till_next_line(char* s, size_t& line_len) |
|
1415 |
+{ |
|
1416 |
+ char* next_line=s; |
|
1417 |
+ line_len = 0; |
|
1418 |
+ |
|
1419 |
+ //search for next line |
|
1420 |
+ while( *next_line != '\0') { |
|
1421 |
+ if (*next_line == CR) { |
|
1422 |
+ next_line++; |
|
1423 |
+ if (*next_line == LF) { |
|
1424 |
+ next_line++; |
|
1425 |
+ break; |
|
1426 |
+ } else { |
|
1427 |
+ continue; |
|
1428 |
+ } |
|
1429 |
+ } else if (*next_line == LF){ |
|
1430 |
+ next_line++; |
|
1431 |
+ break; |
|
1432 |
+ } |
|
1433 |
+ line_len++; |
|
1434 |
+ next_line++; |
|
1435 |
+ } |
|
1436 |
+ |
|
1437 |
+ return next_line; |
|
1438 |
+} |
|
1360 | 1439 |
|
1361 | 1440 |
/* |
1362 | 1441 |
*Check if known media type is used |
28 | 29 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,90 @@ |
1 |
+#include "fct.h" |
|
2 |
+ |
|
3 |
+#include "log.h" |
|
4 |
+ |
|
5 |
+#include "AmSdp.h" |
|
6 |
+ |
|
7 |
+#define CRLF "\r\n" |
|
8 |
+#define LF "\n" |
|
9 |
+ |
|
10 |
+FCTMF_SUITE_BGN(test_sdp) { |
|
11 |
+ |
|
12 |
+ FCT_TEST_BGN(normal_sdp_ok) { |
|
13 |
+ AmSdp s; |
|
14 |
+ string sdp = |
|
15 |
+ "v=0" CRLF |
|
16 |
+ "o=- 3615077380 3615077398 IN IP4 178.66.14.5" CRLF |
|
17 |
+ "s=-" CRLF |
|
18 |
+ "c=IN IP4 178.66.14.5" CRLF |
|
19 |
+ "t=0 0" CRLF |
|
20 |
+ "m=audio 21964 RTP/AVP 0 101" CRLF |
|
21 |
+ "a=sendrecv" CRLF |
|
22 |
+ "a=ptime:20" CRLF |
|
23 |
+ "a=rtpmap:0 PCMU/8000" CRLF |
|
24 |
+ "a=rtpmap:101 telephone-event/8000" CRLF |
|
25 |
+ "a=fmtp:101 0-15" CRLF ; |
|
26 |
+ |
|
27 |
+ fct_chk(!s.parse(sdp.c_str())); |
|
28 |
+ fct_chk(s.version==0); |
|
29 |
+ fct_chk(s.origin.user == "-"); |
|
30 |
+ fct_chk(s.origin.sessId == 3615077380); |
|
31 |
+ fct_chk(s.origin.sessV == 3615077398); |
|
32 |
+ fct_chk(s.origin.conn.address == "178.66.14.5"); |
|
33 |
+ fct_chk(s.origin.conn.network == NT_IN); |
|
34 |
+ fct_chk(s.origin.conn.addrType == AT_V4); |
|
35 |
+ |
|
36 |
+ fct_chk(s.conn.address == "178.66.14.5"); |
|
37 |
+ fct_chk(s.conn.network == NT_IN); |
|
38 |
+ fct_chk(s.conn.addrType == AT_V4); |
|
39 |
+ |
|
40 |
+ fct_chk(s.media.size() == 1); |
|
41 |
+ fct_chk(s.media[0].type == MT_AUDIO); |
|
42 |
+ fct_chk(s.media[0].port == 21964); |
|
43 |
+ fct_chk(s.media[0].transport == TP_RTPAVP); |
|
44 |
+ fct_chk(s.media[0].payloads.size()==2); |
|
45 |
+ fct_chk(s.media[0].payloads[0].payload_type==0); |
|
46 |
+ fct_chk(s.media[0].payloads[1].payload_type==101); |
|
47 |
+ fct_chk(s.media[0].payloads[0].encoding_name=="PCMU"); |
|
48 |
+ fct_chk(s.media[0].payloads[1].encoding_name=="telephone-event"); |
|
49 |
+ } FCT_TEST_END(); |
|
50 |
+ |
|
51 |
+ FCT_TEST_BGN(sdp_LF_no_CRLF) { |
|
52 |
+ AmSdp s; |
|
53 |
+ string sdp = |
|
54 |
+ "v=0" LF |
|
55 |
+ "o=- 3615077380 3615077398 IN IP4 178.66.14.5" LF |
|
56 |
+ "s=-" LF |
|
57 |
+ "c=IN IP4 178.66.14.5" LF |
|
58 |
+ "t=0 0" LF |
|
59 |
+ "m=audio 21964 RTP/AVP 0 101" LF |
|
60 |
+ "a=sendrecv" LF |
|
61 |
+ "a=ptime:20" LF |
|
62 |
+ "a=rtpmap:0 PCMU/8000" LF |
|
63 |
+ "a=rtpmap:101 telephone-event/8000" LF |
|
64 |
+ "a=fmtp:101 0-15" LF ; |
|
65 |
+ |
|
66 |
+ fct_chk(!s.parse(sdp.c_str())); |
|
67 |
+ fct_chk(s.version==0); |
|
68 |
+ fct_chk(s.origin.user == "-"); |
|
69 |
+ fct_chk(s.origin.sessId == 3615077380); |
|
70 |
+ fct_chk(s.origin.sessV == 3615077398); |
|
71 |
+ fct_chk(s.origin.conn.address == "178.66.14.5"); |
|
72 |
+ fct_chk(s.origin.conn.network == NT_IN); |
|
73 |
+ fct_chk(s.origin.conn.addrType == AT_V4); |
|
74 |
+ |
|
75 |
+ fct_chk(s.conn.address == "178.66.14.5"); |
|
76 |
+ fct_chk(s.conn.network == NT_IN); |
|
77 |
+ fct_chk(s.conn.addrType == AT_V4); |
|
78 |
+ |
|
79 |
+ fct_chk(s.media.size() == 1); |
|
80 |
+ fct_chk(s.media[0].type == MT_AUDIO); |
|
81 |
+ fct_chk(s.media[0].port == 21964); |
|
82 |
+ fct_chk(s.media[0].transport == TP_RTPAVP); |
|
83 |
+ fct_chk(s.media[0].payloads.size()==2); |
|
84 |
+ fct_chk(s.media[0].payloads[0].payload_type==0); |
|
85 |
+ fct_chk(s.media[0].payloads[1].payload_type==101); |
|
86 |
+ fct_chk(s.media[0].payloads[0].encoding_name=="PCMU"); |
|
87 |
+ fct_chk(s.media[0].payloads[1].encoding_name=="telephone-event"); |
|
88 |
+ } FCT_TEST_END(); |
|
89 |
+ |
|
90 |
+} FCTMF_SUITE_END(); |