winlin

refine protocol send. add utest for server auto response message

@@ -460,15 +460,15 @@ int SrsProtocol::do_send_message(SrsMessage* msg, SrsPacket* packet) @@ -460,15 +460,15 @@ int SrsProtocol::do_send_message(SrsMessage* msg, SrsPacket* packet)
460 // chunk message header, 11 bytes 460 // chunk message header, 11 bytes
461 // timestamp, 3bytes, big-endian 461 // timestamp, 3bytes, big-endian
462 u_int32_t timestamp = (u_int32_t)msg->header.timestamp; 462 u_int32_t timestamp = (u_int32_t)msg->header.timestamp;
463 - if (timestamp >= RTMP_EXTENDED_TIMESTAMP) {  
464 - *pheader++ = 0xFF;  
465 - *pheader++ = 0xFF;  
466 - *pheader++ = 0xFF;  
467 - } else { 463 + if (timestamp < RTMP_EXTENDED_TIMESTAMP) {
468 pp = (char*)&timestamp; 464 pp = (char*)&timestamp;
469 *pheader++ = pp[2]; 465 *pheader++ = pp[2];
470 *pheader++ = pp[1]; 466 *pheader++ = pp[1];
471 *pheader++ = pp[0]; 467 *pheader++ = pp[0];
  468 + } else {
  469 + *pheader++ = 0xFF;
  470 + *pheader++ = 0xFF;
  471 + *pheader++ = 0xFF;
472 } 472 }
473 473
474 // message_length, 3bytes, big-endian 474 // message_length, 3bytes, big-endian
@@ -5117,10 +5117,202 @@ VOID TEST(ProtocolStackTest, ProtocolSendSrsUserControlPacket) @@ -5117,10 +5117,202 @@ VOID TEST(ProtocolStackTest, ProtocolSendSrsUserControlPacket)
5117 (char)0x00, (char)0x01, (char)0x00, (char)0x00, (char)0x00, (char)0x10 5117 (char)0x00, (char)0x01, (char)0x00, (char)0x00, (char)0x00, (char)0x10
5118 }; 5118 };
5119 5119
5120 - __srs_bytes_print(bio.out_buffer.bytes(), bio.out_buffer.length());  
5121 - __srs_bytes_print(buf, sizeof(buf));  
5122 -  
5123 EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf))); 5120 EXPECT_TRUE(srs_bytes_equals(bio.out_buffer.bytes(), buf, sizeof(buf)));
5124 EXPECT_TRUE(true); 5121 EXPECT_TRUE(true);
5125 } 5122 }
5126 5123
  5124 +/**
  5125 +* recv video message from multiple chunks,
  5126 +* the next chunks must not be fmt=0 which means new msg.
  5127 +*/
  5128 +// when exists cache msg, means got an partial message,
  5129 +// the fmt must not be type0 which means new message.
  5130 +VOID TEST(ProtocolStackTest, ProtocolRecvVMessageFmtInvalid)
  5131 +{
  5132 + MockBufferIO bio;
  5133 + SrsProtocol proto(&bio);
  5134 +
  5135 + // video message
  5136 + char data[] = {
  5137 + // 12bytes header, 1byts chunk header, 11bytes msg heder
  5138 + (char)0x03,
  5139 + (char)0x00, (char)0x00, (char)0x00, // timestamp
  5140 + (char)0x00, (char)0x01, (char)0x10, // length, 272
  5141 + (char)0x09, // message_type
  5142 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id
  5143 + // msg payload start
  5144 + (char)0x02, (char)0x00, (char)0x07, (char)0x63,
  5145 + (char)0x6f, (char)0x6e, (char)0x6e, (char)0x65, (char)0x63, (char)0x74, (char)0x00, (char)0x3f, (char)0xf0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x03,
  5146 + (char)0x00, (char)0x03, (char)0x61, (char)0x70, (char)0x70, (char)0x02, (char)0x00, (char)0x04, (char)0x6c, (char)0x69, (char)0x76, (char)0x65, (char)0x00, (char)0x08, (char)0x66, (char)0x6c,
  5147 + (char)0x61, (char)0x73, (char)0x68, (char)0x56, (char)0x65, (char)0x72, (char)0x02, (char)0x00, (char)0x0d, (char)0x57, (char)0x49, (char)0x4e, (char)0x20, (char)0x31, (char)0x32, (char)0x2c,
  5148 + (char)0x30, (char)0x2c, (char)0x30, (char)0x2c, (char)0x34, (char)0x31, (char)0x00, (char)0x06, (char)0x73, (char)0x77, (char)0x66, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00,
  5149 + (char)0x51, (char)0x68, (char)0x74, (char)0x74, (char)0x70, (char)0x3a, (char)0x2f, (char)0x2f, (char)0x77, (char)0x77, (char)0x77, (char)0x2e, (char)0x6f, (char)0x73, (char)0x73, (char)0x72,
  5150 + (char)0x73, (char)0x2e, (char)0x6e, (char)0x65, (char)0x74, (char)0x3a, (char)0x38, (char)0x30, (char)0x38, (char)0x35, (char)0x2f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65,
  5151 + (char)0x72, (char)0x73, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c, (char)0x61, (char)0x79, (char)0x65, (char)0x72, (char)0x2f, (char)0x72, (char)0x65,
  5152 + (char)0x6c, (char)0x65, (char)0x61, (char)0x73, (char)0x65, (char)0x2f, (char)0x73, (char)0x72, (char)0x73, (char)0x5f, (char)0x70, (char)0x6c,
  5153 + (char)0x03, /*next chunk.*/ (char)0x61, (char)0x79, (char)0x65, (char)0x72,
  5154 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e,
  5155 + (char)0x32, (char)0x33, (char)0x00, (char)0x05, (char)0x74, (char)0x63, (char)0x55, (char)0x72, (char)0x6c, (char)0x02, (char)0x00, (char)0x14, (char)0x72, (char)0x74, (char)0x6d, (char)0x70,
  5156 + (char)0x3a, (char)0x2f, (char)0x2f, (char)0x64, (char)0x65, (char)0x76, (char)0x3a, (char)0x31, (char)0x39, (char)0x33, (char)0x35, (char)0x2f, (char)0x6c, (char)0x69, (char)0x76, (char)0x65,
  5157 + (char)0x00, (char)0x04, (char)0x66, (char)0x70, (char)0x61, (char)0x64, (char)0x01, (char)0x00, (char)0x00, (char)0x0c, (char)0x63, (char)0x61, (char)0x70, (char)0x61, (char)0x62, (char)0x69,
  5158 + (char)0x6c, (char)0x69, (char)0x74, (char)0x69, (char)0x65, (char)0x73, (char)0x00, (char)0x40, (char)0x6d, (char)0xe0, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  5159 + (char)0x0b, (char)0x61, (char)0x75, (char)0x64, (char)0x69, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65, (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0xab, (char)0xee,
  5160 + (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x0b, (char)0x76, (char)0x69, (char)0x64, (char)0x65, (char)0x6f, (char)0x43, (char)0x6f, (char)0x64, (char)0x65,
  5161 + (char)0x63, (char)0x73, (char)0x00, (char)0x40, (char)0x6f, (char)0x80, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00, (char)0x00,
  5162 + (char)0xC3, /*next chunk.*/
  5163 + (char)0x2e, (char)0x73, (char)0x77, (char)0x66, (char)0x3f, (char)0x5f, (char)0x76, (char)0x65, (char)0x72, (char)0x73, (char)0x69, (char)0x6f, (char)0x6e, (char)0x3d, (char)0x31, (char)0x2e
  5164 + };
  5165 + bio.in_buffer.append(data, sizeof(data));
  5166 +
  5167 + SrsMessage* msg = NULL;
  5168 + EXPECT_FALSE(ERROR_SUCCESS == proto.recv_message(&msg));
  5169 +}
  5170 +
  5171 +/**
  5172 +* when recv bytes archive the ack-size, server must response a acked-size auto.
  5173 +*/
  5174 +VOID TEST(ProtocolStackTest, ProtocolAckSizeFlow)
  5175 +{
  5176 + MockBufferIO bio;
  5177 + SrsProtocol proto(&bio);
  5178 +
  5179 + if (true) {
  5180 + SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket();
  5181 + pkt->ackowledgement_window_size = 512;
  5182 +
  5183 + EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
  5184 + }
  5185 +
  5186 + if (true) {
  5187 + SrsMessage* msg = new SrsCommonMessage();
  5188 + msg->header.payload_length = msg->size = 4096;
  5189 + msg->payload = new char[msg->size];
  5190 +
  5191 + msg->header.message_type = 9;
  5192 + EXPECT_TRUE(msg->header.is_video());
  5193 +
  5194 + EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_message(msg, 1));
  5195 + }
  5196 +
  5197 + // copy output to input
  5198 + if (true) {
  5199 + bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
  5200 + bio.out_buffer.erase(bio.out_buffer.length());
  5201 + }
  5202 +
  5203 + // recv SrsSetWindowAckSizePacket
  5204 + if (true) {
  5205 + SrsMessage* msg = NULL;
  5206 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  5207 + SrsAutoFree(SrsMessage, msg);
  5208 + ASSERT_TRUE(msg->header.is_window_ackledgement_size());
  5209 + }
  5210 + // recv video
  5211 + if (true) {
  5212 + SrsMessage* msg = NULL;
  5213 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  5214 + SrsAutoFree(SrsMessage, msg);
  5215 + ASSERT_TRUE(msg->header.is_video());
  5216 + }
  5217 +
  5218 + // copy output to input
  5219 + if (true) {
  5220 + bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
  5221 + bio.out_buffer.erase(bio.out_buffer.length());
  5222 + }
  5223 + // recv auto send acked size. #1
  5224 + if (true) {
  5225 + SrsMessage* msg = NULL;
  5226 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  5227 + SrsAutoFree(SrsMessage, msg);
  5228 + ASSERT_TRUE(msg->header.is_ackledgement());
  5229 + }
  5230 +
  5231 + // send again
  5232 + if (true) {
  5233 + SrsMessage* msg = new SrsCommonMessage();
  5234 + msg->header.payload_length = msg->size = 4096;
  5235 + msg->payload = new char[msg->size];
  5236 +
  5237 + msg->header.message_type = 9;
  5238 + EXPECT_TRUE(msg->header.is_video());
  5239 +
  5240 + EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_message(msg, 1));
  5241 + }
  5242 + // copy output to input
  5243 + if (true) {
  5244 + bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
  5245 + bio.out_buffer.erase(bio.out_buffer.length());
  5246 + }
  5247 + // recv video
  5248 + if (true) {
  5249 + SrsMessage* msg = NULL;
  5250 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  5251 + SrsAutoFree(SrsMessage, msg);
  5252 + ASSERT_TRUE(msg->header.is_video());
  5253 + }
  5254 +
  5255 + // copy output to input
  5256 + if (true) {
  5257 + bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
  5258 + bio.out_buffer.erase(bio.out_buffer.length());
  5259 + }
  5260 + // recv auto send acked size. #2
  5261 + if (true) {
  5262 + SrsMessage* msg = NULL;
  5263 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  5264 + SrsAutoFree(SrsMessage, msg);
  5265 + ASSERT_TRUE(msg->header.is_ackledgement());
  5266 + }
  5267 +}
  5268 +
  5269 +/**
  5270 +* when recv ping message, server will response it auto.
  5271 +*/
  5272 +VOID TEST(ProtocolStackTest, ProtocolPingFlow)
  5273 +{
  5274 + MockBufferIO bio;
  5275 + SrsProtocol proto(&bio);
  5276 +
  5277 + // ping request
  5278 + if (true) {
  5279 + SrsUserControlPacket* pkt = new SrsUserControlPacket();
  5280 + pkt->event_type = SrcPCUCPingRequest;
  5281 + pkt->event_data = 0x3456;
  5282 + EXPECT_TRUE(ERROR_SUCCESS == proto.send_and_free_packet(pkt, 0));
  5283 + }
  5284 + // copy output to input
  5285 + if (true) {
  5286 + bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
  5287 + bio.out_buffer.erase(bio.out_buffer.length());
  5288 + }
  5289 + // recv ping
  5290 + if (true) {
  5291 + SrsMessage* msg = NULL;
  5292 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  5293 + SrsAutoFree(SrsMessage, msg);
  5294 + EXPECT_TRUE(msg->header.is_user_control_message());
  5295 + }
  5296 +
  5297 + // recv the server auto send ping response message
  5298 + // copy output to input
  5299 + if (true) {
  5300 + bio.in_buffer.append(bio.out_buffer.bytes(), bio.out_buffer.length());
  5301 + bio.out_buffer.erase(bio.out_buffer.length());
  5302 + }
  5303 + // recv ping
  5304 + if (true) {
  5305 + SrsMessage* msg = NULL;
  5306 + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg));
  5307 + SrsAutoFree(SrsMessage, msg);
  5308 + ASSERT_TRUE(msg->header.is_user_control_message());
  5309 +
  5310 + SrsPacket* pkt = NULL;
  5311 + ASSERT_TRUE(ERROR_SUCCESS == proto.decode_message(msg, &pkt));
  5312 + SrsUserControlPacket* spkt = dynamic_cast<SrsUserControlPacket*>(pkt);
  5313 + ASSERT_TRUE(spkt != NULL);
  5314 +
  5315 + EXPECT_TRUE(SrcPCUCPingResponse == spkt->event_type);
  5316 + EXPECT_TRUE(0x3456 == spkt->event_data);
  5317 + }
  5318 +}