stream-deploy/ZLM/3rdpart/media-server/librtmp/source/rtmp-control-handler.c

119 lines
2.8 KiB
C++

#include "rtmp-internal.h"
#include "rtmp-msgtypeid.h"
#include "rtmp-util.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define RTMP_CHUNK_SIZE_MINIMUM 64
#define RTMP_CHUNK_SIZE_MAXIMUM 0x800000
/// 5.4.1. Set Chunk Size (1)
/// @return 0-error, >0-ok
static int rtmp_read_chunk_size(const uint8_t* out, size_t size, uint32_t *chunkSize)
{
if (size >= 4)
{
be_read_uint32(out, chunkSize);
if (*chunkSize < RTMP_CHUNK_SIZE_MINIMUM || *chunkSize > RTMP_CHUNK_SIZE_MAXIMUM)
return 0;
return 4;
}
return 0;
}
/// 5.4.2. Abort Message (2)
/// @return 0-error, >0-ok
static int rtmp_read_abort_message(const uint8_t* out, size_t size, uint32_t* chunkStreamId)
{
if (size >= 4)
{
be_read_uint32(out, chunkStreamId);
return 4;
}
return 0;
}
/// 5.4.3. Acknowledgement (3)
/// @return 0-error, >0-ok
static int rtmp_read_acknowledgement(const uint8_t* out, size_t size, uint32_t* sequenceNumber)
{
if (size >= 4)
{
be_read_uint32(out, sequenceNumber);
return 4;
}
return 0;
}
/// 5.4.4. Window Acknowledgement Size (5)
/// @return 0-error, >0-ok
static int rtmp_read_window_acknowledgement_size(const uint8_t* out, size_t size, uint32_t* windowSize)
{
if (size >= 4)
{
be_read_uint32(out, windowSize);
return 4;
}
return 0;
}
/// 5.4.5. Set Peer Bandwidth (6)
/// @return 0-error, >0-ok
static int rtmp_read_set_peer_bandwidth(const uint8_t* out, size_t size, uint32_t *windowSize, uint8_t *limitType)
{
if (size >= 5)
{
be_read_uint32(out, windowSize);
*limitType = out[4];
return 5;
}
return 0;
}
int rtmp_control_handler(struct rtmp_t* rtmp, const struct rtmp_chunk_header_t* header, const uint8_t* data)
{
uint32_t chunk_stream_id = 0;
assert(2 == header->cid);
switch (header->type)
{
case RTMP_TYPE_SET_CHUNK_SIZE:
assert(4 == header->length);
return rtmp_read_chunk_size(data, header->length, &rtmp->in_chunk_size);
case RTMP_TYPE_ABORT:
assert(4 == header->length);
if (4 == rtmp_read_abort_message(data, header->length, &chunk_stream_id))
{
rtmp->onabort(rtmp->param, chunk_stream_id);
return 4;
}
return 0;
case RTMP_TYPE_ACKNOWLEDGEMENT:
assert(4 == header->length);
return rtmp_read_acknowledgement(data, header->length, &rtmp->sequence_number);
case RTMP_TYPE_WINDOW_ACKNOWLEDGEMENT_SIZE:
assert(4 == header->length);
return rtmp_read_window_acknowledgement_size(data, header->length, &rtmp->window_size);
case RTMP_TYPE_SET_PEER_BANDWIDTH:
assert(5 == header->length);
if (5 == rtmp_read_set_peer_bandwidth(data, header->length, &rtmp->peer_bandwidth, &rtmp->limit_type))
{
rtmp->client.onbandwidth ? rtmp->client.onbandwidth(rtmp->param) : 0;
return 5;
}
return 0;
default:
printf("unknown rtmp protocol control message: %d\n", (int)header->type);
assert(0);
return 0;
}
}