winlin

support ecma array. connect app response.

@@ -54,6 +54,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -54,6 +54,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
54 #define RTMP_AMF0_Invalid 0x3F 54 #define RTMP_AMF0_Invalid 0x3F
55 55
56 int srs_amf0_get_object_eof_size(); 56 int srs_amf0_get_object_eof_size();
  57 +int srs_amf0_get_any_size(SrsAmf0Any* value);
57 int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&); 58 int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&);
58 int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*); 59 int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*);
59 int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value); 60 int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value);
@@ -88,43 +89,51 @@ bool SrsAmf0Any::is_object() @@ -88,43 +89,51 @@ bool SrsAmf0Any::is_object()
88 return marker == RTMP_AMF0_Object; 89 return marker == RTMP_AMF0_Object;
89 } 90 }
90 91
  92 +bool SrsAmf0Any::is_ecma_array()
  93 +{
  94 + return marker == RTMP_AMF0_EcmaArray;
  95 +}
  96 +
91 bool SrsAmf0Any::is_object_eof() 97 bool SrsAmf0Any::is_object_eof()
92 { 98 {
93 return marker == RTMP_AMF0_ObjectEnd; 99 return marker == RTMP_AMF0_ObjectEnd;
94 } 100 }
95 101
96 -SrsAmf0String::SrsAmf0String() 102 +SrsAmf0String::SrsAmf0String(const char* _value)
97 { 103 {
98 marker = RTMP_AMF0_String; 104 marker = RTMP_AMF0_String;
  105 + if (_value) {
  106 + value = _value;
  107 + }
99 } 108 }
100 109
101 SrsAmf0String::~SrsAmf0String() 110 SrsAmf0String::~SrsAmf0String()
102 { 111 {
103 } 112 }
104 113
105 -SrsAmf0Boolean::SrsAmf0Boolean() 114 +SrsAmf0Boolean::SrsAmf0Boolean(bool _value)
106 { 115 {
107 marker = RTMP_AMF0_Boolean; 116 marker = RTMP_AMF0_Boolean;
108 - value = false; 117 + value = _value;
109 } 118 }
110 119
111 SrsAmf0Boolean::~SrsAmf0Boolean() 120 SrsAmf0Boolean::~SrsAmf0Boolean()
112 { 121 {
113 } 122 }
114 123
115 -SrsAmf0Number::SrsAmf0Number() 124 +SrsAmf0Number::SrsAmf0Number(double _value)
116 { 125 {
117 marker = RTMP_AMF0_Number; 126 marker = RTMP_AMF0_Number;
118 - value = 0; 127 + value = _value;
119 } 128 }
120 129
121 SrsAmf0Number::~SrsAmf0Number() 130 SrsAmf0Number::~SrsAmf0Number()
122 { 131 {
123 - marker = RTMP_AMF0_ObjectEnd;  
124 } 132 }
125 133
126 SrsAmf0ObjectEOF::SrsAmf0ObjectEOF() 134 SrsAmf0ObjectEOF::SrsAmf0ObjectEOF()
127 { 135 {
  136 + marker = RTMP_AMF0_ObjectEnd;
128 utf8_empty = 0x00; 137 utf8_empty = 0x00;
129 } 138 }
130 139
@@ -173,6 +182,47 @@ SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name) @@ -173,6 +182,47 @@ SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name)
173 return prop; 182 return prop;
174 } 183 }
175 184
  185 +SrsASrsAmf0EcmaArray::SrsASrsAmf0EcmaArray()
  186 +{
  187 + marker = RTMP_AMF0_EcmaArray;
  188 +}
  189 +
  190 +SrsASrsAmf0EcmaArray::~SrsASrsAmf0EcmaArray()
  191 +{
  192 + std::map<std::string, SrsAmf0Any*>::iterator it;
  193 + for (it = properties.begin(); it != properties.end(); ++it) {
  194 + SrsAmf0Any* any = it->second;
  195 + delete any;
  196 + }
  197 + properties.clear();
  198 +}
  199 +
  200 +SrsAmf0Any* SrsASrsAmf0EcmaArray::get_property(std::string name)
  201 +{
  202 + std::map<std::string, SrsAmf0Any*>::iterator it;
  203 +
  204 + if ((it = properties.find(name)) == properties.end()) {
  205 + return NULL;
  206 + }
  207 +
  208 + return it->second;
  209 +}
  210 +
  211 +SrsAmf0Any* SrsASrsAmf0EcmaArray::ensure_property_string(std::string name)
  212 +{
  213 + SrsAmf0Any* prop = get_property(name);
  214 +
  215 + if (!prop) {
  216 + return NULL;
  217 + }
  218 +
  219 + if (!prop->is_string()) {
  220 + return NULL;
  221 + }
  222 +
  223 + return prop;
  224 +}
  225 +
