summaryrefslogtreecommitdiff
path: root/src/input/librtsp/rtsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/input/librtsp/rtsp.c')
-rw-r--r--src/input/librtsp/rtsp.c148
1 files changed, 68 insertions, 80 deletions
diff --git a/src/input/librtsp/rtsp.c b/src/input/librtsp/rtsp.c
index 530ffc6cf..ebac49079 100644
--- a/src/input/librtsp/rtsp.c
+++ b/src/input/librtsp/rtsp.c
@@ -21,6 +21,10 @@
* *not* RFC 2326 compilant yet.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
@@ -40,7 +44,7 @@
#define LOG_VERBOSE
/*
#define LOG
-*/
+*/
#include "rtsp.h"
#include "io_helper.h"
@@ -65,7 +69,7 @@ struct rtsp_s {
char *server;
unsigned int server_state;
uint32_t server_caps;
-
+
unsigned int cseq;
char *session;
@@ -101,17 +105,17 @@ const char rtsp_protocol_version[]="RTSP/1.0";
* rtsp_get gets a line from stream
* and returns a null terminated string (must be freed).
*/
-
+
static char *rtsp_get(rtsp_t *s) {
char *buffer = malloc(BUF_SIZE);
char *string = NULL;
-
+
if ( _x_io_tcp_read_line(s->stream, s->s, buffer, BUF_SIZE) >= 0 ) {
lprintf("<< '%s'\n", buffer);
string = strdup( buffer );
}
-
+
free(buffer);
return string;
}
@@ -120,10 +124,10 @@ static char *rtsp_get(rtsp_t *s) {
/*
* rtsp_put puts a line on stream
*/
-
+
static void rtsp_put(rtsp_t *s, const char *string) {
- int len=strlen(string);
+ size_t len=strlen(string);
char *buf = malloc(sizeof(char)*len+2);
lprintf(">> '%s'", string);
@@ -133,7 +137,7 @@ static void rtsp_put(rtsp_t *s, const char *string) {
buf[len+1]=0x0a;
_x_io_tcp_write(s->stream, s->s, buf, len+2);
-
+
lprintf("done.\n");
free(buf);
@@ -147,7 +151,7 @@ static int rtsp_get_code(rtsp_t *s, const char *string) {
char buf[4];
int code=0;
-
+
if (!strncmp(string, rtsp_protocol_version, strlen(rtsp_protocol_version)))
{
memcpy(buf, string+strlen(rtsp_protocol_version)+1, 3);
@@ -158,7 +162,7 @@ static int rtsp_get_code(rtsp_t *s, const char *string) {
return RTSP_STATUS_SET_PARAMETER;
}
- if(code != 200)
+ if(code != 200)
xprintf(s->stream->xine, XINE_VERBOSITY_DEBUG, "librtsp: server responds: '%s'\n", string);
return code;
@@ -172,10 +176,8 @@ static void rtsp_send_request(rtsp_t *s, const char *type, const char *what) {
char **payload=s->scheduled;
char *buf;
-
- buf = malloc(strlen(type)+strlen(what)+strlen(rtsp_protocol_version)+3);
-
- sprintf(buf,"%s %s %s",type, what, rtsp_protocol_version);
+
+ asprintf(&buf,"%s %s %s",type, what, rtsp_protocol_version);
rtsp_put(s,buf);
free(buf);
if (payload)
@@ -194,14 +196,13 @@ static void rtsp_send_request(rtsp_t *s, const char *type, const char *what) {
static void rtsp_schedule_standard(rtsp_t *s) {
char tmp[17];
-
+
sprintf(tmp, "Cseq: %u", s->cseq);
rtsp_schedule_field(s, tmp);
-
+
if (s->session) {
char *buf;
- buf = malloc(strlen(s->session)+15);
- sprintf(buf, "Session: %s", s->session);
+ asprintf(&buf, "Session: %s", s->session);
rtsp_schedule_field(s, buf);
free(buf);
}
@@ -209,7 +210,7 @@ static void rtsp_schedule_standard(rtsp_t *s) {
/*
* get the answers, if server responses with something != 200, return NULL
*/
-
+
static int rtsp_get_answers(rtsp_t *s) {
char *answer=NULL;
@@ -217,7 +218,7 @@ static int rtsp_get_answers(rtsp_t *s) {
char **answer_ptr=s->answers;
int code;
int ans_count = 0;
-
+
answer=rtsp_get(s);
if (!answer)
return 0;
@@ -225,55 +226,49 @@ static int rtsp_get_answers(rtsp_t *s) {
free(answer);
rtsp_free_answers(s);
-
+
do { /* while we get answer lines */
-
+
answer=rtsp_get(s);
if (!answer)
return 0;
-
- if (!strncasecmp(answer,"Cseq:",5)) {
- sscanf(answer,"%*s %u",&answer_seq);
+
+ if (!strncasecmp(answer,"Cseq: ",6)) {
+ sscanf(answer+6,"%u",&answer_seq);
if (s->cseq != answer_seq) {
lprintf("warning: Cseq mismatch. got %u, assumed %u", answer_seq, s->cseq);
s->cseq=answer_seq;
}
}
- if (!strncasecmp(answer,"Server:",7)) {
- char *buf = xine_xmalloc(strlen(answer));
- sscanf(answer,"%*s %s",buf);
- if (s->server) free(s->server);
- s->server=strdup(buf);
- free(buf);
+ if (!strncasecmp(answer,"Server: ",8)) {
+ free(s->server);
+ s->server = strdup(answer + 8);
}
- if (!strncasecmp(answer,"Session:",8)) {
- char *buf = xine_xmalloc(strlen(answer));
- sscanf(answer,"%*s %s",buf);
+ if (!strncasecmp(answer,"Session: ",9)) {
+ char *tmp = answer + 9;
if (s->session) {
- if (strcmp(buf, s->session)) {
- xprintf(s->stream->xine, XINE_VERBOSITY_DEBUG,
- "rtsp: warning: setting NEW session: %s\n", buf);
- free(s->session);
- s->session=strdup(buf);
+ if (strcmp(tmp, s->session)) {
+ xprintf(s->stream->xine, XINE_VERBOSITY_DEBUG,
+ "rtsp: warning: setting NEW session: %s\n", tmp);
+ s->session=strdup(tmp);
}
} else
{
- lprintf("setting session id to: %s\n", buf);
+ lprintf("setting session id to: %s\n", tmp);
- s->session=strdup(buf);
+ s->session=strdup(tmp);
}
- free(buf);
}
*answer_ptr=answer;
answer_ptr++;
} while ((strlen(answer)!=0) && (++ans_count < MAX_FIELDS));
-
+
s->cseq++;
-
+
*answer_ptr=NULL;
rtsp_schedule_standard(s);
-
+
return code;
}
@@ -283,7 +278,7 @@ static int rtsp_get_answers(rtsp_t *s) {
int rtsp_send_ok(rtsp_t *s) {
char cseq[16];
-
+
rtsp_put(s, "RTSP/1.0 200 OK");
sprintf(cseq,"CSeq: %u", s->cseq);
rtsp_put(s, cseq);
@@ -304,8 +299,7 @@ int rtsp_request_options(rtsp_t *s, const char *what) {
buf=strdup(what);
} else
{
- buf = malloc(sizeof(char)*(strlen(s->host)+16));
- sprintf(buf,"rtsp://%s:%i", s->host, s->port);
+ asprintf(&buf,"rtsp://%s:%i", s->host, s->port);
}
rtsp_send_request(s,"OPTIONS",buf);
free(buf);
@@ -321,19 +315,18 @@ int rtsp_request_describe(rtsp_t *s, const char *what) {
buf=strdup(what);
} else
{
- buf = malloc(sizeof(char)*(strlen(s->host)+strlen(s->path)+16));
- sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
+ asprintf(&buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
}
rtsp_send_request(s,"DESCRIBE",buf);
free(buf);
-
+
return rtsp_get_answers(s);
}
int rtsp_request_setup(rtsp_t *s, const char *what) {
rtsp_send_request(s,"SETUP",what);
-
+
return rtsp_get_answers(s);
}
@@ -345,12 +338,11 @@ int rtsp_request_setparameter(rtsp_t *s, const char *what) {
buf=strdup(what);
} else
{
- buf = malloc(sizeof(char)*(strlen(s->host)+strlen(s->path)+16));
- sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
+ asprintf(&buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
}
rtsp_send_request(s,"SET_PARAMETER",buf);
free(buf);
-
+
return rtsp_get_answers(s);
}
@@ -362,19 +354,18 @@ int rtsp_request_play(rtsp_t *s, const char *what) {
buf=strdup(what);
} else
{
- buf = malloc(sizeof(char)*(strlen(s->host)+strlen(s->path)+16));
- sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
+ asprintf(&buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
}
rtsp_send_request(s,"PLAY",buf);
free(buf);
-
+
return rtsp_get_answers(s);
}
int rtsp_request_tearoff(rtsp_t *s, const char *what) {
rtsp_send_request(s,"TEAROFF",what);
-
+
return rtsp_get_answers(s);
}
@@ -394,7 +385,7 @@ int rtsp_read_data(rtsp_t *s, char *buffer, unsigned int size) {
char *rest=rtsp_get(s);
if (!rest)
return -1;
-
+
seq=-1;
do {
free(rest);
@@ -412,8 +403,7 @@ int rtsp_read_data(rtsp_t *s, char *buffer, unsigned int size) {
}
/* lets make the server happy */
rtsp_put(s, "RTSP/1.0 451 Parameter Not Understood");
- rest = malloc(sizeof(char)*17);
- sprintf(rest,"CSeq: %u", seq);
+ asprintf(&rest,"CSeq: %u", seq);
rtsp_put(s, rest);
free(rest);
rtsp_put(s, "");
@@ -442,14 +432,14 @@ rtsp_t *rtsp_connect(xine_stream_t *stream, const char *mrl, const char *user_ag
char *slash, *colon;
int hostend, i;
size_t pathbegin;
-
+
if (strncmp(mrl,"rtsp://",7))
{
xprintf(stream->xine, XINE_VERBOSITY_LOG, _("rtsp: bad mrl: %s\n"), mrl);
free(s);
return NULL;
}
-
+
mrl_ptr+=7;
for (i=0; i<MAX_FIELDS; i++) {
@@ -463,14 +453,14 @@ rtsp_t *rtsp_connect(xine_stream_t *stream, const char *mrl, const char *user_ag
s->path=NULL;
s->mrl=NULL;
s->mrl=strdup(mrl);
-
+
s->server=NULL;
s->server_state=0;
s->server_caps=0;
-
+
s->cseq=0;
s->session=NULL;
-
+
if (user_agent)
s->user_agent=strdup(user_agent);
else
@@ -480,20 +470,18 @@ rtsp_t *rtsp_connect(xine_stream_t *stream, const char *mrl, const char *user_ag
colon=strchr(mrl_ptr,':');
if(!slash) slash=mrl_ptr+strlen(mrl_ptr)+1;
- if(!colon) colon=slash;
+ if(!colon) colon=slash;
if(colon > slash) colon=slash;
pathbegin=slash-mrl_ptr;
hostend=colon-mrl_ptr;
- s->host = malloc(sizeof(char)*hostend+1);
- strncpy(s->host, mrl_ptr, hostend);
- s->host[hostend]=0;
+ s->host = strndup(mrl_ptr, hostend);
if (pathbegin < strlen(mrl_ptr)) s->path=strdup(mrl_ptr+pathbegin+1);
if (colon != slash) {
char buffer[pathbegin-hostend];
-
+
strncpy(buffer,mrl_ptr+hostend+1, pathbegin-hostend-1);
buffer[pathbegin-hostend-1]=0;
s->port=atoi(buffer);
@@ -529,7 +517,7 @@ rtsp_t *rtsp_connect(xine_stream_t *stream, const char *mrl, const char *user_ag
/*
- * closes an rtsp connection
+ * closes an rtsp connection
*/
void rtsp_close(rtsp_t *s) {
@@ -542,7 +530,7 @@ void rtsp_close(rtsp_t *s) {
if (s->user_agent) free(s->user_agent);
rtsp_free_answers(s);
rtsp_unschedule_all(s);
- free(s);
+ free(s);
}
/*
@@ -554,7 +542,7 @@ char *rtsp_search_answers(rtsp_t *s, const char *tag) {
char **answer;
char *ptr;
-
+
if (!s->answers) return NULL;
answer=s->answers;
@@ -603,7 +591,7 @@ char *rtsp_get_mrl(rtsp_t *s) {
void rtsp_schedule_field(rtsp_t *s, const char *string) {
int i=0;
-
+
if (!string) return;
while(s->scheduled[i]) {
@@ -613,13 +601,13 @@ void rtsp_schedule_field(rtsp_t *s, const char *string) {
}
/*
- * removes the first scheduled field which prefix matches string.
+ * removes the first scheduled field which prefix matches string.
*/
void rtsp_unschedule_field(rtsp_t *s, const char *string) {
char **ptr=s->scheduled;
-
+
if (!string) return;
while(*ptr) {
@@ -640,7 +628,7 @@ void rtsp_unschedule_field(rtsp_t *s, const char *string) {
void rtsp_unschedule_all(rtsp_t *s) {
char **ptr;
-
+
if (!s->scheduled) return;
ptr=s->scheduled;
@@ -657,7 +645,7 @@ void rtsp_unschedule_all(rtsp_t *s) {
void rtsp_free_answers(rtsp_t *s) {
char **answer;
-
+
if (!s->answers) return;
answer=s->answers;