📄 rtsp_func.c
字号:
#include "rtsp_func.h"
/*
* 函数 char *get_stat(int err) :
* 用于获取状态值对应返回状态
*/
char *get_stat(int err)
{
struct {
char *token;
int code;
} status[] = {
{
"Continue", 100}, {
"OK", 200}, {
"Created", 201}, {
"Accepted", 202}, {
"Non-Authoritative Information", 203}, {
"No Content", 204}, {
"Reset Content", 205}, {
"Partial Content", 206}, {
"Multiple Choices", 300}, {
"Moved Permanently", 301}, {
"Moved Temporarily", 302}, {
"Bad Request", 400}, {
"Unauthorized", 401}, {
"Payment Required", 402}, {
"Forbidden", 403}, {
"Not Found", 404}, {
"Method Not Allowed", 405}, {
"Not Acceptable", 406}, {
"Proxy Authentication Required", 407}, {
"Request Time-out", 408}, {
"Conflict", 409}, {
"Gone", 410}, {
"Length Required", 411}, {
"Precondition Failed", 412}, {
"Request Entity Too Large", 413}, {
"Request-URI Too Large", 414}, {
"Unsupported Media Type", 415}, {
"Bad Extension", 420}, {
"Invalid Parameter", 450}, {
"Parameter Not Understood", 451}, {
"Conference Not Found", 452}, {
"Not Enough Bandwidth", 453}, {
"Session Not Found", 454}, {
"Method Not Valid In This State", 455}, {
"Header Field Not Valid for Resource", 456}, {
"Invalid Range", 457}, {
"Parameter Is Read-Only", 458}, {
"Unsupported transport", 461}, {
"Internal Server Error", 500}, {
"Not Implemented", 501}, {
"Bad Gateway", 502}, {
"Service Unavailable", 503}, {
"Gateway Time-out", 504}, {
"RTSP Version Not Supported", 505}, {
"Option not supported", 551}, {
"Extended Error:", 911}, {
NULL, -1}
};
int i;
for (i = 0; status[i].code != err && status[i].code != -1; ++i);
return status[i].token;
}
/**********************************************************************/
/*
* 函数 void RTSP_state_machine(RTSP_buffer * rtsp, int method) :
* RTSP协议状态机
*/
void RTSP_state_machine(RTSP_buffer * rtsp, int method)
{
/*
* All state transitions are made here except when the last stream packet
* is sent during a PLAY. That transition is located in stream_event().
*/
char *s;
RTSP_session *p;
long int session_id;
char trash[255];
if ((s = strstr(rtsp->in_buffer, HDR_SESSION)) != NULL) {
if (sscanf(s, "%254s %ld", trash, &session_id) != 2) {
printf("Invalid Session number in Session header\n");
send_reply(454, 0, rtsp); /* Session Not Found */
return;
}
}
p = rtsp->session_list;
if (p == NULL) {
return;
}
switch (p->cur_state) {
case INIT_STATE:{
switch (method) {
case RTSP_ID_DESCRIBE:
RTSP_describe(rtsp);
break;
case RTSP_ID_SETUP:
if (RTSP_setup(rtsp, &p) == ERR_NOERROR) {
p->cur_state = READY_STATE;
}
break;
case RTSP_ID_TEARDOWN:
// if (RTSP_teardown(rtsp) == ERR_NOERROR) { // shawill
// p->cur_state = INIT_STATE;
// }
RTSP_teardown(rtsp);
break;
case RTSP_ID_OPTIONS:
if (RTSP_options(rtsp) == ERR_NOERROR) {
p->cur_state = INIT_STATE;
}
break;
case RTSP_ID_PLAY: /* method not valid this state. */
case RTSP_ID_PAUSE:
send_reply(455, "Accept: OPTIONS, DESCRIBE, SETUP, TEARDOWN\n", rtsp);
break;
default:
send_reply(501, "Accept: OPTIONS, DESCRIBE, SETUP, TEARDOWN\n", rtsp);
break;
}
break;
} /* INIT state */
case READY_STATE:{
switch (method) {
case RTSP_ID_PLAY:
if (RTSP_play(rtsp) == ERR_NOERROR) {
p->cur_state = PLAY_STATE;
}
break;
case RTSP_ID_SETUP:
if (RTSP_setup(rtsp, &p) == ERR_NOERROR) {
p->cur_state = READY_STATE;
}
break;
case RTSP_ID_TEARDOWN:
// if (RTSP_teardown(rtsp) == ERR_NOERROR) { // shawill
// p->cur_state = INIT_STATE;
// }
RTSP_teardown(rtsp);
break;
case RTSP_ID_OPTIONS:
break;
case RTSP_ID_PAUSE: /* method not valid this state. */
send_reply(455, "Accept: OPTIONS, SETUP, PLAY, TEARDOWN\n", rtsp);
break;
case RTSP_ID_DESCRIBE:
RTSP_describe(rtsp);
break;
default:
send_reply(501, "Accept: OPTIONS, SETUP, PLAY, TEARDOWN\n", rtsp);
break;
}
break;
} /* READY state */
case PLAY_STATE:{
switch (method) {
case RTSP_ID_PLAY:
// Feature not supported
printf("UNSUPPORTED: Play while playing.\n");
send_reply(551, 0, rtsp); /* Option not supported */
break;
case RTSP_ID_PAUSE:
if (RTSP_pause(rtsp) == ERR_NOERROR) {
p->cur_state = READY_STATE;
}
break;
case RTSP_ID_TEARDOWN:
// if (RTSP_teardown(rtsp) == ERR_NOERROR) { // shawill
// p->cur_state = INIT_STATE;
// }
RTSP_teardown(rtsp);
break;
case RTSP_ID_OPTIONS:
break;
case RTSP_ID_DESCRIBE:
RTSP_describe(rtsp);
break;
case RTSP_ID_SETUP:
break;
}
break;
} /* PLAY state */
default:{ /* invalid/unexpected current state. */
printf("State error: unknown state=%d, method code=%d\n", p->cur_state, method);
}
break;
} /* end of current state switch */
}
/**********************************************************************/
/*
* 函数send_reply(int err, char *addon, RTSP_buffer * rtsp) :
* 服务器回复消息通过此函数存入RTSP_buffer,err为对应的消息号。
*/
int send_reply(int err, char *addon, RTSP_buffer * rtsp)
{
unsigned int len;
char *b;
char *p;
int res;
char method[32];
char object[256];
char ver[32];
if (addon != NULL) {
len = 256 + strlen(addon);
} else {
len = 256;
}
b = (char *) malloc(len);
if (b == NULL) {
printf("send_reply(): memory allocation error.\n");
return ERR_ALLOC;
}
memset(b, 0, sizeof(b));
sprintf(b, "%s %d %s\r\nCSeq: %d\r\n\r\n", RTSP_VER, err, get_stat(err), rtsp->rtsp_cseq);
res = bwrite(b, (unsigned short) strlen(b), rtsp);
free(b);
sscanf(rtsp->in_buffer, " %31s %255s %31s ", method, object, ver);
printf("%s %s %s %d - - ", method, object, ver, err);
return res;
}
/**********************************************************************/
/**********************************************************************/
/*
* 函数 :
* 用于获取状态值对应返回状态
*/
/**********************************************************************/
/**********************************************************************/
/*
* 函数 :
* 用于获取状态值对应返回状态
*/
/**********************************************************************/
/**********************************************************************/
/*
* 函数 :
* 用于获取状态值对应返回状态
*/
/**********************************************************************/
/**********************************************************************/
/*
* 函数 :
* 用于获取状态值对应返回状态
*/
/**********************************************************************/
/**********************************************************************/
/*
* 函数 bwrite(char *buffer, unsigned short len, RTSP_buffer * rtsp) :
* 把buffer中的数据写到RTSP_buffer结构体中
*/
int bwrite(char *buffer, unsigned short len, RTSP_buffer * rtsp)
{
if ((rtsp->out_size + len) > (int) sizeof(rtsp->out_buffer)) {
fnc_log(FNC_LOG_ERR,"bwrite(): not enough free space in out message buffer.\n");
return ERR_ALLOC;
}
memcpy(&(rtsp->out_buffer[rtsp->out_size]), buffer, len);
rtsp->out_buffer[rtsp->out_size + len] = '\0';
rtsp->out_size += len;
return ERR_NOERROR;
}
/**********************************************************************/
/**********************************************************************/
/*
* 函数 :
* 用于获取状态值对应返回状态
*/
/**********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -