Пример #1
0
bool BaseVariantProtocol::SignalInputData(IOBuffer &buffer) {
	if (_pProtocolHandler == NULL) {
		FATAL("This protocol is not registered to any application yet");
		return false;
	}

	if (_pFarProtocol->GetType() == PT_OUTBOUND_HTTP
			|| _pFarProtocol->GetType() == PT_INBOUND_HTTP) {
#ifdef HAS_PROTOCOL_HTTP
		//1. This is a HTTP based transfer. We only start doing stuff
		//after a complete request is made.
		BaseHTTPProtocol *pHTTPProtocol = (BaseHTTPProtocol *) _pFarProtocol;
		if (!pHTTPProtocol->TransferCompleted())
			return true;

		if (!Deserialize(GETIBPOINTER(buffer), pHTTPProtocol->GetContentLength(),
				_lastReceived)) {
			FATAL("Unable to deserialize content");
			return false;
		}
		buffer.Ignore(pHTTPProtocol->GetContentLength());

		_lastReceived.Compact();

		return _pProtocolHandler->ProcessMessage(this, _lastSent, _lastReceived);
#else
		FATAL("HTTP protocol not supported");
		return false;
#endif /* HAS_PROTOCOL_HTTP */
	} else if (_pFarProtocol->GetType() == PT_TCP) {
		while (GETAVAILABLEBYTESCOUNT(buffer) > 4) {
			uint32_t size = ENTOHLP(GETIBPOINTER(buffer));
			if (size > 4 * 1024 * 1024) {
				FATAL("Size too big: %u", size);
				return false;
			}
			if (GETAVAILABLEBYTESCOUNT(buffer) < size + 4) {
				FINEST("Need more data");
				return true;
			}

			if (!Deserialize(GETIBPOINTER(buffer) + 4, size, _lastReceived)) {
				FATAL("Unable to deserialize variant");
				return false;
			}
			buffer.Ignore(size + 4);

			_lastReceived.Compact();

			if (!_pProtocolHandler->ProcessMessage(this, _lastSent, _lastReceived)) {
				FATAL("Unable to process message");
				return false;
			}
		}
		return true;
	} else {
		FATAL("Invalid protocol stack");
		return false;
	}
}
Пример #2
0
bool AMF0Serializer::ReadLongString(IOBuffer &buffer, Variant &variant, bool readType) {
	if (readType) {
		AMF_CHECK_BOUNDARIES(buffer, 1);
		if (GETIBPOINTER(buffer)[0] != AMF0_LONG_STRING) {
			FATAL("AMF type not valid: want: %hhu; got: %hhu",
					AMF0_LONG_STRING, GETIBPOINTER(buffer)[0]);
			return false;
		}

		if (!buffer.Ignore(1)) {
			FATAL("Unable to ignore 1 bytes");
			return false;
		}
	}

	AMF_CHECK_BOUNDARIES(buffer, 4);
	uint32_t length = ENTOHLP(GETIBPOINTER(buffer)); //----MARKED-LONG---
	if (!buffer.Ignore(4)) {
		FATAL("Unable to ignore 4 bytes");
		return false;
	}

	AMF_CHECK_BOUNDARIES(buffer, length);
	variant = string((char *) (GETIBPOINTER(buffer)), length);
	if (!buffer.Ignore(length)) {
		FATAL("Unable to ignore %u bytes", length);
		return false;
	}
	return true;
}
Пример #3
0
bool _VIDEO_AVC::Deserialize(IOBuffer &src, _VIDEO_AVC &dest) {
	dest.Clear();
	uint8_t *pBuffer = GETIBPOINTER(src);
	uint32_t length = GETAVAILABLEBYTESCOUNT(src);
	if (length<sizeof (dest._spsLength)) {
		FATAL("Not enough data");
		return false;
	}
	dest._spsLength = ENTOHSP(pBuffer);
	if (length < (
			sizeof (dest._spsLength)
			+ dest._spsLength
			+ sizeof (dest._ppsLength)
			+ 2 * sizeof (uint32_t))) {
		FATAL("Not enough data");
		return false;
	}
	dest._ppsLength = ENTOHSP(pBuffer + sizeof (dest._spsLength) + dest._spsLength);
	if (length < (
			sizeof (dest._spsLength)
			+ dest._spsLength
			+ sizeof (dest._ppsLength)
			+ dest._ppsLength
			+ 2 * sizeof (uint32_t))) {
		FATAL("Not enough data");
		return false;
	}
	if (!dest.Init(
			pBuffer + sizeof (dest._spsLength), dest._spsLength,
			pBuffer + sizeof (dest._spsLength) + dest._spsLength + sizeof (dest._ppsLength), dest._ppsLength)) {
		FATAL("Unable to init AVC");
		return false;
	}
	dest._widthOverride = ENTOHLP(pBuffer + sizeof (dest._spsLength) + dest._spsLength + sizeof (dest._ppsLength) + dest._ppsLength);
	dest._heightOverride = ENTOHLP(pBuffer + sizeof (dest._spsLength) + dest._spsLength + sizeof (dest._ppsLength) + dest._ppsLength + sizeof (uint32_t));

	return src.Ignore(sizeof (dest._spsLength) + dest._spsLength + sizeof (dest._ppsLength) + dest._ppsLength + sizeof (uint32_t) + sizeof (uint32_t));
}
Пример #4
0
bool StreamCapabilities::Deserialize(IOBuffer &src, StreamCapabilities &capabilities) {
	uint8_t *pBuffer = GETIBPOINTER(src);
	uint32_t length = GETAVAILABLEBYTESCOUNT(src);
	if (length < 28) {
		FATAL("Not enough data");
		return false;
	}
	uint64_t ver = ENTOHLLP(pBuffer);
	if (ver != __STREAM_CAPABILITIES_VERSION) {
		FATAL("Invalid stream capabilities version. Wanted: %"PRIu64"; Got: %"PRIu64,
				__STREAM_CAPABILITIES_VERSION, ver);
		return false;
	}
	capabilities.Clear();
	capabilities.videoCodecId = ENTOHLLP(pBuffer + 8);
	capabilities.audioCodecId = ENTOHLLP(pBuffer + 16);
	capabilities.bandwidthHint = ENTOHLP(pBuffer + 24);
	src.Ignore(28);
	switch (capabilities.videoCodecId) {
		case CODEC_VIDEO_AVC:
		{
			if (!_VIDEO_AVC::Deserialize(src, capabilities.avc)) {
				FATAL("Unable to deserialize avc");
				return false;
			}
			break;
		}
		default:
		{
			break;
		}
	}
	switch (capabilities.audioCodecId) {
		case CODEC_AUDIO_AAC:
		{
			if (!_AUDIO_AAC::Deserialize(src, capabilities.aac)) {
				FATAL("Unable to deserialize aac");
				return false;
			}
			break;
		}
		default:
		{
			break;
		}
	}
	return true;
}
Пример #5
0
bool VariantConnection::SendMessage(Variant &message, Variant &response) {
	string rawContent = "    ";
	if (!message.SerializeToBin(rawContent)) {
		FATAL("Unable to serialize message");
		return false;
	}
	uint8_t *pBuffer = (uint8_t *) rawContent.c_str();
	uint32_t size = rawContent.size();
	EHTONLP(pBuffer, size - 4);

	int32_t totalSentAmount = 0;
	int32_t sentAmount = 0;

	while (totalSentAmount < (int32_t) size) {
		sentAmount = send(_fd, pBuffer + totalSentAmount, size - totalSentAmount, 0);
		if (sentAmount <= 0) {
			return false;
		}
		totalSentAmount += sentAmount;
	}

	_buffer.IgnoreAll();
	int32_t recvAmount = 0;
	for (;;) {
		if (!_buffer.ReadFromTCPFd(_fd, 1024 * 1024, recvAmount)) {
			FATAL("Unable to read from socket");
			return false;
		}
		size = GETAVAILABLEBYTESCOUNT(_buffer);
		pBuffer = GETIBPOINTER(_buffer);
		if (size < 4) {
			WARN("not enough data. Wait for more...");
			continue;
		}
		uint32_t variantSize = ENTOHLP(pBuffer);
		if (variantSize + 4 > size) {
			WARN("not enough data. Wait for more...");
			continue;
		}
		if (!Variant::DeserializeFromBin(pBuffer + 4, variantSize, response)) {
			FATAL("Unable to deserialize buffer");
			return false;
		}
		return true;
	}
}
Пример #6
0
bool _AUDIO_AAC::Deserialize(IOBuffer &src, _AUDIO_AAC &dest) {
	dest.Clear();
	uint8_t *pBuffer = GETIBPOINTER(src);
	uint32_t length = GETAVAILABLEBYTESCOUNT(src);
	if (length<sizeof (dest._aacLength)) {
		FATAL("Not enough data");
		return false;
	}
	dest._aacLength = ENTOHLP(pBuffer);
	if (length<sizeof (dest._aacLength) + dest._aacLength) {
		FATAL("Not enough data");
		return false;
	}
	if (!dest.Init(pBuffer + sizeof (dest._aacLength), dest._aacLength)) {
		FATAL("Unable to init AAC");
		return false;
	}
	return src.Ignore(sizeof (dest._aacLength) + dest._aacLength);
}
Пример #7
0
bool Header::Read(uint32_t channelId, uint8_t type, IOBuffer &buffer,
		uint32_t availableBytes) {
	ht = type;
	ci = channelId;

	switch (ht) {
		case HT_FULL:
		{
			isAbsolute = true;
			if (availableBytes < 11) {
				readCompleted = false;
				return true;
			}
			memcpy(hf.datac + 1, GETIBPOINTER(buffer), 11);
			hf.s.ts = ENTOHL(hf.s.ts)&0x00ffffff; //----MARKED-LONG---
			hf.s.ml = ENTOHL(hf.s.ml) >> 8; //----MARKED-LONG---

			if (hf.s.ts == 0x00ffffff) {
				skip4bytes = true;
				if (availableBytes < 15) {
					readCompleted = false;
					return true;
				}
				hf.s.ts = ENTOHLP(GETIBPOINTER(buffer) + 11);
				readCompleted = true;
				return buffer.Ignore(15);
			} else {
				skip4bytes = false;
				readCompleted = true;
				return buffer.Ignore(11);
			}
		}
		case HT_SAME_STREAM:
		{
			isAbsolute = false;
			if (availableBytes < 7) {
				readCompleted = false;
				return true;
			}
			memcpy(hf.datac + 1, GETIBPOINTER(buffer), 7);
			hf.s.ts = ENTOHL(hf.s.ts)&0x00ffffff; //----MARKED-LONG---
			hf.s.ml = ENTOHL(hf.s.ml) >> 8; //----MARKED-LONG---

			if (hf.s.ts == 0x00ffffff) {
				skip4bytes = true;
				if (availableBytes < 11) {
					readCompleted = false;
					return true;
				}
				hf.s.ts = ENTOHLP(GETIBPOINTER(buffer) + 7);
				readCompleted = true;
				return buffer.Ignore(11);
			} else {
				skip4bytes = false;
				readCompleted = true;
				return buffer.Ignore(7);
			}
		}
		case HT_SAME_LENGTH_AND_STREAM:
		{
			isAbsolute = false;
			if (availableBytes < 3) {
				readCompleted = false;
				return true;
			}
			memcpy(hf.datac + 1, GETIBPOINTER(buffer), 3);
			hf.s.ts = ENTOHL(hf.s.ts)&0x00ffffff; //----MARKED-LONG---

			if (hf.s.ts == 0x00ffffff) {
				skip4bytes = true;
				if (availableBytes < 7) {
					readCompleted = false;
					return true;
				}
				hf.s.ts = ENTOHLP(GETIBPOINTER(buffer) + 3);
				readCompleted = true;
				return buffer.Ignore(7);
			} else {
				skip4bytes = false;
				readCompleted = true;
				return buffer.Ignore(3);
			}
		}
		case HT_CONTINUATION:
		{
			isAbsolute = false;
			if (skip4bytes) {
				if (availableBytes < 4) {
					readCompleted = false;
					return true;
				}
				readCompleted = true;
				return buffer.Ignore(4);
			} else {
				readCompleted = true;
				return true;
			}
		}
		default:
		{
			FATAL("Invalid header type: %hhu", ht);
			return false;
		}
	}
}
Пример #8
0
void CommonTestsSuite::test_Endianess() {
	uint16_t ui16 = 0x0102;
	uint32_t ui32 = 0x01020304;
	uint64_t ui64 = 0x0102030405060708LL;
	double d = 123.456;

	//host to network
	uint8_t *pBuffer = NULL;
	ui16 = EHTONS(ui16);
	pBuffer = (uint8_t *) & ui16;
	TS_ASSERT(pBuffer[0] == 0x01);
	TS_ASSERT(pBuffer[1] == 0x02);

	pBuffer = NULL;
	ui32 = EHTONL(ui32);
	pBuffer = (uint8_t *) & ui32;
	TS_ASSERT(pBuffer[0] == 0x01);
	TS_ASSERT(pBuffer[1] == 0x02);
	TS_ASSERT(pBuffer[2] == 0x03);
	TS_ASSERT(pBuffer[3] == 0x04);

	pBuffer = NULL;
	ui32 = 0x01020304;
	ui32 = EHTONA(ui32);
	pBuffer = (uint8_t *) & ui32;
	TS_ASSERT(pBuffer[0] == 0x02);
	TS_ASSERT(pBuffer[1] == 0x03);
	TS_ASSERT(pBuffer[2] == 0x04);
	TS_ASSERT(pBuffer[3] == 0x01);

	pBuffer = NULL;
	ui64 = EHTONLL(ui64);
	pBuffer = (uint8_t *) & ui64;
	TS_ASSERT(pBuffer[0] == 0x01);
	TS_ASSERT(pBuffer[1] == 0x02);
	TS_ASSERT(pBuffer[2] == 0x03);
	TS_ASSERT(pBuffer[3] == 0x04);
	TS_ASSERT(pBuffer[4] == 0x05);
	TS_ASSERT(pBuffer[5] == 0x06);
	TS_ASSERT(pBuffer[6] == 0x07);
	TS_ASSERT(pBuffer[7] == 0x08);

	pBuffer = NULL;
	EHTOND(d, ui64);
	pBuffer = (uint8_t *) & ui64;
	TS_ASSERT(pBuffer[0] == 0x40);
	TS_ASSERT(pBuffer[1] == 0x5e);
	TS_ASSERT(pBuffer[2] == 0xdd);
	TS_ASSERT(pBuffer[3] == 0x2f);
	TS_ASSERT(pBuffer[4] == 0x1a);
	TS_ASSERT(pBuffer[5] == 0x9f);
	TS_ASSERT(pBuffer[6] == 0xbe);
	TS_ASSERT(pBuffer[7] == 0x77);

	//network to host pointer
	char buffer[] = {
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f
	};

	ui16 = ENTOHSP(buffer);
	TS_ASSERT(ui16 == 0x0001);
	ui16 = ENTOHSP(buffer + 1);
	TS_ASSERT(ui16 == 0x0102);
	ui16 = ENTOHSP(buffer + 2);
	TS_ASSERT(ui16 == 0x0203);
	ui16 = ENTOHSP(buffer + 3);
	TS_ASSERT(ui16 == 0x0304);
	ui16 = ENTOHSP(buffer + 4);
	TS_ASSERT(ui16 == 0x0405);
	ui16 = ENTOHSP(buffer + 5);
	TS_ASSERT(ui16 == 0x0506);
	ui16 = ENTOHSP(buffer + 6);
	TS_ASSERT(ui16 == 0x0607);
	ui16 = ENTOHSP(buffer + 7);
	TS_ASSERT(ui16 == 0x0708);
	ui16 = ENTOHSP(buffer + 8);
	TS_ASSERT(ui16 == 0x0809);
	ui16 = ENTOHSP(buffer + 9);
	TS_ASSERT(ui16 == 0x090a);
	ui16 = ENTOHSP(buffer + 10);
	TS_ASSERT(ui16 == 0x0a0b);
	ui16 = ENTOHSP(buffer + 11);
	TS_ASSERT(ui16 == 0x0b0c);
	ui16 = ENTOHSP(buffer + 12);
	TS_ASSERT(ui16 == 0x0c0d);
	ui16 = ENTOHSP(buffer + 13);
	TS_ASSERT(ui16 == 0x0d0e);
	ui16 = ENTOHSP(buffer + 14);
	TS_ASSERT(ui16 == 0x0e0f);

	ui32 = ENTOHLP(buffer);
	TS_ASSERT(ui32 == 0x00010203);
	ui32 = ENTOHLP(buffer + 1);
	TS_ASSERT(ui32 == 0x01020304);
	ui32 = ENTOHLP(buffer + 2);
	TS_ASSERT(ui32 == 0x02030405);
	ui32 = ENTOHLP(buffer + 3);
	TS_ASSERT(ui32 == 0x03040506);
	ui32 = ENTOHLP(buffer + 4);
	TS_ASSERT(ui32 == 0x04050607);
	ui32 = ENTOHLP(buffer + 5);
	TS_ASSERT(ui32 == 0x05060708);
	ui32 = ENTOHLP(buffer + 6);
	TS_ASSERT(ui32 == 0x06070809);
	ui32 = ENTOHLP(buffer + 7);
	TS_ASSERT(ui32 == 0x0708090a);
	ui32 = ENTOHLP(buffer + 8);
	TS_ASSERT(ui32 == 0x08090a0b);
	ui32 = ENTOHLP(buffer + 9);
	TS_ASSERT(ui32 == 0x090a0b0c);
	ui32 = ENTOHLP(buffer + 10);
	TS_ASSERT(ui32 == 0x0a0b0c0d);
	ui32 = ENTOHLP(buffer + 11);
	TS_ASSERT(ui32 == 0x0b0c0d0e);
	ui32 = ENTOHLP(buffer + 12);
	TS_ASSERT(ui32 == 0x0c0d0e0f);

	ui32 = ENTOHAP(buffer);
	TS_ASSERT(ui32 == 0x03000102);
	ui32 = ENTOHAP(buffer + 1);
	TS_ASSERT(ui32 == 0x04010203);
	ui32 = ENTOHAP(buffer + 2);
	TS_ASSERT(ui32 == 0x05020304);
	ui32 = ENTOHAP(buffer + 3);
	TS_ASSERT(ui32 == 0x06030405);
	ui32 = ENTOHAP(buffer + 4);
	TS_ASSERT(ui32 == 0x07040506);
	ui32 = ENTOHAP(buffer + 5);
	TS_ASSERT(ui32 == 0x08050607);
	ui32 = ENTOHAP(buffer + 6);
	TS_ASSERT(ui32 == 0x09060708);
	ui32 = ENTOHAP(buffer + 7);
	TS_ASSERT(ui32 == 0x0a070809);
	ui32 = ENTOHAP(buffer + 8);
	TS_ASSERT(ui32 == 0x0b08090a);
	ui32 = ENTOHAP(buffer + 9);
	TS_ASSERT(ui32 == 0x0c090a0b);
	ui32 = ENTOHAP(buffer + 10);
	TS_ASSERT(ui32 == 0x0d0a0b0c);
	ui32 = ENTOHAP(buffer + 11);
	TS_ASSERT(ui32 == 0x0e0b0c0d);
	ui32 = ENTOHAP(buffer + 12);
	TS_ASSERT(ui32 == 0x0f0c0d0e);

	ui64 = ENTOHLLP(buffer);
	TS_ASSERT(ui64 == 0x0001020304050607LL);
	ui64 = ENTOHLLP(buffer + 1);
	TS_ASSERT(ui64 == 0x0102030405060708LL);
	ui64 = ENTOHLLP(buffer + 2);
	TS_ASSERT(ui64 == 0x0203040506070809LL);
	ui64 = ENTOHLLP(buffer + 3);
	TS_ASSERT(ui64 == 0x030405060708090aLL);
	ui64 = ENTOHLLP(buffer + 4);
	TS_ASSERT(ui64 == 0x0405060708090a0bLL);
	ui64 = ENTOHLLP(buffer + 5);
	TS_ASSERT(ui64 == 0x05060708090a0b0cLL);
	ui64 = ENTOHLLP(buffer + 6);
	TS_ASSERT(ui64 == 0x060708090a0b0c0dLL);
	ui64 = ENTOHLLP(buffer + 7);
	TS_ASSERT(ui64 == 0x0708090a0b0c0d0eLL);
	ui64 = ENTOHLLP(buffer + 8);
	TS_ASSERT(ui64 == 0x08090a0b0c0d0e0fLL);

	char *pTempBuffer = new char[64 + 8];
	unsigned char rawDouble[] = {0x40, 0x5E, 0xDD, 0x2F, 0x1A, 0x9F, 0xBE, 0x77};
	double tempDoubleVal = 0;
	for (int i = 0; i <= 64; i++) {
		memset(pTempBuffer, 0, i);
		memcpy(pTempBuffer + i, rawDouble, 8);
		memset(pTempBuffer + i + 8, 0, 64 + 8 - i - 8);
		ENTOHDP((pTempBuffer + i), tempDoubleVal);
		TS_ASSERT(d == tempDoubleVal);
	}
	delete[] pTempBuffer;

	//network to host
#ifdef LITTLE_ENDIAN_BYTE_ALIGNED
	TS_ASSERT(ENTOHA(0x01040302) == 0x01020304);
	TS_ASSERT(ENTOHLL(0x0807060504030201LL) == 0x0102030405060708LL);
	ENTOHD(0x77BE9F1A2FDD5E40LL, tempDoubleVal);
	TS_ASSERT(d == tempDoubleVal);
#endif /* LITTLE_ENDIAN_BYTE_ALIGNED */

#ifdef LITTLE_ENDIAN_SHORT_ALIGNED
	TS_ASSERT(ENTOHA(0x01040302) == 0x01020304);
	TS_ASSERT(ENTOHLL(0x0807060504030201LL) == 0x0102030405060708LL);
	ENTOHD(0x77BE9F1A2FDD5E40LL, tempDoubleVal);
	TS_ASSERT(d == tempDoubleVal);
#endif /* LITTLE_ENDIAN_SHORT_ALIGNED */

#ifdef BIG_ENDIAN_BYTE_ALIGNED
	TS_ASSERT(ENTOHA(0x02030401) == 0x01020304);
	TS_ASSERT(ENTOHLL(0x0102030405060708LL) == 0x0102030405060708LL);
#error ENTOHD not tested
#endif /* BIG_ENDIAN_BYTE_ALIGNED */

#ifdef BIG_ENDIAN_SHORT_ALIGNED
#error BIG_ENDIAN_SHORT_ALIGNED set of tests not yet implemented!!! Please take care of this first!!!
#endif /* BIG_ENDIAN_SHORT_ALIGNED */

	//double mirror
	TS_ASSERT(ENTOHS(EHTONS(0x0102)) == 0x0102);
	TS_ASSERT(EHTONS(ENTOHS(0x0102)) == 0x0102);

	TS_ASSERT(ENTOHL(EHTONL(0x01020304)) == 0x01020304);
	TS_ASSERT(EHTONL(ENTOHL(0x01020304)) == 0x01020304);

	TS_ASSERT(ENTOHLL(EHTONLL(0x0102030405060708LL)) == 0x0102030405060708LL);
	TS_ASSERT(EHTONLL(ENTOHLL(0x0102030405060708LL)) == 0x0102030405060708LL);

	//EHTOND/ENTOHD are different. Requires 2 parameters. So, no double mirror

	TS_ASSERT(ENTOHA(EHTONA(0x01020304)) == 0x01020304);
	TS_ASSERT(EHTONA(ENTOHA(0x01020304)) == 0x01020304);

	// Buffer Put routines
	for (int i = 0; i < 16; i++) {
		EHTONSP(buffer + i, 0x0102);
		TS_ASSERT(ENTOHSP(buffer + i) == 0x0102);

		EHTONLP(buffer + i, 0x01020304);
		TS_ASSERT(ENTOHLP(buffer + i) == 0x01020304);

		EHTONLLP(buffer + i, 0x0102030405060708LL);
		TS_ASSERT(ENTOHLLP(buffer + i) == 0x0102030405060708LL);

		EHTONDP(d, (buffer + i));
		ENTOHDP(buffer + i, tempDoubleVal);
		TS_ASSERT(d == tempDoubleVal);
	}
}
Пример #9
0
bool InboundRTMPProtocol::PerformHandshake(IOBuffer &buffer) {
	switch (_rtmpState) {
		case RTMP_STATE_NOT_INITIALIZED:
		{
			if (GETAVAILABLEBYTESCOUNT(buffer) < 1537) {
				return true;
			}
			uint8_t handshakeType = GETIBPOINTER(buffer)[0];
			if (!buffer.Ignore(1)) {
				FATAL("Unable to ignore one byte");
				return false;
			}

			_currentFPVersion = ENTOHLP(GETIBPOINTER(buffer) + 4);

			switch (handshakeType) {
				case 3: //plain
				{
					return PerformHandshake(buffer, false);
				}
				case 6: //encrypted
				{
					return PerformHandshake(buffer, true);
				}
				default:
				{
					FATAL("Handshake type not implemented: %hhu", handshakeType);
					return false;
				}
			}
		}
		case RTMP_STATE_SERVER_RESPONSE_SENT:
		{
			if (GETAVAILABLEBYTESCOUNT(buffer) < 1536) {
				return true;
			} else {
				//ignore the client's last handshake part
				if (!buffer.Ignore(1536)) {
					FATAL("Unable to ignore inbound data");
					return false;
				}
				_handshakeCompleted = true;
				_rtmpState = RTMP_STATE_DONE;

				if (_pKeyIn != NULL && _pKeyOut != NULL) {
					//insert the RTMPE protocol in the current protocol stack
					BaseProtocol *pFarProtocol = GetFarProtocol();
					RTMPEProtocol *pRTMPE = new RTMPEProtocol(_pKeyIn, _pKeyOut);
					ResetFarProtocol();
					pFarProtocol->SetNearProtocol(pRTMPE);
					pRTMPE->SetNearProtocol(this);
					FINEST("New protocol chain: %s", STR(*pFarProtocol));

					//decrypt the leftovers
					RC4(_pKeyIn, GETAVAILABLEBYTESCOUNT(buffer),
							GETIBPOINTER(buffer),
							GETIBPOINTER(buffer));
				}

				return true;
			}
		}
		default:
		{
			FATAL("Invalid RTMP state: %d", _rtmpState);
			return false;
		}
	}
}
Пример #10
0
bool RTCPProtocol::SignalInputData(IOBuffer &buffer, sockaddr_in *pPeerAddress) {
	//0. Save the last known address
	if (&_lastAddress != pPeerAddress) {
		_lastAddress = *pPeerAddress;
		_validLastAddress = true;
	}

	//1. Parse the SR
	uint8_t *pBuffer = GETIBPOINTER(buffer);
	uint32_t bufferLength = GETAVAILABLEBYTESCOUNT(buffer);
	while (bufferLength > 0) {
		if (bufferLength < 4) {
			buffer.IgnoreAll();
			return true;
		}

		uint8_t PT = pBuffer[1];
		uint16_t len = ENTOHSP(pBuffer + 2);
		len = (len + 1)*4;
		if (len > bufferLength) {
			buffer.IgnoreAll();
			return true;
		}

		switch (PT) {
			case 200: //SR
			{
				if (len < 28) {
					buffer.IgnoreAll();
					return true;
				}
				uint32_t ntpSec = ENTOHLP(pBuffer + 8) - 2208988800UL;
				uint32_t ntpFrac = ENTOHLP(pBuffer + 12);
				uint64_t ntpMicroseconds = (uint32_t) (((double) ntpFrac / (double) (0x100000000LL))*1000000.0);
				ntpMicroseconds += ((uint64_t) ntpSec)*1000000;
				uint32_t rtpTimestamp = ENTOHLP(pBuffer + 16);
				if (_pConnectivity == NULL) {
					FATAL("No connectivity, unable to send SR");
					return false;
				}
				_pConnectivity->ReportSR(ntpMicroseconds, rtpTimestamp, _isAudio);

				_lsr = ENTOHLP(pBuffer + 10);

				if (!_pConnectivity->SendRR(_isAudio)) {
					FATAL("Unable to send RR");
					_pConnectivity->EnqueueForDelete();
					_pConnectivity = NULL;
					return false;
				}
				break;
			}
			case 203: //BYE
			{
				if (_pConnectivity == NULL) {
					FATAL("No connectivity, BYE packet ignored");
					return false;
				}
				_pConnectivity->EnqueueForDelete();
				_pConnectivity = NULL;
				break;
			}
			default:
			{
				break;
			}
		}

		buffer.Ignore(len);

		pBuffer = GETIBPOINTER(buffer);
		bufferLength = GETAVAILABLEBYTESCOUNT(buffer);
	}

	return true;
}
Пример #11
0
bool OutboundConnectivity::FeedData(MSGHDR &message, double absoluteTimestamp,
		bool isAudio) {

	if (absoluteTimestamp == 0) {
		return true;
  }

#if 0
	//double rate = isAudio ? _pOutStream->GetCapabilities()->aac._sampleRate : 90000.0;
	double rate = 90000.0;
  if (isAudio) {
    BaseInStream *pPCMInStream = NULL;
    pPCMInStream = reinterpret_cast<BaseInStream*>(_pOutStream->GetStreamsManager()->FindFirstByTypeByName(ST_IN_AUDIO_PCM, QIC_STREAM_WAVE));
    StreamCapabilities *pAudioCapabilities = NULL;

    if (pPCMInStream == NULL) {
      FATAL("Inbound stream %s not found", QIC_STREAM_WAVE);
      return false;
    } else {
      pAudioCapabilities = pPCMInStream->GetCapabilities();
      if (pAudioCapabilities == NULL) {
        FATAL("Inbound stream capability %s not found", QIC_STREAM_WAVE);
        return false;
      }
    }

    rate = (CODEC_AUDIO_PCM == pAudioCapabilities->audioCodecId) ?
           pAudioCapabilities->pcm._sampleRate : _pOutStream->GetCapabilities()->aac._sampleRate;
  }

	uint32_t ssrc = isAudio ? _pOutStream->AudioSSRC() : _pOutStream->VideoSSRC();
#endif
	uint16_t messageLength = 0;
	for (uint32_t i = 0; i < (uint32_t) message.MSGHDR_MSG_IOVLEN; i++) {
		messageLength += (uint16_t) message.MSGHDR_MSG_IOV[i].IOVEC_IOV_LEN;
	}

	bool &hasTrack = isAudio ? _rtpClient.hasAudio : _rtpClient.hasVideo;
	uint32_t &packetsCount = isAudio ? _rtpClient.audioPacketsCount : _rtpClient.videoPacketsCount;
	uint32_t &bytesCount = isAudio ? _rtpClient.audioBytesCount : _rtpClient.videoBytesCount;
	uint32_t &startRTP = isAudio ? _rtpClient.audioStartRTP : _rtpClient.videoStartRTP;
	double &startTS = isAudio ? _rtpClient.audioStartTS : _rtpClient.videoStartTS;
	if (!hasTrack) {
		return true;
	}

	if (startRTP == 0xffffffff) {
		startRTP = ENTOHLP(((uint8_t *) message.MSGHDR_MSG_IOV[0].IOVEC_IOV_BASE) + 4);
		startTS = absoluteTimestamp;
	}

#if 0
/*
** temporary disable it to prevent client to enable a/v sync mechanism
** because video/audio timestamp could somehow out of sync
** it could make video or audio packets been dropped due to PTS out of range
*/
	if ((packetsCount % 500) == 0) {
		//FINEST("Send %c RTCP: %u", isAudio ? 'A' : 'V', packetsCount);
		EHTONLP(((uint8_t *) _rtcpMessage.MSGHDR_MSG_IOV[0].IOVEC_IOV_BASE) + 4, ssrc); //SSRC


		//NTP
		uint32_t integerValue = (uint32_t) (absoluteTimestamp / 1000.0);
		double fractionValue = (absoluteTimestamp / 1000.0 - ((uint32_t) (absoluteTimestamp / 1000.0)))*4294967296.0;
		uint64_t ntpVal = (_startupTime + integerValue + 2208988800ULL) << 32;
		ntpVal |= (uint32_t) fractionValue;
		EHTONLLP(_pRTCPNTP, ntpVal);

		//RTP
		uint64_t rtp = (uint64_t) (((double) (integerValue) + fractionValue / 4294967296.0) * rate);
		rtp &= 0xffffffff;
		EHTONLP(_pRTCPRTP, (uint32_t) rtp);

		//packet count
		EHTONLP(_pRTCPSPC, packetsCount);

		//octet count
		EHTONLP(_pRTCPSOC, bytesCount);
		//			FINEST("\n%s", STR(IOBuffer::DumpBuffer(((uint8_t *) _rtcpMessage.MSGHDR_MSG_IOV[0].IOVEC_IOV_BASE),
		//					_rtcpMessage.MSGHDR_MSG_IOV[0].IOVEC_IOV_LEN)));

		if (_rtpClient.isUdp) {
			SOCKET rtcpFd = isAudio ? _audioRTCPFd : _videoRTCPFd;
			sockaddr_in &rtcpAddress = isAudio ? _rtpClient.audioRtcpAddress : _rtpClient.videoRtcpAddress;
			_rtcpMessage.MSGHDR_MSG_NAME = (sockaddr *) & rtcpAddress;
			_amountSent = SENDMSG(rtcpFd, &_rtcpMessage, 0, &_dummyValue);
			if (_amountSent < 0) {
				FATAL("Unable to send message");
				return false;
			}
			ADD_OUT_BYTES_MANAGED(IOHT_UDP_CARRIER, _amountSent);
		} else {
			if (_pRTSPProtocol != NULL) {
				if (!_pRTSPProtocol->SendRaw(&_rtcpMessage,
						(uint16_t) (_rtcpMessage.MSGHDR_MSG_IOV[0].IOVEC_IOV_LEN), &_rtpClient, isAudio, false)) {
					FATAL("Unable to send raw rtcp audio data");
					return false;
				}
			}
		}
	}
#endif

	if (_rtpClient.isUdp) {
		SOCKET dataFd = isAudio ? _audioDataFd : _videoDataFd;
		sockaddr_in &dataAddress = isAudio ? _rtpClient.audioDataAddress : _rtpClient.videoDataAddress;
		message.MSGHDR_MSG_NAME = (sockaddr *) & dataAddress;
		_amountSent = SENDMSG(dataFd, &message, 0, &_dummyValue);
		if (_amountSent < 0) {
			int err = errno;
			FATAL("Unable to send message: %d; %s", err, strerror(errno));
			return false;
		}
		ADD_OUT_BYTES_MANAGED(IOHT_UDP_CARRIER, _amountSent);
	} else {
		if (_pRTSPProtocol != NULL) {
			if (!_pRTSPProtocol->SendRaw(&message, messageLength, &_rtpClient,
					isAudio, true)) {
				FATAL("Unable to send raw rtcp audio data");
				return false;
			}
		}
	}

  //INFO("send rtp data pkt %d byte cout %d", packetsCount, bytesCount);
	packetsCount++;
	bytesCount += messageLength;

	return true;
}