176 int srs_amf0_read_utf8(SrsStream* stream, std::string& value) 226 int srs_amf0_read_utf8(SrsStream* stream, std::string& value)
177 { 227 {
178 int ret = ERROR_SUCCESS; 228 int ret = ERROR_SUCCESS;
@@ -481,6 +531,14 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value) @@ -481,6 +531,14 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)
481 value = p; 531 value = p;
482 return ret; 532 return ret;
483 } 533 }
  534 + case RTMP_AMF0_EcmaArray: {
  535 + SrsASrsAmf0EcmaArray* p = NULL;
  536 + if ((ret = srs_amf0_read_ecma_array(stream, p)) != ERROR_SUCCESS) {
  537 + return ret;
  538 + }
  539 + value = p;
  540 + return ret;
  541 + }
484 case RTMP_AMF0_Invalid: 542 case RTMP_AMF0_Invalid:
485 default: { 543 default: {
486 ret = ERROR_RTMP_AMF0_INVALID; 544 ret = ERROR_RTMP_AMF0_INVALID;
@@ -518,6 +576,10 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value) @@ -518,6 +576,10 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)
518 SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value); 576 SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value);
519 return srs_amf0_write_object(stream, p); 577 return srs_amf0_write_object(stream, p);
520 } 578 }
  579 + case RTMP_AMF0_EcmaArray: {
  580 + SrsASrsAmf0EcmaArray* p = srs_amf0_convert<SrsASrsAmf0EcmaArray>(value);
  581 + return srs_amf0_write_ecma_array(stream, p);
  582 + }
521 case RTMP_AMF0_Invalid: 583 case RTMP_AMF0_Invalid:
522 default: { 584 default: {
523 ret = ERROR_RTMP_AMF0_INVALID; 585 ret = ERROR_RTMP_AMF0_INVALID;
@@ -529,6 +591,52 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value) @@ -529,6 +591,52 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)
529 return ret; 591 return ret;
530 } 592 }
531 593
  594 +int srs_amf0_get_any_size(SrsAmf0Any* value)
  595 +{
  596 + if (!value) {
  597 + return 0;
  598 + }
  599 +
  600 + int size = 0;
  601 +
  602 + switch (value->marker) {
  603 + case RTMP_AMF0_String: {
  604 + SrsAmf0String* p = srs_amf0_convert<SrsAmf0String>(value);
  605 + size += srs_amf0_get_string_size(p->value);
  606 + break;
  607 + }
  608 + case RTMP_AMF0_Boolean: {
  609 + size += srs_amf0_get_boolean_size();
  610 + break;
  611 + }
  612 + case RTMP_AMF0_Number: {
  613 + size += srs_amf0_get_number_size();
  614 + break;
  615 + }
  616 + case RTMP_AMF0_ObjectEnd: {
  617 + size += srs_amf0_get_object_eof_size();
  618 + break;
  619 + }
  620 + case RTMP_AMF0_Object: {
  621 + SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value);
  622 + size += srs_amf0_get_object_size(p);
  623 + break;
  624 + }
  625 + case RTMP_AMF0_EcmaArray: {
  626 + SrsASrsAmf0EcmaArray* p = srs_amf0_convert<SrsASrsAmf0EcmaArray>(value);
  627 + size += srs_amf0_get_ecma_array_size(p);
  628 + break;
  629 + }
  630 + default: {
  631 + // TOOD: other AMF0 types.
  632 + srs_warn("ignore unkown AMF0 type size.");
  633 + break;
  634 + }
  635 + }
  636 +
  637 + return size;
  638 +}
  639 +
