Files
ANSCORE/MediaClient/rtsp/rtsp_ws.cpp

212 lines
5.3 KiB
C++

/***************************************************************************************
*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
*
* Redistribution and use in binary forms, with or without modification, are permitted.
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*
****************************************************************************************/
#include "sys_inc.h"
#include "rtsp_ws.h"
#include "rtp.h"
int rtsp_ws_decode_data(WSMSG * p_msg)
{
int length, has_mask;
char * p_buff = p_msg->buff;
/**
* Extracting information from frame
*/
has_mask = p_buff[1] & 0x80 ? 1 : 0;
length = p_buff[1] & 0x7f;
p_msg->opcode = (p_buff[0] & 0xF);
p_msg->finbit = ((p_buff[0] & 0x80) ? 1 : 0);
/**
* We need to handle the received frame differently according to which
* length that the frame has set.
*
* length <= 125: We know that length is the actual length of the message,
* and that the maskin data must be placed 2 bytes further
* ahead.
* length == 126: We know that the length is an unsigned 16 bit integer,
* which is placed at the 2 next bytes, and that the masking
* data must be further 2 bytes away.
* length == 127: We know that the length is an unsigned 64 bit integer,
* which is placed at the 8 next bytes, and that the masking
* data must be further 2 bytes away.
*/
if (length <= 125)
{
if (p_msg->rcv_len < 6)
{
return 0;
}
p_msg->msg_len = length;
p_msg->skip = 2;
if (has_mask)
{
p_msg->skip += 4;
memcpy(&p_msg->mask, p_buff + 2, sizeof(p_msg->mask));
}
}
else if (length == 126)
{
if (p_msg->rcv_len < 8)
{
return 0;
}
p_msg->msg_len = rtp_read_uint16((uint8 *)p_buff + 2);
p_msg->skip = 4;
if (has_mask)
{
p_msg->skip += 4;
memcpy(&p_msg->mask, p_buff + 4, sizeof(p_msg->mask));
}
}
else if (length == 127)
{
if (p_msg->rcv_len < 14)
{
return 0;
}
p_msg->msg_len = (uint32)rtp_read_uint64((uint8 *)p_buff + 2);
p_msg->skip = 10;
if (has_mask)
{
p_msg->skip += 4;
memcpy(&p_msg->mask, p_buff + 10, sizeof(p_msg->mask));
}
}
else
{
log_print(HT_LOG_ERR, "%s, Obscure length received from client: %d\r\n", __FUNCTION__, length);
return -1;
}
/**
* If the message length is greater that our WS_MAXMESSAGE constant, we
* skip the message and close the connection.
*/
if (p_msg->msg_len > WS_MAXMESSAGE)
{
log_print(HT_LOG_ERR, "%s, Message received was bigger than WS_MAXMESSAGE\r\n", __FUNCTION__);
return -1;
}
uint32 buf_len = (p_msg->rcv_len - p_msg->skip);
/**
* The message read from recv is larger than the message we are supposed
* to receive. This means that we have received the first part of the next
* message as well.
*/
if (buf_len >= p_msg->msg_len)
{
if (has_mask)
{
char * buff = p_msg->buff + p_msg->skip;
/**
* If everything went well, we have to remove the masking from the data.
*/
for (uint32 i = 0; i < p_msg->msg_len; i++)
{
buff[i] = buff[i] ^ p_msg->mask[i % 4];
}
}
return 1;
}
return 0;
}
/***
* websocket encod data, add websocket header before p_data
* The p_data pointer must reserve a certain amount of space
*/
int rtsp_ws_encode_data(uint8 * p_data, int len, uint8 opcode, uint8 have_mask)
{
int offset = 0;
uint8 mask[4];
if (have_mask)
{
mask[0] = rand();
mask[1] = rand();
mask[2] = rand();
mask[3] = rand();
for (int32 i = 0; i < len; i++)
{
p_data[i] = p_data[i] ^ mask[i % 4];
}
}
/**
* RFC6455 message encoding
*/
if (len <= 125)
{
p_data -= have_mask ? 6 : 2;
p_data[0] = opcode;
p_data[1] = have_mask ? (len | 0x80) : len;
if (have_mask)
{
memcpy(p_data+2, mask, 4);
}
offset = have_mask ? 6 : 2;
}
else if (len <= 65535)
{
p_data -= have_mask ? 8 : 4;
p_data[0] = opcode;
p_data[1] = have_mask ? (126 | 0x80) : 126;
rtp_write_uint16(p_data + 2, len);
if (have_mask)
{
memcpy(p_data+4, mask, 4);
}
offset = have_mask ? 8 : 4;
}
else
{
uint64 len64 = len;
p_data -= have_mask ? 14 : 10;
p_data[0] = opcode;
p_data[1] = have_mask ? (127 | 0x80) : 127;
rtp_write_uint32(p_data + 2, len64 & 0xFFFF);
rtp_write_uint32(p_data + 6, (len64 >> 32) & 0xFFFF);
if (have_mask)
{
memcpy(p_data+10, mask, 4);
}
offset = have_mask ? 14 : 10;
}
return offset;
}