change bzr to git
[gnash.git] / libbase / RTMP.cpp
blobb39d27b9f7c41439238f3eb1a8813ecac44cbc8d
1 //
2 // Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 #include <cstdlib>
19 #include <cstring>
20 #include <cassert>
21 #include <cstdio>
22 #include <boost/lexical_cast.hpp>
24 #include "GnashSystemNetHeaders.h"
26 // Replace!!
27 #ifndef _WIN32
28 # include <sys/times.h>
29 #else
30 // TODO: use uptime properly on win32.
31 # include <ctime>
32 #endif
34 #include "RTMP.h"
35 #include "log.h"
36 #include "AMF.h"
37 #include "GnashAlgorithm.h"
38 #include "URL.h"
39 #include "ClockTime.h"
41 namespace gnash {
42 namespace rtmp {
44 namespace {
46 bool sendBytesReceived(RTMP* r);
48 // Not sure we ever want to do this.
49 bool sendServerBW(RTMP& r);
51 void handleMetadata(RTMP& r, const boost::uint8_t *payload,
52 unsigned int len);
53 void handleChangeChunkSize(RTMP& r, const RTMPPacket& packet);
54 void handleControl(RTMP& r, const RTMPPacket& packet);
55 void handleServerBW(RTMP& r, const RTMPPacket& packet);
56 void handleClientBW(RTMP& r, const RTMPPacket& packet);
58 void setupInvokePacket(RTMPPacket& packet);
59 boost::uint32_t getUptime();
61 boost::int32_t decodeInt32LE(const boost::uint8_t* c);
62 int encodeInt32LE(boost::uint8_t *output, int nVal);
63 unsigned int decodeInt24(const boost::uint8_t* c);
64 boost::uint8_t* encodeInt16(boost::uint8_t *output, boost::uint8_t *outend,
65 short nVal);
66 boost::uint8_t* encodeInt24(boost::uint8_t *output, boost::uint8_t *outend,
67 int nVal);
68 boost::uint8_t* encodeInt32(boost::uint8_t *output, boost::uint8_t *outend,
69 int nVal);
71 static const int packetSize[] = { 12, 8, 4, 1 };
75 namespace {
77 /// A random generator for generating the signature.
79 /// TODO: do this properly (it's currently not very random).
80 struct RandomByte
82 bool operator()() const {
83 return std::rand() % 256;
89 /// A utility functor for carrying out the handshake.
90 class HandShaker
92 public:
94 static const int sigSize = 1536;
96 HandShaker(Socket& s);
98 /// Calls the next stage in the handshake process.
99 void call();
101 bool success() const {
102 return _complete;
105 bool error() const {
106 return _error || _socket.bad();
109 private:
111 /// These are the stages of the handshake.
113 /// If the socket is not ready, they will return false. If the socket
114 /// is in error, they will set _error.
115 bool stage0();
116 bool stage1();
117 bool stage2();
118 bool stage3();
120 Socket _socket;
121 std::vector<boost::uint8_t> _sendBuf;
122 std::vector<boost::uint8_t> _recvBuf;
123 bool _error;
124 bool _complete;
125 size_t _stage;
128 RTMPPacket::RTMPPacket(size_t reserve)
130 header(),
131 buffer(new SimpleBuffer(reserve + RTMPHeader::headerSize)),
132 bytesRead(0)
134 // This is space for the header be filled in later.
135 buffer->resize(RTMPHeader::headerSize);
138 RTMPPacket::RTMPPacket(const RTMPPacket& other)
140 header(other.header),
141 buffer(other.buffer)
144 const size_t RTMPHeader::headerSize;
146 RTMP::RTMP()
148 _inChunkSize(RTMP_DEFAULT_CHUNKSIZE),
149 m_mediaChannel(0),
150 m_nClientBW2(2),
151 _bytesIn(0),
152 _bytesInSent(0),
153 _serverBandwidth(2500000),
154 _bandwidth(2500000),
155 _outChunkSize(RTMP_DEFAULT_CHUNKSIZE),
156 _connected(false),
157 _error(false)
161 RTMP::~RTMP()
165 bool
166 RTMP::hasPacket(ChannelType t, size_t channel) const
168 const ChannelSet& set = (t == CHANNELS_OUT) ? _outChannels : _inChannels;
169 return set.find(channel) != set.end();
172 RTMPPacket&
173 RTMP::getPacket(ChannelType t, size_t channel)
175 ChannelSet& set = (t == CHANNELS_OUT) ? _outChannels : _inChannels;
176 return set[channel];
179 RTMPPacket&
180 RTMP::storePacket(ChannelType t, size_t channel, const RTMPPacket& p)
182 ChannelSet& set = (t == CHANNELS_OUT) ? _outChannels : _inChannels;
183 RTMPPacket& stored = set[channel];
184 stored = p;
185 return stored;
188 void
189 RTMP::setBufferTime(size_t size, int streamID)
191 sendCtrl(*this, CONTROL_BUFFER_TIME, streamID, size);
194 void
195 RTMP::call(const SimpleBuffer& amf)
197 RTMPPacket p(amf.size());
198 setupInvokePacket(p);
200 // Copy the data.
201 p.buffer->append(amf.data(), amf.size());
202 sendPacket(p);
205 bool
206 RTMP::connect(const URL& url)
208 log_debug("Connecting to %s", url.str());
210 const std::string& hostname = url.hostname();
211 const std::string& p = url.port();
213 // Default port.
214 boost::uint16_t port = 1935;
215 if (!p.empty()) {
216 try {
217 port = boost::lexical_cast<boost::uint16_t>(p);
219 catch (boost::bad_lexical_cast&) {}
222 // Basic connection attempt.
223 if (!_socket.connect(hostname, port)) {
224 log_error("Initial connection failed");
225 return false;
228 _handShaker.reset(new HandShaker(_socket));
230 // Start handshake attempt immediately.
231 _handShaker->call();
233 return true;
236 void
237 RTMP::update()
239 if (!connected()) {
240 _handShaker->call();
241 if (_handShaker->error()) {
242 _error = true;
244 if (!_handShaker->success()) return;
245 _connected = true;
248 const size_t reads = 10;
250 for (size_t i = 0; i < reads; ++i) {
252 /// No need to continue reading (though it should do no harm).
253 if (error()) return;
255 RTMPPacket p;
257 // If we haven't finished reading a packet, retrieve it; otherwise
258 // use an empty one.
259 if (_incompletePacket.get()) {
260 log_debug("Doing incomplete packet");
261 p = *_incompletePacket;
262 _incompletePacket.reset();
264 else {
265 if (!readPacketHeader(p)) continue;
268 // Get the payload if possible.
269 if (hasPayload(p) && !readPacketPayload(p)) {
270 // If the payload is not completely readable, store it and
271 // continue.
272 _incompletePacket.reset(new RTMPPacket(p));
273 continue;
276 // Store a copy of the packet for later additions and as a reference for
277 // future sends.
278 RTMPPacket& stored = storePacket(CHANNELS_IN, p.header.channel, p);
280 // If the packet is complete, the stored packet no longer needs to
281 // keep the data alive.
282 if (isReady(p)) {
283 clearPayload(stored);
284 handlePacket(p);
285 return;
290 void
291 RTMP::handlePacket(const RTMPPacket& packet)
293 const PacketType t = packet.header.packetType;
295 log_debug("Received %s", t);
297 switch (t) {
299 case PACKET_TYPE_CHUNK_SIZE:
300 handleChangeChunkSize(*this, packet);
301 break;
303 case PACKET_TYPE_BYTES_READ:
304 break;
306 case PACKET_TYPE_CONTROL:
307 handleControl(*this, packet);
308 break;
310 case PACKET_TYPE_SERVERBW:
311 handleServerBW(*this, packet);
312 break;
314 case PACKET_TYPE_CLIENTBW:
315 handleClientBW(*this, packet);
316 break;
318 case PACKET_TYPE_AUDIO:
319 if (!m_mediaChannel) m_mediaChannel = packet.header.channel;
320 break;
322 case PACKET_TYPE_VIDEO:
323 if (!m_mediaChannel) m_mediaChannel = packet.header.channel;
324 break;
326 case PACKET_TYPE_FLEX_STREAM_SEND:
327 LOG_ONCE(log_unimpl("unsupported packet %s received"));
328 break;
330 case PACKET_TYPE_FLEX_SHARED_OBJECT:
331 LOG_ONCE(log_unimpl("unsupported packet %s received"));
332 break;
334 case PACKET_TYPE_FLEX_MESSAGE:
336 LOG_ONCE(log_unimpl("partially supported packet %s received"));
337 _messageQueue.push_back(packet.buffer);
338 break;
341 case PACKET_TYPE_METADATA:
342 handleMetadata(*this, payloadData(packet), payloadSize(packet));
343 break;
345 case PACKET_TYPE_SHARED_OBJECT:
346 LOG_ONCE(log_unimpl("packet %s received"));
347 break;
349 case PACKET_TYPE_INVOKE:
350 _messageQueue.push_back(packet.buffer);
351 break;
353 case PACKET_TYPE_FLV:
354 _flvQueue.push_back(packet.buffer);
355 break;
357 default:
358 log_error("Unknown packet %s received", t);
365 RTMP::readSocket(boost::uint8_t* buffer, int n)
368 assert(n >= 0);
370 const std::streamsize bytesRead = _socket.read(buffer, n);
372 if (_socket.bad()) {
373 _error = true;
374 return 0;
377 if (!bytesRead) return 0;
379 _bytesIn += bytesRead;
381 // Report bytes recieved every time we reach half the bandwidth.
382 // Doesn't seem very likely to be the way the pp does it.
383 if (_bytesIn > _bytesInSent + _bandwidth / 2) {
384 sendBytesReceived(this);
385 log_debug("Sent bytes received");
388 buffer += bytesRead;
389 return bytesRead;
392 void
393 RTMP::play(const SimpleBuffer& buf, int streamID)
395 RTMPPacket packet(buf.size());
397 packet.header.channel = CHANNEL_VIDEO;
398 packet.header.packetType = PACKET_TYPE_INVOKE;
400 packet.header._streamID = streamID;
402 packet.buffer->append(buf.data(), buf.size());
403 sendPacket(packet);
406 /// Fills a pre-existent RTMPPacket with information.
408 /// This is either read entirely from incoming data, or copied from a
409 /// previous packet in the same channel. This happens when the header type
410 /// is less than RTMP_PACKET_SIZE_LARGE.
412 /// It seems as if new packets can add to the data of old ones if they have
413 /// a minimal, small header.
414 bool
415 RTMP::readPacketHeader(RTMPPacket& packet)
418 RTMPHeader& hr = packet.header;
420 boost::uint8_t hbuf[RTMPHeader::headerSize] = { 0 };
421 boost::uint8_t* header = hbuf;
423 // The first read may fail, but otherwise we expect a complete header.
424 if (readSocket(hbuf, 1) == 0) {
425 return false;
428 //log_debug("Packet is %s", boost::io::group(std::hex, (unsigned)hbuf[0]));
430 const int htype = ((hbuf[0] & 0xc0) >> 6);
431 //log_debug("Thingy whatsit (packet size type): %s", htype);
433 const int channel = (hbuf[0] & 0x3f);
434 //log_debug("Channel: %s", channel);
436 hr.headerType = static_cast<PacketSize>(htype);
437 hr.channel = channel;
438 ++header;
440 if (hr.channel == 0) {
441 if (readSocket(&hbuf[1], 1) != 1) {
442 log_error("failed to read RTMP packet header 2nd byte");
443 return false;
445 hr.channel = hbuf[1] + 64;
446 ++header;
448 else if (hr.channel == 1) {
449 if (readSocket(&hbuf[1], 2) != 2) {
450 log_error("Failed to read RTMP packet header 3nd byte");
451 return false;
454 const boost::uint32_t tmp = (hbuf[2] << 8) + hbuf[1];
455 hr.channel = tmp + 64;
456 log_debug( "%s, channel: %0x", __FUNCTION__, hr.channel);
457 header += 2;
460 // This is the size in bytes of the packet header according to the
461 // type.
462 int nSize = packetSize[htype];
464 /// If we didn't receive a large header, the timestamp is relative
465 if (htype != RTMP_PACKET_SIZE_LARGE) {
467 if (!hasPacket(CHANNELS_IN, hr.channel)) {
468 log_error("Incomplete packet received on channel %s", channel);
469 return false;
472 // For all other header types, copy values from the last message of
473 // this channel. This includes any payload data from incomplete
474 // messages.
475 packet = getPacket(CHANNELS_IN, hr.channel);
478 --nSize;
480 if (nSize > 0 && readSocket(header, nSize) != nSize) {
481 log_error( "Failed to read RTMP packet header. type: %s",
482 static_cast<unsigned>(hbuf[0]));
483 return false;
486 // nSize is predicted size - 1. Add what we've read already.
487 int hSize = nSize + (header - hbuf);
489 if (nSize >= 3) {
491 const boost::uint32_t timestamp = decodeInt24(header);
493 // Make our packet timestamp absolute. If the value is 0xffffff,
494 // the absolute value comes later.
495 if (timestamp != 0xffffff) {
496 if (htype != RTMP_PACKET_SIZE_LARGE) {
497 packet.header._timestamp += timestamp;
499 else {
500 packet.header._timestamp = timestamp;
504 // Have at least a different size payload from the last packet.
505 if (nSize >= 6) {
507 // We do this in case there was an incomplete packet in the
508 // channel already.
509 clearPayload(packet);
510 hr.dataSize = decodeInt24(header + 3);
512 // More than six: read packet type
513 if (nSize > 6) {
514 hr.packetType = static_cast<PacketType>(header[6]);
516 // Large packets have a streamID.
517 if (nSize == 11) {
518 hr._streamID = decodeInt32LE(header + 7);
524 if (hr._timestamp == 0xffffff) {
525 if (readSocket(header+nSize, 4) != 4) {
526 log_error( "%s, failed to read extended timestamp",
527 __FUNCTION__);
528 return false;
530 hr._timestamp = amf::readNetworkLong(header+nSize);
531 hSize += 4;
535 const size_t bufSize = hr.dataSize + RTMPHeader::headerSize;
537 // If the packet does not have a payload, it was a complete packet stored in
538 // the channel for reference. This is the only case when a packet should
539 // exist but have no payload. We re-allocate in this case.
540 if (!hasPayload(packet)) {
541 packet.buffer.reset(new SimpleBuffer(bufSize));
543 // Why do this again? In case it was copied from the old packet?
544 hr.headerType = static_cast<PacketSize>(htype);
547 // Resize anyway. If it's different from what it was before, we should
548 // already have cleared it.
549 packet.buffer->resize(bufSize);
550 return true;
553 bool
554 RTMP::readPacketPayload(RTMPPacket& packet)
556 RTMPHeader& hr = packet.header;
558 const size_t bytesRead = packet.bytesRead;
560 const int nToRead = hr.dataSize - bytesRead;
562 const int nChunk = std::min<int>(nToRead, _inChunkSize);
563 assert(nChunk >= 0);
565 // This is fine. We'll keep trying to read this payload until there
566 // is enough data.
567 if (readSocket(payloadData(packet) + bytesRead, nChunk) != nChunk) {
568 return false;
571 packet.bytesRead += nChunk;
573 return true;
576 bool
577 RTMP::handShake()
580 /// It is a size type, but our socket functions return int.
581 const int sigSize = 1536;
583 boost::uint8_t clientbuf[sigSize + 1];
584 boost::uint8_t* ourSig = clientbuf + 1;
586 // Not encrypted
587 clientbuf[0] = 0x03;
589 // TODO: do this properly.
590 boost::uint32_t uptime = htonl(getUptime());
591 std::memcpy(ourSig, &uptime, 4);
593 std::fill_n(ourSig + 4, 4, 0);
595 // Generate 1536 random bytes.
596 std::generate(ourSig + 8, ourSig + sigSize, RandomByte());
598 // Send it to server.
599 if (_socket.write(clientbuf, sigSize + 1) != sigSize + 1) {
600 return false;
603 // Expect the same byte as we sent.
604 boost::uint8_t type;
605 if (readSocket(&type, 1) != 1) {
606 return false;
609 log_debug( "%s: Type Answer : %02X", __FUNCTION__, (int)type);
611 if (type != clientbuf[0]) {
612 log_error( "%s: Type mismatch: client sent %d, server answered %d",
613 __FUNCTION__, clientbuf[0], type);
616 boost::uint8_t serverSig[sigSize];
618 // Read from server.
619 if (readSocket(serverSig, sigSize) != sigSize) {
620 return false;
623 // decode server response
624 boost::uint32_t suptime;
626 memcpy(&suptime, serverSig, 4);
627 suptime = ntohl(suptime);
629 log_debug("Server Uptime : %d", suptime);
630 log_debug("FMS Version : %d.%d.%d.%d",
631 +serverSig[4], +serverSig[5], +serverSig[6], +serverSig[7]);
633 // Send what we received from server.
634 if (_socket.write(serverSig, sigSize) != sigSize) {
635 return false;
638 // Expect it back again.
639 if (readSocket(serverSig, sigSize) != sigSize) {
640 return false;
643 const bool match = std::equal(serverSig, serverSig + arraySize(serverSig),
644 ourSig);
646 if (!match) {
647 log_error( "Signatures do not match during handshake!");
649 return true;
653 bool
654 RTMP::sendPacket(RTMPPacket& packet)
656 // Set the data size of the packet to send.
657 RTMPHeader& hr = packet.header;
659 hr.dataSize = payloadSize(packet);
661 // This is the timestamp for our message.
662 const boost::uint32_t uptime = getUptime();
664 // Look at the previous packet on the channel.
665 bool prev = hasPacket(CHANNELS_OUT, hr.channel);
667 // The packet shall be large if it contains an absolute timestamp.
668 // * This is necessary if there is no previous packet, or if the
669 // timestamp is smaller than the last packet.
670 // Else it shall be medium if data size and packet type are the same
671 // It shall be small if ...
672 // It shall be minimal if it is exactly the same as its predecessor.
674 // All packets should start off as large. They will stay large if there
675 // is no previous packet.
676 assert(hr.headerType == RTMP_PACKET_SIZE_LARGE);
678 if (!prev) {
679 hr._timestamp = uptime;
681 else {
683 const RTMPPacket& prevPacket = getPacket(CHANNELS_OUT, hr.channel);
684 const RTMPHeader& oldh = prevPacket.header;
685 const boost::uint32_t prevTimestamp = oldh._timestamp;
687 // If this timestamp is later than the other and the difference fits
688 // in 3 bytes, encode a relative one.
689 if (uptime >= oldh._timestamp && uptime - prevTimestamp < 0xffffff) {
690 //log_debug("Shrinking to medium");
691 hr.headerType = RTMP_PACKET_SIZE_MEDIUM;
692 hr._timestamp = uptime - prevTimestamp;
694 // It can be still smaller if the data size is the same.
695 if (oldh.dataSize == hr.dataSize &&
696 oldh.packetType == hr.packetType) {
697 //log_debug("Shrinking to small");
698 hr.headerType = RTMP_PACKET_SIZE_SMALL;
699 // If there is no timestamp difference, the minimum size
700 // is possible.
701 if (hr._timestamp == 0) {
702 //log_debug("Shrinking to minimum");
703 hr.headerType = RTMP_PACKET_SIZE_MINIMUM;
707 else {
708 // Otherwise we need an absolute one, so a large header.
709 hr.headerType = RTMP_PACKET_SIZE_LARGE;
710 hr._timestamp = uptime;
714 assert (hr.headerType < 4);
716 int nSize = packetSize[hr.headerType];
718 int hSize = nSize;
719 boost::uint8_t* header;
720 boost::uint8_t* hptr;
721 boost::uint8_t* hend;
722 boost::uint8_t c;
724 // If there is a payload, the same buffer is used to write the header.
725 // Otherwise a separate buffer is used. But as we write them separately
726 // anyway, why do we do that?
728 // Work out where the beginning of the header is.
729 header = payloadData(packet) - nSize;
730 hend = payloadData(packet);
732 // The header size includes only a single channel/type. If we need more,
733 // they have to be added on.
734 const int channelSize = hr.channel > 319 ? 3 : hr.channel > 63 ? 1 : 0;
735 header -= channelSize;
736 hSize += channelSize;
738 /// Add space for absolute timestamp if necessary.
739 if (hr.headerType == RTMP_PACKET_SIZE_LARGE && hr._timestamp >= 0xffffff) {
740 header -= 4;
741 hSize += 4;
744 hptr = header;
745 c = hr.headerType << 6;
746 switch (channelSize) {
747 case 0:
748 c |= hr.channel;
749 break;
750 case 1:
751 break;
752 case 2:
753 c |= 1;
754 break;
756 *hptr++ = c;
758 if (channelSize) {
759 const int tmp = hr.channel - 64;
760 *hptr++ = tmp & 0xff;
761 if (channelSize == 2) *hptr++ = tmp >> 8;
764 if (hr.headerType == RTMP_PACKET_SIZE_LARGE && hr._timestamp >= 0xffffff) {
765 // Signify that the extended timestamp field is present.
766 const boost::uint32_t t = 0xffffff;
767 hptr = encodeInt24(hptr, hend, t);
769 else if (hr.headerType != RTMP_PACKET_SIZE_MINIMUM) {
770 // Write absolute or relative timestamp. Only minimal packets have
771 // no timestamp.
772 hptr = encodeInt24(hptr, hend, hr._timestamp);
775 /// Encode dataSize and packet type for medium packets.
776 if (nSize > 4) {
777 hptr = encodeInt24(hptr, hend, hr.dataSize);
778 *hptr++ = hr.packetType;
781 /// Encode streamID for large packets.
782 if (hr.headerType == RTMP_PACKET_SIZE_LARGE) {
783 hptr += encodeInt32LE(hptr, hr._streamID);
786 // Encode extended absolute timestamp if needed.
787 if (hr.headerType == RTMP_PACKET_SIZE_LARGE && hr._timestamp >= 0xffffff) {
788 hptr += encodeInt32LE(hptr, hr._timestamp);
791 nSize = hr.dataSize;
792 boost::uint8_t *buffer = payloadData(packet);
793 int nChunkSize = _outChunkSize;
795 std::string hx = hexify(header, payloadEnd(packet) - header, false);
797 while (nSize + hSize) {
799 if (nSize < nChunkSize) nChunkSize = nSize;
801 // First write header.
802 if (header) {
803 const int chunk = nChunkSize + hSize;
804 if (_socket.write(header, chunk) != chunk) {
805 return false;
807 header = NULL;
808 hSize = 0;
811 else {
812 // Then write data.
813 if (_socket.write(buffer, nChunkSize) != nChunkSize) {
814 return false;
819 nSize -= nChunkSize;
820 buffer += nChunkSize;
822 if (nSize > 0) {
823 header = buffer - 1;
824 hSize = 1;
825 if (channelSize) {
826 header -= channelSize;
827 hSize += channelSize;
830 *header = (0xc0 | c);
831 if (channelSize) {
832 int tmp = hr.channel - 64;
833 header[1] = tmp & 0xff;
834 if (channelSize == 2) header[2] = tmp >> 8;
839 /* we invoked a remote method */
840 if (hr.packetType == PACKET_TYPE_INVOKE) {
841 assert(payloadData(packet)[0] == amf::STRING_AMF0);
842 const boost::uint8_t* pos = payloadData(packet) + 1;
843 const boost::uint8_t* end = payloadEnd(packet);
844 const std::string& s = amf::readString(pos, end);
845 log_debug( "Calling remote method %s", s);
848 RTMPPacket& storedpacket = storePacket(CHANNELS_OUT, hr.channel, packet);
850 // Make it absolute for the next delta.
851 storedpacket.header._timestamp = uptime;
853 return true;
856 void
857 RTMP::close()
859 _socket.close();
860 _inChannels.clear();
861 _outChannels.clear();
862 _inChunkSize = RTMP_DEFAULT_CHUNKSIZE;
863 _outChunkSize = RTMP_DEFAULT_CHUNKSIZE;
864 _bytesIn = 0;
865 _bytesInSent = 0;
866 _bandwidth = 2500000;
867 m_nClientBW2 = 2;
868 _serverBandwidth = 2500000;
872 /////////////////////////////////////
873 /// HandShaker implementation
874 /////////////////////////////////////
876 HandShaker::HandShaker(Socket& s)
878 _socket(s),
879 _sendBuf(sigSize + 1),
880 _recvBuf(sigSize + 1),
881 _error(false),
882 _complete(false),
883 _stage(0)
885 // Not encrypted
886 _sendBuf[0] = 0x03;
888 // TODO: do this properly.
889 boost::uint32_t uptime = htonl(getUptime());
891 boost::uint8_t* ourSig = &_sendBuf.front() + 1;
892 std::memcpy(ourSig, &uptime, 4);
893 std::fill_n(ourSig + 4, 4, 0);
895 // Generate 1536 random bytes.
896 std::generate(ourSig + 8, ourSig + sigSize, RandomByte());
901 /// Calls the next stage in the handshake process.
902 void
903 HandShaker::call()
905 if (error() || !_socket.connected()) return;
907 switch (_stage) {
908 case 0:
909 if (!stage0()) return;
910 _stage = 1;
911 case 1:
912 if (!stage1()) return;
913 _stage = 2;
914 case 2:
915 if (!stage2()) return;
916 _stage = 3;
917 case 3:
918 if (!stage3()) return;
919 log_debug("Handshake completed");
920 _complete = true;
924 bool
925 HandShaker::stage0()
927 std::streamsize sent = _socket.write(&_sendBuf.front(), sigSize + 1);
929 // This should probably not happen, but we can try again. An error will
930 // be signalled later if the socket is no longer usable.
931 if (!sent) {
932 log_error("Stage 1 socket not ready. This should not happen.");
933 return false;
936 /// If we sent the wrong amount of data, we can't recover.
937 if (sent != sigSize + 1) {
938 log_error("Could not send stage 1 data");
939 _error = true;
940 return false;
942 return true;
945 bool
946 HandShaker::stage1()
949 std::streamsize read = _socket.read(&_recvBuf.front(), sigSize + 1);
951 if (!read) {
952 // If we receive nothing, wait until the next try.
953 return false;
956 // The read should never return anything but 0 or what we asked for.
957 assert (read == sigSize + 1);
959 if (_recvBuf[0] != _sendBuf[0]) {
960 log_error( "Type mismatch: client sent %d, server answered %d",
961 _recvBuf[0], _sendBuf[0]);
964 const boost::uint8_t* serverSig = &_recvBuf.front() + 1;
966 // decode server response
967 boost::uint32_t suptime;
968 std::memcpy(&suptime, serverSig, 4);
969 suptime = ntohl(suptime);
971 log_debug("Server Uptime : %d", suptime);
972 log_debug("FMS Version : %d.%d.%d.%d",
973 +serverSig[4], +serverSig[5], +serverSig[6], +serverSig[7]);
975 return true;
978 bool
979 HandShaker::stage2()
982 std::streamsize sent = _socket.write(&_recvBuf.front() + 1, sigSize);
984 // This should probably not happen.
985 if (!sent) return false;
987 if (sent != sigSize) {
988 log_error("Could not send complete signature.");
989 _error = true;
990 return false;
993 return true;
996 bool
997 HandShaker::stage3()
1000 // Expect it back again.
1001 std::streamsize got = _socket.read(&_recvBuf.front(), sigSize);
1003 if (!got) return false;
1005 assert (got == sigSize);
1007 const boost::uint8_t* serverSig = &_recvBuf.front();
1008 const boost::uint8_t* ourSig = &_sendBuf.front() + 1;
1010 const bool match = std::equal(serverSig, serverSig + sigSize, ourSig);
1012 // Should we set an error here?
1013 if (!match) {
1014 log_error( "Signatures do not match during handshake!");
1016 return true;
1019 /// The type of Ping packet is 0x4 and contains two mandatory parameters
1020 /// and two optional parameters. The first parameter is
1021 /// the type of Ping and in short integer. The second parameter is the
1022 /// target of the ping. As Ping is always sent in Channel 2
1023 /// (control channel) and the target object in RTMP header is always 0 whicj
1024 /// means the Connection object, it's necessary to put an extra parameter
1025 /// to indicate the exact target object the Ping is sent to. The second
1026 /// parameter takes this responsibility. The value has the same meaning
1027 /// as the target object field in RTMP header. (The second value could also
1028 /// be used as other purposes, like RTT Ping/Pong. It is used as the
1029 /// timestamp.) The third and fourth parameters are optional and could be
1030 /// looked upon as the parameter of the Ping packet.
1031 bool
1032 sendCtrl(RTMP& r, ControlType t, unsigned int nObject, unsigned int nTime)
1034 log_debug( "Sending control type %s %s", +t, t);
1036 RTMPPacket packet(256);
1038 packet.header.channel = CHANNEL_CONTROL1;
1039 packet.header.headerType = RTMP_PACKET_SIZE_LARGE;
1040 packet.header.packetType = PACKET_TYPE_CONTROL;
1042 // type 3 is the buffer time and requires all 3 parameters.
1043 // all in all 10 bytes.
1044 int nSize = (t == CONTROL_BUFFER_TIME ? 10 : 6);
1045 if (t == CONTROL_RESPOND_VERIFY) nSize = 44;
1047 SimpleBuffer& buf = *packet.buffer;
1049 buf.appendNetworkShort(t);
1051 if (t == CONTROL_RESPOND_VERIFY) { }
1052 else {
1053 if (nSize > 2) buf.appendNetworkLong(nObject);
1054 if (nSize > 6) buf.appendNetworkLong(nTime);
1056 return r.sendPacket(packet);
1059 namespace {
1061 /// Send the server bandwidth.
1063 /// Why would we want to send this?
1064 bool
1065 sendServerBW(RTMP& r)
1067 RTMPPacket packet(4);
1069 packet.header.channel = CHANNEL_CONTROL1;
1070 packet.header.packetType = PACKET_TYPE_SERVERBW;
1072 SimpleBuffer& buf = *packet.buffer;
1074 buf.appendNetworkLong(r.serverBandwidth());
1075 return r.sendPacket(packet);
1079 bool
1080 sendBytesReceived(RTMP* r)
1082 RTMPPacket packet(4);
1084 packet.header.channel = CHANNEL_CONTROL1;
1085 packet.header.packetType = PACKET_TYPE_BYTES_READ;
1087 SimpleBuffer& buf = *packet.buffer;
1089 buf.appendNetworkLong(r->_bytesIn);
1090 r->_bytesInSent = r->_bytesIn;
1092 return r->sendPacket(packet);
1096 void
1097 handleMetadata(RTMP& /*r*/, const boost::uint8_t* /* payload*/,
1098 unsigned int /*len*/)
1100 return;
1103 void
1104 handleChangeChunkSize(RTMP& r, const RTMPPacket& packet)
1106 if (payloadSize(packet) >= 4) {
1107 r._inChunkSize = amf::readNetworkLong(payloadData(packet));
1108 log_debug( "Changed chunk size to %d", r._inChunkSize);
1112 void
1113 handleControl(RTMP& r, const RTMPPacket& packet)
1116 const size_t size = payloadSize(packet);
1118 if (size < 2) {
1119 log_error("Control packet too short");
1120 return;
1123 const ControlType t =
1124 static_cast<ControlType>(amf::readNetworkShort(payloadData(packet)));
1126 if (size < 6) {
1127 log_error("Control packet (%s) data too short", t);
1128 return;
1131 const int arg = amf::readNetworkLong(payloadData(packet) + 2);
1132 log_debug( "Received control packet %s with argument %s", t, arg);
1134 switch (t)
1137 case CONTROL_CLEAR_STREAM:
1138 // TODO: handle this.
1139 break;
1141 case CONTROL_CLEAR_BUFFER:
1142 // TODO: handle this.
1143 break;
1145 case CONTROL_STREAM_DRY:
1146 break;
1148 case CONTROL_RESET_STREAM:
1149 log_debug("Stream is recorded: %s", arg);
1150 break;
1152 case CONTROL_PING:
1153 sendCtrl(r, CONTROL_PONG, arg, 0);
1154 break;
1156 case CONTROL_BUFFER_EMPTY:
1157 // TODO: handle.
1158 break;
1160 case CONTROL_BUFFER_READY:
1161 // TODO: handle
1162 break;
1164 default:
1165 log_error("Received unknown or unhandled control %s", t);
1166 break;
1171 void
1172 handleServerBW(RTMP& r, const RTMPPacket& packet)
1174 const boost::uint32_t bw = amf::readNetworkLong(payloadData(packet));
1175 log_debug( "Server bandwidth is %s", bw);
1176 r.setServerBandwidth(bw);
1179 void
1180 handleClientBW(RTMP& r, const RTMPPacket& packet)
1182 const boost::uint32_t bw = amf::readNetworkLong(payloadData(packet));
1184 r.setBandwidth(bw);
1186 if (payloadSize(packet) > 4) r.m_nClientBW2 = payloadData(packet)[4];
1187 else r.m_nClientBW2 = -1;
1189 log_debug( "Client bandwidth is %d %d", r.bandwidth(), +r.m_nClientBW2);
1194 boost::int32_t
1195 decodeInt32LE(const boost::uint8_t* c)
1197 return (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0];
1201 encodeInt32LE(boost::uint8_t *output, int nVal)
1203 output[0] = nVal;
1204 nVal >>= 8;
1205 output[1] = nVal;
1206 nVal >>= 8;
1207 output[2] = nVal;
1208 nVal >>= 8;
1209 output[3] = nVal;
1210 return 4;
1213 void
1214 setupInvokePacket(RTMPPacket& packet)
1216 RTMPHeader& hr = packet.header;
1217 // Control channel
1218 hr.channel = CHANNEL_CONTROL2;
1219 // Invoke
1220 hr.packetType = PACKET_TYPE_INVOKE;
1223 unsigned int
1224 decodeInt24(const boost::uint8_t *c)
1226 unsigned int val;
1227 val = (c[0] << 16) | (c[1] << 8) | c[2];
1228 return val;
1231 boost::uint8_t*
1232 encodeInt16(boost::uint8_t *output, boost::uint8_t *outend, short nVal)
1234 if (output+2 > outend) return NULL;
1236 output[1] = nVal & 0xff;
1237 output[0] = nVal >> 8;
1238 return output + 2;
1241 boost::uint8_t*
1242 encodeInt24(boost::uint8_t *output, boost::uint8_t *outend, int nVal)
1244 if (output + 3 > outend) return NULL;
1246 output[2] = nVal & 0xff;
1247 output[1] = nVal >> 8;
1248 output[0] = nVal >> 16;
1249 return output+3;
1252 boost::uint8_t*
1253 encodeInt32(boost::uint8_t *output, boost::uint8_t *outend, int nVal)
1255 if (output+4 > outend) return NULL;
1257 output[3] = nVal & 0xff;
1258 output[2] = nVal >> 8;
1259 output[1] = nVal >> 16;
1260 output[0] = nVal >> 24;
1261 return output + 4;
1264 boost::uint32_t
1265 getUptime()
1267 #if !defined(_WIN32) && !defined(__amigaos4__)
1268 struct tms t;
1269 return times(&t) * 1000 / sysconf(_SC_CLK_TCK);
1270 #elif defined(__amigaos4__)
1271 struct tms t;
1272 return times(&t) * 1000 / 50;
1273 #else
1274 return std::clock() * 100 / CLOCKS_PER_SEC;
1275 #endif
1278 } // anonymous namespace
1280 std::ostream&
1281 operator<<(std::ostream& o, PacketType p)
1283 switch(p) {
1284 case PACKET_TYPE_CHUNK_SIZE:
1285 return o << "<chunk size packet>";
1286 case PACKET_TYPE_BYTES_READ:
1287 return o << "<bytes read packet>";
1288 case PACKET_TYPE_CONTROL:
1289 return o << "<control packet>";
1290 case PACKET_TYPE_SERVERBW:
1291 return o << "<server bw packet>";
1292 case PACKET_TYPE_CLIENTBW:
1293 return o << "<client bw packet>";
1294 case PACKET_TYPE_AUDIO:
1295 return o << "<audio packet>";
1296 case PACKET_TYPE_VIDEO:
1297 return o << "<video packet>";
1298 case PACKET_TYPE_FLEX_STREAM_SEND:
1299 return o << "<flex stream send packet>";
1300 case PACKET_TYPE_FLEX_SHARED_OBJECT:
1301 return o << "<flex sharedobject packet>";
1302 case PACKET_TYPE_FLEX_MESSAGE:
1303 return o << "<flex message packet>";
1304 case PACKET_TYPE_METADATA:
1305 return o << "<metadata packet>";
1306 case PACKET_TYPE_SHARED_OBJECT:
1307 return o << "<sharedobject packet>";
1308 case PACKET_TYPE_INVOKE:
1309 return o << "<invoke packet>";
1310 case PACKET_TYPE_FLV:
1311 return o << "<flv packet>";
1312 default:
1313 return o << "<unknown packet type " << +p << ">";
1317 std::ostream&
1318 operator<<(std::ostream& o, ControlType t)
1320 switch (t) {
1322 case CONTROL_CLEAR_STREAM:
1323 return o << "<clear stream>";
1324 case CONTROL_CLEAR_BUFFER:
1325 return o << "<clear buffer>";
1326 case CONTROL_STREAM_DRY:
1327 return o << "<stream dry>";
1328 case CONTROL_BUFFER_TIME:
1329 return o << "<buffer time>";
1330 case CONTROL_RESET_STREAM:
1331 return o << "<reset stream>";
1332 case CONTROL_PING:
1333 return o << "<ping>";
1334 case CONTROL_PONG:
1335 return o << "<pong>";
1336 case CONTROL_REQUEST_VERIFY:
1337 return o << "<verify request>";
1338 case CONTROL_RESPOND_VERIFY:
1339 return o << "<verify response>";
1340 case CONTROL_BUFFER_EMPTY:
1341 return o << "<buffer empty>";
1342 case CONTROL_BUFFER_READY:
1343 return o << "<buffer ready>";
1344 default:
1345 return o << "<unknown control " << +t << ">";
1349 } // namespace rtmp
1350 } // namespace gnash