532 int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value) 640 int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value)
533 { 641 {
534 int ret = ERROR_SUCCESS; 642 int ret = ERROR_SUCCESS;
@@ -699,6 +807,125 @@ int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value) @@ -699,6 +807,125 @@ int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value)
699 return ret; 807 return ret;
700 } 808 }
701 809
  810 +int srs_amf0_read_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray*& value)
  811 +{
  812 + int ret = ERROR_SUCCESS;
  813 +
  814 + // marker
  815 + if (!stream->require(1)) {
  816 + ret = ERROR_RTMP_AMF0_DECODE;
  817 + srs_error("amf0 read ecma_array marker failed. ret=%d", ret);
  818 + return ret;
  819 + }
  820 +
  821 + char marker = stream->read_1bytes();
  822 + if (marker != RTMP_AMF0_EcmaArray) {
  823 + ret = ERROR_RTMP_AMF0_DECODE;
  824 + srs_error("amf0 check ecma_array marker failed. "
  825 + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret);
  826 + return ret;
  827 + }
  828 + srs_verbose("amf0 read ecma_array marker success");
  829 +
  830 + // count
  831 + if (!stream->require(4)) {
  832 + ret = ERROR_RTMP_AMF0_DECODE;
  833 + srs_error("amf0 read ecma_array count failed. ret=%d", ret);
  834 + return ret;
  835 + }
  836 +
  837 + int32_t count = stream->read_4bytes();
  838 + srs_verbose("amf0 read ecma_array count success. count=%d", count);
  839 +
  840 + // value
  841 + value = new SrsASrsAmf0EcmaArray();
  842 + value->count = count;
  843 +
  844 + while (!stream->empty()) {
  845 + // property-name: utf8 string
  846 + std::string property_name;
  847 + if ((ret =srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) {
  848 + srs_error("amf0 ecma_array read property name failed. ret=%d", ret);
  849 + return ret;
  850 + }
  851 + // property-value: any
  852 + SrsAmf0Any* property_value = NULL;
  853 + if ((ret = srs_amf0_read_any(stream, property_value)) != ERROR_SUCCESS) {
  854 + srs_error("amf0 ecma_array read property_value failed. "
  855 + "name=%s, ret=%d", property_name.c_str(), ret);
  856 + return ret;
  857 + }
  858 +
  859 + // AMF0 Object EOF.
  860 + if (property_name.empty() || !property_value || property_value->is_object_eof()) {
  861 + if (property_value) {
  862 + delete property_value;
  863 + }
  864 + srs_info("amf0 read ecma_array EOF.");
  865 + break;
  866 + }
  867 +
  868 + // add property
  869 + value->properties[property_name] = property_value;
  870 + }
  871 +
  872 + return ret;
  873 +}
  874 +int srs_amf0_write_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray* value)
  875 +{
  876 + int ret = ERROR_SUCCESS;
  877 +
  878 + srs_assert(value != NULL);
  879 +
  880 + // marker
  881 + if (!stream->require(1)) {
  882 + ret = ERROR_RTMP_AMF0_ENCODE;
  883 + srs_error("amf0 write ecma_array marker failed. ret=%d", ret);
  884 + return ret;
  885 + }
  886 +
  887 + stream->write_1bytes(RTMP_AMF0_EcmaArray);
  888 + srs_verbose("amf0 write ecma_array marker success");
  889 +
  890 + // count
  891 + if (!stream->require(4)) {
  892 + ret = ERROR_RTMP_AMF0_ENCODE;
  893 + srs_error("amf0 write ecma_array count failed. ret=%d", ret);
  894 + return ret;
  895 + }
  896 +
  897 + stream->write_4bytes(value->count);
  898 + srs_verbose("amf0 write ecma_array count success. count=%d", value->count);
  899 +
  900 + // value
  901 + std::map<std::string, SrsAmf0Any*>::iterator it;
  902 + for (it = value->properties.begin(); it != value->properties.end(); ++it) {
  903 + std::string name = it->first;
  904 + SrsAmf0Any* any = it->second;
  905 +
  906 + if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) {
  907 + srs_error("write ecma_array property name failed. ret=%d", ret);
  908 + return ret;
  909 + }
  910 +
  911 + if ((ret = srs_amf0_write_any(stream, any)) != ERROR_SUCCESS) {
  912 + srs_error("write ecma_array property value failed. ret=%d", ret);
  913 + return ret;
  914 + }
  915 +
  916 + srs_verbose("write amf0 property success. name=%s", name.c_str());
  917 + }
  918 +
  919 + if ((ret = srs_amf0_write_object_eof(stream, &value->eof)) != ERROR_SUCCESS) {
  920 + srs_error("write ecma_array eof failed. ret=%d", ret);
  921 + return ret;
  922 + }
  923 +
  924 + srs_verbose("write ecma_array object success.");
  925 +
  926 + return ret;
  927 +}
  928 +
702 int srs_amf0_get_utf8_size(std::string value) 929 int srs_amf0_get_utf8_size(std::string value)
703 { 930 {
704 return 2 + value.length(); 931 return 2 + value.length();
@@ -733,21 +960,29 @@ int srs_amf0_get_object_size(SrsAmf0Object* obj) @@ -733,21 +960,29 @@ int srs_amf0_get_object_size(SrsAmf0Object* obj)
733 SrsAmf0Any* value = it->second; 960 SrsAmf0Any* value = it->second;
734 961
735 size += srs_amf0_get_utf8_size(name); 962 size += srs_amf0_get_utf8_size(name);
  963 + size += srs_amf0_get_any_size(value);
  964 + }
  965 +
  966 + size += srs_amf0_get_object_eof_size();
  967 +
  968 + return size;
  969 +}
  970 +
  971 +int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr)
  972 +{
  973 + if (!arr) {
  974 + return 0;
  975 + }
  976 +
  977 + int size = 1 + 4;
  978 +
  979 + std::map<std::string, SrsAmf0Any*>::iterator it;
  980 + for (it = arr->properties.begin(); it != arr->properties.end(); ++it) {
  981 + std::string name = it->first;
  982 + SrsAmf0Any* value = it->second;
736 983
737 - if (value->is_boolean()) {  
738 - size += srs_amf0_get_boolean_size();  
739 - } else if (value->is_number()) {  
740 - size += srs_amf0_get_number_size();  
741 - } else if (value->is_string()) {  
742 - SrsAmf0String* p = srs_amf0_convert<SrsAmf0String>(value);  
743 - size += srs_amf0_get_string_size(p->value);  
744 - } else if (value->is_object()) {  
745 - SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value);  
746 - size += srs_amf0_get_object_size(p);  
747 - } else {  
748 - // TOOD: other AMF0 types.  
749 - srs_warn("ignore unkown AMF0 type size.");  
750 - } 984 + size += srs_amf0_get_utf8_size(name);
  985 + size += srs_amf0_get_any_size(value);
751 } 986 }
752 987
753 size += srs_amf0_get_object_eof_size(); 988 size += srs_amf0_get_object_eof_size();
@@ -56,6 +56,7 @@ struct SrsAmf0Any @@ -56,6 +56,7 @@ struct SrsAmf0Any
56 virtual bool is_number(); 56 virtual bool is_number();
57 virtual bool is_object(); 57 virtual bool is_object();
58 virtual bool is_object_eof(); 58 virtual bool is_object_eof();
  59 + virtual bool is_ecma_array();
