winlin

support encode amf0 packet, connect app response packet

@@ -53,6 +53,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -53,6 +53,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
53 // User defined 53 // User defined
54 #define RTMP_AMF0_Invalid 0x3F 54 #define RTMP_AMF0_Invalid 0x3F
55 55
  56 +int srs_amf0_get_object_eof_size();
  57 +int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&);
  58 +int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*);
  59 +int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value);
  60 +int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value);
  61 +
56 SrsAmf0Any::SrsAmf0Any() 62 SrsAmf0Any::SrsAmf0Any()
57 { 63 {
58 marker = RTMP_AMF0_Invalid; 64 marker = RTMP_AMF0_Invalid;
@@ -167,8 +173,6 @@ SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name) @@ -167,8 +173,6 @@ SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name)
167 return prop; 173 return prop;
168 } 174 }
169 175
170 -int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&);  
171 -  
172 int srs_amf0_read_utf8(SrsStream* stream, std::string& value) 176 int srs_amf0_read_utf8(SrsStream* stream, std::string& value)
173 { 177 {
174 int ret = ERROR_SUCCESS; 178 int ret = ERROR_SUCCESS;
@@ -213,6 +217,36 @@ int srs_amf0_read_utf8(SrsStream* stream, std::string& value) @@ -213,6 +217,36 @@ int srs_amf0_read_utf8(SrsStream* stream, std::string& value)
213 217
214 return ret; 218 return ret;
215 } 219 }
  220 +int srs_amf0_write_utf8(SrsStream* stream, std::string value)
  221 +{
  222 + int ret = ERROR_SUCCESS;
  223 +
  224 + // len
  225 + if (!stream->require(2)) {
  226 + ret = ERROR_RTMP_AMF0_ENCODE;
  227 + srs_error("amf0 write string length failed. ret=%d", ret);
  228 + return ret;
  229 + }
  230 + stream->write_2bytes(value.length());
  231 + srs_verbose("amf0 write string length success. len=%d", (int)value.length());
  232 +
  233 + // empty string
  234 + if (value.length() <= 0) {
  235 + srs_verbose("amf0 write empty string. ret=%d", ret);
  236 + return ret;
  237 + }
  238 +
  239 + // data
  240 + if (!stream->require(value.length())) {
  241 + ret = ERROR_RTMP_AMF0_ENCODE;
  242 + srs_error("amf0 write string data failed. ret=%d", ret);
  243 + return ret;
  244 + }
  245 + stream->write_string(value);
  246 + srs_verbose("amf0 write string data success. str=%s", value.c_str());
  247 +
  248 + return ret;
  249 +}
216 250
217 int srs_amf0_read_string(SrsStream* stream, std::string& value) 251 int srs_amf0_read_string(SrsStream* stream, std::string& value)
218 { 252 {
@@ -237,6 +271,23 @@ int srs_amf0_read_string(SrsStream* stream, std::string& value) @@ -237,6 +271,23 @@ int srs_amf0_read_string(SrsStream* stream, std::string& value)
237 return srs_amf0_read_utf8(stream, value); 271 return srs_amf0_read_utf8(stream, value);
238 } 272 }
239 273
  274 +int srs_amf0_write_string(SrsStream* stream, std::string value)
  275 +{
  276 + int ret = ERROR_SUCCESS;
  277 +
  278 + // marker
  279 + if (!stream->require(1)) {
  280 + ret = ERROR_RTMP_AMF0_ENCODE;
  281 + srs_error("amf0 write string marker failed. ret=%d", ret);
  282 + return ret;
  283 + }
  284 +
  285 + stream->write_1bytes(RTMP_AMF0_String);
  286 + srs_verbose("amf0 write string marker success");
  287 +
  288 + return srs_amf0_write_utf8(stream, value);
  289 +}
  290 +
