📄 rtsp_response.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / IETF RTP/RTSP/SDP sub-project * * GPAC is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GPAC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <gpac/internal/ietf_dev.h>#include <gpac/token.h>GF_EXPORTGF_RTSPResponse *gf_rtsp_response_new(){ GF_RTSPResponse *tmp; GF_SAFEALLOC(tmp, GF_RTSPResponse); tmp->Transports = gf_list_new(); tmp->RTP_Infos = gf_list_new(); tmp->Xtensions = gf_list_new(); return tmp;}#define RSP_FREE_CLEAN(hdr) if (rsp->hdr) free(rsp->hdr); \ rsp->hdr = NULL;GF_EXPORTvoid gf_rtsp_response_reset(GF_RTSPResponse *rsp){ GF_RTPInfo *inf; GF_RTSPTransport *trans; GF_X_Attribute *att; if (!rsp) return; //free all headers RSP_FREE_CLEAN(Accept); RSP_FREE_CLEAN(Accept_Encoding); RSP_FREE_CLEAN(Accept_Language); RSP_FREE_CLEAN(Allow); RSP_FREE_CLEAN(Authorization); RSP_FREE_CLEAN(Cache_Control); RSP_FREE_CLEAN(Conference); RSP_FREE_CLEAN(Connection); RSP_FREE_CLEAN(Content_Base); RSP_FREE_CLEAN(Content_Encoding); RSP_FREE_CLEAN(Content_Language); RSP_FREE_CLEAN(Content_Location); RSP_FREE_CLEAN(Content_Type); RSP_FREE_CLEAN(Date); RSP_FREE_CLEAN(Expires); RSP_FREE_CLEAN(From); RSP_FREE_CLEAN(Host); RSP_FREE_CLEAN(If_Match); RSP_FREE_CLEAN(If_Modified_Since); RSP_FREE_CLEAN(Last_Modified); RSP_FREE_CLEAN(Location); RSP_FREE_CLEAN(Proxy_Authenticate); RSP_FREE_CLEAN(Proxy_Require); RSP_FREE_CLEAN(Public); RSP_FREE_CLEAN(Referer); RSP_FREE_CLEAN(Require); RSP_FREE_CLEAN(Retry_After); RSP_FREE_CLEAN(Server); RSP_FREE_CLEAN(Session); RSP_FREE_CLEAN(Timestamp); RSP_FREE_CLEAN(Unsupported); RSP_FREE_CLEAN(User_Agent); RSP_FREE_CLEAN(Vary); RSP_FREE_CLEAN(Via); RSP_FREE_CLEAN(WWW_Authenticate); //this is for us RSP_FREE_CLEAN(ResponseInfo); RSP_FREE_CLEAN(body); rsp->Bandwidth = rsp->Blocksize = rsp->ResponseCode = rsp->Content_Length = rsp->CSeq = 0; rsp->Scale = rsp->Speed = 0.0; if (rsp->Range) free(rsp->Range); rsp->Range = NULL; rsp->SessionTimeOut = 0; while (gf_list_count(rsp->Transports)) { trans = (GF_RTSPTransport*) gf_list_get(rsp->Transports, 0); gf_list_rem(rsp->Transports, 0); gf_rtsp_transport_del(trans); } while (gf_list_count(rsp->RTP_Infos)) { inf = (GF_RTPInfo*) gf_list_get(rsp->RTP_Infos, 0); gf_list_rem(rsp->RTP_Infos, 0); if (inf->url) free(inf->url); free(inf); } while (gf_list_count(rsp->Xtensions)) { att = (GF_X_Attribute*)gf_list_get(rsp->Xtensions, 0); gf_list_rem(rsp->Xtensions, 0); free(att->Name); free(att->Value); free(att); }}GF_EXPORTvoid gf_rtsp_response_del(GF_RTSPResponse *rsp){ if (!rsp) return; gf_rtsp_response_reset(rsp); gf_list_del(rsp->RTP_Infos); gf_list_del(rsp->Xtensions); gf_list_del(rsp->Transports); free(rsp);}GF_EXPORTGF_RTSPRange *gf_rtsp_range_parse(char *range_buf){ GF_RTSPRange *rg; if (!strstr(range_buf, "npt")) return NULL; GF_SAFEALLOC(rg, GF_RTSPRange); if (sscanf(range_buf, "npt=%lf-%lf", &rg->start, &rg->end) != 2) { rg->end = -1.0; sscanf(range_buf, "npt=%lf-", &rg->start); } return rg;}GF_EXPORTvoid gf_rtsp_transport_del(GF_RTSPTransport *transp){ if (!transp) return; if (transp->destination) free(transp->destination); if (transp->Profile) free(transp->Profile); if (transp->source) free(transp->source); free(transp);}GF_EXPORTGF_RTSPTransport *gf_rtsp_transport_clone(GF_RTSPTransport *original){ GF_RTSPTransport *tr; if (!original) return NULL; tr = (GF_RTSPTransport*) malloc(sizeof(GF_RTSPTransport)); memcpy(tr, original, sizeof(GF_RTSPTransport)); tr->destination = tr->source = tr->Profile = NULL; if (original->destination) tr->destination = strdup(original->destination); if (original->source) tr->source = strdup(original->source); if (original->Profile) tr->Profile = strdup(original->Profile); return tr;}GF_EXPORTGF_RTSPRange *gf_rtsp_range_new(){ GF_RTSPRange *tmp; GF_SAFEALLOC(tmp, GF_RTSPRange); return tmp;}GF_EXPORTvoid gf_rtsp_range_del(GF_RTSPRange *range){ if (!range) return; free(range);}void gf_rtsp_set_response_value(GF_RTSPResponse *rsp, char *Header, char *Value){ char LineBuffer[400], buf[100], param_name[100], param_val[100]; s32 LinePos, Pos, nPos, s_val; GF_RTPInfo *info; GF_RTSPTransport *trans; GF_X_Attribute *x_Att; if (!stricmp(Header, "Accept")) rsp->Accept = strdup(Value); else if (!stricmp(Header, "Accept-Encoding")) rsp->Accept_Encoding = strdup(Value); else if (!stricmp(Header, "Accept-Language")) rsp->Accept_Language = strdup(Value); else if (!stricmp(Header, "Allow")) rsp->Allow = strdup(Value); else if (!stricmp(Header, "Authorization")) rsp->Authorization = strdup(Value); else if (!stricmp(Header, "Bandwidth")) sscanf(Value, "%d", &rsp->Bandwidth); else if (!stricmp(Header, "Blocksize")) sscanf(Value, "%d", &rsp->Blocksize); else if (!stricmp(Header, "Cache-Control")) rsp->Cache_Control = strdup(Value); else if (!stricmp(Header, "Conference")) rsp->Conference = strdup(Value); else if (!stricmp(Header, "Connection")) rsp->Connection = strdup(Value); else if (!stricmp(Header, "Content-Base")) rsp->Content_Base = strdup(Value); else if (!stricmp(Header, "Content-Encoding")) rsp->Content_Encoding = strdup(Value); else if (!stricmp(Header, "Content-Length")) sscanf(Value, "%d", &rsp->Content_Length); else if (!stricmp(Header, "Content-Language")) rsp->Content_Language = strdup(Value); else if (!stricmp(Header, "Content-Location")) rsp->Content_Location = strdup(Value); else if (!stricmp(Header, "Content-Type")) rsp->Content_Type = strdup(Value); else if (!stricmp(Header, "CSeq")) sscanf(Value, "%d", &rsp->CSeq); else if (!stricmp(Header, "Date")) rsp->Date = strdup(Value); else if (!stricmp(Header, "Expires")) rsp->Expires = strdup(Value); else if (!stricmp(Header, "From")) rsp->From = strdup(Value); else if (!stricmp(Header, "Host")) rsp->Host = strdup(Value); else if (!stricmp(Header, "If-Match")) rsp->If_Match = strdup(Value); else if (!stricmp(Header, "If-Modified-Since")) rsp->If_Modified_Since = strdup(Value); else if (!stricmp(Header, "Last-Modified")) rsp->Last_Modified = strdup(Value); else if (!stricmp(Header, "Location")) rsp->Location = strdup(Value); else if (!stricmp(Header, "Proxy-Authenticate")) rsp->Proxy_Authenticate = strdup(Value); else if (!stricmp(Header, "Proxy-Require")) rsp->Proxy_Require = strdup(Value); else if (!stricmp(Header, "Public")) rsp->Public = strdup(Value); else if (!stricmp(Header, "Referer")) rsp->Referer = strdup(Value); else if (!stricmp(Header, "Require")) rsp->Require = strdup(Value); else if (!stricmp(Header, "Retry-After")) rsp->Retry_After = strdup(Value); else if (!stricmp(Header, "Scale")) sscanf(Value, "%lf", &rsp->Scale); else if (!stricmp(Header, "Server")) rsp->Server = strdup(Value); else if (!stricmp(Header, "Speed")) sscanf(Value, "%lf", &rsp->Speed); else if (!stricmp(Header, "Timestamp")) rsp->Timestamp = strdup(Value); else if (!stricmp(Header, "Unsupported")) rsp->Unsupported = strdup(Value); else if (!stricmp(Header, "User-Agent")) rsp->User_Agent = strdup(Value); else if (!stricmp(Header, "Vary")) rsp->Vary = strdup(Value); else if (!stricmp(Header, "Via")) rsp->Vary = strdup(Value); else if (!stricmp(Header, "WWW_Authenticate")) rsp->Vary = strdup(Value); else if (!stricmp(Header, "Transport")) { LinePos = 0; while (1) { LinePos = gf_token_get(Value, LinePos, "\r\n", LineBuffer, 400); if (LinePos <= 0) return; trans = gf_rtsp_transport_parse(Value); if (trans) gf_list_add(rsp->Transports, trans); } } //Session else if (!stricmp(Header, "Session")) { LinePos = gf_token_get(Value, 0, ";\r\n", LineBuffer, 400); rsp->Session = strdup(LineBuffer); //get timeout if any if (Value[LinePos] == ';') { LinePos += 1; LinePos = gf_token_get(Value, LinePos, ";\r\n", LineBuffer, 400); //default rsp->SessionTimeOut = 60; sscanf(LineBuffer, "timeout=%d", &rsp->SessionTimeOut); } } //Range else if (!stricmp(Header, "Range")) rsp->Range = gf_rtsp_range_parse(Value); //RTP-Info else if (!stricmp(Header, "RTP-Info")) { LinePos = 0; while (1) { LinePos = gf_token_get(Value, LinePos, ",\r\n", LineBuffer, 400); if (LinePos <= 0) return; GF_SAFEALLOC(info, GF_RTPInfo); Pos = 0; while (1) { Pos = gf_token_get(LineBuffer, Pos, " ;", buf, 100); if (Pos <= 0) break; if (strstr(buf, "=")) { nPos = gf_token_get(buf, 0, "=", param_name, 100); nPos += 1; nPos = gf_token_get(buf, nPos, "", param_val, 100); } else { strcpy(param_name, buf); } if (!stricmp(param_name, "url")) info->url = strdup(param_val); else if (!stricmp(param_name, "seq")) sscanf(param_val, "%d", &info->seq); else if (!stricmp(param_name, "rtptime")) { sscanf(param_val, "%i", &s_val); info->rtp_time = (s_val>0) ? s_val : 0; } else if (!stricmp(param_name, "ssrc")) { sscanf(param_val, "%i", &s_val); info->ssrc = (s_val>0) ? s_val : 0; } } gf_list_add(rsp->RTP_Infos, info); } } //check for extended attributes else if (!strnicmp(Header, "x-", 2)) { x_Att = (GF_X_Attribute*)malloc(sizeof(GF_X_Attribute)); x_Att->Name = strdup(Header+2); x_Att->Value = NULL; if (Value && strlen(Value)) x_Att->Value = strdup(Value); gf_list_add(rsp->Xtensions, x_Att); } //unknown field - skip it}//parse all fields in the headerGF_Err RTSP_ParseResponseHeader(GF_RTSPSession *sess, GF_RTSPResponse *rsp, u32 BodyStart){ char LineBuffer[1024]; char ValBuf[400]; char *buffer; s32 Pos, ret; u32 Size; Size = sess->CurrentSize - sess->CurrentPos; buffer = sess->TCPBuffer + sess->CurrentPos; //parse first line ret = gf_token_get_line(buffer, 0, Size, LineBuffer, 1024); if (ret < 0) return GF_REMOTE_SERVICE_ERROR; //RTSP/1.0 Pos = gf_token_get(LineBuffer, 0, " \t\r\n", ValBuf, 400); if (Pos <= 0) return GF_REMOTE_SERVICE_ERROR; if (strcmp(ValBuf, GF_RTSP_VERSION)) return GF_SERVICE_ERROR; //CODE Pos = gf_token_get(LineBuffer, Pos, " \t\r\n", ValBuf, 400); if (Pos <= 0) return GF_REMOTE_SERVICE_ERROR; rsp->ResponseCode = atoi(ValBuf); //string info Pos = gf_token_get(LineBuffer, Pos, "\t\r\n", ValBuf, 400); if (Pos > 0) rsp->ResponseInfo = strdup(ValBuf); return gf_rtsp_parse_header(buffer + ret, Size - ret, BodyStart, NULL, rsp);}u32 IsRTSPMessage(char *buffer){ if (!buffer) return 0; if (buffer[0]=='$') return 0; if (!strncmp(buffer, "RTSP", 4)) return 1; if (!strncmp(buffer, "GET_PARAMETER", strlen("GET_PARAMETER"))) return 1; if (!strncmp(buffer, "ANNOUNCE", strlen("ANNOUNCE"))) return 1; if (!strncmp(buffer, "SET_PARAMETER", strlen("SET_PARAMETER"))) return 1; if (!strncmp(buffer, "REDIRECT", strlen("REDIRECT"))) return 1; if (!strncmp(buffer, "OPTIONS", strlen("OPTIONS"))) return 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -