正在显示
8 个修改的文件
包含
272 行增加
和
28 行删除
| @@ -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 |
-
请 注册 或 登录 后发表评论