240 int srs_amf0_read_boolean(SrsStream* stream, bool& value) 291 int srs_amf0_read_boolean(SrsStream* stream, bool& value)
241 { 292 {
242 int ret = ERROR_SUCCESS; 293 int ret = ERROR_SUCCESS;
@@ -274,6 +325,36 @@ int srs_amf0_read_boolean(SrsStream* stream, bool& value) @@ -274,6 +325,36 @@ int srs_amf0_read_boolean(SrsStream* stream, bool& value)
274 325
275 return ret; 326 return ret;
276 } 327 }
  328 +int srs_amf0_write_boolean(SrsStream* stream, bool value)
  329 +{
  330 + int ret = ERROR_SUCCESS;
  331 +
  332 + // marker
  333 + if (!stream->require(1)) {
  334 + ret = ERROR_RTMP_AMF0_ENCODE;
  335 + srs_error("amf0 write bool marker failed. ret=%d", ret);
  336 + return ret;
  337 + }
  338 + stream->write_1bytes(RTMP_AMF0_Boolean);
  339 + srs_verbose("amf0 write bool marker success");
  340 +
  341 + // value
  342 + if (!stream->require(1)) {
  343 + ret = ERROR_RTMP_AMF0_ENCODE;
  344 + srs_error("amf0 write bool value failed. ret=%d", ret);
  345 + return ret;
  346 + }
  347 +
  348 + if (value) {
  349 + stream->write_1bytes(0x01);
  350 + } else {
  351 + stream->write_1bytes(0x00);
  352 + }
  353 +
  354 + srs_verbose("amf0 write bool value success. value=%d", value);
  355 +
  356 + return ret;
  357 +}
277 358
278 int srs_amf0_read_number(SrsStream* stream, double& value) 359 int srs_amf0_read_number(SrsStream* stream, double& value)
279 { 360 {
@@ -309,6 +390,35 @@ int srs_amf0_read_number(SrsStream* stream, double& value) @@ -309,6 +390,35 @@ int srs_amf0_read_number(SrsStream* stream, double& value)
309 390
310 return ret; 391 return ret;
311 } 392 }
  393 +int srs_amf0_write_number(SrsStream* stream, double value)
  394 +{
  395 + int ret = ERROR_SUCCESS;
  396 +
  397 + // marker
  398 + if (!stream->require(1)) {
  399 + ret = ERROR_RTMP_AMF0_ENCODE;
  400 + srs_error("amf0 write number marker failed. ret=%d", ret);
  401 + return ret;
  402 + }
  403 +
  404 + stream->write_1bytes(RTMP_AMF0_Number);
  405 + srs_verbose("amf0 write number marker success");
  406 +
  407 + // value
  408 + if (!stream->require(8)) {
  409 + ret = ERROR_RTMP_AMF0_ENCODE;
  410 + srs_error("amf0 write number value failed. ret=%d", ret);
  411 + return ret;
  412 + }
  413 +
  414 + int64_t temp = 0x00;
  415 + memcpy(&temp, &value, 8);
  416 + stream->write_8bytes(temp);
  417 +
  418 + srs_verbose("amf0 write number value success. value=%.2f", value);
  419 +
  420 + return ret;
  421 +}
312 422
313 int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value) 423 int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)
314 { 424 {
@@ -381,11 +491,66 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value) @@ -381,11 +491,66 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)
381 491
382 return ret; 492 return ret;
383 } 493 }
  494 +int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)
  495 +{
  496 + int ret = ERROR_SUCCESS;
  497 +
  498 + srs_assert(value != NULL);
  499 +
  500 + switch (value->marker) {
  501 + case RTMP_AMF0_String: {
  502 + std::string data = srs_amf0_convert<SrsAmf0String>(value)->value;
  503 + return srs_amf0_write_string(stream, data);
  504 + }
  505 + case RTMP_AMF0_Boolean: {
  506 + bool data = srs_amf0_convert<SrsAmf0Boolean>(value)->value;
  507 + return srs_amf0_write_boolean(stream, data);
  508 + }
  509 + case RTMP_AMF0_Number: {
  510 + double data = srs_amf0_convert<SrsAmf0Number>(value)->value;
  511 + return srs_amf0_write_number(stream, data);
  512 + }
  513 + case RTMP_AMF0_ObjectEnd: {
  514 + SrsAmf0ObjectEOF* p = srs_amf0_convert<SrsAmf0ObjectEOF>(value);
  515 + return srs_amf0_write_object_eof(stream, p);
  516 + }
  517 + case RTMP_AMF0_Object: {
  518 + SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value);
  519 + return srs_amf0_write_object(stream, p);
  520 + }
  521 + case RTMP_AMF0_Invalid:
  522 + default: {
  523 + ret = ERROR_RTMP_AMF0_INVALID;
  524 + srs_error("invalid amf0 message type. marker=%#x, ret=%d", value->marker, ret);
  525 + return ret;
  526 + }
  527 + }
  528 +
  529 + return ret;
  530 +}
