winlin

decode the amf0 command message: connect.

@@ -22,3 +22,69 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -22,3 +22,69 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */ 22 */
23 23
24 #include <srs_core_amf0.hpp> 24 #include <srs_core_amf0.hpp>
  25 +
  26 +#include <srs_core_log.hpp>
  27 +#include <srs_core_stream.hpp>
  28 +
  29 +// AMF0 marker
  30 +#define RTMP_AMF0_Number 0x00
  31 +#define RTMP_AMF0_Boolean 0x01
  32 +#define RTMP_AMF0_String 0x02
  33 +#define RTMP_AMF0_Object 0x03
  34 +#define RTMP_AMF0_MovieClip 0x04 // reserved, not supported
  35 +#define RTMP_AMF0_Null 0x05
  36 +#define RTMP_AMF0_Undefined 0x06
  37 +#define RTMP_AMF0_Reference 0x07
  38 +#define RTMP_AMF0_EcmaArray 0x08
  39 +#define RTMP_AMF0_ObjectEnd 0x09
  40 +#define RTMP_AMF0_StrictArray 0x0A
  41 +#define RTMP_AMF0_Date 0x0B
  42 +#define RTMP_AMF0_LongString 0x0C
  43 +#define RTMP_AMF0_UnSupported 0x0D
  44 +#define RTMP_AMF0_RecordSet 0x0E // reserved, not supported
  45 +#define RTMP_AMF0_XmlDocument 0x0F
  46 +#define RTMP_AMF0_TypedObject 0x10
  47 +// AVM+ object is the AMF3 object.
  48 +#define RTMP_AMF0_AVMplusObject 0x11
  49 +// origin array whos data takes the same form as LengthValueBytes
  50 +#define RTMP_AMF0_OriginStrictArray 0x20
  51 +
  52 +std::string srs_amf0_read_string(SrsStream* stream)
  53 +{
  54 + std::string str;
  55 +
  56 + // marker
  57 + if (!stream->require(1)) {
  58 + return str;
  59 + }
  60 +
  61 + char marker = stream->read_char();
  62 + if (marker != RTMP_AMF0_String) {
  63 + return str;
  64 + }
  65 +
  66 + // len
  67 + if (!stream->require(2)) {
  68 + return str;
  69 + }
  70 + int16_t len = stream->read_2bytes();
  71 +
  72 + // data
  73 + if (!stream->require(len)) {
  74 + return str;
  75 + }
  76 + str = stream->read_string(len);
  77 +
  78 + // support utf8-1 only
  79 + // 1.3.1 Strings and UTF-8
  80 + // UTF8-1 = %x00-7F
  81 + for (int i = 0; i < len; i++) {
  82 + char ch = *(str.data() + i);
  83 + if ((ch & 0x80) != 0) {
  84 + srs_warn("only support utf8-1, 0x00-0x7F, actual is %#x", (int)ch);
  85 + return "";
  86 + }
  87 + }
  88 +
  89 + return str;
  90 +}
@@ -30,4 +30,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -30,4 +30,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 30
31 #include <srs_core.hpp> 31 #include <srs_core.hpp>
32 32
  33 +#include <string>
  34 +
  35 +class SrsStream;
  36 +
  37 +/**
  38 +* read amf0 string from stream.
  39 +*/
  40 +extern std::string srs_amf0_read_string(SrsStream* stream);
  41 +
