1/*
2 * RTSP demuxer
3 * Copyright (c) 2002 Fabrice Bellard
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include "libavutil/avstring.h"
23#include "libavutil/intreadwrite.h"
24#include "libavutil/mathematics.h"
25#include "libavutil/random_seed.h"
26#include "libavutil/time.h"
27#include "avformat.h"
28
29#include "internal.h"
30#include "network.h"
31#include "os_support.h"
32#include "rtpproto.h"
33#include "rtsp.h"
34#include "rdt.h"
35#include "url.h"
36
37static const struct RTSPStatusMessage {
38    enum RTSPStatusCode code;
39    const char *message;
40} status_messages[] = {
41    { RTSP_STATUS_OK,             "OK"                               },
42    { RTSP_STATUS_METHOD,         "Method Not Allowed"               },
43    { RTSP_STATUS_BANDWIDTH,      "Not Enough Bandwidth"             },
44    { RTSP_STATUS_SESSION,        "Session Not Found"                },
45    { RTSP_STATUS_STATE,          "Method Not Valid in This State"   },
46    { RTSP_STATUS_AGGREGATE,      "Aggregate operation not allowed"  },
47    { RTSP_STATUS_ONLY_AGGREGATE, "Only aggregate operation allowed" },
48    { RTSP_STATUS_TRANSPORT,      "Unsupported transport"            },
49    { RTSP_STATUS_INTERNAL,       "Internal Server Error"            },
50    { RTSP_STATUS_SERVICE,        "Service Unavailable"              },
51    { RTSP_STATUS_VERSION,        "RTSP Version not supported"       },
52    { 0,                          "NULL"                             }
53};
54
55static int rtsp_read_close(AVFormatContext *s)
56{
57    RTSPState *rt = s->priv_data;
58
59    if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN))
60        ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
61
62    ff_rtsp_close_streams(s);
63    ff_rtsp_close_connections(s);
64    ff_network_close();
65    rt->real_setup = NULL;
66    av_freep(&rt->real_setup_cache);
67    return 0;
68}
69
70static inline int read_line(AVFormatContext *s, char *rbuf, const int rbufsize,
71                            int *rbuflen)
72{
73    RTSPState *rt = s->priv_data;
74    int idx       = 0;
75    int ret       = 0;
76    *rbuflen      = 0;
77
78    do {
79        ret = ffurl_read_complete(rt->rtsp_hd, rbuf + idx, 1);
80        if (ret <= 0)
81            return ret ? ret : AVERROR_EOF;
82        if (rbuf[idx] == '\r') {
83            /* Ignore */
84        } else if (rbuf[idx] == '\n') {
85            rbuf[idx] = '\0';
86            *rbuflen  = idx;
87            return 0;
88        } else
89            idx++;
90    } while (idx < rbufsize);
91    av_log(s, AV_LOG_ERROR, "Message too long\n");
92    return AVERROR(EIO);
93}
94
95static int rtsp_send_reply(AVFormatContext *s, enum RTSPStatusCode code,
96                           const char *extracontent, uint16_t seq)
97{
98    RTSPState *rt = s->priv_data;
99    char message[4096];
100    int index = 0;
101    while (status_messages[index].code) {
102        if (status_messages[index].code == code) {
103            snprintf(message, sizeof(message), "RTSP/1.0 %d %s\r\n",
104                     code, status_messages[index].message);
105            break;
106        }
107        index++;
108    }
109    if (!status_messages[index].code)
110        return AVERROR(EINVAL);
111    av_strlcatf(message, sizeof(message), "CSeq: %d\r\n", seq);
112    av_strlcatf(message, sizeof(message), "Server: %s\r\n", LIBAVFORMAT_IDENT);
113    if (extracontent)
114        av_strlcat(message, extracontent, sizeof(message));
115    av_strlcat(message, "\r\n", sizeof(message));
116    av_dlog(s, "Sending response:\n%s", message);
117    ffurl_write(rt->rtsp_hd, message, strlen(message));
118
119    return 0;
120}
121
122static inline int check_sessionid(AVFormatContext *s,
123                                  RTSPMessageHeader *request)
124{
125    RTSPState *rt = s->priv_data;
126    unsigned char *session_id = rt->session_id;
127    if (!session_id[0]) {
128        av_log(s, AV_LOG_WARNING, "There is no session-id at the moment\n");
129        return 0;
130    }
131    if (strcmp(session_id, request->session_id)) {
132        av_log(s, AV_LOG_ERROR, "Unexpected session-id %s\n",
133               request->session_id);
134        rtsp_send_reply(s, RTSP_STATUS_SESSION, NULL, request->seq);
135        return AVERROR_STREAM_NOT_FOUND;
136    }
137    return 0;
138}
139
140static inline int rtsp_read_request(AVFormatContext *s,
141                                    RTSPMessageHeader *request,
142                                    const char *method)
143{
144    RTSPState *rt = s->priv_data;
145    char rbuf[1024];
146    int rbuflen, ret;
147    do {
148        ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
149        if (ret)
150            return ret;
151        if (rbuflen > 1) {
152            av_dlog(s, "Parsing[%d]: %s\n", rbuflen, rbuf);
153            ff_rtsp_parse_line(request, rbuf, rt, method);
154        }
155    } while (rbuflen > 0);
156    if (request->seq != rt->seq + 1) {
157        av_log(s, AV_LOG_ERROR, "Unexpected Sequence number %d\n",
158               request->seq);
159        return AVERROR(EINVAL);
160    }
161    if (rt->session_id[0] && strcmp(method, "OPTIONS")) {
162        ret = check_sessionid(s, request);
163        if (ret)
164            return ret;
165    }
166
167    return 0;
168}
169
170static int rtsp_read_announce(AVFormatContext *s)
171{
172    RTSPState *rt             = s->priv_data;
173    RTSPMessageHeader request = { 0 };
174    char sdp[4096];
175    int  ret;
176
177    ret = rtsp_read_request(s, &request, "ANNOUNCE");
178    if (ret)
179        return ret;
180    rt->seq++;
181    if (strcmp(request.content_type, "application/sdp")) {
182        av_log(s, AV_LOG_ERROR, "Unexpected content type %s\n",
183               request.content_type);
184        rtsp_send_reply(s, RTSP_STATUS_SERVICE, NULL, request.seq);
185        return AVERROR_OPTION_NOT_FOUND;
186    }
187    if (request.content_length && request.content_length < sizeof(sdp) - 1) {
188        /* Read SDP */
189        if (ffurl_read_complete(rt->rtsp_hd, sdp, request.content_length)
190            < request.content_length) {
191            av_log(s, AV_LOG_ERROR,
192                   "Unable to get complete SDP Description in ANNOUNCE\n");
193            rtsp_send_reply(s, RTSP_STATUS_INTERNAL, NULL, request.seq);
194            return AVERROR(EIO);
195        }
196        sdp[request.content_length] = '\0';
197        av_log(s, AV_LOG_VERBOSE, "SDP: %s\n", sdp);
198        ret = ff_sdp_parse(s, sdp);
199        if (ret)
200            return ret;
201        rtsp_send_reply(s, RTSP_STATUS_OK, NULL, request.seq);
202        return 0;
203    }
204    av_log(s, AV_LOG_ERROR,
205           "Content-Length header value exceeds sdp allocated buffer (4KB)\n");
206    rtsp_send_reply(s, RTSP_STATUS_INTERNAL,
207                    "Content-Length exceeds buffer size", request.seq);
208    return AVERROR(EIO);
209}
210
211static int rtsp_read_options(AVFormatContext *s)
212{
213    RTSPState *rt             = s->priv_data;
214    RTSPMessageHeader request = { 0 };
215    int ret                   = 0;
216
217    /* Parsing headers */
218    ret = rtsp_read_request(s, &request, "OPTIONS");
219    if (ret)
220        return ret;
221    rt->seq++;
222    /* Send Reply */
223    rtsp_send_reply(s, RTSP_STATUS_OK,
224                    "Public: ANNOUNCE, PAUSE, SETUP, TEARDOWN, RECORD\r\n",
225                    request.seq);
226    return 0;
227}
228
229static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl)
230{
231    RTSPState *rt             = s->priv_data;
232    RTSPMessageHeader request = { 0 };
233    int ret                   = 0;
234    char url[1024];
235    RTSPStream *rtsp_st;
236    char responseheaders[1024];
237    int localport    = -1;
238    int transportidx = 0;
239    int streamid     = 0;
240
241    ret = rtsp_read_request(s, &request, "SETUP");
242    if (ret)
243        return ret;
244    rt->seq++;
245    if (!request.nb_transports) {
246        av_log(s, AV_LOG_ERROR, "No transport defined in SETUP\n");
247        return AVERROR_INVALIDDATA;
248    }
249    for (transportidx = 0; transportidx < request.nb_transports;
250         transportidx++) {
251        if (!request.transports[transportidx].mode_record ||
252            (request.transports[transportidx].lower_transport !=
253             RTSP_LOWER_TRANSPORT_UDP &&
254             request.transports[transportidx].lower_transport !=
255             RTSP_LOWER_TRANSPORT_TCP)) {
256            av_log(s, AV_LOG_ERROR, "mode=record/receive not set or transport"
257                   " protocol not supported (yet)\n");
258            return AVERROR_INVALIDDATA;
259        }
260    }
261    if (request.nb_transports > 1)
262        av_log(s, AV_LOG_WARNING, "More than one transport not supported, "
263               "using first of all\n");
264    for (streamid = 0; streamid < rt->nb_rtsp_streams; streamid++) {
265        if (!strcmp(rt->rtsp_streams[streamid]->control_url,
266                    controlurl))
267            break;
268    }
269    if (streamid == rt->nb_rtsp_streams) {
270        av_log(s, AV_LOG_ERROR, "Unable to find requested track\n");
271        return AVERROR_STREAM_NOT_FOUND;
272    }
273    rtsp_st   = rt->rtsp_streams[streamid];
274    localport = rt->rtp_port_min;
275
276    if (request.transports[0].lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
277        rt->lower_transport = RTSP_LOWER_TRANSPORT_TCP;
278        if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
279            rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
280            return ret;
281        }
282        rtsp_st->interleaved_min = request.transports[0].interleaved_min;
283        rtsp_st->interleaved_max = request.transports[0].interleaved_max;
284        snprintf(responseheaders, sizeof(responseheaders), "Transport: "
285                 "RTP/AVP/TCP;unicast;mode=receive;interleaved=%d-%d"
286                 "\r\n", request.transports[0].interleaved_min,
287                 request.transports[0].interleaved_max);
288    } else {
289        do {
290            ff_url_join(url, sizeof(url), "rtp", NULL, host, localport, NULL);
291            av_dlog(s, "Opening: %s", url);
292            ret = ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
293                             &s->interrupt_callback, NULL);
294            if (ret)
295                localport += 2;
296        } while (ret || localport > rt->rtp_port_max);
297        if (localport > rt->rtp_port_max) {
298            rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
299            return ret;
300        }
301
302        av_dlog(s, "Listening on: %d",
303                ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle));
304        if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
305            rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
306            return ret;
307        }
308
309        localport = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
310        snprintf(responseheaders, sizeof(responseheaders), "Transport: "
311                 "RTP/AVP/UDP;unicast;mode=receive;source=%s;"
312                 "client_port=%d-%d;server_port=%d-%d\r\n",
313                 host, request.transports[0].client_port_min,
314                 request.transports[0].client_port_max, localport,
315                 localport + 1);
316    }
317
318    /* Establish sessionid if not previously set */
319    /* Put this in a function? */
320    /* RFC 2326: session id must be at least 8 digits */
321    while (strlen(rt->session_id) < 8)
322        av_strlcatf(rt->session_id, 512, "%u", av_get_random_seed());
323
324    av_strlcatf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
325                rt->session_id);
326    /* Send Reply */
327    rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
328
329    rt->state = RTSP_STATE_PAUSED;
330    return 0;
331}
332
333static int rtsp_read_record(AVFormatContext *s)
334{
335    RTSPState *rt             = s->priv_data;
336    RTSPMessageHeader request = { 0 };
337    int ret                   = 0;
338    char responseheaders[1024];
339
340    ret = rtsp_read_request(s, &request, "RECORD");
341    if (ret)
342        return ret;
343    ret = check_sessionid(s, &request);
344    if (ret)
345        return ret;
346    rt->seq++;
347    snprintf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
348             rt->session_id);
349    rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
350
351    rt->state = RTSP_STATE_STREAMING;
352    return 0;
353}
354
355static inline int parse_command_line(AVFormatContext *s, const char *line,
356                                     int linelen, char *uri, int urisize,
357                                     char *method, int methodsize,
358                                     enum RTSPMethod *methodcode)
359{
360    RTSPState *rt = s->priv_data;
361    const char *linept, *searchlinept;
362    linept = strchr(line, ' ');
363    if (!linept) {
364        av_log(s, AV_LOG_ERROR, "Error parsing method string\n");
365        return AVERROR_INVALIDDATA;
366    }
367    if (linept - line > methodsize - 1) {
368        av_log(s, AV_LOG_ERROR, "Method string too long\n");
369        return AVERROR(EIO);
370    }
371    memcpy(method, line, linept - line);
372    method[linept - line] = '\0';
373    linept++;
374    if (!strcmp(method, "ANNOUNCE"))
375        *methodcode = ANNOUNCE;
376    else if (!strcmp(method, "OPTIONS"))
377        *methodcode = OPTIONS;
378    else if (!strcmp(method, "RECORD"))
379        *methodcode = RECORD;
380    else if (!strcmp(method, "SETUP"))
381        *methodcode = SETUP;
382    else if (!strcmp(method, "PAUSE"))
383        *methodcode = PAUSE;
384    else if (!strcmp(method, "TEARDOWN"))
385        *methodcode = TEARDOWN;
386    else
387        *methodcode = UNKNOWN;
388    /* Check method with the state  */
389    if (rt->state == RTSP_STATE_IDLE) {
390        if ((*methodcode != ANNOUNCE) && (*methodcode != OPTIONS)) {
391            av_log(s, AV_LOG_ERROR, "Unexpected command in Idle State %s\n",
392                   line);
393            return AVERROR_PROTOCOL_NOT_FOUND;
394        }
395    } else if (rt->state == RTSP_STATE_PAUSED) {
396        if ((*methodcode != OPTIONS) && (*methodcode != RECORD)
397            && (*methodcode != SETUP)) {
398            av_log(s, AV_LOG_ERROR, "Unexpected command in Paused State %s\n",
399                   line);
400            return AVERROR_PROTOCOL_NOT_FOUND;
401        }
402    } else if (rt->state == RTSP_STATE_STREAMING) {
403        if ((*methodcode != PAUSE) && (*methodcode != OPTIONS)
404            && (*methodcode != TEARDOWN)) {
405            av_log(s, AV_LOG_ERROR, "Unexpected command in Streaming State"
406                   " %s\n", line);
407            return AVERROR_PROTOCOL_NOT_FOUND;
408        }
409    } else {
410        av_log(s, AV_LOG_ERROR, "Unexpected State [%d]\n", rt->state);
411        return AVERROR_BUG;
412    }
413
414    searchlinept = strchr(linept, ' ');
415    if (searchlinept == NULL) {
416        av_log(s, AV_LOG_ERROR, "Error parsing message URI\n");
417        return AVERROR_INVALIDDATA;
418    }
419    if (searchlinept - linept > urisize - 1) {
420        av_log(s, AV_LOG_ERROR, "uri string length exceeded buffer size\n");
421        return AVERROR(EIO);
422    }
423    memcpy(uri, linept, searchlinept - linept);
424    uri[searchlinept - linept] = '\0';
425    if (strcmp(rt->control_uri, uri)) {
426        char host[128], path[512], auth[128];
427        int port;
428        char ctl_host[128], ctl_path[512], ctl_auth[128];
429        int ctl_port;
430        av_url_split(NULL, 0, auth, sizeof(auth), host, sizeof(host), &port,
431                     path, sizeof(path), uri);
432        av_url_split(NULL, 0, ctl_auth, sizeof(ctl_auth), ctl_host,
433                     sizeof(ctl_host), &ctl_port, ctl_path, sizeof(ctl_path),
434                     rt->control_uri);
435        if (strcmp(host, ctl_host))
436            av_log(s, AV_LOG_INFO, "Host %s differs from expected %s\n",
437                   host, ctl_host);
438        if (strcmp(path, ctl_path) && *methodcode != SETUP)
439            av_log(s, AV_LOG_WARNING, "WARNING: Path %s differs from expected"
440                   " %s\n", path, ctl_path);
441        if (*methodcode == ANNOUNCE) {
442            av_log(s, AV_LOG_INFO,
443                   "Updating control URI to %s\n", uri);
444            av_strlcpy(rt->control_uri, uri, sizeof(rt->control_uri));
445        }
446    }
447
448    linept = searchlinept + 1;
449    if (!av_strstart(linept, "RTSP/1.0", NULL)) {
450        av_log(s, AV_LOG_ERROR, "Error parsing protocol or version\n");
451        return AVERROR_PROTOCOL_NOT_FOUND;
452    }
453    return 0;
454}
455
456int ff_rtsp_parse_streaming_commands(AVFormatContext *s)
457{
458    RTSPState *rt = s->priv_data;
459    unsigned char rbuf[4096];
460    unsigned char method[10];
461    char uri[500];
462    int ret;
463    int rbuflen               = 0;
464    RTSPMessageHeader request = { 0 };
465    enum RTSPMethod methodcode;
466
467    ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
468    if (ret < 0)
469        return ret;
470    ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
471                             sizeof(method), &methodcode);
472    if (ret) {
473        av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
474        return ret;
475    }
476
477    ret = rtsp_read_request(s, &request, method);
478    if (ret)
479        return ret;
480    rt->seq++;
481    if (methodcode == PAUSE) {
482        rt->state = RTSP_STATE_PAUSED;
483        ret       = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
484        // TODO: Missing date header in response
485    } else if (methodcode == OPTIONS) {
486        ret = rtsp_send_reply(s, RTSP_STATUS_OK,
487                              "Public: ANNOUNCE, PAUSE, SETUP, TEARDOWN, "
488                              "RECORD\r\n", request.seq);
489    } else if (methodcode == TEARDOWN) {
490        rt->state = RTSP_STATE_IDLE;
491        ret       = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
492        return 0;
493    }
494    return ret;
495}
496
497static int rtsp_read_play(AVFormatContext *s)
498{
499    RTSPState *rt = s->priv_data;
500    RTSPMessageHeader reply1, *reply = &reply1;
501    int i;
502    char cmd[1024];
503
504    av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
505    rt->nb_byes = 0;
506
507    if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
508        if (rt->transport == RTSP_TRANSPORT_RTP) {
509            for (i = 0; i < rt->nb_rtsp_streams; i++) {
510                RTSPStream *rtsp_st = rt->rtsp_streams[i];
511                RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
512                if (!rtpctx)
513                    continue;
514                ff_rtp_reset_packet_queue(rtpctx);
515                rtpctx->last_rtcp_ntp_time  = AV_NOPTS_VALUE;
516                rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE;
517                rtpctx->base_timestamp      = 0;
518                rtpctx->timestamp           = 0;
519                rtpctx->unwrapped_timestamp = 0;
520                rtpctx->rtcp_ts_offset      = 0;
521            }
522        }
523        if (rt->state == RTSP_STATE_PAUSED) {
524            cmd[0] = 0;
525        } else {
526            snprintf(cmd, sizeof(cmd),
527                     "Range: npt=%"PRId64".%03"PRId64"-\r\n",
528                     rt->seek_timestamp / AV_TIME_BASE,
529                     rt->seek_timestamp / (AV_TIME_BASE / 1000) % 1000);
530        }
531        ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL);
532        if (reply->status_code != RTSP_STATUS_OK) {
533            return -1;
534        }
535        if (rt->transport == RTSP_TRANSPORT_RTP &&
536            reply->range_start != AV_NOPTS_VALUE) {
537            for (i = 0; i < rt->nb_rtsp_streams; i++) {
538                RTSPStream *rtsp_st = rt->rtsp_streams[i];
539                RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
540                AVStream *st = NULL;
541                if (!rtpctx || rtsp_st->stream_index < 0)
542                    continue;
543                st = s->streams[rtsp_st->stream_index];
544                rtpctx->range_start_offset =
545                    av_rescale_q(reply->range_start, AV_TIME_BASE_Q,
546                                 st->time_base);
547            }
548        }
549    }
550    rt->state = RTSP_STATE_STREAMING;
551    return 0;
552}
553
554/* pause the stream */
555static int rtsp_read_pause(AVFormatContext *s)
556{
557    RTSPState *rt = s->priv_data;
558    RTSPMessageHeader reply1, *reply = &reply1;
559
560    if (rt->state != RTSP_STATE_STREAMING)
561        return 0;
562    else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
563        ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL);
564        if (reply->status_code != RTSP_STATUS_OK) {
565            return -1;
566        }
567    }
568    rt->state = RTSP_STATE_PAUSED;
569    return 0;
570}
571
572int ff_rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply)
573{
574    RTSPState *rt = s->priv_data;
575    char cmd[1024];
576    unsigned char *content = NULL;
577    int ret;
578
579    /* describe the stream */
580    snprintf(cmd, sizeof(cmd),
581             "Accept: application/sdp\r\n");
582    if (rt->server_type == RTSP_SERVER_REAL) {
583        /**
584         * The Require: attribute is needed for proper streaming from
585         * Realmedia servers.
586         */
587        av_strlcat(cmd,
588                   "Require: com.real.retain-entity-for-setup\r\n",
589                   sizeof(cmd));
590    }
591    ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content);
592    if (!content)
593        return AVERROR_INVALIDDATA;
594    if (reply->status_code != RTSP_STATUS_OK) {
595        av_freep(&content);
596        return AVERROR_INVALIDDATA;
597    }
598
599    av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content);
600    /* now we got the SDP description, we parse it */
601    ret = ff_sdp_parse(s, (const char *)content);
602    av_freep(&content);
603    if (ret < 0)
604        return ret;
605
606    return 0;
607}
608
609static int rtsp_listen(AVFormatContext *s)
610{
611    RTSPState *rt = s->priv_data;
612    char host[128], path[512], auth[128];
613    char uri[500];
614    int port;
615    char tcpname[500];
616    unsigned char rbuf[4096];
617    unsigned char method[10];
618    int rbuflen = 0;
619    int ret;
620    enum RTSPMethod methodcode;
621
622    /* extract hostname and port */
623    av_url_split(NULL, 0, auth, sizeof(auth), host, sizeof(host), &port,
624                 path, sizeof(path), s->filename);
625
626    /* ff_url_join. No authorization by now (NULL) */
627    ff_url_join(rt->control_uri, sizeof(rt->control_uri), "rtsp", NULL, host,
628                port, "%s", path);
629
630    if (port < 0)
631        port = RTSP_DEFAULT_PORT;
632
633    /* Create TCP connection */
634    ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port,
635                "?listen&listen_timeout=%d", rt->initial_timeout * 1000);
636
637    if (ret = ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
638                         &s->interrupt_callback, NULL)) {
639        av_log(s, AV_LOG_ERROR, "Unable to open RTSP for listening\n");
640        return ret;
641    }
642    rt->state       = RTSP_STATE_IDLE;
643    rt->rtsp_hd_out = rt->rtsp_hd;
644    for (;;) { /* Wait for incoming RTSP messages */
645        ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
646        if (ret < 0)
647            return ret;
648        ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
649                                 sizeof(method), &methodcode);
650        if (ret) {
651            av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
652            return ret;
653        }
654
655        if (methodcode == ANNOUNCE) {
656            ret       = rtsp_read_announce(s);
657            rt->state = RTSP_STATE_PAUSED;
658        } else if (methodcode == OPTIONS) {
659            ret = rtsp_read_options(s);
660        } else if (methodcode == RECORD) {
661            ret = rtsp_read_record(s);
662            if (!ret)
663                return 0; // We are ready for streaming
664        } else if (methodcode == SETUP)
665            ret = rtsp_read_setup(s, host, uri);
666        if (ret) {
667            ffurl_close(rt->rtsp_hd);
668            return AVERROR_INVALIDDATA;
669        }
670    }
671    return 0;
672}
673
674static int rtsp_probe(AVProbeData *p)
675{
676    if (av_strstart(p->filename, "rtsp:", NULL))
677        return AVPROBE_SCORE_MAX;
678    return 0;
679}
680
681static int rtsp_read_header(AVFormatContext *s)
682{
683    RTSPState *rt = s->priv_data;
684    int ret;
685
686    if (rt->initial_timeout > 0)
687        rt->rtsp_flags |= RTSP_FLAG_LISTEN;
688
689    if (rt->rtsp_flags & RTSP_FLAG_LISTEN) {
690        ret = rtsp_listen(s);
691        if (ret)
692            return ret;
693    } else {
694        ret = ff_rtsp_connect(s);
695        if (ret)
696            return ret;
697
698        rt->real_setup_cache = !s->nb_streams ? NULL :
699            av_mallocz_array(s->nb_streams, 2 * sizeof(*rt->real_setup_cache));
700        if (!rt->real_setup_cache && s->nb_streams)
701            return AVERROR(ENOMEM);
702        rt->real_setup = rt->real_setup_cache + s->nb_streams;
703
704        if (rt->initial_pause) {
705            /* do not start immediately */
706        } else {
707            if (rtsp_read_play(s) < 0) {
708                ff_rtsp_close_streams(s);
709                ff_rtsp_close_connections(s);
710                return AVERROR_INVALIDDATA;
711            }
712        }
713    }
714
715    return 0;
716}
717
718int ff_rtsp_tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
719                            uint8_t *buf, int buf_size)
720{
721    RTSPState *rt = s->priv_data;
722    int id, len, i, ret;
723    RTSPStream *rtsp_st;
724
725    av_dlog(s, "tcp_read_packet:\n");
726redo:
727    for (;;) {
728        RTSPMessageHeader reply;
729
730        ret = ff_rtsp_read_reply(s, &reply, NULL, 1, NULL);
731        if (ret < 0)
732            return ret;
733        if (ret == 1) /* received '$' */
734            break;
735        /* XXX: parse message */
736        if (rt->state != RTSP_STATE_STREAMING)
737            return 0;
738    }
739    ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
740    if (ret != 3)
741        return -1;
742    id  = buf[0];
743    len = AV_RB16(buf + 1);
744    av_dlog(s, "id=%d len=%d\n", id, len);
745    if (len > buf_size || len < 8)
746        goto redo;
747    /* get the data */
748    ret = ffurl_read_complete(rt->rtsp_hd, buf, len);
749    if (ret != len)
750        return -1;
751    if (rt->transport == RTSP_TRANSPORT_RDT &&
752        ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0)
753        return -1;
754
755    /* find the matching stream */
756    for (i = 0; i < rt->nb_rtsp_streams; i++) {
757        rtsp_st = rt->rtsp_streams[i];
758        if (id >= rtsp_st->interleaved_min &&
759            id <= rtsp_st->interleaved_max)
760            goto found;
761    }
762    goto redo;
763found:
764    *prtsp_st = rtsp_st;
765    return len;
766}
767
768static int resetup_tcp(AVFormatContext *s)
769{
770    RTSPState *rt = s->priv_data;
771    char host[1024];
772    int port;
773
774    av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0,
775                 s->filename);
776    ff_rtsp_undo_setup(s, 0);
777    return ff_rtsp_make_setup_request(s, host, port, RTSP_LOWER_TRANSPORT_TCP,
778                                      rt->real_challenge);
779}
780
781static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
782{
783    RTSPState *rt = s->priv_data;
784    int ret;
785    RTSPMessageHeader reply1, *reply = &reply1;
786    char cmd[1024];
787
788retry:
789    if (rt->server_type == RTSP_SERVER_REAL) {
790        int i;
791
792        for (i = 0; i < s->nb_streams; i++)
793            rt->real_setup[i] = s->streams[i]->discard;
794
795        if (!rt->need_subscription) {
796            if (memcmp (rt->real_setup, rt->real_setup_cache,
797                        sizeof(enum AVDiscard) * s->nb_streams)) {
798                snprintf(cmd, sizeof(cmd),
799                         "Unsubscribe: %s\r\n",
800                         rt->last_subscription);
801                ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
802                                 cmd, reply, NULL);
803                if (reply->status_code != RTSP_STATUS_OK)
804                    return AVERROR_INVALIDDATA;
805                rt->need_subscription = 1;
806            }
807        }
808
809        if (rt->need_subscription) {
810            int r, rule_nr, first = 1;
811
812            memcpy(rt->real_setup_cache, rt->real_setup,
813                   sizeof(enum AVDiscard) * s->nb_streams);
814            rt->last_subscription[0] = 0;
815
816            snprintf(cmd, sizeof(cmd),
817                     "Subscribe: ");
818            for (i = 0; i < rt->nb_rtsp_streams; i++) {
819                rule_nr = 0;
820                for (r = 0; r < s->nb_streams; r++) {
821                    if (s->streams[r]->id == i) {
822                        if (s->streams[r]->discard != AVDISCARD_ALL) {
823                            if (!first)
824                                av_strlcat(rt->last_subscription, ",",
825                                           sizeof(rt->last_subscription));
826                            ff_rdt_subscribe_rule(
827                                rt->last_subscription,
828                                sizeof(rt->last_subscription), i, rule_nr);
829                            first = 0;
830                        }
831                        rule_nr++;
832                    }
833                }
834            }
835            av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);
836            ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
837                             cmd, reply, NULL);
838            if (reply->status_code != RTSP_STATUS_OK)
839                return AVERROR_INVALIDDATA;
840            rt->need_subscription = 0;
841
842            if (rt->state == RTSP_STATE_STREAMING)
843                rtsp_read_play (s);
844        }
845    }
846
847    ret = ff_rtsp_fetch_packet(s, pkt);
848    if (ret < 0) {
849        if (ret == AVERROR(ETIMEDOUT) && !rt->packets) {
850            if (rt->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
851                rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_TCP)) {
852                RTSPMessageHeader reply1, *reply = &reply1;
853                av_log(s, AV_LOG_WARNING, "UDP timeout, retrying with TCP\n");
854                if (rtsp_read_pause(s) != 0)
855                    return -1;
856                // TEARDOWN is required on Real-RTSP, but might make
857                // other servers close the connection.
858                if (rt->server_type == RTSP_SERVER_REAL)
859                    ff_rtsp_send_cmd(s, "TEARDOWN", rt->control_uri, NULL,
860                                     reply, NULL);
861                rt->session_id[0] = '\0';
862                if (resetup_tcp(s) == 0) {
863                    rt->state = RTSP_STATE_IDLE;
864                    rt->need_subscription = 1;
865                    if (rtsp_read_play(s) != 0)
866                        return -1;
867                    goto retry;
868                }
869            }
870        }
871        return ret;
872    }
873    rt->packets++;
874
875    if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN)) {
876        /* send dummy request to keep TCP connection alive */
877        if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2 ||
878            rt->auth_state.stale) {
879            if (rt->server_type == RTSP_SERVER_WMS ||
880                (rt->server_type != RTSP_SERVER_REAL &&
881                 rt->get_parameter_supported)) {
882                ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
883            } else {
884                ff_rtsp_send_cmd_async(s, "OPTIONS", rt->control_uri, NULL);
885            }
886            /* The stale flag should be reset when creating the auth response in
887             * ff_rtsp_send_cmd_async, but reset it here just in case we never
888             * called the auth code (if we didn't have any credentials set). */
889            rt->auth_state.stale = 0;
890        }
891    }
892
893    return 0;
894}
895
896static int rtsp_read_seek(AVFormatContext *s, int stream_index,
897                          int64_t timestamp, int flags)
898{
899    RTSPState *rt = s->priv_data;
900
901    rt->seek_timestamp = av_rescale_q(timestamp,
902                                      s->streams[stream_index]->time_base,
903                                      AV_TIME_BASE_Q);
904    switch(rt->state) {
905    default:
906    case RTSP_STATE_IDLE:
907        break;
908    case RTSP_STATE_STREAMING:
909        if (rtsp_read_pause(s) != 0)
910            return -1;
911        rt->state = RTSP_STATE_SEEKING;
912        if (rtsp_read_play(s) != 0)
913            return -1;
914        break;
915    case RTSP_STATE_PAUSED:
916        rt->state = RTSP_STATE_IDLE;
917        break;
918    }
919    return 0;
920}
921
922static const AVClass rtsp_demuxer_class = {
923    .class_name     = "RTSP demuxer",
924    .item_name      = av_default_item_name,
925    .option         = ff_rtsp_options,
926    .version        = LIBAVUTIL_VERSION_INT,
927};
928
929AVInputFormat ff_rtsp_demuxer = {
930    .name           = "rtsp",
931    .long_name      = NULL_IF_CONFIG_SMALL("RTSP input"),
932    .priv_data_size = sizeof(RTSPState),
933    .read_probe     = rtsp_probe,
934    .read_header    = rtsp_read_header,
935    .read_packet    = rtsp_read_packet,
936    .read_close     = rtsp_read_close,
937    .read_seek      = rtsp_read_seek,
938    .flags          = AVFMT_NOFILE,
939    .read_play      = rtsp_read_play,
940    .read_pause     = rtsp_read_pause,
941    .priv_class     = &rtsp_demuxer_class,
942};
943