384 531
385 int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value) 532 int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value)
386 { 533 {
387 int ret = ERROR_SUCCESS; 534 int ret = ERROR_SUCCESS;
388 535
  536 + // auto skip -2 to read the object eof.
  537 + srs_assert(stream->pos() >= 2);
  538 + stream->skip(-2);
  539 +
  540 + // value
  541 + if (!stream->require(2)) {
  542 + ret = ERROR_RTMP_AMF0_DECODE;
  543 + srs_error("amf0 read object eof value failed. ret=%d", ret);
  544 + return ret;
  545 + }
  546 + int16_t temp = stream->read_2bytes();
  547 + if (temp != 0x00) {
  548 + ret = ERROR_RTMP_AMF0_DECODE;
  549 + srs_error("amf0 read object eof value check failed. "
  550 + "must be 0x00, actual is %#x, ret=%d", temp, ret);
  551 + return ret;
  552 + }
  553 +
389 // marker 554 // marker
390 if (!stream->require(1)) { 555 if (!stream->require(1)) {
391 ret = ERROR_RTMP_AMF0_DECODE; 556 ret = ERROR_RTMP_AMF0_DECODE;
@@ -402,9 +567,36 @@ int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value) @@ -402,9 +567,36 @@ int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value)
402 } 567 }
403 srs_verbose("amf0 read object eof marker success"); 568 srs_verbose("amf0 read object eof marker success");
404 569
405 - // value  
406 value = new SrsAmf0ObjectEOF(); 570 value = new SrsAmf0ObjectEOF();
407 - srs_verbose("amf0 read object eof marker success"); 571 + srs_verbose("amf0 read object eof success");
  572 +
  573 + return ret;
  574 +}
  575 +int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF* value)
  576 +{
  577 + int ret = ERROR_SUCCESS;
  578 +
  579 + srs_assert(value != NULL);
  580 +
  581 + // value
  582 + if (!stream->require(2)) {
  583 + ret = ERROR_RTMP_AMF0_ENCODE;
  584 + srs_error("amf0 write object eof value failed. ret=%d", ret);
  585 + return ret;
  586 + }
  587 + stream->write_2bytes(0x00);
  588 + srs_verbose("amf0 write object eof value success");
  589 +
  590 + // marker
  591 + if (!stream->require(1)) {
  592 + ret = ERROR_RTMP_AMF0_ENCODE;
  593 + srs_error("amf0 write object eof marker failed. ret=%d", ret);
  594 + return ret;
  595 + }
  596 +
  597 + stream->write_1bytes(RTMP_AMF0_ObjectEnd);
  598 +
  599 + srs_verbose("amf0 read object eof success");
408 600
409 return ret; 601 return ret;
410 } 602 }
@@ -462,3 +654,108 @@ int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value) @@ -462,3 +654,108 @@ int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value)
462 654
463 return ret; 655 return ret;
464 } 656 }
  657 +int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value)
  658 +{
  659 + int ret = ERROR_SUCCESS;
  660 +
  661 + srs_assert(value != NULL);
  662 +
  663 + // marker
  664 + if (!stream->require(1)) {
  665 + ret = ERROR_RTMP_AMF0_ENCODE;
  666 + srs_error("amf0 write object marker failed. ret=%d", ret);
  667 + return ret;
  668 + }
  669 +
  670 + stream->write_1bytes(RTMP_AMF0_Object);
  671 + srs_verbose("amf0 write object marker success");
  672 +
  673 + // value
  674 + std::map<std::string, SrsAmf0Any*>::iterator it;
  675 + for (it = value->properties.begin(); it != value->properties.end(); ++it) {
  676 + std::string name = it->first;
  677 + SrsAmf0Any* any = it->second;
  678 +
  679 + if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) {
  680 + srs_error("write object property name failed. ret=%d", ret);
  681 + return ret;
  682 + }
  683 +
  684 + if ((ret = srs_amf0_write_any(stream, any)) != ERROR_SUCCESS) {
  685 + srs_error("write object property value failed. ret=%d", ret);
  686 + return ret;
  687 + }
  688 +
  689 + srs_verbose("write amf0 property success. name=%s", name.c_str());
  690 + }
  691 +
  692 + if ((ret = srs_amf0_write_object_eof(stream, &value->eof)) != ERROR_SUCCESS) {
  693 + srs_error("write object eof failed. ret=%d", ret);
  694 + return ret;
  695 + }
  696 +
  697 + srs_verbose("write amf0 object success.");
  698 +
  699 + return ret;
  700 +}
  701 +
  702 +int srs_amf0_get_utf8_size(std::string value)
  703 +{
  704 + return 2 + value.length();
  705 +}
  706 +
  707 +int srs_amf0_get_string_size(std::string value)
  708 +{
  709 + return 1 + srs_amf0_get_utf8_size(value);
  710 +}
  711 +
  712 +int srs_amf0_get_number_size()
  713 +{
  714 + return 1 + 8;
  715 +}
  716 +
  717 +int srs_amf0_get_boolean_size()
  718 +{
  719 + return 1 + 1;
  720 +}
  721 +
  722 +int srs_amf0_get_object_size(SrsAmf0Object* obj)
  723 +{
  724 + if (!obj) {
  725 + return 0;
  726 + }
  727 +
  728 + int size = 1;
  729 +
  730 + std::map<std::string, SrsAmf0Any*>::iterator it;
  731 + for (it = obj->properties.begin(); it != obj->properties.end(); ++it) {
  732 + std::string name = it->first;
  733 + SrsAmf0Any* value = it->second;
  734 +
  735 + size += srs_amf0_get_utf8_size(name);
  736 +
  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 + }
  751 + }
  752 +
  753 + size += srs_amf0_get_object_eof_size();
  754 +
  755 + return size;
  756 +}
  757 +
  758 +int srs_amf0_get_object_eof_size()
  759 +{
  760 + return 2 + 1;
  761 +}
