2 // Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
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.
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
22 #include <boost/lexical_cast.hpp>
24 #include "GnashSystemNetHeaders.h"
28 # include <sys/times.h>
30 // TODO: use uptime properly on win32.
37 #include "GnashAlgorithm.h"
39 #include "ClockTime.h"
46 bool sendBytesReceived(RTMP
* r
);
48 void handleMetadata(RTMP
& r
, const boost::uint8_t *payload
,
50 void handleChangeChunkSize(RTMP
& r
, const RTMPPacket
& packet
);
51 void handleControl(RTMP
& r
, const RTMPPacket
& packet
);
52 void handleServerBW(RTMP
& r
, const RTMPPacket
& packet
);
53 void handleClientBW(RTMP
& r
, const RTMPPacket
& packet
);
55 void setupInvokePacket(RTMPPacket
& packet
);
56 boost::uint32_t getUptime();
58 boost::int32_t decodeInt32LE(const boost::uint8_t* c
);
59 int encodeInt32LE(boost::uint8_t *output
, int nVal
);
60 unsigned int decodeInt24(const boost::uint8_t* c
);
61 boost::uint8_t* encodeInt16(boost::uint8_t *output
, boost::uint8_t *outend
,
63 boost::uint8_t* encodeInt24(boost::uint8_t *output
, boost::uint8_t *outend
,
65 boost::uint8_t* encodeInt32(boost::uint8_t *output
, boost::uint8_t *outend
,
68 static const int packetSize
[] = { 12, 8, 4, 1 };
74 /// A random generator for generating the signature.
76 /// TODO: do this properly (it's currently not very random).
79 bool operator()() const {
80 return std::rand() % 256;
86 /// A utility functor for carrying out the handshake.
91 static const int sigSize
= 1536;
93 HandShaker(Socket
& s
);
95 /// Calls the next stage in the handshake process.
98 bool success() const {
103 return _error
|| _socket
.bad();
108 /// These are the stages of the handshake.
110 /// If the socket is not ready, they will return false. If the socket
111 /// is in error, they will set _error.
118 std::vector
<boost::uint8_t> _sendBuf
;
119 std::vector
<boost::uint8_t> _recvBuf
;
125 RTMPPacket::RTMPPacket(size_t reserve
)
128 buffer(new SimpleBuffer(reserve
+ RTMPHeader::headerSize
)),
131 // This is space for the header be filled in later.
132 buffer
->resize(RTMPHeader::headerSize
);
135 RTMPPacket::RTMPPacket(const RTMPPacket
& other
)
137 header(other
.header
),
141 const size_t RTMPHeader::headerSize
;
145 _inChunkSize(RTMP_DEFAULT_CHUNKSIZE
),
150 _serverBandwidth(2500000),
152 _outChunkSize(RTMP_DEFAULT_CHUNKSIZE
),
163 RTMP::hasPacket(ChannelType t
, size_t channel
) const
165 const ChannelSet
& set
= (t
== CHANNELS_OUT
) ? _outChannels
: _inChannels
;
166 return set
.find(channel
) != set
.end();
170 RTMP::getPacket(ChannelType t
, size_t channel
)
172 ChannelSet
& set
= (t
== CHANNELS_OUT
) ? _outChannels
: _inChannels
;
177 RTMP::storePacket(ChannelType t
, size_t channel
, const RTMPPacket
& p
)
179 ChannelSet
& set
= (t
== CHANNELS_OUT
) ? _outChannels
: _inChannels
;
180 RTMPPacket
& stored
= set
[channel
];
186 RTMP::setBufferTime(size_t size
, int streamID
)
188 sendCtrl(*this, CONTROL_BUFFER_TIME
, streamID
, size
);
192 RTMP::call(const SimpleBuffer
& amf
)
194 RTMPPacket
p(amf
.size());
195 setupInvokePacket(p
);
198 p
.buffer
->append(amf
.data(), amf
.size());
203 RTMP::connect(const URL
& url
)
205 log_debug("Connecting to %s", url
.str());
207 const std::string
& hostname
= url
.hostname();
208 const std::string
& p
= url
.port();
211 boost::uint16_t port
= 1935;
214 port
= boost::lexical_cast
<boost::uint16_t>(p
);
216 catch (const boost::bad_lexical_cast
&) {}
219 // Basic connection attempt.
220 if (!_socket
.connect(hostname
, port
)) {
221 log_error("Initial connection failed");
225 _handShaker
.reset(new HandShaker(_socket
));
227 // Start handshake attempt immediately.
238 if (_handShaker
->error()) {
241 if (!_handShaker
->success()) return;
245 const size_t reads
= 10;
247 for (size_t i
= 0; i
< reads
; ++i
) {
249 /// No need to continue reading (though it should do no harm).
254 // If we haven't finished reading a packet, retrieve it; otherwise
256 if (_incompletePacket
.get()) {
257 log_debug("Doing incomplete packet");
258 p
= *_incompletePacket
;
259 _incompletePacket
.reset();
262 if (!readPacketHeader(p
)) continue;
265 // Get the payload if possible.
266 if (hasPayload(p
) && !readPacketPayload(p
)) {
267 // If the payload is not completely readable, store it and
269 _incompletePacket
.reset(new RTMPPacket(p
));
273 // Store a copy of the packet for later additions and as a reference for
275 RTMPPacket
& stored
= storePacket(CHANNELS_IN
, p
.header
.channel
, p
);
277 // If the packet is complete, the stored packet no longer needs to
278 // keep the data alive.
280 clearPayload(stored
);
288 RTMP::handlePacket(const RTMPPacket
& packet
)
290 const PacketType t
= packet
.header
.packetType
;
292 log_debug("Received %s", t
);
296 case PACKET_TYPE_CHUNK_SIZE
:
297 handleChangeChunkSize(*this, packet
);
300 case PACKET_TYPE_BYTES_READ
:
303 case PACKET_TYPE_CONTROL
:
304 handleControl(*this, packet
);
307 case PACKET_TYPE_SERVERBW
:
308 handleServerBW(*this, packet
);
311 case PACKET_TYPE_CLIENTBW
:
312 handleClientBW(*this, packet
);
315 case PACKET_TYPE_AUDIO
:
316 if (!m_mediaChannel
) m_mediaChannel
= packet
.header
.channel
;
319 case PACKET_TYPE_VIDEO
:
320 if (!m_mediaChannel
) m_mediaChannel
= packet
.header
.channel
;
323 case PACKET_TYPE_FLEX_STREAM_SEND
:
324 LOG_ONCE(log_unimpl("unsupported packet %s received"));
327 case PACKET_TYPE_FLEX_SHARED_OBJECT
:
328 LOG_ONCE(log_unimpl("unsupported packet %s received"));
331 case PACKET_TYPE_FLEX_MESSAGE
:
333 LOG_ONCE(log_unimpl("partially supported packet %s received"));
334 _messageQueue
.push_back(packet
.buffer
);
338 case PACKET_TYPE_METADATA
:
339 handleMetadata(*this, payloadData(packet
), payloadSize(packet
));
342 case PACKET_TYPE_SHARED_OBJECT
:
343 LOG_ONCE(log_unimpl("packet %s received"));
346 case PACKET_TYPE_INVOKE
:
347 _messageQueue
.push_back(packet
.buffer
);
350 case PACKET_TYPE_FLV
:
351 _flvQueue
.push_back(packet
.buffer
);
355 log_error("Unknown packet %s received", t
);
362 RTMP::readSocket(boost::uint8_t* buffer
, int n
)
367 const std::streamsize bytesRead
= _socket
.read(buffer
, n
);
369 if (_socket
.bad() || _socket
.eof() || !_socket
.connected()) {
374 if (!bytesRead
) return 0;
376 _bytesIn
+= bytesRead
;
378 // Report bytes recieved every time we reach half the bandwidth.
379 // Doesn't seem very likely to be the way the pp does it.
380 if (_bytesIn
> _bytesInSent
+ _bandwidth
/ 2) {
381 sendBytesReceived(this);
382 log_debug("Sent bytes received");
390 RTMP::play(const SimpleBuffer
& buf
, int streamID
)
392 RTMPPacket
packet(buf
.size());
394 packet
.header
.channel
= CHANNEL_VIDEO
;
395 packet
.header
.packetType
= PACKET_TYPE_INVOKE
;
397 packet
.header
._streamID
= streamID
;
399 packet
.buffer
->append(buf
.data(), buf
.size());
403 /// Send the server bandwidth.
405 /// Why would we want to send this?
407 sendServerBW(RTMP
& r
)
409 RTMPPacket
packet(4);
411 packet
.header
.channel
= CHANNEL_CONTROL1
;
412 packet
.header
.packetType
= PACKET_TYPE_SERVERBW
;
414 SimpleBuffer
& buf
= *packet
.buffer
;
416 buf
.appendNetworkLong(r
.serverBandwidth());
417 return r
.sendPacket(packet
);
421 /// Fills a pre-existent RTMPPacket with information.
423 /// This is either read entirely from incoming data, or copied from a
424 /// previous packet in the same channel. This happens when the header type
425 /// is less than RTMP_PACKET_SIZE_LARGE.
427 /// It seems as if new packets can add to the data of old ones if they have
428 /// a minimal, small header.
430 RTMP::readPacketHeader(RTMPPacket
& packet
)
433 RTMPHeader
& hr
= packet
.header
;
435 boost::uint8_t hbuf
[RTMPHeader::headerSize
] = { 0 };
436 boost::uint8_t* header
= hbuf
;
438 // The first read may fail, but otherwise we expect a complete header.
439 if (readSocket(hbuf
, 1) == 0) {
443 //log_debug("Packet is %s", boost::io::group(std::hex, (unsigned)hbuf[0]));
445 const int htype
= ((hbuf
[0] & 0xc0) >> 6);
446 //log_debug("Thingy whatsit (packet size type): %s", htype);
448 const int channel
= (hbuf
[0] & 0x3f);
449 //log_debug("Channel: %s", channel);
451 hr
.headerType
= static_cast<PacketSize
>(htype
);
452 hr
.channel
= channel
;
455 if (hr
.channel
== 0) {
456 if (readSocket(&hbuf
[1], 1) != 1) {
457 log_error("failed to read RTMP packet header 2nd byte");
460 hr
.channel
= hbuf
[1] + 64;
463 else if (hr
.channel
== 1) {
464 if (readSocket(&hbuf
[1], 2) != 2) {
465 log_error("Failed to read RTMP packet header 3nd byte");
469 const boost::uint32_t tmp
= (hbuf
[2] << 8) + hbuf
[1];
470 hr
.channel
= tmp
+ 64;
471 log_debug( "%s, channel: %0x", __FUNCTION__
, hr
.channel
);
475 // This is the size in bytes of the packet header according to the
477 int nSize
= packetSize
[htype
];
479 /// If we didn't receive a large header, the timestamp is relative
480 if (htype
!= RTMP_PACKET_SIZE_LARGE
) {
482 if (!hasPacket(CHANNELS_IN
, hr
.channel
)) {
483 log_error("Incomplete packet received on channel %s", channel
);
487 // For all other header types, copy values from the last message of
488 // this channel. This includes any payload data from incomplete
490 packet
= getPacket(CHANNELS_IN
, hr
.channel
);
495 if (nSize
> 0 && readSocket(header
, nSize
) != nSize
) {
496 log_error( "Failed to read RTMP packet header. type: %s",
497 static_cast<unsigned>(hbuf
[0]));
501 // nSize is predicted size - 1. Add what we've read already.
502 int hSize
= nSize
+ (header
- hbuf
);
506 const boost::uint32_t timestamp
= decodeInt24(header
);
508 // Make our packet timestamp absolute. If the value is 0xffffff,
509 // the absolute value comes later.
510 if (timestamp
!= 0xffffff) {
511 if (htype
!= RTMP_PACKET_SIZE_LARGE
) {
512 packet
.header
._timestamp
+= timestamp
;
515 packet
.header
._timestamp
= timestamp
;
519 // Have at least a different size payload from the last packet.
522 // We do this in case there was an incomplete packet in the
524 clearPayload(packet
);
525 hr
.dataSize
= decodeInt24(header
+ 3);
527 // More than six: read packet type
529 hr
.packetType
= static_cast<PacketType
>(header
[6]);
531 // Large packets have a streamID.
533 hr
._streamID
= decodeInt32LE(header
+ 7);
539 if (hr
._timestamp
== 0xffffff) {
540 if (readSocket(header
+nSize
, 4) != 4) {
541 log_error( "%s, failed to read extended timestamp",
545 hr
._timestamp
= amf::readNetworkLong(header
+nSize
);
550 const size_t bufSize
= hr
.dataSize
+ RTMPHeader::headerSize
;
552 // If the packet does not have a payload, it was a complete packet stored in
553 // the channel for reference. This is the only case when a packet should
554 // exist but have no payload. We re-allocate in this case.
555 if (!hasPayload(packet
)) {
556 packet
.buffer
.reset(new SimpleBuffer(bufSize
));
558 // Why do this again? In case it was copied from the old packet?
559 hr
.headerType
= static_cast<PacketSize
>(htype
);
562 // Resize anyway. If it's different from what it was before, we should
563 // already have cleared it.
564 packet
.buffer
->resize(bufSize
);
569 RTMP::readPacketPayload(RTMPPacket
& packet
)
571 RTMPHeader
& hr
= packet
.header
;
573 const size_t bytesRead
= packet
.bytesRead
;
575 const int nToRead
= hr
.dataSize
- bytesRead
;
577 const int nChunk
= std::min
<int>(nToRead
, _inChunkSize
);
580 // This is fine. We'll keep trying to read this payload until there
582 if (readSocket(payloadData(packet
) + bytesRead
, nChunk
) != nChunk
) {
586 packet
.bytesRead
+= nChunk
;
595 /// It is a size type, but our socket functions return int.
596 const int sigSize
= 1536;
598 boost::uint8_t clientbuf
[sigSize
+ 1];
599 boost::uint8_t* ourSig
= clientbuf
+ 1;
604 // TODO: do this properly.
605 boost::uint32_t uptime
= htonl(getUptime());
606 std::memcpy(ourSig
, &uptime
, 4);
608 std::fill_n(ourSig
+ 4, 4, 0);
610 // Generate 1536 random bytes.
611 std::generate(ourSig
+ 8, ourSig
+ sigSize
, RandomByte());
613 // Send it to server.
614 if (_socket
.write(clientbuf
, sigSize
+ 1) != sigSize
+ 1) {
618 // Expect the same byte as we sent.
620 if (readSocket(&type
, 1) != 1) {
624 log_debug( "%s: Type Answer : %02X", __FUNCTION__
, (int)type
);
626 if (type
!= clientbuf
[0]) {
627 log_error( "%s: Type mismatch: client sent %d, server answered %d",
628 __FUNCTION__
, clientbuf
[0], type
);
631 boost::uint8_t serverSig
[sigSize
];
634 if (readSocket(serverSig
, sigSize
) != sigSize
) {
638 // decode server response
639 boost::uint32_t suptime
;
641 memcpy(&suptime
, serverSig
, 4);
642 suptime
= ntohl(suptime
);
644 log_debug("Server Uptime : %d", suptime
);
645 log_debug("FMS Version : %d.%d.%d.%d",
646 +serverSig
[4], +serverSig
[5], +serverSig
[6], +serverSig
[7]);
648 // Send what we received from server.
649 if (_socket
.write(serverSig
, sigSize
) != sigSize
) {
653 // Expect it back again.
654 if (readSocket(serverSig
, sigSize
) != sigSize
) {
658 const bool match
= std::equal(serverSig
, serverSig
+ arraySize(serverSig
),
662 log_error( "Signatures do not match during handshake!");
669 RTMP::sendPacket(RTMPPacket
& packet
)
671 // Set the data size of the packet to send.
672 RTMPHeader
& hr
= packet
.header
;
674 hr
.dataSize
= payloadSize(packet
);
676 // This is the timestamp for our message.
677 const boost::uint32_t uptime
= getUptime();
679 // Look at the previous packet on the channel.
680 bool prev
= hasPacket(CHANNELS_OUT
, hr
.channel
);
682 // The packet shall be large if it contains an absolute timestamp.
683 // * This is necessary if there is no previous packet, or if the
684 // timestamp is smaller than the last packet.
685 // Else it shall be medium if data size and packet type are the same
686 // It shall be small if ...
687 // It shall be minimal if it is exactly the same as its predecessor.
689 // All packets should start off as large. They will stay large if there
690 // is no previous packet.
691 assert(hr
.headerType
== RTMP_PACKET_SIZE_LARGE
);
694 hr
._timestamp
= uptime
;
698 const RTMPPacket
& prevPacket
= getPacket(CHANNELS_OUT
, hr
.channel
);
699 const RTMPHeader
& oldh
= prevPacket
.header
;
700 const boost::uint32_t prevTimestamp
= oldh
._timestamp
;
702 // If this timestamp is later than the other and the difference fits
703 // in 3 bytes, encode a relative one.
704 if (uptime
>= oldh
._timestamp
&& uptime
- prevTimestamp
< 0xffffff) {
705 //log_debug("Shrinking to medium");
706 hr
.headerType
= RTMP_PACKET_SIZE_MEDIUM
;
707 hr
._timestamp
= uptime
- prevTimestamp
;
709 // It can be still smaller if the data size is the same.
710 if (oldh
.dataSize
== hr
.dataSize
&&
711 oldh
.packetType
== hr
.packetType
) {
712 //log_debug("Shrinking to small");
713 hr
.headerType
= RTMP_PACKET_SIZE_SMALL
;
714 // If there is no timestamp difference, the minimum size
716 if (hr
._timestamp
== 0) {
717 //log_debug("Shrinking to minimum");
718 hr
.headerType
= RTMP_PACKET_SIZE_MINIMUM
;
723 // Otherwise we need an absolute one, so a large header.
724 hr
.headerType
= RTMP_PACKET_SIZE_LARGE
;
725 hr
._timestamp
= uptime
;
729 assert (hr
.headerType
< 4);
731 int nSize
= packetSize
[hr
.headerType
];
734 boost::uint8_t* header
;
735 boost::uint8_t* hptr
;
736 boost::uint8_t* hend
;
739 // If there is a payload, the same buffer is used to write the header.
740 // Otherwise a separate buffer is used. But as we write them separately
741 // anyway, why do we do that?
743 // Work out where the beginning of the header is.
744 header
= payloadData(packet
) - nSize
;
745 hend
= payloadData(packet
);
747 // The header size includes only a single channel/type. If we need more,
748 // they have to be added on.
749 const int channelSize
= hr
.channel
> 319 ? 3 : hr
.channel
> 63 ? 1 : 0;
750 header
-= channelSize
;
751 hSize
+= channelSize
;
753 /// Add space for absolute timestamp if necessary.
754 if (hr
.headerType
== RTMP_PACKET_SIZE_LARGE
&& hr
._timestamp
>= 0xffffff) {
760 c
= hr
.headerType
<< 6;
761 switch (channelSize
) {
774 const int tmp
= hr
.channel
- 64;
775 *hptr
++ = tmp
& 0xff;
776 if (channelSize
== 2) *hptr
++ = tmp
>> 8;
779 if (hr
.headerType
== RTMP_PACKET_SIZE_LARGE
&& hr
._timestamp
>= 0xffffff) {
780 // Signify that the extended timestamp field is present.
781 const boost::uint32_t t
= 0xffffff;
782 hptr
= encodeInt24(hptr
, hend
, t
);
784 else if (hr
.headerType
!= RTMP_PACKET_SIZE_MINIMUM
) {
785 // Write absolute or relative timestamp. Only minimal packets have
787 hptr
= encodeInt24(hptr
, hend
, hr
._timestamp
);
790 /// Encode dataSize and packet type for medium packets.
792 hptr
= encodeInt24(hptr
, hend
, hr
.dataSize
);
793 *hptr
++ = hr
.packetType
;
796 /// Encode streamID for large packets.
797 if (hr
.headerType
== RTMP_PACKET_SIZE_LARGE
) {
798 hptr
+= encodeInt32LE(hptr
, hr
._streamID
);
801 // Encode extended absolute timestamp if needed.
802 if (hr
.headerType
== RTMP_PACKET_SIZE_LARGE
&& hr
._timestamp
>= 0xffffff) {
803 hptr
+= encodeInt32LE(hptr
, hr
._timestamp
);
807 boost::uint8_t *buffer
= payloadData(packet
);
808 int nChunkSize
= _outChunkSize
;
810 std::string hx
= hexify(header
, payloadEnd(packet
) - header
, false);
812 while (nSize
+ hSize
) {
814 if (nSize
< nChunkSize
) nChunkSize
= nSize
;
816 // First write header.
818 const int chunk
= nChunkSize
+ hSize
;
819 if (_socket
.write(header
, chunk
) != chunk
) {
828 if (_socket
.write(buffer
, nChunkSize
) != nChunkSize
) {
835 buffer
+= nChunkSize
;
841 header
-= channelSize
;
842 hSize
+= channelSize
;
845 *header
= (0xc0 | c
);
847 int tmp
= hr
.channel
- 64;
848 header
[1] = tmp
& 0xff;
849 if (channelSize
== 2) header
[2] = tmp
>> 8;
854 /* we invoked a remote method */
855 if (hr
.packetType
== PACKET_TYPE_INVOKE
) {
856 assert(payloadData(packet
)[0] == amf::STRING_AMF0
);
857 const boost::uint8_t* pos
= payloadData(packet
) + 1;
858 const boost::uint8_t* end
= payloadEnd(packet
);
859 const std::string
& s
= amf::readString(pos
, end
);
860 log_debug( "Calling remote method %s", s
);
863 RTMPPacket
& storedpacket
= storePacket(CHANNELS_OUT
, hr
.channel
, packet
);
865 // Make it absolute for the next delta.
866 storedpacket
.header
._timestamp
= uptime
;
876 _outChannels
.clear();
877 _inChunkSize
= RTMP_DEFAULT_CHUNKSIZE
;
878 _outChunkSize
= RTMP_DEFAULT_CHUNKSIZE
;
881 _bandwidth
= 2500000;
883 _serverBandwidth
= 2500000;
887 /////////////////////////////////////
888 /// HandShaker implementation
889 /////////////////////////////////////
891 HandShaker::HandShaker(Socket
& s
)
894 _sendBuf(sigSize
+ 1),
895 _recvBuf(sigSize
+ 1),
903 // TODO: do this properly.
904 boost::uint32_t uptime
= htonl(getUptime());
906 boost::uint8_t* ourSig
= &_sendBuf
.front() + 1;
907 std::memcpy(ourSig
, &uptime
, 4);
908 std::fill_n(ourSig
+ 4, 4, 0);
910 // Generate 1536 random bytes.
911 std::generate(ourSig
+ 8, ourSig
+ sigSize
, RandomByte());
916 /// Calls the next stage in the handshake process.
920 if (error() || !_socket
.connected()) return;
924 if (!stage0()) return;
927 if (!stage1()) return;
930 if (!stage2()) return;
933 if (!stage3()) return;
934 log_debug("Handshake completed");
942 std::streamsize sent
= _socket
.write(&_sendBuf
.front(), sigSize
+ 1);
944 // This should probably not happen, but we can try again. An error will
945 // be signalled later if the socket is no longer usable.
947 log_error("Stage 1 socket not ready. This should not happen.");
951 /// If we sent the wrong amount of data, we can't recover.
952 if (sent
!= sigSize
+ 1) {
953 log_error("Could not send stage 1 data");
964 std::streamsize read
= _socket
.read(&_recvBuf
.front(), sigSize
+ 1);
967 // If we receive nothing, wait until the next try.
971 // The read should never return anything but 0 or what we asked for.
972 assert (read
== sigSize
+ 1);
974 if (_recvBuf
[0] != _sendBuf
[0]) {
975 log_error( "Type mismatch: client sent %d, server answered %d",
976 _recvBuf
[0], _sendBuf
[0]);
979 const boost::uint8_t* serverSig
= &_recvBuf
.front() + 1;
981 // decode server response
982 boost::uint32_t suptime
;
983 std::memcpy(&suptime
, serverSig
, 4);
984 suptime
= ntohl(suptime
);
986 log_debug("Server Uptime : %d", suptime
);
987 log_debug("FMS Version : %d.%d.%d.%d",
988 +serverSig
[4], +serverSig
[5], +serverSig
[6], +serverSig
[7]);
997 std::streamsize sent
= _socket
.write(&_recvBuf
.front() + 1, sigSize
);
999 // This should probably not happen.
1000 if (!sent
) return false;
1002 if (sent
!= sigSize
) {
1003 log_error("Could not send complete signature.");
1012 HandShaker::stage3()
1015 // Expect it back again.
1016 std::streamsize got
= _socket
.read(&_recvBuf
.front(), sigSize
);
1018 if (!got
) return false;
1020 assert (got
== sigSize
);
1022 const boost::uint8_t* serverSig
= &_recvBuf
.front();
1023 const boost::uint8_t* ourSig
= &_sendBuf
.front() + 1;
1025 const bool match
= std::equal(serverSig
, serverSig
+ sigSize
, ourSig
);
1027 // Should we set an error here?
1029 log_error( "Signatures do not match during handshake!");
1034 /// The type of Ping packet is 0x4 and contains two mandatory parameters
1035 /// and two optional parameters. The first parameter is
1036 /// the type of Ping and in short integer. The second parameter is the
1037 /// target of the ping. As Ping is always sent in Channel 2
1038 /// (control channel) and the target object in RTMP header is always 0 whicj
1039 /// means the Connection object, it's necessary to put an extra parameter
1040 /// to indicate the exact target object the Ping is sent to. The second
1041 /// parameter takes this responsibility. The value has the same meaning
1042 /// as the target object field in RTMP header. (The second value could also
1043 /// be used as other purposes, like RTT Ping/Pong. It is used as the
1044 /// timestamp.) The third and fourth parameters are optional and could be
1045 /// looked upon as the parameter of the Ping packet.
1047 sendCtrl(RTMP
& r
, ControlType t
, unsigned int nObject
, unsigned int nTime
)
1049 log_debug( "Sending control type %s %s", +t
, t
);
1051 RTMPPacket
packet(256);
1053 packet
.header
.channel
= CHANNEL_CONTROL1
;
1054 packet
.header
.headerType
= RTMP_PACKET_SIZE_LARGE
;
1055 packet
.header
.packetType
= PACKET_TYPE_CONTROL
;
1057 // type 3 is the buffer time and requires all 3 parameters.
1058 // all in all 10 bytes.
1059 int nSize
= (t
== CONTROL_BUFFER_TIME
? 10 : 6);
1060 if (t
== CONTROL_RESPOND_VERIFY
) nSize
= 44;
1062 SimpleBuffer
& buf
= *packet
.buffer
;
1064 buf
.appendNetworkShort(t
);
1066 if (t
== CONTROL_RESPOND_VERIFY
) { }
1068 if (nSize
> 2) buf
.appendNetworkLong(nObject
);
1069 if (nSize
> 6) buf
.appendNetworkLong(nTime
);
1071 return r
.sendPacket(packet
);
1078 sendBytesReceived(RTMP
* r
)
1080 RTMPPacket
packet(4);
1082 packet
.header
.channel
= CHANNEL_CONTROL1
;
1083 packet
.header
.packetType
= PACKET_TYPE_BYTES_READ
;
1085 SimpleBuffer
& buf
= *packet
.buffer
;
1087 buf
.appendNetworkLong(r
->_bytesIn
);
1088 r
->_bytesInSent
= r
->_bytesIn
;
1090 return r
->sendPacket(packet
);
1095 handleMetadata(RTMP
& /*r*/, const boost::uint8_t* /* payload*/,
1096 unsigned int /*len*/)
1102 handleChangeChunkSize(RTMP
& r
, const RTMPPacket
& packet
)
1104 if (payloadSize(packet
) >= 4) {
1105 r
._inChunkSize
= amf::readNetworkLong(payloadData(packet
));
1106 log_debug( "Changed chunk size to %d", r
._inChunkSize
);
1111 handleControl(RTMP
& r
, const RTMPPacket
& packet
)
1114 const size_t size
= payloadSize(packet
);
1117 log_error("Control packet too short");
1121 const ControlType t
=
1122 static_cast<ControlType
>(amf::readNetworkShort(payloadData(packet
)));
1125 log_error("Control packet (%s) data too short", t
);
1129 const int arg
= amf::readNetworkLong(payloadData(packet
) + 2);
1130 log_debug( "Received control packet %s with argument %s", t
, arg
);
1135 case CONTROL_CLEAR_STREAM
:
1136 // TODO: handle this.
1139 case CONTROL_CLEAR_BUFFER
:
1140 // TODO: handle this.
1143 case CONTROL_STREAM_DRY
:
1146 case CONTROL_RESET_STREAM
:
1147 log_debug("Stream is recorded: %s", arg
);
1151 sendCtrl(r
, CONTROL_PONG
, arg
, 0);
1154 case CONTROL_BUFFER_EMPTY
:
1158 case CONTROL_BUFFER_READY
:
1163 log_error("Received unknown or unhandled control %s", t
);
1170 handleServerBW(RTMP
& r
, const RTMPPacket
& packet
)
1172 const boost::uint32_t bw
= amf::readNetworkLong(payloadData(packet
));
1173 log_debug( "Server bandwidth is %s", bw
);
1174 r
.setServerBandwidth(bw
);
1178 handleClientBW(RTMP
& r
, const RTMPPacket
& packet
)
1180 const boost::uint32_t bw
= amf::readNetworkLong(payloadData(packet
));
1184 if (payloadSize(packet
) > 4) r
.m_nClientBW2
= payloadData(packet
)[4];
1185 else r
.m_nClientBW2
= -1;
1187 log_debug( "Client bandwidth is %d %d", r
.bandwidth(), +r
.m_nClientBW2
);
1193 decodeInt32LE(const boost::uint8_t* c
)
1195 return (c
[3] << 24) | (c
[2] << 16) | (c
[1] << 8) | c
[0];
1199 encodeInt32LE(boost::uint8_t *output
, int nVal
)
1212 setupInvokePacket(RTMPPacket
& packet
)
1214 RTMPHeader
& hr
= packet
.header
;
1216 hr
.channel
= CHANNEL_CONTROL2
;
1218 hr
.packetType
= PACKET_TYPE_INVOKE
;
1222 decodeInt24(const boost::uint8_t *c
)
1225 val
= (c
[0] << 16) | (c
[1] << 8) | c
[2];
1230 encodeInt16(boost::uint8_t *output
, boost::uint8_t *outend
, short nVal
)
1232 if (output
+2 > outend
) return NULL
;
1234 output
[1] = nVal
& 0xff;
1235 output
[0] = nVal
>> 8;
1240 encodeInt24(boost::uint8_t *output
, boost::uint8_t *outend
, int nVal
)
1242 if (output
+ 3 > outend
) return NULL
;
1244 output
[2] = nVal
& 0xff;
1245 output
[1] = nVal
>> 8;
1246 output
[0] = nVal
>> 16;
1251 encodeInt32(boost::uint8_t *output
, boost::uint8_t *outend
, int nVal
)
1253 if (output
+4 > outend
) return NULL
;
1255 output
[3] = nVal
& 0xff;
1256 output
[2] = nVal
>> 8;
1257 output
[1] = nVal
>> 16;
1258 output
[0] = nVal
>> 24;
1265 #if !defined(_WIN32) && !defined(__amigaos4__)
1267 return times(&t
) * 1000 / sysconf(_SC_CLK_TCK
);
1268 #elif defined(__amigaos4__)
1270 return times(&t
) * 1000 / 50;
1272 return std::clock() * 100 / CLOCKS_PER_SEC
;
1276 } // anonymous namespace
1279 operator<<(std::ostream
& o
, PacketType p
)
1282 case PACKET_TYPE_CHUNK_SIZE
:
1283 return o
<< "<chunk size packet>";
1284 case PACKET_TYPE_BYTES_READ
:
1285 return o
<< "<bytes read packet>";
1286 case PACKET_TYPE_CONTROL
:
1287 return o
<< "<control packet>";
1288 case PACKET_TYPE_SERVERBW
:
1289 return o
<< "<server bw packet>";
1290 case PACKET_TYPE_CLIENTBW
:
1291 return o
<< "<client bw packet>";
1292 case PACKET_TYPE_AUDIO
:
1293 return o
<< "<audio packet>";
1294 case PACKET_TYPE_VIDEO
:
1295 return o
<< "<video packet>";
1296 case PACKET_TYPE_FLEX_STREAM_SEND
:
1297 return o
<< "<flex stream send packet>";
1298 case PACKET_TYPE_FLEX_SHARED_OBJECT
:
1299 return o
<< "<flex sharedobject packet>";
1300 case PACKET_TYPE_FLEX_MESSAGE
:
1301 return o
<< "<flex message packet>";
1302 case PACKET_TYPE_METADATA
:
1303 return o
<< "<metadata packet>";
1304 case PACKET_TYPE_SHARED_OBJECT
:
1305 return o
<< "<sharedobject packet>";
1306 case PACKET_TYPE_INVOKE
:
1307 return o
<< "<invoke packet>";
1308 case PACKET_TYPE_FLV
:
1309 return o
<< "<flv packet>";
1311 return o
<< "<unknown packet type " << +p
<< ">";
1316 operator<<(std::ostream
& o
, ControlType t
)
1320 case CONTROL_CLEAR_STREAM
:
1321 return o
<< "<clear stream>";
1322 case CONTROL_CLEAR_BUFFER
:
1323 return o
<< "<clear buffer>";
1324 case CONTROL_STREAM_DRY
:
1325 return o
<< "<stream dry>";
1326 case CONTROL_BUFFER_TIME
:
1327 return o
<< "<buffer time>";
1328 case CONTROL_RESET_STREAM
:
1329 return o
<< "<reset stream>";
1331 return o
<< "<ping>";
1333 return o
<< "<pong>";
1334 case CONTROL_REQUEST_VERIFY
:
1335 return o
<< "<verify request>";
1336 case CONTROL_RESPOND_VERIFY
:
1337 return o
<< "<verify response>";
1338 case CONTROL_BUFFER_EMPTY
:
1339 return o
<< "<buffer empty>";
1340 case CONTROL_BUFFER_READY
:
1341 return o
<< "<buffer ready>";
1343 return o
<< "<unknown control " << +t
<< ">";
1348 } // namespace gnash