1 // 2 // Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 3 // Free Software Foundation, Inc 4 // 5 // This program is free software; you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation; either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with this program; if not, write to the Free Software 17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 19 #ifndef GNASH_LIBNET_RTMP_H 20 #define GNASH_LIBNET_RTMP_H 21 22 #include <deque> 23 #include <cstdint> 24 #include <memory> 25 #include <boost/lexical_cast.hpp> 26 #include <string> 27 #include <vector> 28 #include <time.h> 29 30 #include "amf.h" 31 #include "element.h" 32 #include "network.h" 33 #include "buffer.h" 34 #include "rtmp_msg.h" 35 #include "cque.h" 36 #include "dsodefs.h" 37 #include "utility.h" 38 39 namespace gnash 40 { 41 42 /// \page RTMP RTMP Protocol 43 /// \section rtmp_handshake RTMP Handshake 44 /// The headers and data for the initial RTMP handshake differ from 45 /// what is used by RTMP during normal message processing. The layout 46 /// is this: 47 /// <pre> 48 /// [version (1 byte)] 49 /// [1st timestamp (4 bytes)] 50 /// [2nd timestamp (4 bytes)] 51 /// [1528 bytes of random data] 52 /// </pre> 53 /// 54 /// The handshake process is client sends a handhsake request to the 55 /// server. This is 1537 bytes (version + handshake). 56 /// The server then responds with a 3073 byte packet, which is the 57 /// version byte plus two 1536 byte packets, the second one being the 58 /// the same random data as we originally sent, but with the header 59 /// changed. 60 /// 61 /// \section rtmp_packet RTMP Packet 62 /// An RTMP packet has a variablew length header field, followed by data 63 /// encoded in AMF format. The header can be one of 1, 4, 8, or 12 bytes. 64 /// 65 66 67 /// \var RTMP_HANDSHAKE_VERSION_SIZE 68 /// The RTMP version field of the handshake is 1 byte large 69 const int RTMP_HANDSHAKE_VERSION_SIZE = 1; 70 /// \var RTMP_VERSION 71 /// The RTMP version number for now is always a 3. 72 const std::uint8_t RTMP_VERSION = 0x3; 73 /// \var 74 /// This is the total size of an RTMP packet, not including the 75 /// version field. 76 const int RTMP_HANDSHAKE_SIZE = 1536; 77 /// \var 78 /// This is the size of the random data section in the RTMP handshake 79 const int RTMP_RANDOM_SIZE = 1528; 80 /// \var 81 /// The RTMP handshake header if always 2 32bit words. (8 bytes) 82 const int RTMP_HANDSHAKE_HEADER_SIZE = 8; 83 84 /// \var 85 /// This is the maximum number of channels supported in a single 86 /// RTMP connection. 87 const int MAX_AMF_INDEXES = 64; 88 89 /// \par RTMP Header 90 /// 91 /// \var 92 /// This is a mask to get to the upper 2 bits of the header 93 const int RTMP_HEADSIZE_MASK = 0xc0; 94 /// \var 95 /// This is a mask to get to the lower 6 bits of the header 96 const char RTMP_INDEX_MASK = 0x3f; 97 /// \var 98 /// All video data packets are 128 bytes 99 const int RTMP_VIDEO_PACKET_SIZE = 128; 100 /// \var 101 /// All audio data packets are 64 bytes 102 const int RTMP_AUDIO_PACKET_SIZE = 64; 103 /// \var 104 /// While the RTMP header can be one of 4 sizes, this is the 105 /// maximum size used 106 const int RTMP_MAX_HEADER_SIZE = 12; 107 /// \var 108 /// All System Ping messages are 6 bytes 109 const int PING_MSG_SIZE = 6; 110 /// \var 111 /// This is a reserved channel for system messages 112 const int RTMP_SYSTEM_CHANNEL = 2; 113 114 // For terminating sequences, a byte with value 0x09 is used. 115 const char TERMINATOR = 0x09; 116 117 // Each packet consists of the following: 118 // 119 // The first byte of the AMF file/stream is believed to be a version 120 // indicator. So far the only valid value for this field that has been 121 // found is 0x00. If it is anything other than 0x00 (zero), your 122 // system should consider the AMF file/stream to be 123 // 'malformed'd. This can happen in the IDE if AMF calls are put 124 // on the stack but never executed and the user exits the movie from the 125 // IDE; the two top bytes will be random and the number of headers will 126 // be unreliable. 127 128 // The third and fourth bytes form an integer value that specifies the 129 // number of headers. 130 typedef struct { 131 std::uint8_t version; 132 std::uint8_t source; 133 std::uint32_t count; 134 } amfpacket_t; 135 136 typedef enum { 137 onStatus, 138 onResult, 139 onDebugEvents 140 } amfresponse_e; 141 142 class DSOEXPORT RTMP : public Network 143 { 144 public: 145 typedef std::map<const char*, cygnal::Element> AMFProperties; 146 typedef std::deque<CQue *> queues_t; 147 typedef enum { 148 ENCODE_AMF0=0x0, 149 ENCODE_AMF3=0x3 150 } encoding_types_e; 151 typedef enum { 152 RAW = 0x0001, 153 ADPCM = 0x0002, 154 MP3 = 0x0004, 155 INTEL = 0x0005, 156 CELT = 0x0008, // unique to Gnash 157 NELLY8 = 0x0020, 158 NELLY = 0x0040, 159 G711A = 0x0080, 160 G711U = 0x0100, 161 NELLY16 = 0x0200, 162 AAC = 0x0400, 163 SPEEX = 0x0800, 164 DEFAULT_AUDIO_SET = 0x0267, 165 ALLAUDIO = 0x0fff 166 } audiocodecs_e; 167 typedef enum { 168 UNUSED = 0x0001, 169 JPEG = 0x0002, 170 SORENSON = 0x4, 171 ADOBE = 0x0008, 172 VP6 = 0x0010, 173 VP6ALPHA = 0x0020, 174 SCREEN2 = 0x0040, 175 H264 = 0x0080, 176 DEFAULT_VIDEO_SET = 0x007c, 177 ALLVIDEO = 0x00ff 178 } videocodecs_e; 179 typedef enum { 180 SEEK = 0x1, 181 AMF0 = 0x0, 182 AMF3 = 0x3 183 } videofunction_e; 184 // The second byte of the AMF file/stream is appears to be 0x00 if the 185 // client is the Flash Player and 0x01 if the client is the FlashCom 186 // server. 187 typedef enum { 188 NONE = 0x0, 189 CHUNK_SIZE = 0x1, 190 ABORT = 0x2, 191 BYTES_READ = 0x3, 192 USER = 0x4, 193 WINDOW_SIZE = 0x5, 194 SET_BANDWITH = 0x6, 195 ROUTE = 0x7, 196 AUDIO_DATA = 0x8, 197 VIDEO_DATA = 0x9, 198 SHARED_OBJ = 0xa, 199 AMF3_NOTIFY = 0xf, 200 AMF3_SHARED_OBJ = 0x10, 201 AMF3_INVOKE = 0x11, 202 NOTIFY = 0x12, 203 INVOKE = 0x14, 204 FLV_DATA = 0x16 205 } content_types_e; 206 typedef enum { 207 STREAM_START = 0x0, 208 STREAM_EOF = 0x1, 209 STREAM_NODATA = 0x2, 210 STREAM_BUFFER = 0x3, 211 STREAM_LIVE = 0x4, 212 STREAM_PING = 0x6, 213 STREAM_PONG = 0x7 214 } user_control_e; 215 typedef enum { 216 CREATE_OBJ = 0x1, // Client sends event 217 DELETE_OBJ = 0x2, // Client sends event 218 REQUEST_CHANGE = 0x3, // Client sends event 219 CHANGE = 0x4, // Server sends event 220 SUCCESS_CLIENT = 0x5, // Server sends event 221 SEND_MESSAGE = 0x6, // Client sends event 222 STATUS = 0x7, // Server sends evetn 223 CLEAR = 0x8, // Server sends event 224 DELETE_SLOT = 0x9, // Server sends event 225 REQUEST_DELETE_SLOT = 0xa, // Client sends event 226 SUCCESS_SERVER = 0xb // Server sends event 227 } sharedobj_types_e; 228 typedef enum { 229 PING_CLEAR = 0x0, // clear the stream 230 PING_PLAY = 0x1, // clear the playing buffer 231 PING_TIME = 0x3, // Buffer time in milliseconds 232 PING_RESET = 0x4, // Reset stream 233 PING_CLIENT = 0x6, // Ping the client from the server 234 PONG_CLIENT = 0x7 // pong reply from client to server 235 } rtmp_ping_e; 236 typedef enum { 237 STREAM_PLAY, // play the existing stream 238 STREAM_PAUSE, // pause the existing stream 239 STREAM_PUBLISH, // publish the existing stream 240 STREAM_STOP, // stop the existing stream 241 STREAM_SEEK // seek in the existing stream 242 } rtmp_op_e; 243 typedef struct { 244 rtmp_ping_e type; // the type of the ping message 245 std::uint16_t target; // all Ping message data fields 246 std::uint16_t param1; // are 2 bytes long 247 std::uint16_t param2; 248 std::uint16_t param3; 249 } rtmp_ping_t; 250 typedef struct { 251 user_control_e type; 252 std::uint32_t param1; 253 std::uint32_t param2; // only used by 254 } user_event_t; 255 typedef enum { 256 RTMP_STATE_HANDSHAKE_SEND, 257 RTMP_STATE_HANDSHAKE_RECV, 258 RTMP_STATE_HANDSHAKE_ACK, 259 RTMP_STATE_CONNECT, 260 RTMP_STATE_NETCONNECT, 261 RTMP_STATE_NETSTREAM, 262 RTMP_STATE_HEADER, 263 RTMP_STATE_DONE 264 } rtmp_state_t; 265 // typedef struct { 266 // rtmp_status_e status; 267 // std::string method; 268 // double streamid; 269 // std::vector<std::shared_ptr<cygnal::Element> > objs; 270 // } rtmp_msg_t; 271 typedef enum { 272 RTMP_ERR_UNDEF, 273 RTMP_ERR_NOTFOUND, 274 RTMP_ERR_PERM, 275 RTMP_ERR_DISKFULL, 276 RTMP_ERR_ILLEGAL, 277 RTMP_ERR_UNKNOWNID, 278 RTMP_ERR_EXISTS, 279 RTMP_ERR_NOSUCHUSER, 280 RTMP_ERR_TIMEOUT, 281 RTMP_ERR_NORESPONSE 282 } rtmp_error_t; 283 284 // Each header consists of the following: 285 // a single byte that is the index of the RTMP channel, 286 // then two bits that's a flag to note the size of the header, 287 // which can be 1, 4, 8, or 12 bytes long. 288 289 // More info at http://wiki.gnashdev.org/RTMP 290 typedef struct { 291 int channel; 292 int head_size; 293 int bodysize; 294 RTMPMsg::rtmp_source_e src_dest; 295 content_types_e type; 296 } rtmp_head_t; 297 typedef struct { 298 std::uint32_t uptime; 299 std::uint8_t version[4]; 300 } rtmp_handshake_head_t; 301 typedef enum { 302 HEADER_12 = 0x0, 303 HEADER_8 = 0x40, 304 HEADER_4 = 0x80, 305 HEADER_1 = 0xc0 306 } rtmp_headersize_e; 307 308 // Each body consists of the following: 309 // 310 // * UTF String - Target 311 // * UTF String - Response 312 // * Long - Body length in bytes 313 // * Variable - Actual data (including a type code) 314 // typedef struct { 315 // amf::amfutf8_t target; 316 // amf::amfutf8_t response; 317 // std::uint32_t length; 318 // void *data; 319 // } rtmp_body_t; 320 321 RTMP(); 322 virtual ~RTMP(); 323 324 // Decode 325 std::shared_ptr<rtmp_head_t> decodeHeader(std::uint8_t *header); 326 std::shared_ptr<rtmp_head_t> decodeHeader(cygnal::Buffer &data); 327 328 std::shared_ptr<cygnal::Buffer> encodeHeader(int amf_index, 329 rtmp_headersize_e head_size, 330 size_t total_size, content_types_e type, 331 RTMPMsg::rtmp_source_e routing); 332 std::shared_ptr<cygnal::Buffer> encodeHeader(int amf_index, 333 rtmp_headersize_e head_size); 334 335 void addProperty(cygnal::Element &el); 336 void addProperty(char *name, cygnal::Element &el); 337 void addProperty(std::string &name, cygnal::Element &el); 338 cygnal::Element &getProperty(const std::string &name); 339 // void setHandler(Handler *hand) { _handler = hand; }; 340 int headerSize(std::uint8_t header); 341 getHeader()342 rtmp_head_t *getHeader() { return &_header; }; getHeaderSize()343 int getHeaderSize() { return _header.head_size; }; getTotalSize()344 int getTotalSize() { return _header.bodysize; }; getRouting()345 RTMPMsg::rtmp_source_e getRouting() { return _header.src_dest; }; getChannel()346 int getChannel() { return _header.channel; }; getPacketSize()347 int getPacketSize() { return _packet_size; }; getMysteryWord()348 int getMysteryWord() { return _mystery_word; }; 349 350 // Decode an RTMP message 351 std::shared_ptr<RTMPMsg> decodeMsgBody(std::uint8_t *data, size_t size); 352 std::shared_ptr<RTMPMsg> decodeMsgBody(cygnal::Buffer &buf); 353 354 virtual std::shared_ptr<rtmp_ping_t> decodePing(std::uint8_t *data); 355 std::shared_ptr<rtmp_ping_t> decodePing(cygnal::Buffer &buf); 356 357 virtual std::shared_ptr<user_event_t> decodeUserControl(std::uint8_t *data); 358 std::shared_ptr<user_event_t> decodeUserControl(cygnal::Buffer &buf); 359 virtual std::shared_ptr<cygnal::Buffer> encodeUserControl(user_control_e, std::uint32_t data); 360 361 362 // These are handlers for the various types 363 virtual std::shared_ptr<cygnal::Buffer> encodeChunkSize(int size); 364 virtual void decodeChunkSize(); 365 366 virtual std::shared_ptr<cygnal::Buffer> encodeBytesRead(); 367 virtual void decodeBytesRead(); 368 virtual std::shared_ptr<cygnal::Buffer> encodeServer(); 369 virtual void decodeServer(); 370 371 virtual std::shared_ptr<cygnal::Buffer> encodeClient(); 372 virtual void decodeClient(); 373 374 virtual std::shared_ptr<cygnal::Buffer> encodeAudioData(); 375 virtual void decodeAudioData(); 376 377 virtual std::shared_ptr<cygnal::Buffer> encodeVideoData(); 378 virtual void decodeVideoData(); 379 380 virtual std::shared_ptr<cygnal::Buffer> encodeNotify(); 381 virtual void decodeNotify(); 382 383 virtual std::shared_ptr<cygnal::Buffer> encodeSharedObj(); 384 virtual void decodeSharedObj(); 385 386 virtual std::shared_ptr<cygnal::Buffer> encodeInvoke(); 387 virtual void decodeInvoke(); 388 389 // Receive a message, which is a series of AMF elements, seperated 390 // by a one byte header at regular byte intervals. (128 bytes for 391 // video data by default). Each message may contain multiple packets. 392 std::shared_ptr<cygnal::Buffer> recvMsg(); 393 std::shared_ptr<cygnal::Buffer> recvMsg(int fd); 394 395 // Send a message, usually a single ActionScript object. This message 396 // may be broken down into a series of packets on a regular byte 397 // interval. (128 bytes for video data by default). Each message main 398 // contain multiple packets. 399 bool sendMsg(cygnal::Buffer &data); 400 bool sendMsg(int channel, rtmp_headersize_e head_size, 401 size_t total_size, content_types_e type, 402 RTMPMsg::rtmp_source_e routing, cygnal::Buffer &data); 403 bool sendMsg(int fd, int channel, rtmp_headersize_e head_size, 404 size_t total_size, content_types_e type, 405 RTMPMsg::rtmp_source_e routing, cygnal::Buffer &data); 406 bool sendMsg(int channel, rtmp_headersize_e head_size, 407 size_t total_size, content_types_e type, 408 RTMPMsg::rtmp_source_e routing, std::uint8_t *data, size_t size); 409 bool sendMsg(int fd, int channel, rtmp_headersize_e head_size, 410 size_t total_size, content_types_e type, 411 RTMPMsg::rtmp_source_e routing, std::uint8_t *data, size_t size); 412 413 #if 0 414 // Send a Msg, and expect a response back of some kind. 415 RTMPMsg *sendRecvMsg(int amf_index, rtmp_headersize_e head_size, 416 size_t total_size, content_types_e type, 417 RTMPMsg::rtmp_source_e routing, cygnal::Buffer &buf); 418 #endif 419 // Split a large buffer into multiple smaller ones of the default chunksize 420 // of 128 bytes. We read network data in big chunks because it's more efficient, 421 // but RTMP uses a weird scheme of a standard header, and then every chunksize 422 // bytes another 1 byte RTMP header. The header itself is not part of the byte 423 // count. 424 std::shared_ptr<queues_t> split(cygnal::Buffer &buf); 425 std::shared_ptr<queues_t> split(std::uint8_t *data, size_t size); 426 427 CQue &operator[] (size_t x) { return _queues[x]; } 428 429 /// \method getTime 430 /// The time on most systems these days is a 64 bit long, but swf 431 /// is old, so it only uses a 32 bit integer instead. We know casting 432 /// looses precision, but that's just the way it is in RTMP. getTime()433 std::uint32_t getTime() { 434 time_t t; 435 time(&t); 436 return boost::lexical_cast<std::uint32_t>(t); 437 }; 438 439 void dump(); 440 protected: 441 AMFProperties _properties; 442 cygnal::Buffer *_handshake; 443 // Handler *_handler; 444 rtmp_head_t _header; 445 int _packet_size; 446 int _mystery_word; 447 size_t _chunksize[MAX_AMF_INDEXES]; 448 size_t _lastsize[MAX_AMF_INDEXES]; 449 std::vector<size_t> _bodysize; 450 std::vector<content_types_e> _type; 451 int _timeout; 452 CQue _queues[MAX_AMF_INDEXES]; 453 // queues_t _channels; 454 cygnal::Buffer _buffer; 455 rtmp_handshake_head_t _handshake_header; 456 }; 457 458 } // end of gnash namespace 459 // end of _RTMP_H_ 460 #endif 461 462 // local Variables: 463 // mode: C++ 464 // indent-tabs-mode: t 465 // End: 466 467