@@ -140,6 +140,7 @@ struct SrsAmf0Object : public SrsAmf0Any @@ -140,6 +140,7 @@ struct SrsAmf0Object : public SrsAmf0Any
140 * @remark only support UTF8-1 char. 140 * @remark only support UTF8-1 char.
141 */ 141 */
142 extern int srs_amf0_read_utf8(SrsStream* stream, std::string& value); 142 extern int srs_amf0_read_utf8(SrsStream* stream, std::string& value);
  143 +extern int srs_amf0_write_utf8(SrsStream* stream, std::string value);
143 144
144 /** 145 /**
145 * read amf0 string from stream. 146 * read amf0 string from stream.
@@ -147,6 +148,7 @@ extern int srs_amf0_read_utf8(SrsStream* stream, std::string& value); @@ -147,6 +148,7 @@ extern int srs_amf0_read_utf8(SrsStream* stream, std::string& value);
147 * string-type = string-marker UTF-8 148 * string-type = string-marker UTF-8
148 */ 149 */
149 extern int srs_amf0_read_string(SrsStream* stream, std::string& value); 150 extern int srs_amf0_read_string(SrsStream* stream, std::string& value);
  151 +extern int srs_amf0_write_string(SrsStream* stream, std::string value);
150 152
151 /** 153 /**
152 * read amf0 boolean from stream. 154 * read amf0 boolean from stream.
@@ -155,6 +157,7 @@ extern int srs_amf0_read_string(SrsStream* stream, std::string& value); @@ -155,6 +157,7 @@ extern int srs_amf0_read_string(SrsStream* stream, std::string& value);
155 * 0 is false, <> 0 is true 157 * 0 is false, <> 0 is true
156 */ 158 */
157 extern int srs_amf0_read_boolean(SrsStream* stream, bool& value); 159 extern int srs_amf0_read_boolean(SrsStream* stream, bool& value);
  160 +extern int srs_amf0_write_boolean(SrsStream* stream, bool value);
