#include "rtspserver.h"
//#include "libctaocrypt/base64.h"
#include "sslApi.h"
#include "auth/authentication.h"
#include "rtsp_server_module.h"
#include "datasrc/data_src.h"
#include "rtspsession/rtp4server.h"
extern pthread_mutex_t g_rtsp_mutex;
static int TPRtspSocketInit(TPRTSPSERVER *pRtspServer);
static int TPRtspClose(TPRTSPSERVER *pRtspServer);
static int TPRtspCloseClientSocket(TPRTSPSERVER *pRtspServer, int iClientSocket);
int TPRtspInit(TPRTSPSERVER *pRtspServer, int iServerPort, int bNonblockSock)
{
int i;
RETURN_IVALID_IF(!pRtspServer)
pRtspServer->bNonblock = bNonblockSock;
pRtspServer->bIsRunning = 0;
pRtspServer->iNumClients = 0;
pRtspServer->iPlaybackNum = 0;
pRtspServer->pArgs = NULL;
pRtspServer->pOnAcceptSucceededCallback = NULL;
pRtspServer->iSock = -1;
for (i = 0; i < TP_TCP_MAX_CLIENT; i++)
{
pRtspServer->pClients[i] = NULL;
}
memset(&pRtspServer->ServerAddr, 0, sizeof(struct sockaddr_in));
pRtspServer->ServerAddr.sin_family = AF_INET;
#ifdef SRTP_SUPPORT
if (iServerPort == SRTP_DEFAULT_PORT)
{
pRtspServer->ServerAddr.sin_addr.s_addr = inet_addr(LOCAL_IP_ADDR);
}
else
#endif
{
pRtspServer->ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
}
pRtspServer->ServerAddr.sin_port = htons(iServerPort);
pRtspServer->iPort = iServerPort;
pRtspServer->bIsReadytoAccept = 1;
TPRtspUpdateServerIP(pRtspServer);
pRtspServer->iNeedAuthentication = 0;
pRtspServer->media_encrypt = 0;
pRtspServer->rtspAuthManeger = (AUTHMANAGER *)malloc(sizeof(AUTHMANAGER));
if (pRtspServer->rtspAuthManeger == NULL)
{
RTSP_ERROR("no memory!");
return -1;
}
initAuthManager(pRtspServer->rtspAuthManeger, 10, 1800);
pRtspServer->iUserNum = 0;
#ifdef VIDEO_AVBR_ENABLE
pRtspServer->bIsVirtualIFrameEnabled = 1;
#else
pRtspServer->bIsVirtualIFrameEnabled = 0;
#endif
return 0;
}
int TPRtspDeInit(TPRTSPSERVER *pRtspServer)
{
int i = 0;
int trytimes =1000;
RETURN_IVALID_IF(!pRtspServer)
for (i = 0; i < TPRTSPSERVER_MAX_SESSION; i++)
{
pthread_mutex_lock(&g_rtsp_mutex);
if (pRtspServer->pClients[i] != NULL)
{
//TPRtspCloseSession(pRtspServer, i);
pRtspServer->pClients[i]->iStatus = SESSION_STOPPING;
}
pthread_mutex_unlock(&g_rtsp_mutex);
}
while(pRtspServer->iNumClients > 0 && trytimes > 0)
{
usleep(1000);
trytimes--;
}
if (pRtspServer->bIsRunning == 1)
{
TPRtspStop(pRtspServer);
}
DeinitAuthManager(pRtspServer->rtspAuthManeger);
free(pRtspServer->rtspAuthManeger);
if (pRtspServer->iSock >= 0)
{
TPRtspClose(pRtspServer);
}
return 0;
}
static int TPRtspSocketInit(TPRTSPSERVER *pRtspServer)
{
int on = 1;
/* 忽略client网络异常断开所产生的SIGPIPE信号 */
signal(SIGPIPE, SIG_IGN);
if ((pRtspServer->iSock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
RTSP_ERROR("socket create failed.");
return TP_TCP_EC_FAILURE;
}
//允许地址重复绑定
setsockopt(pRtspServer->iSock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
ioctl(pRtspServer->iSock, FIONBIO, &pRtspServer->bNonblock);
if (bind(pRtspServer->iSock, (struct sockaddr *)&pRtspServer->ServerAddr, sizeof(pRtspServer->ServerAddr)))
{
RTSP_ERROR("socket bind failed.");
TPRtspClose(pRtspServer);
return TP_TCP_EC_FAILURE;
}
/* 监听 */
if (listen(pRtspServer->iSock, TP_TCP_MAX_CLIENT))
{
RTSP_ERROR("socket listen failed.");
TPRtspClose(pRtspServer);
return TP_TCP_EC_FAILURE;
}
return TP_TCP_EC_OK;
}
static int TPRtspClose(TPRTSPSERVER *pRtspServer)
{
if(pRtspServer->iSock > 0)
{
close(pRtspServer->iSock);
pRtspServer->iSock = -1;
}
return TP_TCP_EC_OK;
}
static int TPRtspCloseClientSocket(TPRTSPSERVER *pRtspServer, int iClientSocket)
{
if (iClientSocket >= 0)
{
close(iClientSocket);
}
return TP_TCP_EC_OK;
}
static void RtspPutUshortToBufBE(unsigned char * buf, unsigned short value)
{
buf[0] = (value >> 8) & 0xff;
buf[1] = value & 0xff;
}
static void RtspPutUintToBufBE(unsigned char * buf, unsigned int value)
{
buf[0] = (value >> 24) & 0xff;
buf[1] = (value >> 16) & 0xff;
buf[2] = (value >> 8) & 0xff;
buf[3] = value & 0xff;
}
void RtspGetUshortFromBufBE(unsigned char * buf, unsigned short *value)
{
if (buf && value)
{
*value = (buf[0] << 8) | buf[1];
}
}
void RtspGetUintFromBufBE(unsigned char * buf, unsigned int *value)
{
if (buf && value)
{
*value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
}
}
int RtspAddExtention(unsigned char * buf, unsigned long long utctime, unsigned char flag)
{
int ret = RTP_EXTEN_HEADER_LEN;
RtspPutUshortToBufBE(buf, RTP_EXTEN_VERSION);
/*帧标记*/
buf[ret] = RTP_EXTEN_TYPE_FRAME;
RtspPutUshortToBufBE(buf + ret + 1, RTP_EXTEN_FRAM_LEN);
buf[ret + RTP_EXTEN_TYPE_HEADER_LEN] = flag;
ret += RTP_EXTEN_TYPE_HEADER_LEN + RTP_EXTEN_FRAM_LEN;
/*utc时间*/
if(utctime != 0)
{
unsigned int time_sec = (unsigned int)(utctime / 1000000);
buf[ret] = RTP_EXTEN_TYPE_UTC;
RtspPutUshortToBufBE(buf + ret + 1, RTP_EXTEN_UTC_LEN);
buf[ret + RTP_EXTEN_TYPE_HEADER_LEN] = 0x00;
RtspPutUintToBufBE(buf + ret + RTP_EXTEN_LEN_EQUAL_BITS, time_sec);
ret += RTP_EXTEN_TYPE_HEADER_LEN + RTP_EXTEN_UTC_LEN;
}
RtspPutUshortToBufBE(buf + 2, (unsigned short)ret / RTP_EXTEN_LEN_EQUAL_BITS - 1);
return ret;
}
int RtspAddAvbrExtention(unsigned char * buf)
{
int ret = RTP_EXTEN_HEADER_LEN;
RtspPutUshortToBufBE(buf, RTP_RTSP_EXTEN_VERSION);
/*帧标记*/
RtspPutUintToBufBE(buf + ret, RTP_RTSP_VIRTUAL_I_FRAME_VALUE);
ret += RTP_RTSP_VIRTUAL_I_FRAME_LEN;
RtspPutUshortToBufBE(buf + 2, (unsigned short)ret / RTP_EXTEN_LEN_EQUAL_BITS - 1);
return ret;
}
int rtp_set_retry_info(trans_session_desc_t *desc, trans_stream_t *stream)
{
TPRTSPSERVERSESSION *session = NULL;
TPRTPPACKAGE *ptr_rtp_package = NULL;
int tmp = 0;
RETRY_INFO *p_retry_info = NULL;
RETURN_VALUE_IF(!desc || !stream || !stream->package, ERROR);
session = (TPRTSPSERVERSESSION *)desc->priv;
ptr_rtp_package = (TPRTPPACKAGE *)stream->package;
if (ptr_rtp_package->stream_type == RTP_SESSION_AUDIO)
{
p_retry_info = &session->audio_retry_info;
}
else
{
p_retry_info = &session->video_retry_info;
}
ptr_rtp_package->stash_sn = ptr_rtp_package->PayloadContext.RTPHeader.usSequenceNumber;
ptr_rtp_package->PayloadContext.RTPHeader.usSequenceNumber = p_retry_info->sn;
ptr_rtp_package->PayloadContext.cur_nalu_index = p_retry_info->nalu_index;
ptr_rtp_package->pESBuffer->iIndexHead = 0;
tmp = p_retry_info->nalu_index;
while (tmp > 0)
{
MBUFFERESAdvanceFrame(ptr_rtp_package->pESBuffer);
tmp--;
}
rtp_pack_init_payload_context(ptr_rtp_package);
ptr_rtp_package->PayloadContext.bPayloadInited = p_retry_info->payload_init;
ptr_rtp_package->PayloadContext.iCurPayloadPos = p_retry_info->payload_pos;
ptr_rtp_package->PayloadContext.bSbit = p_retry_info->b_sbit;
return OK;
}
int rtp_recover_retry_info(trans_stream_t * stream)
{
RETURN_VALUE_IF(!stream || !stream->package, ERROR);
TPRTPPACKAGE * ptr_rtp_package = (TPRTPPACKAGE *)stream->package;
ptr_rtp_package->PayloadContext.RTPHeader.usSequenceNumber = ptr_rtp_package->stash_sn;
return OK;
}
static void set_retry_info(RETRY_INFO *retry_info, TPRTPPACKAGE *rtp_pack, S32 rtp_len)
{
/* rtp包构建之后,sn会自增1,要保留现场要将当前的sn - 1 */
retry_info->sn = rtp_pack->PayloadContext.RTPHeader.usSequenceNumber - 1;
retry_info->nalu_index = rtp_pack->PayloadContext.sending_nalu_index;
/* payload回退到打包RTP之前的位置 */
retry_info->payload_pos = rtp_pack->PayloadContext.iCurPayloadPos - rtp_len;
retry_info->payload_init = 1;
retry_info->b_sbit = rtp_pack->PayloadContext.last_bSbit;
retry_info->retry_flag = 1;
}
static void reset_retry_info(RETRY_INFO *retry_info, TPRTPPACKAGE *rtp_pack)
{
RETURN_VOID_IF(!retry_info || !rtp_pack);
retry_info->send_pos = 0;
retry_info->sn = rtp_pack->PayloadContext.RTPHeader.usSequenceNumber;
retry_info->payload_init = 0;
retry_info->nalu_index = 0;
retry_info->b_sbit = 0;
retry_info->retry_flag = 0;
retry_info->payload_pos = 0;
}
int rtp_clear_retry_info(trans_session_desc_t *desc, trans_stream_t * stream)
{
RETURN_VALUE_IF(!desc || !stream || !stream->package, ERROR);
TPRTPPACKAGE *ptr_rtp_package = (TPRTPPACKAGE *)stream->package;
TPRTSPSERVERSESSION *pSession = (TPRTSPSERVERSESSION *)desc->priv;
RETRY_INFO *p_retry_info = &pSession->video_retry_info;
reset_retry_info(p_retry_info, ptr_rtp_package);
return OK;
}
int rtp_get_package_sn(trans_session_desc_t *desc, trans_stream_t * stream)
{
RETURN_VALUE_IF(!stream || !stream->package, ERROR);
TPRTPPACKAGE *ptr_rtp_package = (TPRTPPACKAGE *)stream->package;
return ptr_rtp_package->PayloadContext.RTPHeader.usSequenceNumber;
}
int rtp_set_retry_sn(trans_session_desc_t *desc, trans_stream_t * stream, int seq)
{
RETURN_VALUE_IF(!desc || !desc->priv || !stream || !stream->package, ERROR);
TPRTPPACKAGE *ptr_rtp_package = (TPRTPPACKAGE *)stream->package;
TPRTSPSERVERSESSION *pSession = (TPRTSPSERVERSESSION *)desc->priv;
RETRY_INFO *p_retry_info = &pSession->video_retry_info;
reset_retry_info(p_retry_info, ptr_rtp_package);
p_retry_info->sn = seq;
return OK;
}
#ifdef RTP_RETANS_SUPPORT
static int save_rtppackge_2_retrans_queue(TPRTP4SERVER *pserver, int session, MBUFFERByteArray *pByteArray, int is_iframe)
{
if (session != RTP_SESSION_VIDEO)
{
return OK;
}
RETURN_IVALID_IF(!pserver || !pByteArray || !pserver->pSessions[session]);
if (pserver->bRTPOverTCP || !pserver->pSessions[session]->retrans_enable)
{
return OK;
}
int rtplen = MBUFFERByteArrayLength(pByteArray);
int max_size = 0;
TPRTPSESSIONCONTEXT* psession = pserver->pSessions[session];
int pos = psession->qindex & psession->winmask;
int pre_pos = (psession->qindex - 1) & psession->winmask;
BOOL frame_type_changed = FALSE;
max_size = MAX_TRANS_BUF_SIZE;
if (rtplen > max_size)
{
RTSP_ERROR("RTP:rtp size exceed max buf size, max_size = %d!", max_size);
return ERROR;
}
RE_TRANS_NODE ** pqueue = psession->re_trans_queue;
frame_type_changed = ((is_iframe == (pqueue[pre_pos]->is_key_frame)) ? FALSE : TRUE);
if (!pqueue[pos]->buf)
{
pqueue[pos]->buf = malloc(max_size);
if (!pqueue[pos]->buf)
{
RTSP_ERROR("malloc memory failed!");
return ERROR;
}
memset(pqueue[pos]->buf, 0x0, max_size);
}
else
{
reset_rtp_retrans_node(pqueue[pos]);
}
if (is_iframe)
{
if (frame_type_changed)
{
psession->temp_key_frame_count = 0;
}
pqueue[pos]->is_key_frame = TRUE;
psession->temp_key_frame_count++;
}
else
{
if (frame_type_changed)
{
psession->latest_key_frame_qindex = psession->qindex - psession->temp_key_frame_count;
psession->latest_key_frame_count = psession->temp_key_frame_count;
RTSP_DEBUG("RTP:latest_key_frame_qindex = %d, count = %d!", psession->latest_key_frame_qindex, psession->latest_key_frame_count);
}
}
memcpy(pqueue[pos]->buf, pByteArray->pucBuffer, rtplen);
pqueue[pos]->len = rtplen;
pqueue[pos]->send_time = RTSPGetTimeMS();
psession->qindex++;
return OK;
}
#endif
/* 自1900到1970的秒数 由于time获取的是1970到当前时间的时差 而rtcp协议中规定的时间是从1900年开始 */
#define TIME_OFFSET ((70LL * 365 + 17) * 24 * 60 * 60)
#define TEMP_FORMAT_LEN 8
int TPSendRtpQueueCb(trans_session_desc_t *desc, trans_stream_t *stream)
{
RTPDATAFRAME *p_frame = NULL;
TPRTSPSERVERSESSION *pSession = NULL;
TPRTPPACKAGE *ptr_rtp_package = NULL;
int iSessionID = 0;
int sendmute = 0;
unsigned char mutebuf[RTP_MAX_PACKET_SIZE] = {0};
unsigned char RTPextern[RTP_MAX_EXTEN_LEN + 1] = {0};
unsigned char pucPrefix[RTP_PREFIX_SIZE] = {0};
int externtionlen = 0;
unsigned long cur_time = 0;
struct iovec iov[RTP_MAX_SEND_NUM * 2];
int ret = 0;
RETRY_INFO *p_retry_info = NULL;
RETRY_INFO tmp_retry_info = {0};
int iSize = 0;
BOOL bSendRTCP = TRUE;
TPRTPSESSIONCONTEXT * ptprtpsessioncontext = NULL;
unsigned long rtp_timestamp = 0;
unsigned long long ullTimeSent = 0;
unsigned int uSSRC;
int send_freq = 0;
struct timespec CurTimeSpec = {0, 0};
#if (defined SRTP_SUPPORT) || (defined SRTP_ENCRYPT_WITH_KEY_NEGOTIATION)
unsigned char tmpbuf[RTP_MAX_PACKET_SIZE] = {0};
#endif
RETURN_VALUE_IF(!desc || !desc->send_data || !desc->priv || !stream->package, 0);
p_frame = (RTPDATAFRAME *)desc->send_data;
pSession = (TPRTSPSERVERSESSION *)desc->priv;
ptr_rtp_package = (TPRTPPACKAGE *)stream->package;
/* 可能底层给的数据是错的,这里就可能出现打包异常,增加一个防护机制 */
RETURN_VALUE_IF(!p_frame->rtp_head_pos || !p_frame->rtp_payload_pos, 0);
if(pSession->pRTPServer->bIsRunning != 1)
{
return 0;
}
if ( ptr_rtp_package->av_codec >= TP_ENCODE_TYPE_AUDIO_MIN && ptr_rtp_package->av_codec <= TP_ENCODE_TYPE_AUDIO_MAX)
{
iSessionID = RTP_SESSION_AUDIO;
}
#ifdef RTSP_USE_SMART_DATA
else if (TP_ENCODE_TYPE_VIDEO_SMART == ptr_rtp_package->av_codec)
{
iSessionID = RTP_SESSION_SMART_DATA;
}
#endif
else if (TP_ENCODE_TYPE_VIDEO_SMART != ptr_rtp_package->av_codec)
{
iSessionID = RTP_SESSION_VIDEO;
}
p_retry_info = (iSessionID == RTP_SESSION_AUDIO) ? &pSession->audio_retry_info : &pSession->video_retry_info;
if (iSessionID != RTP_SESSION_AUDIO && iSessionID != RTP_SESSION_VIDEO)
{
p_retry_info = &tmp_retry_info;
}
//没收到I帧数据的话其他的数据丢掉
#ifdef JPEG_STREAM_ENABLE
if ((!pSession->getIFrame &&
(!ptr_rtp_package->is_iframe || !ptr_rtp_package->is_first_rtp || p_retry_info->retry_flag)) && pSession->iStreamType != TPRTP_STREAM_TYPE_VIDEO_JPEG)
#else
if (!pSession->getIFrame &&
(!ptr_rtp_package->is_iframe || !ptr_rtp_package->is_first_rtp || p_retry_info->retry_flag))
#endif
{
p_retry_info->send_pos = 0;
p_retry_info->retry_flag = 0;
return 0;
}
#if (defined SRTP_SUPPORT) || (defined SRTP_ENCRYPT_WITH_KEY_NEGOTIATION)
if ((strcmp(pSession->pcClientIP, "127.0.0.1") == 0
#ifdef SRTP_ENCRYPT_WITH_KEY_NEGOTIATION
|| pSession->pRTPServer->srtp
#endif
) && iSessionID == RTP_SESSION_VIDEO && p_frame->rtp_head_len == 12 && (*(p_frame->rtp_payload_pos) & 0x1f) == 0x06)
{
return 0;
}
#endif
if (!pSession->getIFrame && pSession->ulFirstVideoRTPTS == 0)
{
pSession->ulFirstVideoRTPTS = (unsigned long)ptr_rtp_package->curPTS;
}
else if (pSession->getIFrame && pSession->ulFirstAudioRTPTS == 0 && iSessionID == RTP_SESSION_AUDIO)
{
pSession->ulFirstAudioRTPTS = (unsigned long)ptr_rtp_package->curPTS;
}
#ifdef RTSP_USE_SMART_DATA
else if (pSession->getIFrame && pSession->ulFirstSmartRTPTS == 0 && iSessionID == RTP_SESSION_SMART_DATA)
{
pSession->ulFirstSmartRTPTS = (unsigned long)ptr_rtp_package->curPTS;
}
#endif
pSession->getIFrame = 1;
/* 如果音频或视频流没有传输完,则不能交叉传输,需要将剩余数据发完,其他流走重传流程 */
if ((pSession->video_retry_info.send_pos != 0 && iSessionID != RTP_SESSION_VIDEO) ||
(pSession->audio_retry_info.send_pos != 0 && iSessionID != RTP_SESSION_AUDIO))
{
set_retry_info(p_retry_info, ptr_rtp_package, p_frame->rtp_payload_len);
return RTSP_SEND_RETRY;
}
if (ptr_rtp_package->av_codec != TP_ENCODE_TYPE_UNDET && iSessionID == RTP_SESSION_VIDEO)
{
char codestr[TEMP_FORMAT_LEN];
if (ptr_rtp_package->av_codec == TP_ENCODE_TYPE_VIDEO_H264)
snprintf(codestr, TEMP_FORMAT_LEN, "H264");
else if (ptr_rtp_package->av_codec == TP_ENCODE_TYPE_VIDEO_H265)
snprintf(codestr, TEMP_FORMAT_LEN, "H265");
#ifdef JPEG_STREAM_ENABLE
else if (ptr_rtp_package->av_codec == TP_ENCODE_TYPE_SNAPSHOT_JPEG)
snprintf(codestr, TEMP_FORMAT_LEN, "JPEG");
#endif
else
return 0;
if (strcmp(pSession->SDPServer.SDPInfo.MediaInfo.pcVideoFormat, codestr) != 0)
{
snprintf(pSession->SDPServer.SDPInfo.MediaInfo.pcVideoFormat, 16, codestr);
}
}
if(RTP4SIsMulticast(pSession->pRTPServer) && p_frame->multicast_send == 1)
{
return 0;
}
else if(RTP4SIsMulticast(pSession->pRTPServer))
{
p_frame->multicast_send = 1;
}
#ifdef RTCP_PSFB_SUPPORT
if (pSession->pRTPServer->pSessions[ptr_rtp_package->stream_type])
{
pSession->pRTPServer->pSessions[ptr_rtp_package->stream_type]->psfb_control.is_iframe = ptr_rtp_package->is_iframe;
}
#endif
RtspPutUintToBufBE((unsigned char *)p_frame->rtp_head_pos + 8, pSession->pRTPServer->pSessions[iSessionID]->iClientSSRC);
RtspGetUintFromBufBE((unsigned char *)p_frame->rtp_head_pos + 4, (unsigned int *)&cur_time);
rtp_timestamp = cur_time - ((iSessionID == RTP_SESSION_VIDEO) ? pSession->ulFirstVideoRTPTS : pSession->ulFirstAudioRTPTS);
RtspPutUintToBufBE((unsigned char *)p_frame->rtp_head_pos + 4,rtp_timestamp);
#if (defined SRTP_SUPPORT) || (defined SRTP_ENCRYPT_WITH_KEY_NEGOTIATION)
if(strcmp(pSession->pcClientIP, "127.0.0.1") == 0
#ifdef SRTP_ENCRYPT_WITH_KEY_NEGOTIATION
|| pSession->pRTPServer->srtp
#endif
)
{
RtspPutUshortToBufBE((unsigned char *)p_frame->rtp_head_pos + 2, pSession->pRTPServer->pSessions[iSessionID]->seq_no);
}
else
#endif
{
RtspPutUshortToBufBE((unsigned char *)p_frame->rtp_head_pos + 2, pSession->pRTPServer->pSessions[iSessionID]->rtp_seq);
}
#ifdef RTSP_USE_SMART_DATA
if (RTP_SESSION_SMART_DATA == iSessionID)
{
RtspPutUintToBufBE((unsigned char *)p_frame->rtp_head_pos + 4,
cur_time - pSession->ulFirstSmartRTPTS );
}
#endif
/* TP NVR虚拟I帧的RTP包要包含扩展字段 */
if (pSession->bIsVirtualIFrameEnabled && ptr_rtp_package->is_virtual_iframe == 1)
{
*(p_frame->rtp_head_pos) |= RTP_HEADER_EXTENTION_BIT;
externtionlen = RtspAddAvbrExtention(RTPextern);
}
iSize = RTPDataGetFrameSize(p_frame);
if(pSession->bRTPOverTCP)
{
int rtp_length = p_frame->rtp_head_len + p_frame->rtp_payload_len + externtionlen;
int send_count = 0;
int expectlen = 0;
int rtp_cur_index = pSession->rtp_send_data_index;
int i = 0;
pucPrefix[0] = '$';
pucPrefix[1] = pSession->piTCPDataID[iSessionID];
pucPrefix[2] = rtp_length >> 8;
pucPrefix[3] = rtp_length & 0xff;
#ifdef SRTP_ENCRYPT_WITH_KEY_NEGOTIATION
MBUFFERByteArray mBuffer;
unsigned char TXBufferMemSpace[TPRTSPSERVER_BUFFER_SIZE] = {0};
MBUFFERByteArrayInit(TXBufferMemSpace, 0, 0, TPRTSPSERVER_BUFFER_SIZE - 4, &mBuffer);
MBUFFERByteArrayReset(&mBuffer);
if (pSession->pRTPServer->srtp)
{
struct srtp_session *enc_sess = &pSession->pRTPServer->pSessions[iSessionID]->encrypt_session;
unsigned int roc = htonl(pSession->pRTPServer->pSessions[iSessionID]->roc_send);
unsigned int ssrc = htonl(pSession->pRTPServer->pSessions[iSessionID]->iClientSSRC);
unsigned int iv[] = {0x00, ssrc, roc, htonl((pSession->pRTPServer->pSessions[iSessionID]->seq_no) << 16)};
int rtp_payload_len = 0;
/* 将等效payload添加进tmpbuf待加密,RTP头部放入mBbuffer*/
if (p_frame->rtp_head_len == 14) /* 暂不知何时头长度为14字节 */
{
memcpy(tmpbuf, p_frame->rtp_head_pos + 12, 2);
memcpy(tmpbuf + 2, p_frame->rtp_payload_pos, p_frame->rtp_payload_len);
rtp_payload_len = 2 + p_frame->rtp_payload_len;
MBUFFERByteArrayPutMultiUCharBE((unsigned char *)p_frame->rtp_head_pos, 12, &mBuffer);
}
else
{
memcpy(tmpbuf, p_frame->rtp_payload_pos, p_frame->rtp_payload_len);
rtp_payload_len = p_frame->rtp_payload_len;
MBUFFERByteArrayPutMultiUCharBE((unsigned char *)p_frame->rtp_head_pos, p_frame->rtp_head_len, &mBuffer);
}
/* payload加密 */
tpsocket_aes_cm_encrypt((unsigned char *)tmpbuf, (unsigned char *)tmpbuf, rtp_payload_len,
&enc_sess->aes_key, (unsigned char *)enc_sess->rtp_salt, (unsigned char *)&iv);
MBUFFERByteArrayPutMultiUCharBE((unsigned char *)tmpbuf, rtp_payload_len, &mBuffer);
/* rtp头与加密payload一起做hash计算 */
if (enc_sess->auth_len)
{
char hash[20];
struct tpsocket_sha sha;
memcpy(&sha, &enc_sess->sha, sizeof(sha));
tpsocket_sha_update(&sha, mBuffer.pucBuffer, mBuffer.iCurPos);
tpsocket_sha_update(&sha, &roc, sizeof(roc));
tpsocket_sha_final(&sha, (unsigned char *)hash);
tpsocket_sha_init(&sha);
tpsocket_sha_update(&sha, enc_sess->sha_opad, sizeof(enc_sess->sha_opad));
tpsocket_sha_update(&sha, hash, sizeof(hash));
tpsocket_sha_final(&sha, (unsigned char *)hash);
MBUFFERByteArrayPutMultiUCharBE((unsigned char *)hash, enc_sess->auth_len, &mBuffer); // 20 bytes in total, low 10 bytes picked only
}
/* 修改RTSP头部包len说明(增加hash长度) */
rtp_length += enc_sess->auth_len; // 10 bytes hash
pucPrefix[2] = rtp_length >> 8;
pucPrefix[3] = rtp_length & 0xff;
}
#endif
iov[send_count].iov_base = pucPrefix;
iov[send_count++].iov_len = 4;
#ifdef SRTP_ENCRYPT_WITH_KEY_NEGOTIATION
if (pSession->pRTPServer->srtp)
{
iov[send_count].iov_base = mBuffer.pucBuffer;
iov[send_count++].iov_len = p_frame->rtp_head_len;
}
else
#endif
{
if (externtionlen > 0)
{
int fu_header_len = p_frame->rtp_head_len - RTP_HEADER_SIZE;
iov[send_count].iov_base = p_frame->rtp_head_pos;
iov[send_count++].iov_len = RTP_HEADER_SIZE;
iov[send_count].iov_base = RTPextern;
iov[send_count++].iov_len = externtionlen;
if(fu_header_len > 0)
{
iov[send_count].iov_base = p_frame->rtp_head_pos + RTP_HEADER_SIZE;
iov[send_count++].iov_len = fu_header_len;
}
}
else
{
iov[send_count].iov_base = p_frame->rtp_head_pos;
iov[send_count++].iov_len = p_frame->rtp_head_len;
}
}
iov[send_count].iov_base = sendmute ? mutebuf : p_frame->rtp_payload_pos;
iov[send_count++].iov_len = p_frame->rtp_payload_len;
pSession->rtp_send_data[rtp_cur_index].rtp_head_size = 0;
for (i = 0; i < send_count - 1; i ++)
{
memcpy(pSession->rtp_send_data[rtp_cur_index].rtp_header_data + pSession->rtp_send_data[rtp_cur_index].rtp_head_size, iov[i].iov_base, iov[i].iov_len);
pSession->rtp_send_data[rtp_cur_index].rtp_head_size += iov[i].iov_len;
}
#ifdef SRTP_ENCRYPT_WITH_KEY_NEGOTIATION
/* 包数据存入rtp_send_data */
if (pSession->pRTPServer->srtp)
{
if(NULL == pSession->rtp_send_data[rtp_cur_index].rtp_playload_pos || 0 == pSession->rtp_send_data[rtp_cur_index].rtp_playload_size)
pSession->rtp_send_data[rtp_cur_index].rtp_playload_pos = (unsigned char *)malloc(RTP_MAX_PACKET_SIZE + 100);
memcpy(pSession->rtp_send_data[rtp_cur_index].rtp_playload_pos, mBuffer.pucBuffer + p_frame->rtp_head_len, mBuffer.iCurPos - p_frame->rtp_head_len);
pSession->rtp_send_data[rtp_cur_index].rtp_playload_size = mBuffer.iCurPos - p_frame->rtp_head_len;
}
else
#endif
{
pSession->rtp_send_data[rtp_cur_index].rtp_playload_pos = iov[i].iov_base;
pSession->rtp_send_data[rtp_cur_index].rtp_playload_size = iov[i].iov_len;
}
pSession->rtp_send_data_index++;
/*还原设置的拓展标记,避免对其他会话的影响*/
if(*(p_frame->rtp_head_pos) & RTP_HEADER_EXTENTION_BIT)
{
*(p_frame->rtp_head_pos) &= ~RTP_HEADER_EXTENTION_BIT;
}
RtspPutUintToBufBE((unsigned char *)p_frame->rtp_head_pos + 4, cur_time);
if (pSession->rtp_send_data_index >= RTP_MAX_SEND_NUM || desc->frame_end)
{
int send_pos = p_retry_info->send_pos;
int iov_index = 0;
int left_size = 0;
int send_len = 0;
int rtp_index = 0;
expectlen = 0;
if (send_pos > 0)
{
while (send_pos >= send_len)
{
send_len += (pSession->rtp_send_data[rtp_index].rtp_head_size + pSession->rtp_send_data[rtp_index].rtp_playload_size);
rtp_index++;
}
rtp_index--;
left_size = send_len - send_pos;
if (left_size > pSession->rtp_send_data[rtp_index].rtp_playload_size)
{
iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_header_data + (pSession->rtp_send_data[rtp_index].rtp_playload_size + pSession->rtp_send_data[rtp_index].rtp_head_size - left_size);
iov[iov_index++].iov_len = left_size - pSession->rtp_send_data[rtp_index].rtp_playload_size;
expectlen += left_size - pSession->rtp_send_data[rtp_index].rtp_playload_size;
left_size = pSession->rtp_send_data[rtp_index].rtp_playload_size;
}
iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_playload_pos + pSession->rtp_send_data[rtp_index].rtp_playload_size - left_size;
iov[iov_index++].iov_len = left_size;
expectlen += left_size;
rtp_index++;
}
for (; rtp_index < pSession->rtp_send_data_index; rtp_index++)
{
iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_header_data;
iov[iov_index++].iov_len = pSession->rtp_send_data[rtp_index].rtp_head_size;
iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_playload_pos;
iov[iov_index++].iov_len = pSession->rtp_send_data[rtp_index].rtp_playload_size;
expectlen += (pSession->rtp_send_data[rtp_index].rtp_head_size + pSession->rtp_send_data[rtp_index].rtp_playload_size);
}
ret = RTSPSessionSendV(pSession, iov, iov_index);
if (ret == TP_TCP_EC_FAILURE)
{
pSession->pRTPServer->iRTPStatus = RTP_STATUS_SEND_FAILURE;
set_retry_info(p_retry_info, ptr_rtp_package, p_frame->rtp_payload_len);
p_retry_info->send_pos = 0;
pSession->rtp_send_data_index--;
return TP_TCP_EC_FAILURE;
}
else if(ret != expectlen) // 接收方缓冲区满了,发不出去了
{
set_retry_info(p_retry_info, ptr_rtp_package, p_frame->rtp_payload_len);
p_retry_info->send_pos += ret > 0 ? ret : 0;
pSession->rtp_send_data_index--;
return RTSP_SEND_RETRY;
}
#ifdef SRTP_ENCRYPT_WITH_KEY_NEGOTIATION
/* 释放内存 */
if(pSession->pRTPServer->srtp)
for (rtp_index = 0; rtp_index < pSession->rtp_send_data_index; rtp_index++)
{
if(pSession->rtp_send_data[rtp_cur_index].rtp_playload_pos != NULL)
{
free(pSession->rtp_send_data[rtp_cur_index].rtp_playload_pos);
pSession->rtp_send_data[rtp_cur_index].rtp_playload_pos = NULL;
pSession->rtp_send_data[rtp_cur_index].rtp_playload_size = 0;
}
}
#endif
desc->frame_end = 0;
memset(pSession->rtp_send_data, 0, sizeof(RTPSENDDATA));
pSession->rtp_send_data_index = 0;
p_retry_info->send_pos = 0;
}
else
{
bSendRTCP = FALSE;
}
}
else
{
MBUFFERByteArray mBuffer;
unsigned char TXBufferMemSpace[TPRTSPSERVER_BUFFER_SIZE] = {0};
MBUFFERByteArrayInit(TXBufferMemSpace, 0, 0, TPRTSPSERVER_BUFFER_SIZE - 4, &mBuffer);
MBUFFERByteArrayReset(&mBuffer);
#if (defined SRTP_SUPPORT) || (defined SRTP_ENCRYPT_WITH_KEY_NEGOTIATION)
if (pSession->pRTPServer->srtp)
{
struct srtp_session *enc_sess = &pSession->pRTPServer->pSessions[iSessionID]->encrypt_session;
unsigned int roc = htonl(pSession->pRTPServer->pSessions[iSessionID]->roc_send);
unsigned int ssrc = htonl(pSession->pRTPServer->pSessions[iSessionID]->iClientSSRC);
unsigned int iv[] = {0x00, ssrc, roc, htonl((pSession->pRTPServer->pSessions[iSessionID]->seq_no) << 16)};
int rtp_payload_len = 0;
if (p_frame->rtp_head_len == 14)
{
memcpy(tmpbuf, p_frame->rtp_head_pos + 12, 2);
memcpy(tmpbuf + 2, p_frame->rtp_payload_pos, p_frame->rtp_payload_len);
rtp_payload_len = 2 + p_frame->rtp_payload_len;
MBUFFERByteArrayPutMultiUCharBE((unsigned char *)p_frame->rtp_head_pos, 12, &mBuffer);
}
else
{
memcpy(tmpbuf, p_frame->rtp_payload_pos, p_frame->rtp_payload_len);
rtp_payload_len = p_frame->rtp_payload_len;
MBUFFERByteArrayPutMultiUCharBE((unsigned char *)p_frame->rtp_head_pos, p_frame->rtp_head_len, &mBuffer);
}
tpsocket_aes_cm_encrypt((unsigned char *)tmpbuf, (unsigned char *)tmpbuf, rtp_payload_len,
&enc_sess->aes_key, (unsigned char *)enc_sess->rtp_salt, (unsigned char *)&iv);
MBUFFERByteArrayPutMultiUCharBE((unsigned char *)tmpbuf, rtp_payload_len, &mBuffer);
if (enc_sess->auth_len)
{
char hash[20];
struct tpsocket_sha sha;
memcpy(&sha, &enc_sess->sha, sizeof(sha));
tpsocket_sha_update(&sha, mBuffer.pucBuffer, mBuffer.iCurPos);
tpsocket_sha_update(&sha, &roc, sizeof(roc));
tpsocket_sha_final(&sha, (unsigned char *)hash);
tpsocket_sha_init(&sha);
tpsocket_sha_update(&sha, enc_sess->sha_opad, sizeof(enc_sess->sha_opad));
tpsocket_sha_update(&sha, hash, sizeof(hash));
tpsocket_sha_final(&sha, (unsigned char *)hash);
MBUFFERByteArrayPutMultiUCharBE((unsigned char *)hash, enc_sess->auth_len, &mBuffer); // 20 bytes in total, low 10 bytes picked only
}
}
else
#endif
{
MBUFFERByteArrayPutMultiUCharBE((unsigned char *)p_frame->rtp_head_pos, p_frame->rtp_head_len, &mBuffer);
if(externtionlen > 0)
{
MBUFFERByteArrayPutMultiUCharBE(RTPextern, externtionlen, &mBuffer);
}
MBUFFERByteArrayPutMultiUCharBE(sendmute ? mutebuf : p_frame->rtp_payload_pos, p_frame->rtp_payload_len, &mBuffer);
}
MBUFFERByteConvert2ReadBuff(&mBuffer);
#ifdef RTP_RETANS_SUPPORT
save_rtppackge_2_retrans_queue(pSession->pRTPServer, iSessionID, &mBuffer, ptr_rtp_package->is_iframe);
#endif
TPUdpSendByBuffer(pSession->pRTPServer->pSessions[iSessionID]->DataServer, &mBuffer);
/*还原设置的拓展标记,避免对其他会话的影响*/
if(*(p_frame->rtp_head_pos) & RTP_HEADER_EXTENTION_BIT)
{
*(p_frame->rtp_head_pos) &= ~RTP_HEADER_EXTENTION_BIT;
}
RtspPutUintToBufBE((unsigned char *)p_frame->rtp_head_pos + 4, cur_time);
}
/* send rtcp/srtcp */
ullTimeSent = tpgetboottime(); // get current time here
ptprtpsessioncontext = pSession->pRTPServer->pSessions[iSessionID];
if (bSendRTCP)
{
pSession->pRTPServer->pSessions[ptr_rtp_package->stream_type]->uiNumPacketsSent++;
pSession->pRTPServer->pSessions[ptr_rtp_package->stream_type]->iOctetsSent += iSize;
}
//根据video的session是否收到RR为标准,来确定audio和video的sr频率
if (pSession->pRTPServer->pSessions[RTP_SESSION_VIDEO]->SRFlag == 1)
{
send_freq = RTP_RECEIVER_REPORT_INTERVAL;
}
else
{
send_freq = RTP_RECEIVER_REPORT_INTERVAL_HF;
}
if (ullTimeSent - ptprtpsessioncontext->ullLastSRTime >= send_freq && bSendRTCP)
{
if(pSession->bRTPOverTCP)/* additional 4 bytes are used for reusing TCP channel */
{
MBUFFERByteArrayPutUIntBE(0, &(ptprtpsessioncontext->ControlFrame2Send.ByteArray));
}
RTPCONTROLSENDERREPORT RTCPSenderReport;
#ifdef SRTP_SUPPORT
if(strcmp(pSession->pcClientIP, "127.0.0.1") == 0)
{
uSSRC = ptprtpsessioncontext->iClientSSRC; // webrtc方案时使用远端透传的ssrc
}
else
{
uSSRC = ptr_rtp_package->PayloadContext.RTPHeader.ulSSRC;
}
#else
uSSRC = ptr_rtp_package->PayloadContext.RTPHeader.ulSSRC;
#endif
RTCPSenderReport.uiSsrc = uSSRC;
RTCPSenderReport.uiRTPTS = rtp_timestamp;
RTCPSenderReport.uiNumOctetsSent = ptprtpsessioncontext->iOctetsSent;
RTCPSenderReport.uiNumPacketsSent = ptprtpsessioncontext->uiNumPacketsSent;
/*
* NTP TimeStamp is a 64-bit fix-point number
* with the integer part in the first 32 bits,
* and the fractional part in the last 32 bits.
*/
clock_gettime(CLOCK_REALTIME, &CurTimeSpec);
RTCPSenderReport.uiNTPSec = TIME_OFFSET + CurTimeSpec.tv_sec;
RTCPSenderReport.uiNTPFrac = CurTimeSpec.tv_nsec;
RTPControlBuildSR(&RTCPSenderReport, 0, NULL, &(ptprtpsessioncontext->ControlFrame2Send));
ptprtpsessioncontext->ullLastSRTime = ullTimeSent;
ptprtpsessioncontext->SDESFrame.uiSrc = uSSRC;
RTPControlBuildSDES(&(pSession->pRTPServer->pSessions[iSessionID]->SDESFrame), &(pSession->pRTPServer->pSessions[iSessionID]->ControlFrame2Send));
#if (defined SRTP_SUPPORT) || (defined SRTP_ENCRYPT_WITH_KEY_NEGOTIATION)
MBUFFERByteArray *pByteArray = &pSession->pRTPServer->pSessions[iSessionID]->ControlFrame2Send.ByteArray;
#endif
if(pSession->bRTPOverTCP)
{
iSize = MBUFFERByteArrayCurPos(&ptprtpsessioncontext->ControlFrame2Send.ByteArray);
MBUFFERByteArraySeek(0,&ptprtpsessioncontext->ControlFrame2Send.ByteArray);
MBUFFERByteArrayPutUChar('$', &ptprtpsessioncontext->ControlFrame2Send.ByteArray);
MBUFFERByteArrayPutUChar(ptprtpsessioncontext->iTCPControlID, &ptprtpsessioncontext->ControlFrame2Send.ByteArray);
#ifdef SRTP_ENCRYPT_WITH_KEY_NEGOTIATION
if (pSession->pRTPServer->srtp)
{/* iSize-4:4字节rtsp长度减去,+ 4:payload以及校验位之间的u_int(4字节)rtcp_seq_no */
MBUFFERByteArrayPutUShortBE(iSize - 4 + pSession->pRTPServer->pSessions[iSessionID]->encrypt_session.auth_len + sizeof(unsigned int),
&ptprtpsessioncontext->ControlFrame2Send.ByteArray);
}
else
#endif
{
MBUFFERByteArrayPutUShortBE(iSize - 4, &ptprtpsessioncontext->ControlFrame2Send.ByteArray);
}
MBUFFERByteArraySeek(iSize, &ptprtpsessioncontext->ControlFrame2Send.ByteArray);
}
#if (defined SRTP_SUPPORT) || (defined SRTP_ENCRYPT_WITH_KEY_NEGOTIATION)
if (pSession->pRTPServer->srtp)
{
struct srtp_session *enc_sess = &pSession->pRTPServer->pSessions[iSessionID]->encrypt_session;
unsigned int ssrc = htonl(pSession->pRTPServer->pSessions[iSessionID]->iClientSSRC);
unsigned int iv[] = {0x00, ssrc, htonl((pSession->pRTPServer->pSessions[iSessionID]->rtcp_seq_no) >> 16), htonl((pSession->pRTPServer->pSessions[iSessionID]->rtcp_seq_no) << 16)};
int rtcp_payload_len = pByteArray->iCurPos - 8;
unsigned char * rtcp_payload_pos = pByteArray->pucBuffer + 8;
tpsocket_aes_cm_encrypt((unsigned char *)rtcp_payload_pos, (unsigned char *)rtcp_payload_pos, rtcp_payload_len,
&enc_sess->aes_key2, (unsigned char *)enc_sess->rtcp_salt, (unsigned char *)&iv);
MBUFFERByteArrayPutUIntBE(pSession->pRTPServer->pSessions[iSessionID]->rtcp_seq_no + (unsigned int)2147483648u, pByteArray);
if (enc_sess->auth_len)
{
char hash[20];
struct tpsocket_sha sha;
memcpy(&sha, &enc_sess->sha1, sizeof(sha));
if(pSession->bRTPOverTCP)
{/* 计算校验的时候,前面4字节rtsp不能算进去 */
tpsocket_sha_update(&sha, pByteArray->pucBuffer+4, pByteArray->iCurPos-4);
}
else
{
tpsocket_sha_update(&sha, pByteArray->pucBuffer, pByteArray->iCurPos);
}
tpsocket_sha_final(&sha, (unsigned char *)hash);
tpsocket_sha_init(&sha);
tpsocket_sha_update(&sha, enc_sess->sha_opad1, sizeof(enc_sess->sha_opad1));
tpsocket_sha_update(&sha, hash, sizeof(hash));
tpsocket_sha_final(&sha, (unsigned char *)hash);
MBUFFERByteArrayPutMultiUCharBE((unsigned char *)hash, enc_sess->auth_len, pByteArray); // 20 bytes in total, low 10 bytes picked only
}
}
pSession->pRTPServer->pSessions[iSessionID]->rtcp_seq_no++;
#endif
RTP4SWriteControl(pSession->pRTPServer, iSessionID);
}
#if (defined SRTP_SUPPORT) || (defined SRTP_ENCRYPT_WITH_KEY_NEGOTIATION)
if (strcmp(pSession->pcClientIP, "127.0.0.1") == 0
#ifdef SRTP_ENCRYPT_WITH_KEY_NEGOTIATION
|| pSession->pRTPServer->srtp
#endif
)
{
pSession->pRTPServer->pSessions[iSessionID]->seq_no++;
if (!pSession->pRTPServer->pSessions[iSessionID]->seq_no)
{
pSession->pRTPServer->pSessions[iSessionID]->roc_send++;
}
}
else
#endif
{
pSession->pRTPServer->pSessions[iSessionID]->rtp_seq++ ;
}
reset_retry_info(p_retry_info, ptr_rtp_package);
return 0;
}
int TPRtspExecute(TPRTSPSERVER *pRtspServer)
{
struct sockaddr_in ClientAddr;
int iClientAddrlen = sizeof(struct sockaddr_in);
int iClientSocket;
char pcClientIP[TP_TCP_CLIENT_IP_SIZE];
if (!pRtspServer)
{
return TP_TCP_EC_FAILURE;
}
if ((iClientSocket = accept(pRtspServer->iSock, (struct sockaddr *)&ClientAddr, (socklen_t *)&iClientAddrlen)) >= 0)
{
strncpy(pcClientIP, inet_ntoa(ClientAddr.sin_addr), TP_TCP_CLIENT_IP_SIZE);
if (pRtspServer->pOnAcceptSucceededCallback != NULL)
{
pRtspServer->pOnAcceptSucceededCallback(iClientSocket, pcClientIP, pRtspServer->pArgs);
}
else
{
#ifdef RTSPD_SUPPORT
if (TP_TCP_EC_FAILURE == TPRtspOnAccept(pRtspServer, iClientSocket, pcClientIP, NULL, NEED_AUTHENTICATION_TRUE))
#else
if (TP_TCP_EC_FAILURE == TPRtspOnAccept(pRtspServer, iClientSocket, pcClientIP, NEED_AUTHENTICATION_TRUE))
#endif
{
TPRtspCloseClientSocket(pRtspServer, iClientSocket);
}
}
return TP_TCP_EC_OK;
}
return TP_TCP_EC_WAIT;
}
int TPRtspRegisterCallback(TPRTSPSERVER *pRtspServer, PONACCEPTSUCCEEDEDCALLBACK pOnAcceptSucceededCallback, void *pArgs)
{
RETURN_IVALID_IF(!pRtspServer)
pRtspServer->pArgs = pArgs;
pRtspServer->pOnAcceptSucceededCallback = pOnAcceptSucceededCallback;
return TP_TCP_EC_OK;
}
int TPRtspCloseSession(TPRTSPSERVER *pRtspServer, int iSessionID)
{
if ((iSessionID > (TPRTSPSERVER_MAX_SESSION - 1)) || (iSessionID < 0) || !pRtspServer)
{
return(TPRTSPSERVER_EC_FAILURE);
}
SYSTEM_DEVSTA dev_sta = {0};
RTSP_INFO_LOG("CloseSession called, %dth in %d", iSessionID, pRtspServer->iNumClients);
TPRTSPSERVERSESSION *pRTSPServerSession = pRtspServer->pClients[iSessionID];
if (pRTSPServerSession)
{
/* pRTSPServerSession->bIsSessionON = 0; */
/* TODO: 暂定Session状态:
* 0 - Session closed
* 1 - Session running
* 2 - Session to be stopped
*/
pRTSPServerSession->bIsSessionON = 0;
RTSPSessionDeinit(pRTSPServerSession);
if (pRTSPServerSession->pRTPServer != NULL)
{
pRTSPServerSession->pRTPServer->bIsRunning = 0;
RTP4SDeInit(pRTSPServerSession->pRTPServer);
free(pRTSPServerSession->pRTPServer);
pRTSPServerSession->pRTPServer = NULL;
}
free(pRtspServer->pClients[iSessionID]);
pRtspServer->pClients[iSessionID] = NULL;
RTSP_DEBUG("rtsp session %d deleted.", iSessionID);
pRtspServer->iNumClients--;
RTSP_DEBUG("Session %d closed, %d remaining", iSessionID, pRtspServer->iNumClients);
/* 主子码流数均>=1,认为设备已接入客户端,修改设备二层广播报文中设备状态为1 */
/* 不统计multitrans连接,该字段只有NVR使用,记录设备是否已被其他NVR接入 */
ds_read(SYSTEM_DEVSTA_PATH, &dev_sta, sizeof(SYSTEM_DEVSTA));
if (rtsp_get_client_num_by_type(CLIENT_TYPE_LOCAL, LEFT_BIT(TPRTP_STREAM_ID_MAIN), TRUE) >= 1 &&
rtsp_get_client_num_by_type(CLIENT_TYPE_LOCAL, LEFT_BIT(TPRTP_STREAM_ID_SUB), TRUE) >= 1)
{
dev_sta.device_status = 1;
}
else
{
dev_sta.device_status = 0;
}
ds_write(SYSTEM_DEVSTA_PATH, &dev_sta, sizeof(SYSTEM_DEVSTA));
}
return(TPRTSPSERVER_EC_OK);
}
#ifdef RTSPD_SUPPORT
int TPRtspOnAccept(TPRTSPSERVER *pRtspServer, int iClientSocket, const char *pcClientIP, TCP_CONNECTION_T * connection, int needAuthentication)
#else
int TPRtspOnAccept(TPRTSPSERVER *pRtspServer, int iClientSocket, const char *pcClientIP, int needAuthentication)
#endif
{
int i = 0;
TPRTSPSERVERSESSION *pSession;
static int ip_lock = 0;
RTSP_INFO_LOG("New client accessing: %s sock %d", pcClientIP, iClientSocket);
/* check if rtsp server is restarting*/
if (pRtspServer->bIsReadytoAccept == 0)
{
/*rtsp server is on restarting, reject the client */
RTSP_ERROR("RTSP Server is restarting, reject");
return(TP_TCP_EC_FAILURE);
}
//收到连接后,不允许再改ip了
if(ip_lock == 0)
{
PROTOCOL_STATUS status;
IPCD_STREAM_OFFERED stream_offered = {0};
status.ip_change_forbidden = 1;
ds_write(PROTOCOL_STATUS_PATH, &status, sizeof(status));
ds_read(IPCD_STREAM_OFFERED_PATH, &stream_offered, sizeof(IPCD_STREAM_OFFERED));
if (0 == stream_offered.status)
{
stream_offered.status = 1;
ds_advanced_write(IPCD_STREAM_OFFERED_PATH, &stream_offered, sizeof(IPCD_STREAM_OFFERED), DS_FLAG_SAVE_FLASH);
}
ip_lock =1;
}
if (pRtspServer->iNumClients < TPRTSPSERVER_MAX_SESSION)
{
for (i = 0; i < TPRTSPSERVER_MAX_SESSION; i++)
{
if (pRtspServer->pClients[i] == NULL)
{
break;
}
}
if (i == TPRTSPSERVER_MAX_SESSION)
{
RTSP_ERROR("Too much clients, reject");
return(TP_TCP_EC_FAILURE);
}
pSession = (TPRTSPSERVERSESSION *)malloc(sizeof(TPRTSPSERVERSESSION));
if (pSession == NULL)
{
RTSP_ERROR("No sufficient memory");
return(TP_TCP_EC_FAILURE);
}
pthread_mutex_lock(&g_rtsp_mutex);
RTSPSessionInit(pSession);
pSession->iSessionID = i;
pSession->iStatus = SESSION_OPEN;
pSession->iSock = iClientSocket;
#ifdef RTSPD_SUPPORT
pSession->web_connection = connection;
#endif
memset(pSession->rtp_send_data, 0, sizeof(RTPSENDDATA));
pSession->rtp_send_data_index = 0;
#ifdef RTSPD_SUPPORT
if(connection != NULL)
{
pSession->ssl = connection->ssl;
pSession->tpssl = connection->tpssl;
pSession->webparam = (webParam_t *)connection->param;
}
else
{
pSession->ssl = NULL;
pSession->tpssl = NULL;
pSession->webparam = NULL;
}
#endif
strncpy(pSession->pcClientIP, pcClientIP, 32);
SDPInit(&pSession->SDPServer);
pSession->pcServerIP = pRtspServer->pcServerIP;
pSession->iServerPort = pRtspServer->iPort;
RTSPSessionGenerateSessionID(pSession);
TPRtspUpdateServerIP(pRtspServer);
SDPSetServerIP(&pSession->SDPServer, pRtspServer->pcServerIP);
pSession->rtspAuthManeger = pRtspServer->rtspAuthManeger;
RTSPSessionSetNonBlock(pSession, 1); /* 设为非阻塞socket */
RTSPSessionSetKeepalive(pSession, 20, 5, 3); /* 设置主动探活,网络异常超过30s,则判为连接失效 */
RTSPSessionSetSendBuf(pSession, get_main_stream_send_buf()); /* 设置SNDBUF发送缓冲区大小 */
RTSPSessionSetRecvBuf(pSession, TPPLAYER_RECVBUF_SIZE);
/* smart encoder related */
SDPEnableVirtualIFrame(&pSession->SDPServer, pRtspServer->bIsVirtualIFrameEnabled);
#ifdef SRTP_SUPPORT
if (pRtspServer->iNeedAuthentication && needAuthentication && strcmp(pcClientIP, "127.0.0.1") != 0)
#else
if (pRtspServer->iNeedAuthentication && needAuthentication)
#endif
{
pSession->iNeedAuthentication = 1;
}
#ifdef SRTP_SUPPORT
if (strcmp(pcClientIP, "127.0.0.1") == 0)
{
pSession->bIsSrtp = 1;
}
#endif
if (strcmp(pcClientIP, "localhost") == 0)
{
pSession->bIsLocalHost = 1;
}
pRtspServer->pClients[i] = pSession;
pRtspServer->iNumClients++;
pthread_mutex_unlock(&g_rtsp_mutex);
}
else
{
RTSP_ERROR("Too much clients, reject");
return(TP_TCP_EC_FAILURE);
}
RTSP_INFO_LOG("Accept client with iSessionID %d", i);
return(TPRTSPSERVER_EC_OK);
}
int TPRtspStart(TPRTSPSERVER *pRtspServer)
{
int iRet = TPRTSPSERVER_EC_OK;
RETURN_IVALID_IF(!pRtspServer)
if (TPRtspSocketInit(pRtspServer) != TP_TCP_EC_OK)
{
RTSP_ERROR("error : RTSP socket init fail");
iRet = TPRTSPSERVER_EC_FAILURE;
}
return(iRet);
}
int TPRtspStop(TPRTSPSERVER *pRtspServer)
{
int iRet = TPRTSPSERVER_EC_OK;
RETURN_IVALID_IF(!pRtspServer);
pRtspServer->bIsRunning = 0;
TPRtspDeInit(pRtspServer);
TPRtspClose(pRtspServer);
return(iRet);
}
int TPRtspSetAuthentication(TPRTSPSERVER *pRtspServer, char *pcUsername[TPRTSPSERVER_MAX_USER_NUM], char *pcPassword[TPRTSPSERVER_MAX_USER_NUM], int iUserNum)
{
int i;
char pcAuthenticationRaw[RTSP_USERNAME_LENGTH * 2];
FACTORY_TEST_MODE factory_test_mode = {0};
RETURN_IVALID_IF(!pRtspServer)
if (iUserNum > TPRTSPSERVER_MAX_USER_NUM)
{
iUserNum = TPRTSPSERVER_MAX_USER_NUM;
}
pRtspServer->iNeedAuthentication = 1;
for (i = 0; i < iUserNum; i++)
{
if ((NULL == pcUsername[i]) || (NULL == pcPassword[i]))
{
RTSP_ERROR("error : something wrong happened, skip this user");
continue;
}
ds_read(FACTORY_TEST_MODE_PATH, &factory_test_mode, sizeof(factory_test_mode));
if (factory_test_mode.enabled == 1)
{
pRtspServer->iNeedAuthentication = 0;
}
strncpy(pRtspServer->pcUsername[i], pcUsername[i], RTSP_USERNAME_LENGTH);
strncpy(pRtspServer->pcPassword[i], pcPassword[i], RTSP_USERNAME_LENGTH);
snprintf(pcAuthenticationRaw, RTSP_USERNAME_LENGTH * 2, "%s:%s", pcUsername[i], pcPassword[i]);
/* 格式"admin:tplink12345"; */
tpssl_base64Encode(pcAuthenticationRaw, strlen(pcAuthenticationRaw), pRtspServer->pcBaseAuthenticationCoded[i]);
}
pRtspServer->iUserNum = iUserNum;
return(RTSP_EC_OK);
}
/**
* UpdateTimeout
* @abstract 外部通过NPT服务器、NVR、APP或者Web页面更改IPC系统时间,可能错误地触发Server超时机制。
* 因此需要在系统时间更改时,调用该接口告知Server更新内部记录的时间标识;
*
* @param[in] ulTargetTime 目标时间,单位毫秒
* @param[in] ulCurrentTime 当前时间,单位毫秒
*
* @return 更新成功返回0
*/
int TPRtspUpdateTimeout(TPRTSPSERVER *pRtspServer, unsigned long long ulTargetTime, unsigned long long ulCurrentTime)
{
int i = 0, j = 0;
TPRTSPSERVERSESSION *pSession;
TPRTPSESSIONCONTEXT *pRTPSession;
for (i = 0; i < TPRTSPSERVER_MAX_SESSION; i++)
{
pthread_mutex_lock(&g_rtsp_mutex);
if (pRtspServer->pClients[i] != NULL)
{
RTSPSessionUpdateTimeout(pRtspServer->pClients[i], ulTargetTime, ulCurrentTime);
pSession = (TPRTSPSERVERSESSION *)(pRtspServer->pClients[i]);
if (pSession->pRTPServer)
{
for (j = 0; j < RTP_SESSION_NUM; j++)
{
pRTPSession = pSession->pRTPServer->pSessions[j];
if (pRTPSession && pRTPSession->DataServer)
{
TPUdpUpdateTimeout(pRTPSession->DataServer, ulTargetTime, ulCurrentTime);
}
}
}
}
pthread_mutex_unlock(&g_rtsp_mutex);
}
return(RTSP_EC_OK);
}
int TPRtspAuthenticate(TPRTSPSERVER *pRtspServer, MBUFFERByteArray *pByteArray, char *pcRequestType, char *pcServerNouce)
{
int iRet = TPRTSP_AUTHENTICATION_FAILURE;
int i;
char pcUserName[RTSP_USERNAME_LENGTH];
char pcRealm[RTSP_USERNAME_LENGTH];
char pcNonce[RTSP_USERNAME_LENGTH];
char pcUri[RTSP_USERNAME_LENGTH];
char pcAlgorithm[RTSP_USERNAME_LENGTH];
char pcResponse[RTSP_USERNAME_LENGTH]; /* 客户端传来的认证字符串 */
char *pcPassword = NULL;
char pcResponseServer[RTSP_USERNAME_LENGTH];/* server 端计算的认证字符串 */
char HA1Hex[TS_HASH_HEX_SIZE + 1] = {0}; /* 中间结果 */
char pcWhiteSpaces[4] = {'=', ' ', '\t', ','};
RETURN_IVALID_IF(!pRtspServer || !pByteArray)
MBUFFERByteArraySetWhiteSpaces(pcWhiteSpaces, 4, pByteArray);
if (pRtspServer->iNeedAuthentication == 0)
{
iRet = TPRTSP_AUTHENTICATION_OK;
}
else if (pRtspServer->iUserNum == 0)
{
iRet = TPRTSP_AUTHENTICATION_FAILURE;
}
else if (strlen(pRtspServer->pcUsername[0]) == 0)
{
iRet = TPRTSP_AUTHENTICATION_FAILURE;
}
else if ((MBUFFERByteArrayPeekString((char *)"Digest", pByteArray)) == 0)
{
MBUFFERByteArrayAdvance(strlen((char *)"Digest"), pByteArray);
while (MBUFFERByteArrayLength(pByteArray) > 0)
{
if (MBUFFERByteArrayFindStringNCase((char *)"username=\"", pByteArray) == MBUFFER_EC_OK)
{
MBUFFERByteArrayGetStringBySeparator(pcUserName, RTSP_USERNAME_LENGTH, '\"', pByteArray);
}
else if (MBUFFERByteArrayFindStringNCase((char *)"realm=\"", pByteArray) == MBUFFER_EC_OK)
{
MBUFFERByteArrayGetStringBySeparator(pcRealm, RTSP_USERNAME_LENGTH, '\"', pByteArray);
}
else if (MBUFFERByteArrayFindStringNCase((char *)"nonce=\"", pByteArray) == MBUFFER_EC_OK)
{
MBUFFERByteArrayGetStringBySeparator(pcNonce, RTSP_USERNAME_LENGTH, '\"', pByteArray);
}
else if (MBUFFERByteArrayFindStringNCase((char *)"uri=\"", pByteArray) == MBUFFER_EC_OK)
{
MBUFFERByteArrayGetStringBySeparator(pcUri, RTSP_USERNAME_LENGTH, '\"', pByteArray);
}
else if (MBUFFERByteArrayFindStringNCase((char *)"response=\"", pByteArray) == MBUFFER_EC_OK)
{
MBUFFERByteArrayGetStringBySeparator(pcResponse, RTSP_USERNAME_LENGTH, '\"', pByteArray);
}
else if (MBUFFERByteArrayFindStringNCase((char*)"algorithm=\"", pByteArray) == MBUFFER_EC_OK)
{
/* We default the algorithm to MD5, so the value of 'pcAlgorithm' is actually not being used */
MBUFFERByteArrayGetStringBySeparator(pcAlgorithm, RTSP_USERNAME_LENGTH, '\"', pByteArray);
}
else
{
return iRet;
}
}
if ((strlen(pcRealm) == strlen(gpucRTSPRealm)) && (strncasecmp(pcRealm, gpucRTSPRealm, strlen(gpucRTSPRealm)) != 0))
{
return iRet;
}
if ((strlen(pcNonce) == strlen(pcServerNouce)) && (strncasecmp(pcNonce, pcServerNouce, RTSP_AUTH_NOUCE_LENGTH) != 0))
{
return iRet;
}
for (i = 0; i < pRtspServer->iUserNum; i++)
{
if (strncmp(pcUserName, pRtspServer->pcUsername[i], RTSP_USERNAME_LENGTH) == 0)
{
pcPassword = pRtspServer->pcPassword[i];
break;
}
}
if (pcPassword == NULL)
{
return iRet;
}
DIGEST_AUTH_ITEM digestItem;
memset(&digestItem, 0, sizeof(DIGEST_AUTH_ITEM));
digestItem.pName = pcUserName;
digestItem.pPswd = pcPassword;
digestItem.pUri = pcUri;
digestItem.pNonce = pcNonce;
digestItem.pRealm = pcRealm;
/* Calc HA1 */
DigestCalcHA1(
digestItem.pAlg,
digestItem.pName,
digestItem.pRealm,
digestItem.pPswd,
digestItem.pNonce,
digestItem.pCnonce,
HA1Hex);
/* Calc response */
digestItem.pRespons = (char *)pcResponseServer;
DigestCalcResponse(
HA1Hex,
digestItem.pNonce,
digestItem.pNc,
digestItem.pCnonce,
digestItem.pQop,
pcRequestType,
digestItem.pUri,
NULL,
pcResponseServer);
RTSP_DEBUG("pcResponse:%s, pcResponseServer:%s", pcResponse, pcResponseServer);
if (strncmp(pcResponseServer, pcResponse, RTSP_USERNAME_LENGTH) == 0)
{
iRet = TPRTSP_AUTHENTICATION_OK;
}
}
else if (MBUFFERByteArrayPeekString((char *)"Basic", pByteArray) == 0)
{
/* 客户端发来"Basic xxxx"鉴权信息 */
MBUFFERByteArrayAdvance(strlen((char *)"Basic"), pByteArray); /* 取得" xxxx" */
MBUFFERByteArraySkipWhiteSpaces(pByteArray); /* 去除空格,取得"xxxx" */
for (i = 0; i < pRtspServer->iUserNum; i++)
{
if (MBUFFERByteArrayLength(pByteArray) != strlen(pRtspServer->pcBaseAuthenticationCoded[i]))
{
iRet = TPRTSP_AUTHENTICATION_FAILURE;
break;
}
if (strncmp((const char *)MBUFFERByteArrayCurBufferPos(pByteArray), (const char *)pRtspServer->pcBaseAuthenticationCoded[i],
strlen(pRtspServer->pcBaseAuthenticationCoded[i])) == 0)
{
iRet = TPRTSP_AUTHENTICATION_OK;
break;
}
}
}
return iRet;
}
int TPRtspUpdateServerIP(TPRTSPSERVER *pRtspServer)
{
/* get local ip address */
char ppcIP[4][TP_IP_MAX_LEN];
int iNumIP, iCount = 4;
int i;
RETURN_IVALID_IF(!pRtspServer)
for (i = 0; i < iCount; i++)
{
ppcIP[i][0] = '\0';
}
iNumIP = GetLocalIP(ppcIP, NULL, iCount);
if (iNumIP > 0)
{
/* For the time being, use the first valid IP addr. */
strncpy(pRtspServer->pcServerIP, ppcIP[0], strlen(ppcIP[0]) + 1);
}
else
{
RTSP_ERROR("Failed to get Server IP!");
return(TPRTSPSERVER_EC_FAILURE);
}
return(TPRTSPSERVER_EC_OK);
}
int TPRtspSetMediaInfo(TPRTSPSERVER *pRtspServer, int iSession, TPMEDIAINFO *pMediaInfo)
{
RETURN_IVALID_IF(!pRtspServer)
if ((iSession < 0) || (iSession > TPRTSPSERVER_MAX_SESSION - 1))
{
return(TPRTSPSERVER_EC_FAILURE);
}
TPRTSPSERVERSESSION *pSession = (TPRTSPSERVERSESSION *)pRtspServer->pClients[iSession];
TPMEDIAINFO *pSessionMediaInfo = &pSession->SDPServer.SDPInfo.MediaInfo;
memcpy(pSessionMediaInfo, pMediaInfo, sizeof(struct TPMEDIAINFO));
return(TPRTSPSERVER_EC_OK);
}
int TPRtspSetMultiCastSocket(TPRTSPSERVER *pRtspServer, int iSession, char *pcIP, int iPort, int iPortAudio)
{
TPRTSPSERVERSESSION *pSession;
if ((iSession < 0) || (iSession > TPRTSPSERVER_MAX_SESSION - 1) || !pRtspServer)
{
return(TPRTSPSERVER_EC_FAILURE);
}
pSession = (TPRTSPSERVERSESSION *)pRtspServer->pClients[iSession];
RTSPSessionSetMultiCastConfig(pSession, pcIP, iPort);
SDPSetMultiCastConfig(&pSession->SDPServer, pcIP, iPort, iPortAudio);
return(TPRTSPSERVER_EC_OK);
}
int TPRtspSetServerReady(TPRTSPSERVER *pRtspServer, int iReady)
{
RETURN_IVALID_IF(!pRtspServer)
pRtspServer->bIsReadytoAccept = iReady;
return(TPRTSPSERVER_EC_OK);
}
int TPRtspEnableVirtualIFrame(TPRTSPSERVER *pRtspServer, int bIfEnable)
{
RETURN_IVALID_IF(!pRtspServer)
pRtspServer->bIsVirtualIFrameEnabled = bIfEnable;
return(TPRTSPSERVER_EC_OK);
}
int TPRtspGetAudioClientNum(TPRTSPSERVER *pRtspServer)
{
int iAudioNum = 0, i = 0;
RETURN_IVALID_IF(!pRtspServer)
for (i = 0; i < TPRTSPSERVER_MAX_SESSION; i++)
{
pthread_mutex_lock(&g_rtsp_mutex);
if (pRtspServer->pClients[i])
{
TPRTSPSERVERSESSION *pSession = (TPRTSPSERVERSESSION *)(pRtspServer->pClients[i]);
if (pSession->iAudioVideo & RTSP_AUDIO)
{
iAudioNum++;
}
}
pthread_mutex_unlock(&g_rtsp_mutex);
}
return iAudioNum;
}
——详解一下这里面digest认证的实现