59 }; 60 };
60 61
61 /** 62 /**
@@ -68,7 +69,7 @@ struct SrsAmf0String : public SrsAmf0Any @@ -68,7 +69,7 @@ struct SrsAmf0String : public SrsAmf0Any
68 { 69 {
69 std::string value; 70 std::string value;
70 71
71 - SrsAmf0String(); 72 + SrsAmf0String(const char* _value = NULL);
72 virtual ~SrsAmf0String(); 73 virtual ~SrsAmf0String();
73 }; 74 };
74 75
@@ -83,7 +84,7 @@ struct SrsAmf0Boolean : public SrsAmf0Any @@ -83,7 +84,7 @@ struct SrsAmf0Boolean : public SrsAmf0Any
83 { 84 {
84 bool value; 85 bool value;
85 86
86 - SrsAmf0Boolean(); 87 + SrsAmf0Boolean(bool _value = false);
87 virtual ~SrsAmf0Boolean(); 88 virtual ~SrsAmf0Boolean();
88 }; 89 };
89 90
@@ -97,7 +98,7 @@ struct SrsAmf0Number : public SrsAmf0Any @@ -97,7 +98,7 @@ struct SrsAmf0Number : public SrsAmf0Any
97 { 98 {
98 double value; 99 double value;
99 100
100 - SrsAmf0Number(); 101 + SrsAmf0Number(double _value = 0.0);
101 virtual ~SrsAmf0Number(); 102 virtual ~SrsAmf0Number();
102 }; 103 };
103 104
@@ -132,6 +133,25 @@ struct SrsAmf0Object : public SrsAmf0Any @@ -132,6 +133,25 @@ struct SrsAmf0Object : public SrsAmf0Any
132 }; 133 };
133 134
134 /** 135 /**
  136 +* 2.10 ECMA Array Type
  137 +* ecma-array-type = associative-count *(object-property)
  138 +* associative-count = U32
  139 +* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
  140 +*/
  141 +struct SrsASrsAmf0EcmaArray : public SrsAmf0Any
  142 +{
  143 + int32_t count;
  144 + std::map<std::string, SrsAmf0Any*> properties;
  145 + SrsAmf0ObjectEOF eof;
  146 +
  147 + SrsASrsAmf0EcmaArray();
  148 + virtual ~SrsASrsAmf0EcmaArray();
  149 +
  150 + virtual SrsAmf0Any* get_property(std::string name);
  151 + virtual SrsAmf0Any* ensure_property_string(std::string name);
  152 +};
  153 +
  154 +/**
135 * read amf0 utf8 string from stream. 155 * read amf0 utf8 string from stream.
136 * 1.3.1 Strings and UTF-8 156 * 1.3.1 Strings and UTF-8
137 * UTF-8 = U16 *(UTF8-char) 157 * UTF-8 = U16 *(UTF8-char)
@@ -177,6 +197,16 @@ extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value); @@ -177,6 +197,16 @@ extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value);
177 extern int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value); 197 extern int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value);
178 198
179 /** 199 /**
  200 +* read amf0 object from stream.
  201 +* 2.10 ECMA Array Type
  202 +* ecma-array-type = associative-count *(object-property)
  203 +* associative-count = U32
  204 +* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
  205 +*/
  206 +extern int srs_amf0_read_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray*& value);
  207 +extern int srs_amf0_write_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray* value);
  208 +
  209 +/**
180 * get amf0 objects size. 210 * get amf0 objects size.
181 */ 211 */
182 extern int srs_amf0_get_utf8_size(std::string value); 212 extern int srs_amf0_get_utf8_size(std::string value);
@@ -184,7 +214,8 @@ extern int srs_amf0_get_string_size(std::string value); @@ -184,7 +214,8 @@ extern int srs_amf0_get_string_size(std::string value);
184 extern int srs_amf0_get_number_size(); 214 extern int srs_amf0_get_number_size();
185 extern int srs_amf0_get_boolean_size(); 215 extern int srs_amf0_get_boolean_size();
186 extern int srs_amf0_get_object_size(SrsAmf0Object* obj); 216 extern int srs_amf0_get_object_size(SrsAmf0Object* obj);
187 - 217 +extern int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr);
  218 +