158 161
159 /** 162 /**
160 * read amf0 number from stream. 163 * read amf0 number from stream.
@@ -162,6 +165,7 @@ extern int srs_amf0_read_boolean(SrsStream* stream, bool& value); @@ -162,6 +165,7 @@ extern int srs_amf0_read_boolean(SrsStream* stream, bool& value);
162 * number-type = number-marker DOUBLE 165 * number-type = number-marker DOUBLE
163 */ 166 */
164 extern int srs_amf0_read_number(SrsStream* stream, double& value); 167 extern int srs_amf0_read_number(SrsStream* stream, double& value);
  168 +extern int srs_amf0_write_number(SrsStream* stream, double value);
165 169
166 /** 170 /**
167 * read amf0 object from stream. 171 * read amf0 object from stream.
@@ -170,6 +174,16 @@ extern int srs_amf0_read_number(SrsStream* stream, double& value); @@ -170,6 +174,16 @@ extern int srs_amf0_read_number(SrsStream* stream, double& value);
170 * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) 174 * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
171 */ 175 */
172 extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value); 176 extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value);
  177 +extern int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value);
  178 +
  179 +/**
  180 +* get amf0 objects size.
  181 +*/
  182 +extern int srs_amf0_get_utf8_size(std::string value);
  183 +extern int srs_amf0_get_string_size(std::string value);
  184 +extern int srs_amf0_get_number_size();
  185 +extern int srs_amf0_get_boolean_size();
  186 +extern int srs_amf0_get_object_size(SrsAmf0Object* obj);
