mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-01-12 00:04:03 +08:00
295 lines
6.6 KiB
C++
295 lines
6.6 KiB
C++
#include "HSExt.hpp"
|
|
|
|
namespace SRT {
|
|
|
|
bool HSExtMessage::loadFromData(uint8_t *buf, size_t len) {
|
|
if (buf == NULL || len != HSEXT_MSG_SIZE) {
|
|
return false;
|
|
}
|
|
|
|
_data = BufferRaw::create();
|
|
_data->assign((char *)buf, len);
|
|
extension_length = 3;
|
|
HSExt::loadHeader();
|
|
|
|
assert(extension_type == SRT_CMD_HSREQ || extension_type == SRT_CMD_HSRSP);
|
|
|
|
uint8_t *ptr = (uint8_t *)_data->data() + 4;
|
|
srt_version = loadUint32(ptr);
|
|
ptr += 4;
|
|
|
|
srt_flag = loadUint32(ptr);
|
|
ptr += 4;
|
|
|
|
recv_tsbpd_delay = loadUint16(ptr);
|
|
ptr += 2;
|
|
|
|
send_tsbpd_delay = loadUint16(ptr);
|
|
ptr += 2;
|
|
|
|
return true;
|
|
}
|
|
|
|
std::string HSExtMessage::dump() {
|
|
_StrPrinter printer;
|
|
printer << "srt version : " << std::hex << srt_version << " srt flag : " << std::hex << srt_flag
|
|
<< " recv_tsbpd_delay=" << recv_tsbpd_delay << " send_tsbpd_delay = " << send_tsbpd_delay;
|
|
return printer;
|
|
}
|
|
|
|
bool HSExtMessage::storeToData() {
|
|
_data = BufferRaw::create();
|
|
_data->setCapacity(HSEXT_MSG_SIZE);
|
|
_data->setSize(HSEXT_MSG_SIZE);
|
|
extension_length = 3;
|
|
HSExt::storeHeader();
|
|
uint8_t *ptr = (uint8_t *)_data->data() + 4;
|
|
|
|
storeUint32(ptr, srt_version);
|
|
ptr += 4;
|
|
|
|
storeUint32(ptr, srt_flag);
|
|
ptr += 4;
|
|
|
|
storeUint16(ptr, recv_tsbpd_delay);
|
|
ptr += 2;
|
|
|
|
storeUint16(ptr, send_tsbpd_delay);
|
|
ptr += 2;
|
|
return true;
|
|
}
|
|
|
|
bool HSExtStreamID::loadFromData(uint8_t *buf, size_t len) {
|
|
if (buf == NULL || len < 4) {
|
|
return false;
|
|
}
|
|
_data = BufferRaw::create();
|
|
_data->assign((char *)buf, len);
|
|
|
|
HSExt::loadHeader();
|
|
|
|
size_t content_size = extension_length * 4;
|
|
if (len < content_size + 4) {
|
|
return false;
|
|
}
|
|
streamid.clear();
|
|
char *ptr = _data->data() + 4;
|
|
|
|
for (size_t i = 0; i < extension_length; ++i) {
|
|
streamid.push_back(*(ptr + 3));
|
|
streamid.push_back(*(ptr + 2));
|
|
streamid.push_back(*(ptr + 1));
|
|
streamid.push_back(*(ptr));
|
|
ptr += 4;
|
|
}
|
|
char zero = 0x00;
|
|
if (!streamid.empty()) {
|
|
if (streamid.back() == zero) {
|
|
streamid.erase(streamid.find_first_of(zero), streamid.size());
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool HSExtStreamID::storeToData() {
|
|
size_t content_size = ((streamid.length() + 4) + 3) / 4 * 4;
|
|
|
|
_data = BufferRaw::create();
|
|
_data->setCapacity(content_size);
|
|
_data->setSize(content_size);
|
|
extension_length = (content_size - 4) / 4;
|
|
extension_type = SRT_CMD_SID;
|
|
HSExt::storeHeader();
|
|
auto ptr = _data->data() + 4;
|
|
memset(ptr, 0, extension_length * 4);
|
|
const char *src = streamid.c_str();
|
|
for (size_t i = 0; i < streamid.length() / 4; ++i) {
|
|
*ptr = *(src + 3 + i * 4);
|
|
ptr++;
|
|
|
|
*ptr = *(src + 2 + i * 4);
|
|
ptr++;
|
|
|
|
*ptr = *(src + 1 + i * 4);
|
|
ptr++;
|
|
|
|
*ptr = *(src + 0 + i * 4);
|
|
ptr++;
|
|
}
|
|
|
|
ptr += 3;
|
|
size_t offset = streamid.length() / 4 * 4;
|
|
for (size_t i = 0; i < streamid.length() % 4; ++i) {
|
|
*ptr = *(src + offset + i);
|
|
ptr -= 1;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
std::string HSExtStreamID::dump() {
|
|
_StrPrinter printer;
|
|
printer << " streamid : " << streamid;
|
|
return printer;
|
|
}
|
|
|
|
size_t KeyMaterial::getContentSize() {
|
|
size_t variable_width = _slen + _warpped_key.size();
|
|
size_t content_size = variable_width + 16;
|
|
return content_size;
|
|
}
|
|
|
|
bool KeyMaterial::loadFromData(uint8_t *buf, size_t len) {
|
|
if (buf == NULL || len < 16) {
|
|
return false;
|
|
}
|
|
uint8_t *ptr = (uint8_t *)buf;
|
|
|
|
_km_version = (*ptr & 0x70) >> 4;
|
|
_pt = *ptr & 0x0f;
|
|
ptr += 1;
|
|
|
|
_sign = loadUint16(ptr);
|
|
ptr += 2;
|
|
|
|
_kk = *ptr & 0x03;
|
|
auto sek_num = 1;
|
|
if (_kk == KEY_BASED_ENCRYPTION_BOTH_SEK) {
|
|
sek_num = 2;
|
|
}
|
|
ptr += 1;
|
|
|
|
_keki = loadUint32(ptr);
|
|
ptr += 4;
|
|
|
|
_cipher = *ptr;
|
|
ptr += 1;
|
|
|
|
_auth = *ptr;
|
|
ptr += 1;
|
|
|
|
_se = *ptr;
|
|
ptr += 1;
|
|
|
|
//Resv2
|
|
ptr += 1;
|
|
//Resv3
|
|
ptr += 2;
|
|
|
|
_slen = *ptr *4;
|
|
ptr += 1;
|
|
|
|
_klen = *ptr *4;
|
|
ptr += 1;
|
|
|
|
size_t wrapped_key_len = 8 + sek_num * _klen;
|
|
size_t variable_width = _slen + wrapped_key_len;
|
|
if (len < variable_width + 16) {
|
|
return false;
|
|
}
|
|
|
|
_salt.assign((const char*)ptr, (size_t)_slen);
|
|
ptr += _slen;
|
|
|
|
_warpped_key.assign((const char*)ptr, (size_t)wrapped_key_len);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool KeyMaterial::storeToData(uint8_t *buf, size_t len) {
|
|
auto content_size = getContentSize();
|
|
if (len < content_size) {
|
|
return false;
|
|
}
|
|
|
|
uint8_t *ptr = (uint8_t *)buf;
|
|
memset(ptr, 0, len);
|
|
|
|
*ptr = ((_km_version << 4)& 0x70) | (_pt & 0x0f);
|
|
ptr += 1;
|
|
|
|
storeUint16(ptr, _sign);
|
|
ptr += 2;
|
|
|
|
*ptr = _kk & 0x03;
|
|
ptr += 1;
|
|
|
|
storeUint32(ptr, _keki);
|
|
ptr += 4;
|
|
|
|
*ptr = _cipher;
|
|
ptr += 1;
|
|
|
|
*ptr = _auth;
|
|
ptr += 1;
|
|
|
|
*ptr = _se;
|
|
ptr += 1;
|
|
|
|
*ptr = 0; //Resv2
|
|
ptr += 1;
|
|
|
|
storeUint16(ptr, 0);//Resv3
|
|
ptr += 2;
|
|
|
|
*ptr = (uint8_t)(_slen/4);
|
|
ptr += 1;
|
|
|
|
*ptr = (uint8_t)(_klen/4);
|
|
ptr += 1;
|
|
|
|
const char *src = _salt.data();
|
|
for (size_t i = 0; i < _salt.size(); ptr++, src++, i++) {
|
|
*ptr = *src;
|
|
}
|
|
|
|
src = _warpped_key.data();
|
|
for (size_t i = 0; i < _warpped_key.size(); ptr++, src++, i++) {
|
|
*ptr = *src;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
std::string KeyMaterial::dump() {
|
|
_StrPrinter printer;
|
|
printer << "kmVersion: " << _km_version
|
|
<< " pt : " << _pt
|
|
<< " sign : " << std::hex << _sign
|
|
<< " kk : " << _kk
|
|
<< " keki : " << _keki
|
|
<< " cipher : " << _cipher
|
|
<< " auth : " << _auth
|
|
<< " se : " << _se
|
|
<< " sLen : " << _slen
|
|
<< " salt : " << std::hex << _salt.data()
|
|
<< " kLen : " << _klen;
|
|
return printer;
|
|
}
|
|
|
|
bool HSExtKeyMaterial::loadFromData(uint8_t *buf, size_t len) {
|
|
if (buf == NULL || len < 4) {
|
|
return false;
|
|
}
|
|
HSExt::_data = BufferRaw::create();
|
|
HSExt::_data->assign((char *)buf, len);
|
|
HSExt::loadHeader();
|
|
assert(extension_type == SRT_CMD_KMREQ || extension_type == SRT_CMD_KMRSP);
|
|
return KeyMaterial::loadFromData(buf +4, len -4);
|
|
}
|
|
|
|
bool HSExtKeyMaterial::storeToData() {
|
|
size_t content_size = ((KeyMaterial::getContentSize() + 4) + 3) / 4 * 4;
|
|
HSExt::_data = BufferRaw::create();
|
|
HSExt::_data->setCapacity(content_size);
|
|
HSExt::_data->setSize(content_size);
|
|
extension_length = (content_size - 4) / 4;
|
|
HSExt::storeHeader();
|
|
return KeyMaterial::storeToData((uint8_t*)_data->data() + 4, content_size - 4);
|
|
}
|
|
|
|
std::string HSExtKeyMaterial::dump() {
|
|
return KeyMaterial::dump();
|
|
}
|
|
|
|
} // namespace SRT
|