188 /** 219 /**
189 * convert the any to specified object. 220 * convert the any to specified object.
190 * @return T*, the converted object. never NULL. 221 * @return T*, the converted object. never NULL.
@@ -92,6 +92,12 @@ int SrsClient::do_cycle() @@ -92,6 +92,12 @@ int SrsClient::do_cycle()
92 return ret; 92 return ret;
93 } 93 }
94 srs_verbose("set peer bandwidth success"); 94 srs_verbose("set peer bandwidth success");
  95 +
  96 + if ((ret = rtmp->response_connect_app()) != ERROR_SUCCESS) {
  97 + srs_error("response connect app failed. ret=%d", ret);
  98 + return ret;
  99 + }
  100 + srs_verbose("response connect app success");
95 101
96 return ret; 102 return ret;
97 } 103 }
@@ -1061,8 +1061,8 @@ SrsConnectAppResPacket::SrsConnectAppResPacket() @@ -1061,8 +1061,8 @@ SrsConnectAppResPacket::SrsConnectAppResPacket()
1061 { 1061 {
1062 command_name = RTMP_AMF0_COMMAND_CONNECT; 1062 command_name = RTMP_AMF0_COMMAND_CONNECT;
1063 transaction_id = 1; 1063 transaction_id = 1;
1064 - props = NULL;  
1065 - info = NULL; 1064 + props = new SrsAmf0Object();
  1065 + info = new SrsAmf0Object();
1066 } 1066 }
1067 1067
1068 SrsConnectAppResPacket::~SrsConnectAppResPacket() 1068 SrsConnectAppResPacket::~SrsConnectAppResPacket()
@@ -30,6 +30,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -30,6 +30,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #include <srs_core_auto_free.hpp> 30 #include <srs_core_auto_free.hpp>
31 #include <srs_core_amf0.hpp> 31 #include <srs_core_amf0.hpp>
32 32
  33 +/**
  34 +* the signature for packets to client.
  35 +*/
  36 +#define RTMP_SIG_FMS_VER "3,5,3,888"
  37 +#define RTMP_SIG_AMF0_VER 3
  38 +#define RTMP_SIG_SRS_NAME "srs(simple rtmp server)"
  39 +#define RTMP_SIG_SRS_URL "https://github.com/winlinvip/simple-rtmp-server"
  40 +#define RTMP_SIG_SRS_VERSION "0.1"
  41 +
33 int SrsRequest::discovery_app() 42 int SrsRequest::discovery_app()
34 { 43 {
35 int ret = ERROR_SUCCESS; 44 int ret = ERROR_SUCCESS;
@@ -205,3 +214,39 @@ int SrsRtmp::set_peer_bandwidth(int bandwidth, int type) @@ -205,3 +214,39 @@ int SrsRtmp::set_peer_bandwidth(int bandwidth, int type)
205 return ret; 214 return ret;
206 } 215 }
207 216
  217 +int SrsRtmp::response_connect_app()
  218 +{
  219 + int ret = ERROR_SUCCESS;
  220 +
  221 + SrsMessage* msg = new SrsMessage();
  222 + SrsConnectAppResPacket* pkt = new SrsConnectAppResPacket();
  223 +
  224 + pkt->command_name = "_result";
  225 +
  226 + pkt->props->properties["fmsVer"] = new SrsAmf0String("FMS/"RTMP_SIG_FMS_VER);
  227 + pkt->props->properties["capabilities"] = new SrsAmf0Number(123);
  228 + pkt->props->properties["mode"] = new SrsAmf0Number(1);
  229 +
  230 + pkt->info->properties["level"] = new SrsAmf0String("status");
  231 + pkt->info->properties["code"] = new SrsAmf0String("NetConnection.Connect.Success");
  232 + pkt->info->properties["description"] = new SrsAmf0String("Connection succeeded");
  233 + pkt->info->properties["objectEncoding"] = new SrsAmf0Number(RTMP_SIG_AMF0_VER);
  234 + SrsASrsAmf0EcmaArray* data = new SrsASrsAmf0EcmaArray();
  235 + pkt->info->properties["data"] = data;
  236 +
  237 + data->properties["version"] = new SrsAmf0String(RTMP_SIG_FMS_VER);
  238 + data->properties["server"] = new SrsAmf0String(RTMP_SIG_SRS_NAME);
  239 + data->properties["srs_url"] = new SrsAmf0String(RTMP_SIG_SRS_URL);
  240 + data->properties["srs_version"] = new SrsAmf0String(RTMP_SIG_SRS_VERSION);
  241 +
  242 + msg->set_packet(pkt);
  243 +
  244 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  245 + srs_error("send connect app response message failed. ret=%d", ret);
  246 + return ret;
  247 + }
  248 + srs_info("send connect app response message success.");
  249 +
  250 + return ret;
  251 +}
  252 +
@@ -79,6 +79,7 @@ public: @@ -79,6 +79,7 @@ public:
79 * using the Limit type field. 79 * using the Limit type field.
80 */ 80 */
81 virtual int set_peer_bandwidth(int bandwidth, int type); 81 virtual int set_peer_bandwidth(int bandwidth, int type);
  82 + virtual int response_connect_app();
82 }; 83 };
83 84
84 #endif 85 #endif