173 187
174 /** 188 /**
175 * convert the any to specified object. 189 * convert the any to specified object.
@@ -58,6 +58,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -58,6 +58,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
58 #define ERROR_RTMP_REQ_TCURL 306 58 #define ERROR_RTMP_REQ_TCURL 306
59 #define ERROR_RTMP_MESSAGE_DECODE 307 59 #define ERROR_RTMP_MESSAGE_DECODE 307
60 #define ERROR_RTMP_MESSAGE_ENCODE 308 60 #define ERROR_RTMP_MESSAGE_ENCODE 308
  61 +#define ERROR_RTMP_AMF0_ENCODE 309
61 62
62 #define ERROR_SYSTEM_STREAM_INIT 400 63 #define ERROR_SYSTEM_STREAM_INIT 400
63 #define ERROR_SYSTEM_PACKET_INVALID 401 64 #define ERROR_SYSTEM_PACKET_INVALID 401
@@ -1010,6 +1010,10 @@ SrsConnectAppPacket::SrsConnectAppPacket() @@ -1010,6 +1010,10 @@ SrsConnectAppPacket::SrsConnectAppPacket()
1010 1010
1011 SrsConnectAppPacket::~SrsConnectAppPacket() 1011 SrsConnectAppPacket::~SrsConnectAppPacket()
1012 { 1012 {
  1013 + if (command_object) {
  1014 + delete command_object;
  1015 + command_object = NULL;
  1016 + }
1013 } 1017 }
1014 1018
1015 int SrsConnectAppPacket::decode(SrsStream* stream) 1019 int SrsConnectAppPacket::decode(SrsStream* stream)
@@ -1053,6 +1057,77 @@ int SrsConnectAppPacket::decode(SrsStream* stream) @@ -1053,6 +1057,77 @@ int SrsConnectAppPacket::decode(SrsStream* stream)
1053 return ret; 1057 return ret;
1054 } 1058 }
1055 1059
  1060 +SrsConnectAppResPacket::SrsConnectAppResPacket()
  1061 +{
  1062 + command_name = RTMP_AMF0_COMMAND_CONNECT;
  1063 + transaction_id = 1;
  1064 + props = NULL;
  1065 + info = NULL;
  1066 +}
  1067 +
  1068 +SrsConnectAppResPacket::~SrsConnectAppResPacket()
  1069 +{
  1070 + if (props) {
  1071 + delete props;
  1072 + props = NULL;
  1073 + }
  1074 +
  1075 + if (info) {
  1076 + delete info;
  1077 + info = NULL;
  1078 + }
  1079 +}
  1080 +
  1081 +int SrsConnectAppResPacket::get_perfer_cid()
  1082 +{
  1083 + return RTMP_CID_OverConnection;
  1084 +}
  1085 +
  1086 +int SrsConnectAppResPacket::get_message_type()
  1087 +{
  1088 + return RTMP_MSG_AMF0CommandMessage;
  1089 +}
  1090 +
  1091 +int SrsConnectAppResPacket::get_size()
  1092 +{
  1093 + return srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size()
  1094 + + srs_amf0_get_object_size(props)+ srs_amf0_get_object_size(info);
  1095 +}
  1096 +
  1097 +int SrsConnectAppResPacket::encode_packet(SrsStream* stream)
  1098 +{
  1099 + int ret = ERROR_SUCCESS;
  1100 +
  1101 + if ((ret = srs_amf0_write_string(stream, command_name)) != ERROR_SUCCESS) {
  1102 + srs_error("encode command_name failed. ret=%d", ret);
  1103 + return ret;
  1104 + }
  1105 + srs_verbose("encode command_name success.");
  1106 +
  1107 + if ((ret = srs_amf0_write_number(stream, transaction_id)) != ERROR_SUCCESS) {
  1108 + srs_error("encode transaction_id failed. ret=%d", ret);
  1109 + return ret;
  1110 + }
  1111 + srs_verbose("encode transaction_id success.");
  1112 +
  1113 + if ((ret = srs_amf0_write_object(stream, props)) != ERROR_SUCCESS) {
  1114 + srs_error("encode props failed. ret=%d", ret);
  1115 + return ret;
  1116 + }
  1117 + srs_verbose("encode props success.");
  1118 +
  1119 + if ((ret = srs_amf0_write_object(stream, info)) != ERROR_SUCCESS) {
  1120 + srs_error("encode info failed. ret=%d", ret);
  1121 + return ret;
  1122 + }
  1123 + srs_verbose("encode info success.");
  1124 +
  1125 +
  1126 + srs_info("encode connect app response packet success.");
  1127 +
  1128 + return ret;
  1129 +}
  1130 +
1056 SrsSetWindowAckSizePacket::SrsSetWindowAckSizePacket() 1131 SrsSetWindowAckSizePacket::SrsSetWindowAckSizePacket()
1057 { 1132 {
1058 ackowledgement_window_size = 0; 1133 ackowledgement_window_size = 0;
@@ -324,6 +324,34 @@ public: @@ -324,6 +324,34 @@ public:
324 public: 324 public:
325 virtual int decode(SrsStream* stream); 325 virtual int decode(SrsStream* stream);
326 }; 326 };
  327 +/**
  328 +* response for SrsConnectAppPacket.
  329 +*/
  330 +class SrsConnectAppResPacket : public SrsPacket
  331 +{
  332 +private:
  333 + typedef SrsPacket super;
  334 +protected:
  335 + virtual const char* get_class_name()
  336 + {
  337 + return CLASS_NAME_STRING(SrsConnectAppResPacket);
  338 + }
  339 +public:
  340 + std::string command_name;
  341 + double transaction_id;
  342 + SrsAmf0Object* props;
  343 + SrsAmf0Object* info;
  344 +public:
  345 + SrsConnectAppResPacket();
  346 + virtual ~SrsConnectAppResPacket();
  347 +public:
  348 + virtual int get_perfer_cid();
  349 +public:
  350 + virtual int get_message_type();
  351 +protected:
  352 + virtual int get_size();
  353 + virtual int encode_packet(SrsStream* stream);
  354 +};