33 #endif 42 #endif
@@ -62,6 +62,8 @@ int SrsBuffer::ensure_buffer_bytes(SrsSocket* skt, int required_size) @@ -62,6 +62,8 @@ int SrsBuffer::ensure_buffer_bytes(SrsSocket* skt, int required_size)
62 { 62 {
63 int ret = ERROR_SUCCESS; 63 int ret = ERROR_SUCCESS;
64 64
  65 + srs_assert(required_size >= 0);
  66 +
65 while (size() < required_size) { 67 while (size() < required_size) {
66 char buffer[SOCKET_READ_SIZE]; 68 char buffer[SOCKET_READ_SIZE];
67 69
@@ -52,6 +52,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -52,6 +52,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52 #define ERROR_RTMP_PLAIN_REQUIRED 300 52 #define ERROR_RTMP_PLAIN_REQUIRED 300
53 #define ERROR_RTMP_CHUNK_START 301 53 #define ERROR_RTMP_CHUNK_START 301
54 #define ERROR_RTMP_MSG_INVLIAD_SIZE 302 54 #define ERROR_RTMP_MSG_INVLIAD_SIZE 302
  55 +#define ERROR_RTMP_AMF0_DECODE 303
55 56
56 #define ERROR_SYSTEM_STREAM_INIT 400 57 #define ERROR_SYSTEM_STREAM_INIT 400
57 58
@@ -24,9 +24,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -24,9 +24,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 #include <srs_core_protocol.hpp> 24 #include <srs_core_protocol.hpp>
25 25
26 #include <srs_core_log.hpp> 26 #include <srs_core_log.hpp>
  27 +#include <srs_core_amf0.hpp>
27 #include <srs_core_error.hpp> 28 #include <srs_core_error.hpp>
28 #include <srs_core_socket.hpp> 29 #include <srs_core_socket.hpp>
29 #include <srs_core_buffer.hpp> 30 #include <srs_core_buffer.hpp>
  31 +#include <srs_core_stream.hpp>
30 32
31 /** 33 /**
32 5. Protocol Control Messages 34 5. Protocol Control Messages
@@ -37,12 +39,12 @@ reserved for usage with RTM Chunk Stream protocol. Protocol messages @@ -37,12 +39,12 @@ reserved for usage with RTM Chunk Stream protocol. Protocol messages
37 with IDs 3-6 are reserved for usage of RTMP. Protocol message with ID 39 with IDs 3-6 are reserved for usage of RTMP. Protocol message with ID
38 7 is used between edge server and origin server. 40 7 is used between edge server and origin server.
39 */ 41 */
40 -#define RTMP_MSG_SetChunkSize 0x01  
41 -#define RTMP_MSG_AbortMessage 0x02  
42 -#define RTMP_MSG_Acknowledgement 0x03  
43 -#define RTMP_MSG_UserControlMessage 0x04  
44 -#define RTMP_MSG_WindowAcknowledgementSize 0x05  
45 -#define RTMP_MSG_SetPeerBandwidth 0x06 42 +#define RTMP_MSG_SetChunkSize 0x01
  43 +#define RTMP_MSG_AbortMessage 0x02
  44 +#define RTMP_MSG_Acknowledgement 0x03
  45 +#define RTMP_MSG_UserControlMessage 0x04
  46 +#define RTMP_MSG_WindowAcknowledgementSize 0x05
  47 +#define RTMP_MSG_SetPeerBandwidth 0x06
46 #define RTMP_MSG_EdgeAndOriginServerCommand 0x07 48 #define RTMP_MSG_EdgeAndOriginServerCommand 0x07
47 /** 49 /**
48 * The server sends this event to test whether the client is reachable. 50 * The server sends this event to test whether the client is reachable.
@@ -50,14 +52,14 @@ with IDs 3-6 are reserved for usage of RTMP. Protocol message with ID @@ -50,14 +52,14 @@ with IDs 3-6 are reserved for usage of RTMP. Protocol message with ID
50 * Event data is a 4-byte timestamp, representing the local server time when the server dispatched the command. 52 * Event data is a 4-byte timestamp, representing the local server time when the server dispatched the command.
51 * The client responds with PingResponse on receiving PingRequest. 53 * The client responds with PingResponse on receiving PingRequest.
52 */ 54 */
53 -#define RTMP_MSG_PCUC_PingRequest 0x06 55 +#define RTMP_MSG_PCUC_PingRequest 0x06
54 56
55 /** 57 /**
56 * The client sends this event to the server in response to the ping request. 58 * The client sends this event to the server in response to the ping request.
57 * 59 *
58 * The event data is a 4-byte timestamp, which was received with the PingRequest request. 60 * The event data is a 4-byte timestamp, which was received with the PingRequest request.
59 */ 61 */
60 -#define RTMP_MSG_PCUC_PingResponse 0x07 62 +#define RTMP_MSG_PCUC_PingResponse 0x07
61 /** 63 /**
62 3. Types of messages 64 3. Types of messages
63 The server and the client send messages over the network to 65 The server and the client send messages over the network to
@@ -77,8 +79,8 @@ contains related parameters. A client or a server can request Remote @@ -77,8 +79,8 @@ contains related parameters. A client or a server can request Remote
77 Procedure Calls (RPC) over streams that are communicated using the 79 Procedure Calls (RPC) over streams that are communicated using the
78 command messages to the peer. 80 command messages to the peer.
79 */ 81 */
80 -#define RTMP_MSG_AMF3CommandMessage 17 // 0x11  
81 -#define RTMP_MSG_AMF0CommandMessage 20 // 0x14 82 +#define RTMP_MSG_AMF3CommandMessage 17 // 0x11
  83 +#define RTMP_MSG_AMF0CommandMessage 20 // 0x14
82 /** 84 /**
83 3.2. Data message 85 3.2. Data message
84 The client or the server sends this message to send Metadata or any 86 The client or the server sends this message to send Metadata or any
@@ -87,8 +89,8 @@ data(audio, video etc.) like creation time, duration, theme and so @@ -87,8 +89,8 @@ data(audio, video etc.) like creation time, duration, theme and so
87 on. These messages have been assigned message type value of 18 for 89 on. These messages have been assigned message type value of 18 for
88 AMF0 and message type value of 15 for AMF3. 90 AMF0 and message type value of 15 for AMF3.
89 */ 91 */
90 -#define RTMP_MSG_AMF0DataMessage 18 // 0x12  
91 -#define RTMP_MSG_AMF3DataMessage 15 // 0x0F 92 +#define RTMP_MSG_AMF0DataMessage 18 // 0x12
  93 +#define RTMP_MSG_AMF3DataMessage 15 // 0x0F
92 /** 94 /**
93 3.3. Shared object message 95 3.3. Shared object message
94 A shared object is a Flash object (a collection of name value pairs) 96 A shared object is a Flash object (a collection of name value pairs)
@@ -97,14 +99,14 @@ so on. The message types kMsgContainer=19 for AMF0 and @@ -97,14 +99,14 @@ so on. The message types kMsgContainer=19 for AMF0 and
97 kMsgContainerEx=16 for AMF3 are reserved for shared object events. 99 kMsgContainerEx=16 for AMF3 are reserved for shared object events.
98 Each message can contain multiple events. 100 Each message can contain multiple events.
99 */ 101 */
100 -#define RTMP_MSG_AMF3SharedObject 16 // 0x10  
101 -#define RTMP_MSG_AMF0SharedObject 19 // 0x13 102 +#define RTMP_MSG_AMF3SharedObject 16 // 0x10
  103 +#define RTMP_MSG_AMF0SharedObject 19 // 0x13
102 /** 104 /**
103 3.4. Audio message 105 3.4. Audio message
104 The client or the server sends this message to send audio data to the 106 The client or the server sends this message to send audio data to the
105 peer. The message type value of 8 is reserved for audio messages. 107 peer. The message type value of 8 is reserved for audio messages.
106 */ 108 */
107 -#define RTMP_MSG_AudioMessage 8 // 0x08 109 +#define RTMP_MSG_AudioMessage 8 // 0x08
108 /* * 110 /* *
109 3.5. Video message 111 3.5. Video message
110 The client or the server sends this message to send video data to the 112 The client or the server sends this message to send video data to the
@@ -113,14 +115,14 @@ These messages are large and can delay the sending of other type of @@ -113,14 +115,14 @@ These messages are large and can delay the sending of other type of
113 messages. To avoid such a situation, the video message is assigned 115 messages. To avoid such a situation, the video message is assigned
114 the lowest priority. 116 the lowest priority.
115 */ 117 */
116 -#define RTMP_MSG_VideoMessage 9 // 0x09 118 +#define RTMP_MSG_VideoMessage 9 // 0x09
117 /** 119 /**
118 3.6. Aggregate message 120 3.6. Aggregate message
119 An aggregate message is a single message that contains a list of submessages. 121 An aggregate message is a single message that contains a list of submessages.
120 The message type value of 22 is reserved for aggregate 122 The message type value of 22 is reserved for aggregate
121 messages. 123 messages.
122 */ 124 */
123 -#define RTMP_MSG_AggregateMessage 22 // 0x16 125 +#define RTMP_MSG_AggregateMessage 22 // 0x16
124 126
125 /** 127 /**
126 * 6.1.2. Chunk Message Header 128 * 6.1.2. Chunk Message Header
@@ -131,21 +133,21 @@ messages. @@ -131,21 +133,21 @@ messages.
131 // Chunks of Type 0 are 11 bytes long. This type MUST be used at the 133 // Chunks of Type 0 are 11 bytes long. This type MUST be used at the
132 // start of a chunk stream, and whenever the stream timestamp goes 134 // start of a chunk stream, and whenever the stream timestamp goes
133 // backward (e.g., because of a backward seek). 135 // backward (e.g., because of a backward seek).
134 -#define RTMP_FMT_TYPE0 0 136 +#define RTMP_FMT_TYPE0 0
135 // 6.1.2.2. Type 1 137 // 6.1.2.2. Type 1
136 // Chunks of Type 1 are 7 bytes long. The message stream ID is not 138 // Chunks of Type 1 are 7 bytes long. The message stream ID is not
137 // included; this chunk takes the same stream ID as the preceding chunk. 139 // included; this chunk takes the same stream ID as the preceding chunk.
138 // Streams with variable-sized messages (for example, many video 140 // Streams with variable-sized messages (for example, many video
139 // formats) SHOULD use this format for the first chunk of each new 141 // formats) SHOULD use this format for the first chunk of each new
140 // message after the first. 142 // message after the first.
141 -#define RTMP_FMT_TYPE1 1 143 +#define RTMP_FMT_TYPE1 1
142 // 6.1.2.3. Type 2 144 // 6.1.2.3. Type 2
143 // Chunks of Type 2 are 3 bytes long. Neither the stream ID nor the 145 // Chunks of Type 2 are 3 bytes long. Neither the stream ID nor the
144 // message length is included; this chunk has the same stream ID and 146 // message length is included; this chunk has the same stream ID and
145 // message length as the preceding chunk. Streams with constant-sized 147 // message length as the preceding chunk. Streams with constant-sized
146 // messages (for example, some audio and data formats) SHOULD use this 148 // messages (for example, some audio and data formats) SHOULD use this
147 // format for the first chunk of each message after the first. 149 // format for the first chunk of each message after the first.
148 -#define RTMP_FMT_TYPE2 2 150 +#define RTMP_FMT_TYPE2 2
149 // 6.1.2.4. Type 3 151 // 6.1.2.4. Type 3
150 // Chunks of Type 3 have no header. Stream ID, message length and 152 // Chunks of Type 3 have no header. Stream ID, message length and
151 // timestamp delta are not present; chunks of this type take values from 153 // timestamp delta are not present; chunks of this type take values from
@@ -160,7 +162,7 @@ messages. @@ -160,7 +162,7 @@ messages.
160 // need for a chunk of type 2 to register the delta. If Type 3 chunk 162 // need for a chunk of type 2 to register the delta. If Type 3 chunk
161 // follows a Type 0 chunk, then timestamp delta for this Type 3 chunk is 163 // follows a Type 0 chunk, then timestamp delta for this Type 3 chunk is
162 // the same as the timestamp of Type 0 chunk. 164 // the same as the timestamp of Type 0 chunk.
163 -#define RTMP_FMT_TYPE3 3 165 +#define RTMP_FMT_TYPE3 3
164 166
165 /** 167 /**
166 * 6. Chunking 168 * 6. Chunking
@@ -172,7 +174,7 @@ messages. @@ -172,7 +174,7 @@ messages.
172 * good for high-bit rate streaming. Chunk size is maintained 174 * good for high-bit rate streaming. Chunk size is maintained
173 * independently for each direction. 175 * independently for each direction.
174 */ 176 */
175 -#define RTMP_DEFAULT_CHUNK_SIZE 128 177 +#define RTMP_DEFAULT_CHUNK_SIZE 128
176 178
177 /** 179 /**
178 * 6.1. Chunk Format 180 * 6.1. Chunk Format
@@ -185,7 +187,12 @@ messages. @@ -185,7 +187,12 @@ messages.
185 * the normal timestamp field MUST NOT be used and MUST be set to 187 * the normal timestamp field MUST NOT be used and MUST be set to
186 * 0xffffff and the extended timestamp MUST be sent. 188 * 0xffffff and the extended timestamp MUST be sent.
187 */ 189 */
188 -#define RTMP_EXTENDED_TIMESTAMP 0xFFFFFF 190 +#define RTMP_EXTENDED_TIMESTAMP 0xFFFFFF
  191 +
  192 +/**
  193 +* amf0 command message, command name: "connect"
  194 +*/
  195 +#define RTMP_AMF0_COMMAND_CONNECT "connect"
189 196
190 SrsMessageHeader::SrsMessageHeader() 197 SrsMessageHeader::SrsMessageHeader()
191 { 198 {
@@ -218,6 +225,7 @@ SrsChunkStream::~SrsChunkStream() @@ -218,6 +225,7 @@ SrsChunkStream::~SrsChunkStream()
218 SrsMessage::SrsMessage() 225 SrsMessage::SrsMessage()
219 { 226 {
220 size = 0; 227 size = 0;
  228 + stream = NULL;
221 payload = NULL; 229 payload = NULL;
222 decoded_payload = NULL; 230 decoded_payload = NULL;
223 } 231 }
@@ -233,6 +241,11 @@ SrsMessage::~SrsMessage() @@ -233,6 +241,11 @@ SrsMessage::~SrsMessage()
233 delete decoded_payload; 241 delete decoded_payload;
234 decoded_payload = NULL; 242 decoded_payload = NULL;
235 } 243 }
  244 +
  245 + if (stream) {
  246 + delete stream;
  247 + stream = NULL;
  248 + }
236 } 249 }
237 250
238 SrsPacket* SrsMessage::get_packet() 251 SrsPacket* SrsMessage::get_packet()
@@ -249,7 +262,44 @@ int SrsMessage::decode_packet() @@ -249,7 +262,44 @@ int SrsMessage::decode_packet()
249 { 262 {
250 int ret = ERROR_SUCCESS; 263 int ret = ERROR_SUCCESS;
251 264
252 - // TODO: decode packet. 265 + srs_assert(payload != NULL);
  266 + srs_assert(size > 0);
  267 +
  268 + if (!stream) {
  269 + srs_verbose("create decode stream for message.");
  270 + stream = new SrsStream();
  271 + }
  272 +
  273 + if (header.message_type == RTMP_MSG_AMF0CommandMessage) {
  274 + srs_verbose("start to decode AMF0 command message.");
  275 +
  276 + // amf0 command message.
  277 + // need to read the command name.
  278 + if ((ret = stream->initialize((char*)payload, size)) != ERROR_SUCCESS) {
  279 + srs_error("initialize stream failed. ret=%d", ret);
  280 + return ret;
  281 + }
  282 + srs_verbose("decode stream initialized success");
  283 +
  284 + std::string command = srs_amf0_read_string(stream);
  285 + srs_verbose("AMF0 command message, command_name=%s", command.c_str());
  286 +
  287 + stream->reset();
  288 + if (command == RTMP_AMF0_COMMAND_CONNECT) {
  289 + srs_info("decode the AMF0 command(connect vhost/app message).");
  290 + decoded_payload = new SrsConnectAppPacket();
  291 + return decoded_payload->decode(stream);
  292 + }
  293 +
  294 + // default packet to drop message.
  295 + srs_trace("drop the AMF0 command message, command_name=%s", command.c_str());
  296 + decoded_payload = new SrsPacket();
  297 + return ret;
  298 + }
  299 +
  300 + // default packet to drop message.
  301 + srs_trace("drop the unknown message, type=%d", header.message_type);
  302 + decoded_payload = new SrsPacket();
253 303
254 return ret; 304 return ret;
255 } 305 }
@@ -262,6 +312,12 @@ SrsPacket::~SrsPacket() @@ -262,6 +312,12 @@ SrsPacket::~SrsPacket()
262 { 312 {
263 } 313 }
264 314
  315 +int SrsPacket::decode(SrsStream* /*stream*/)
  316 +{
  317 + int ret = ERROR_SUCCESS;
  318 + return ret;
  319 +}
  320 +
265 SrsConnectAppPacket::SrsConnectAppPacket() 321 SrsConnectAppPacket::SrsConnectAppPacket()
266 { 322 {
267 } 323 }
@@ -270,6 +326,24 @@ SrsConnectAppPacket::~SrsConnectAppPacket() @@ -270,6 +326,24 @@ SrsConnectAppPacket::~SrsConnectAppPacket()
270 { 326 {
271 } 327 }
272 328
  329 +int SrsConnectAppPacket::decode(SrsStream* stream)
  330 +{
  331 + int ret = ERROR_SUCCESS;
  332 +
  333 + if ((ret = super::decode(stream)) != ERROR_SUCCESS) {
  334 + return ret;
  335 + }
  336 +
  337 + command_name = srs_amf0_read_string(stream);
  338 + if (command_name.empty()) {
  339 + ret = ERROR_RTMP_AMF0_DECODE;
  340 + srs_error("amf0 decode connect command_name failed. ret=%d", ret);
  341 + return ret;
  342 + }
  343 +
  344 + return ret;
  345 +}
  346 +
273 SrsProtocol::SrsProtocol(st_netfd_t client_stfd) 347 SrsProtocol::SrsProtocol(st_netfd_t client_stfd)
274 { 348 {
275 stfd = client_stfd; 349 stfd = client_stfd;
@@ -317,12 +391,21 @@ int SrsProtocol::recv_message(SrsMessage** pmsg) @@ -317,12 +391,21 @@ int SrsProtocol::recv_message(SrsMessage** pmsg)
317 srs_error("recv interlaced message failed. ret=%d", ret); 391 srs_error("recv interlaced message failed. ret=%d", ret);
318 return ret; 392 return ret;
319 } 393 }
  394 + srs_verbose("entire msg received");
320 395
321 if (!msg) { 396 if (!msg) {
322 continue; 397 continue;
323 } 398 }
324 399
325 - // return the msg with raw/undecoded payload 400 + if (msg->size <= 0 || msg->header.payload_length <= 0) {
  401 + srs_trace("ignore empty message(type=%d, size=%d, time=%d, sid=%d).",
  402 + msg->header.message_type, msg->header.payload_length,
  403 + msg->header.timestamp, msg->header.stream_id);
  404 + delete msg;
  405 + continue;
  406 + }
  407 +
  408 + srs_verbose("get a msg with raw/undecoded payload");
326 *pmsg = msg; 409 *pmsg = msg;
327 break; 410 break;
328 } 411 }
@@ -598,9 +681,12 @@ int SrsProtocol::read_message_payload(SrsChunkStream* chunk, int bh_size, int mh @@ -598,9 +681,12 @@ int SrsProtocol::read_message_payload(SrsChunkStream* chunk, int bh_size, int mh
598 // need erase the header in buffer. 681 // need erase the header in buffer.
599 buffer->erase(bh_size + mh_size); 682 buffer->erase(bh_size + mh_size);
600 683
601 - srs_warn("get an empty RTMP " 684 + srs_trace("get an empty RTMP "
602 "message(type=%d, size=%d, time=%d, sid=%d)", chunk->header.message_type, 685 "message(type=%d, size=%d, time=%d, sid=%d)", chunk->header.message_type,
603 chunk->header.payload_length, chunk->header.timestamp, chunk->header.stream_id); 686 chunk->header.payload_length, chunk->header.timestamp, chunk->header.stream_id);
  687 +
  688 + *pmsg = chunk->msg;
  689 + chunk->msg = NULL;
604 690
605 return ret; 691 return ret;
606 } 692 }
@@ -31,6 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,6 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 #include <srs_core.hpp> 31 #include <srs_core.hpp>
32 32
33 #include <map> 33 #include <map>
  34 +#include <string>