327 355
328 /** 356 /**
329 * 5.5. Window Acknowledgement Size (5) 357 * 5.5. Window Acknowledgement Size (5)
@@ -78,6 +78,15 @@ void SrsStream::skip(int size) @@ -78,6 +78,15 @@ void SrsStream::skip(int size)
78 p += size; 78 p += size;
79 } 79 }
80 80
  81 +int SrsStream::pos()
  82 +{
  83 + if (empty()) {
  84 + return 0;
  85 + }
  86 +
  87 + return p - bytes;
  88 +}
  89 +
81 int8_t SrsStream::read_1bytes() 90 int8_t SrsStream::read_1bytes()
82 { 91 {
83 srs_assert(require(1)); 92 srs_assert(require(1));
@@ -141,6 +150,22 @@ std::string SrsStream::read_string(int len) @@ -141,6 +150,22 @@ std::string SrsStream::read_string(int len)
141 return value; 150 return value;
142 } 151 }
143 152
  153 +void SrsStream::write_1bytes(int8_t value)
  154 +{
  155 + srs_assert(require(1));
  156 +
  157 + *p++ = value;
  158 +}
  159 +
  160 +void SrsStream::write_2bytes(int16_t value)
  161 +{
  162 + srs_assert(require(2));
  163 +
  164 + pp = (char*)&value;
  165 + *p++ = pp[1];
  166 + *p++ = pp[0];
  167 +}
  168 +
144 void SrsStream::write_4bytes(int32_t value) 169 void SrsStream::write_4bytes(int32_t value)
145 { 170 {
146 srs_assert(require(4)); 171 srs_assert(require(4));
@@ -152,10 +177,26 @@ void SrsStream::write_4bytes(int32_t value) @@ -152,10 +177,26 @@ void SrsStream::write_4bytes(int32_t value)
152 *p++ = pp[0]; 177 *p++ = pp[0];
153 } 178 }
154 179
155 -void SrsStream::write_1bytes(int8_t value) 180 +void SrsStream::write_8bytes(int64_t value)
156 { 181 {
157 - srs_assert(require(1)); 182 + srs_assert(require(8));
158 183
159 - *p++ = value; 184 + pp = (char*)&value;
  185 + *p++ = pp[7];
  186 + *p++ = pp[6];
  187 + *p++ = pp[5];
  188 + *p++ = pp[4];
  189 + *p++ = pp[3];
  190 + *p++ = pp[2];
  191 + *p++ = pp[1];
  192 + *p++ = pp[0];
  193 +}
  194 +
  195 +void SrsStream::write_string(std::string value)
  196 +{
  197 + srs_assert(require(value.length()));
  198 +
  199 + memcpy(p, value.data(), value.length());
  200 + p += value.length();
160 } 201 }
161 202
@@ -35,7 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -35,7 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 35
36 class SrsStream 36 class SrsStream
37 { 37 {
38 -protected: 38 +private:
39 char* p; 39 char* p;
40 char* pp; 40 char* pp;
41 char* bytes; 41 char* bytes;
@@ -70,6 +70,10 @@ public: @@ -70,6 +70,10 @@ public:
70 * @size can be any value. positive to forward; nagetive to backward. 70 * @size can be any value. positive to forward; nagetive to backward.
71 */ 71 */
72 virtual void skip(int size); 72 virtual void skip(int size);
  73 + /**
  74 + * tell the current pos.
  75 + */
  76 + virtual int pos();
73 public: 77 public:
74 /** 78 /**
75 * get 1bytes char from stream. 79 * get 1bytes char from stream.
@@ -93,13 +97,25 @@ public: @@ -93,13 +97,25 @@ public:
93 virtual std::string read_string(int len); 97 virtual std::string read_string(int len);
94 public: 98 public:
95 /** 99 /**
  100 + * write 1bytes char to stream.
  101 + */
  102 + virtual void write_1bytes(int8_t value);
  103 + /**
  104 + * write 2bytes int to stream.
  105 + */
  106 + virtual void write_2bytes(int16_t value);
  107 + /**
96 * write 4bytes int to stream. 108 * write 4bytes int to stream.
97 */ 109 */
98 virtual void write_4bytes(int32_t value); 110 virtual void write_4bytes(int32_t value);
99 /** 111 /**
100 - * write 1bytes char to stream. 112 + * write 8bytes int to stream.
101 */ 113 */
102 - virtual void write_1bytes(int8_t value); 114 + virtual void write_8bytes(int64_t value);
  115 + /**
  116 + * write string to stream
  117 + */
  118 + virtual void write_string(std::string value);
103 }; 119 };
104 120
105 #endif 121 #endif