34 35
35 #include <st.h> 36 #include <st.h>
36 37
@@ -40,6 +41,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -40,6 +41,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 class SrsSocket; 41 class SrsSocket;
41 class SrsBuffer; 42 class SrsBuffer;
42 class SrsPacket; 43 class SrsPacket;
  44 +class SrsStream;
43 class SrsMessage; 45 class SrsMessage;
44 class SrsChunkStream; 46 class SrsChunkStream;
45 47
@@ -127,6 +129,7 @@ public: @@ -127,6 +129,7 @@ public:
127 int8_t* payload; 129 int8_t* payload;
128 // decoded message payload. 130 // decoded message payload.
129 private: 131 private:
  132 + SrsStream* stream;
130 SrsPacket* decoded_payload; 133 SrsPacket* decoded_payload;
131 public: 134 public:
132 /** 135 /**
@@ -150,13 +153,21 @@ class SrsPacket @@ -150,13 +153,21 @@ class SrsPacket
150 public: 153 public:
151 SrsPacket(); 154 SrsPacket();
152 virtual ~SrsPacket(); 155 virtual ~SrsPacket();
  156 +public:
  157 + virtual int decode(SrsStream* stream);
153 }; 158 };
154 159
155 class SrsConnectAppPacket : public SrsPacket 160 class SrsConnectAppPacket : public SrsPacket
156 { 161 {
  162 +private:
  163 + typedef SrsPacket super;
  164 +private:
  165 + std::string command_name;
157 public: 166 public:
158 SrsConnectAppPacket(); 167 SrsConnectAppPacket();
159 virtual ~SrsConnectAppPacket(); 168 virtual ~SrsConnectAppPacket();
  169 +public:
  170 + virtual int decode(SrsStream* stream);
160 }; 171 };
161 172
162 /** 173 /**
@@ -28,7 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -28,7 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 28
29 SrsStream::SrsStream() 29 SrsStream::SrsStream()
30 { 30 {
31 - bytes = NULL; 31 + p = bytes = NULL;
32 size = 0; 32 size = 0;
33 } 33 }
34 34
@@ -53,8 +53,54 @@ int SrsStream::initialize(char* _bytes, int _size) @@ -53,8 +53,54 @@ int SrsStream::initialize(char* _bytes, int _size)
53 } 53 }
54 54
55 size = _size; 55 size = _size;
56 - bytes = _bytes; 56 + p = bytes = _bytes;
57 57
58 return ret; 58 return ret;
59 } 59 }
60 60
  61 +void SrsStream::reset()
  62 +{
  63 + p = bytes;
  64 +}
  65 +
  66 +bool SrsStream::empty()
  67 +{
  68 + return !p || !bytes || (p >= bytes + size);
  69 +}
  70 +
  71 +bool SrsStream::require(int required_size)
  72 +{
  73 + return !empty() && (required_size < bytes + size - p);
  74 +}
  75 +
  76 +char SrsStream::read_char()
  77 +{
  78 + srs_assert(require(1));
  79 +
  80 + return *p++;
  81 +}
  82 +
  83 +int16_t SrsStream::read_2bytes()
  84 +{
  85 + srs_assert(require(2));
  86 +
  87 + int16_t value;
  88 + pp = (char*)&value;
  89 + pp[1] = *p++;
  90 + pp[0] = *p++;
  91 +
  92 + return value;
  93 +}
  94 +
  95 +std::string SrsStream::read_string(int len)
  96 +{
  97 + srs_assert(require(len));
  98 +
  99 + std::string value;
  100 + value.append(p, len);
  101 +
  102 + p += len;
  103 +
  104 + return value;
  105 +}
  106 +
@@ -30,9 +30,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -30,9 +30,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 30
31 #include <srs_core.hpp> 31 #include <srs_core.hpp>
32 32
  33 +#include <sys/types.h>
  34 +#include <string>
  35 +
33 class SrsStream 36 class SrsStream
34 { 37 {
35 protected: 38 protected:
  39 + char* p;
  40 + char* pp;
36 char* bytes; 41 char* bytes;
37 int size; 42 int size;
38 public: 43 public:
@@ -46,6 +51,24 @@ public: @@ -46,6 +51,24 @@ public:
46 * @remark, stream never free the _bytes, user must free it. 51 * @remark, stream never free the _bytes, user must free it.
47 */ 52 */
48 virtual int initialize(char* _bytes, int _size); 53 virtual int initialize(char* _bytes, int _size);
  54 + /**
  55 + * reset the position to beginning.
  56 + */
  57 + virtual void reset();
  58 + /**
  59 + * whether stream is empty.
  60 + * if empty, never read or write.
  61 + */
  62 + virtual bool empty();
  63 + /**
  64 + * whether required size is ok.
  65 + * @return true if stream can read/write specified required_size bytes.
  66 + */
  67 + virtual bool require(int required_size);
  68 +public:
  69 + virtual char read_char();
  70 + virtual int16_t read_2bytes();
  71 + virtual std::string read_string(int len);
49 }; 72 };
50 73
51 #endif 74 #endif