1 /*
2 * Tvheadend - SAT-IP server - RTSP part
3 *
4 * Copyright (C) 2015 Jaroslav Kysela
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "tvheadend.h"
21 #include "htsbuf.h"
22 #include "config.h"
23 #include "profile.h"
24 #include "streaming.h"
25 #include "satip/server.h"
26 #include "input/mpegts/iptv/iptv_private.h"
27
28 #include <ctype.h>
29
30 #define RTSP_TIMEOUT 30
31 #define RTP_BUFSIZE (256*1024)
32 #define RTCP_BUFSIZE (16*1024)
33
34 #define STATE_DESCRIBE 0
35 #define STATE_SETUP 1
36 #define STATE_PLAY 2
37
38 typedef struct slave_subscription {
39 LIST_ENTRY(slave_subscription) link;
40 mpegts_service_t *service;
41 th_subscription_t *ths;
42 profile_chain_t prch;
43 } slave_subscription_t;
44
45 typedef struct session {
46 TAILQ_ENTRY(session) link;
47 char *peer_ipstr;
48 int stream;
49 int frontend;
50 int findex;
51 int src;
52 int state;
53 int playing;
54 int weight;
55 int used_weight;
56 http_connection_t *shutdown_on_close;
57 http_connection_t *tcp_data;
58 int perm_lock;
59 int no_data;
60 uint32_t nsession;
61 char session[9];
62 dvb_mux_conf_t dmc;
63 dvb_mux_conf_t dmc_tuned;
64 mpegts_apids_t pids;
65 mtimer_t timer;
66 mpegts_mux_t *mux;
67 int mux_created;
68 profile_chain_t prch;
69 th_subscription_t *subs;
70 int rtp_peer_port;
71 int rtp_udp_bound;
72 udp_connection_t *udp_rtp;
73 udp_connection_t *udp_rtcp;
74 void *rtp_handle;
75 http_connection_t *old_hc;
76 LIST_HEAD(, slave_subscription) slaves;
77 } session_t;
78
79 static uint32_t session_number;
80 static uint16_t stream_id;
81 static char *rtsp_ip = NULL;
82 static char *rtsp_nat_ip = NULL;
83 static int rtsp_port = -1;
84 static int rtsp_nat_port = -1;
85 static int rtsp_descramble = 1;
86 static int rtsp_rewrite_pmt = 0;
87 static int rtsp_muxcnf = MUXCNF_AUTO;
88 static void *rtsp_server = NULL;
89 static TAILQ_HEAD(,session) rtsp_sessions;
90 static pthread_mutex_t rtsp_lock;
91
92 static void rtsp_close_session(session_t *rs);
93 static void rtsp_free_session(session_t *rs);
94
95
96 /*
97 *
98 */
99 int
satip_rtsp_delsys(int fe,int * findex,const char ** ftype)100 satip_rtsp_delsys(int fe, int *findex, const char **ftype)
101 {
102 const char *t = NULL;
103 int res, i;
104
105 if (fe < 1)
106 return DVB_SYS_NONE;
107 pthread_mutex_lock(&global_lock);
108 i = satip_server_conf.satip_dvbs;
109 if (fe <= i) {
110 res = DVB_SYS_DVBS;
111 t = "DVB-S";
112 goto result;
113 }
114 fe -= i;
115 i = satip_server_conf.satip_dvbs2;
116 if (fe <= i) {
117 res = DVB_SYS_DVBS;
118 t = "DVB-S2";
119 goto result;
120 }
121 fe -= i;
122 i = satip_server_conf.satip_dvbt;
123 if (fe <= i) {
124 res = DVB_SYS_DVBT;
125 t = "DVB-T";
126 goto result;
127 }
128 fe -= i;
129 i = satip_server_conf.satip_dvbt2;
130 if (fe <= i) {
131 res = DVB_SYS_DVBT;
132 t = "DVB-T2";
133 goto result;
134 }
135 fe -= i;
136 i = satip_server_conf.satip_dvbc;
137 if (fe <= i) {
138 res = DVB_SYS_DVBC_ANNEX_A;
139 t = "DVB-C";
140 goto result;
141 }
142 fe -= i;
143 i = satip_server_conf.satip_dvbc2;
144 if (fe <= i) {
145 res = DVB_SYS_DVBC_ANNEX_A;
146 t = "DVB-C2";
147 goto result;
148 }
149 fe -= i;
150 i = satip_server_conf.satip_atsc_t;
151 if (fe <= i) {
152 res = DVB_SYS_ATSC;
153 t = "ATSC-T";
154 goto result;
155 }
156 fe -= i;
157 i = satip_server_conf.satip_atsc_c;
158 if (fe <= i) {
159 res = DVB_SYS_DVBC_ANNEX_B;
160 t = "ATSC-C";
161 goto result;
162 }
163 pthread_mutex_unlock(&global_lock);
164 return DVB_SYS_NONE;
165 result:
166 pthread_mutex_unlock(&global_lock);
167 *findex = i;
168 if (ftype)
169 *ftype = t;
170 return res;
171 }
172
173 /*
174 *
175 */
176 static struct session *
rtsp_new_session(const char * ipstr,int delsys,uint32_t nsession,int session)177 rtsp_new_session(const char *ipstr, int delsys, uint32_t nsession, int session)
178 {
179 struct session *rs = calloc(1, sizeof(*rs));
180
181 if (rs == NULL)
182 return NULL;
183
184 rs->peer_ipstr = strdup(ipstr);
185 rs->nsession = nsession ?: session_number;
186 snprintf(rs->session, sizeof(rs->session), "%08X", session_number);
187 if (!nsession) {
188 session_number += 9876;
189 if (session_number == 0)
190 session_number += 9876;
191 }
192 mpegts_pid_init(&rs->pids);
193 TAILQ_INSERT_TAIL(&rtsp_sessions, rs, link);
194 return rs;
195 }
196
197 /*
198 *
199 */
200 static struct session *
rtsp_find_session(http_connection_t * hc,int stream)201 rtsp_find_session(http_connection_t *hc, int stream)
202 {
203 struct session *rs, *first = NULL;
204
205 if (stream <= 0)
206 return NULL;
207 TAILQ_FOREACH(rs, &rtsp_sessions, link) {
208 if (hc->hc_session &&
209 strcmp(rs->session, hc->hc_session) == 0 &&
210 strcmp(rs->peer_ipstr, hc->hc_peer_ipstr) == 0) {
211 if (stream == rs->stream)
212 return rs;
213 if (first == NULL)
214 first = rs;
215 }
216 if (rs->old_hc == hc && stream == rs->stream)
217 return rs;
218 }
219 return first;
220 }
221
222 /*
223 *
224 */
225 static void
rtsp_session_timer_cb(void * aux)226 rtsp_session_timer_cb(void *aux)
227 {
228 session_t *rs = aux;
229
230 tvhwarn(LS_SATIPS, "-/%s/%i: session closed (timeout)", rs->session, rs->stream);
231 pthread_mutex_unlock(&global_lock);
232 pthread_mutex_lock(&rtsp_lock);
233 rtsp_close_session(rs);
234 rtsp_free_session(rs);
235 pthread_mutex_unlock(&rtsp_lock);
236 pthread_mutex_lock(&global_lock);
237 }
238
239 static inline void
rtsp_rearm_session_timer(session_t * rs)240 rtsp_rearm_session_timer(session_t *rs)
241 {
242 if (!rs->shutdown_on_close || (rs->rtp_peer_port == RTSP_TCP_DATA)) {
243 pthread_mutex_lock(&global_lock);
244 mtimer_arm_rel(&rs->timer, rtsp_session_timer_cb, rs, sec2mono(RTSP_TIMEOUT));
245 pthread_mutex_unlock(&global_lock);
246 }
247 }
248
249 /*
250 *
251 */
252 static char *
rtsp_check_urlbase(char * u)253 rtsp_check_urlbase(char *u)
254 {
255 char *p, *s;
256 int t;
257
258 if (*u == '/' || strncmp(u, "stream=", 7) == 0)
259 return u;
260 /* expect string: rtsp://<myip>[:<myport>]/ */
261 if (u[0] == '\0' || strncmp(u, "rtsp://", 7))
262 return NULL;
263 u += 7;
264 p = strchr(u, '/');
265 if (p)
266 *p = '\0';
267 if ((s = strchr(u, ':')) != NULL) {
268 *s = '\0';
269 t = atoi(s + 1);
270 if (t != rtsp_port) {
271 if (rtsp_nat_port <= 0 || t != rtsp_nat_port)
272 return NULL;
273 }
274 } else {
275 #if 0 /* VLC is broken */
276 if (rtsp_port != 554)
277 return NULL;
278 #endif
279 }
280 if (strcmp(u, rtsp_ip)) {
281 if (rtsp_nat_ip == NULL)
282 return NULL;
283 if (rtsp_nat_ip[0] != '*')
284 if (rtsp_nat_ip[0] == '\0' || strcmp(u, rtsp_nat_ip))
285 return NULL;
286 }
287 return p ? p + 1 : u + strlen(u);
288 }
289
290 /*
291 *
292 */
293 static int
rtsp_parse_args(http_connection_t * hc,char * u)294 rtsp_parse_args(http_connection_t *hc, char *u)
295 {
296 char *s;
297 int stream = 0;
298
299 if (strncmp(u, "stream=", 7) == 0) {
300 u += 7;
301 for (s = u; isdigit(*s); s++);
302 if (*s == '\0')
303 return atoi(u);
304 if (*s != '/' || *(s+1) != '\0')
305 if (*s != '?')
306 return -1;
307 *s = '\0';
308 stream = atoi(u);
309 u = s + 1;
310 } else {
311 if (*u != '?')
312 return -1;
313 u++;
314 }
315 http_parse_args(&hc->hc_req_args, u);
316 return stream;
317 }
318
319 /*
320 *
321 */
322 static void
rtsp_slave_add(session_t * rs,mpegts_service_t * master,mpegts_service_t * slave)323 rtsp_slave_add
324 (session_t *rs, mpegts_service_t *master, mpegts_service_t *slave)
325 {
326 char buf[128];
327 slave_subscription_t *sub = calloc(1, sizeof(*sub));
328
329 pthread_mutex_lock(&master->s_stream_mutex);
330 if (master->s_slaves_pids == NULL)
331 master->s_slaves_pids = mpegts_pid_alloc();
332 pthread_mutex_unlock(&master->s_stream_mutex);
333 master->s_link(master, slave);
334 sub->service = slave;
335 profile_chain_init(&sub->prch, NULL, slave, 0);
336 snprintf(buf, sizeof(buf), "SAT>IP Slave/%s", slave->s_nicename);
337 sub->ths = subscription_create_from_service(&sub->prch, NULL, rs->used_weight,
338 buf, SUBSCRIPTION_NONE, NULL, NULL,
339 buf, NULL);
340 if (sub->ths == NULL) {
341 tvherror(LS_SATIPS, "%i/%s/%i: unable to subscribe service %s\n",
342 rs->frontend, rs->session, rs->stream, slave->s_nicename);
343 profile_chain_close(&sub->prch);
344 free(sub);
345 master->s_unlink(master, slave);
346 } else {
347 LIST_INSERT_HEAD(&rs->slaves, sub, link);
348 tvhdebug(LS_SATIPS, "%i/%s/%i: slave service %s subscribed",
349 rs->frontend, rs->session, rs->stream, slave->s_nicename);
350 }
351 }
352
353 /*
354 *
355 */
356 static void
rtsp_slave_remove(session_t * rs,mpegts_service_t * master,mpegts_service_t * slave)357 rtsp_slave_remove
358 (session_t *rs, mpegts_service_t *master, mpegts_service_t *slave)
359 {
360 slave_subscription_t *sub;
361
362 if (master == NULL)
363 return;
364 LIST_FOREACH(sub, &rs->slaves, link)
365 if (sub->service == slave)
366 break;
367 if (sub == NULL)
368 return;
369 tvhdebug(LS_SATIPS, "%i/%s/%i: slave service %s unsubscribed",
370 rs->frontend, rs->session, rs->stream, slave->s_nicename);
371 master->s_unlink(master, slave);
372 if (sub->ths)
373 subscription_unsubscribe(sub->ths, UNSUBSCRIBE_FINAL);
374 if (sub->prch.prch_id)
375 profile_chain_close(&sub->prch);
376 LIST_REMOVE(sub, link);
377 free(sub);
378 }
379
380 /*
381 *
382 */
383 static void
rtsp_clean(session_t * rs,int clean_mux)384 rtsp_clean(session_t *rs, int clean_mux)
385 {
386 slave_subscription_t *sub;
387
388 if (rs->rtp_handle) {
389 satip_rtp_close(rs->rtp_handle);
390 rs->rtp_handle = NULL;
391 }
392 if (rs->subs) {
393 while ((sub = LIST_FIRST(&rs->slaves)) != NULL)
394 rtsp_slave_remove(rs, (mpegts_service_t *)rs->subs->ths_raw_service,
395 sub->service);
396 subscription_unsubscribe(rs->subs, UNSUBSCRIBE_FINAL);
397 rs->subs = NULL;
398 }
399 if (rs->prch.prch_id)
400 profile_chain_close(&rs->prch);
401 if (clean_mux) {
402 if (rs->mux && rs->mux_created &&
403 (rtsp_muxcnf != MUXCNF_KEEP || LIST_EMPTY(&rs->mux->mm_services)))
404 rs->mux->mm_delete(rs->mux, 1);
405 rs->mux = NULL;
406 rs->mux_created = 0;
407 }
408 }
409
410 /*
411 *
412 */
413 static void
rtsp_no_data(void * opaque)414 rtsp_no_data(void *opaque)
415 {
416 session_t *rs = opaque;
417 rs->no_data = 1;
418 }
419
420 /*
421 *
422 */
423 static int
rtsp_validate_service(mpegts_service_t * s,mpegts_apids_t * pids)424 rtsp_validate_service(mpegts_service_t *s, mpegts_apids_t *pids)
425 {
426 int av = 0, enc = 0;
427 elementary_stream_t *st;
428
429 pthread_mutex_lock(&s->s_stream_mutex);
430 if (s->s_pmt_pid <= 0 || s->s_pcr_pid <= 0) {
431 pthread_mutex_unlock(&s->s_stream_mutex);
432 return 0;
433 }
434 TAILQ_FOREACH(st, &s->s_components, es_link) {
435 if (st->es_type == SCT_CA)
436 enc = 1;
437 if (st->es_pid > 0)
438 if (pids == NULL || mpegts_pid_wexists(pids, st->es_pid, MPS_WEIGHT_RAW))
439 if ((SCT_ISVIDEO(st->es_type) || SCT_ISAUDIO(st->es_type)))
440 av = 1;
441 }
442 pthread_mutex_unlock(&s->s_stream_mutex);
443 if (enc == 0 || av == 0)
444 return 0;
445 return pids == NULL || mpegts_pid_wexists(pids, s->s_pmt_pid, MPS_WEIGHT_RAW);
446 }
447
448 /*
449 *
450 */
451 static void
rtsp_manage_descramble(session_t * rs)452 rtsp_manage_descramble(session_t *rs)
453 {
454 idnode_set_t *found;
455 mpegts_service_t *s, *snext;
456 mpegts_service_t *master = (mpegts_service_t *)rs->subs->ths_raw_service;
457 slave_subscription_t *sub;
458 mpegts_apids_t pmt_pids;
459 size_t si;
460 int i, used = 0;
461
462 if (rtsp_descramble <= 0)
463 return;
464
465 found = idnode_set_create(1);
466
467 if (rs->mux == NULL || rs->subs == NULL)
468 goto end;
469
470 if (rs->pids.all) {
471 LIST_FOREACH(s, &rs->mux->mm_services, s_dvb_mux_link)
472 if (rtsp_validate_service(s, NULL))
473 idnode_set_add(found, &s->s_id, NULL, NULL);
474 } else {
475 for (i = 0; i < rs->pids.count; i++) {
476 s = mpegts_service_find_by_pid((mpegts_mux_t *)rs->mux, rs->pids.pids[i].pid);
477 if (s != NULL && rtsp_validate_service(s, &rs->pids))
478 if (!idnode_set_exists(found, &s->s_id))
479 idnode_set_add(found, &s->s_id, NULL, NULL);
480 }
481 }
482
483 /* Remove already used or no-longer required services */
484 for (s = LIST_FIRST(&master->s_slaves); s; s = snext) {
485 snext = LIST_NEXT(s, s_slaves_link);
486 if (idnode_set_remove(found, &s->s_id))
487 used++;
488 else if (!idnode_set_exists(found, &s->s_id))
489 rtsp_slave_remove(rs, master, s);
490 }
491
492 /* Add new ones */
493 for (si = 0; used < rtsp_descramble && si < found->is_count; si++, used++) {
494 s = (mpegts_service_t *)found->is_array[si];
495 rtsp_slave_add(rs, master, s);
496 idnode_set_remove(found, &s->s_id);
497 }
498 if (si < found->is_count)
499 tvhwarn(LS_SATIPS, "%i/%s/%i: limit for descrambled services reached (wanted %zd allowed %d)",
500 rs->frontend, rs->session, rs->stream,
501 (used - si) + found->is_count, rtsp_descramble);
502
503 end:
504 idnode_set_free(found);
505
506 if (rtsp_rewrite_pmt) {
507 /* handle PMT rewrite */
508 mpegts_pid_init(&pmt_pids);
509 LIST_FOREACH(sub, &rs->slaves, link) {
510 if ((s = sub->service) == NULL) continue;
511 if (s->s_pmt_pid <= 0 || s->s_pmt_pid >= 8191) continue;
512 mpegts_pid_add(&pmt_pids, s->s_pmt_pid, MPS_WEIGHT_PMT);
513 }
514 satip_rtp_update_pmt_pids(rs->rtp_handle, &pmt_pids);
515 mpegts_pid_done(&pmt_pids);
516 }
517 }
518
519 /*
520 *
521 */
522 static int
rtsp_start(http_connection_t * hc,session_t * rs,char * addrbuf,int newmux,int cmd)523 rtsp_start
524 (http_connection_t *hc, session_t *rs, char *addrbuf,
525 int newmux, int cmd)
526 {
527 mpegts_network_t *mn, *mn2;
528 dvb_network_t *ln;
529 mpegts_mux_t *mux;
530 mpegts_service_t *svc;
531 dvb_mux_conf_t dmc;
532 slave_subscription_t *sub;
533 char buf[384];
534 int res = HTTP_STATUS_NOT_ALLOWED, qsize = 3000000, created = 0, weight;
535
536 pthread_mutex_lock(&global_lock);
537 weight = satip_server_conf.satip_weight;
538 if (satip_server_conf.satip_allow_remote_weight && rs->weight)
539 weight = rs->weight;
540 dmc = rs->dmc_tuned;
541 if (newmux) {
542 mux = NULL;
543 mn2 = NULL;
544 LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) {
545 if (idnode_is_instance(&mn->mn_id, &dvb_network_class)) {
546 ln = (dvb_network_t *)mn;
547 if (ln->ln_type == rs->dmc.dmc_fe_type &&
548 mn->mn_satip_source == rs->src) {
549 if (!mn2) mn2 = mn;
550 mux = (mpegts_mux_t *)
551 dvb_network_find_mux((dvb_network_t *)mn, &rs->dmc,
552 MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, 1, rtsp_muxcnf == MUXCNF_REJECT_EXACT_MATCH );
553 if (mux) {
554 dmc = ((dvb_mux_t *)mux)->lm_tuning;
555 rs->perm_lock = 0;
556 break;
557 }
558 }
559 }
560 #if ENABLE_IPTV
561 if (idnode_is_instance(&mn->mn_id, &iptv_network_class)) {
562 LIST_FOREACH(mux, &mn->mn_muxes, mm_network_link) {
563 if (rs->dmc.dmc_fe_type == DVB_TYPE_T &&
564 deltaU32(rs->dmc.dmc_fe_freq, ((iptv_mux_t *)mux)->mm_iptv_satip_dvbt_freq) < 2000)
565 break;
566 if (rs->dmc.dmc_fe_type == DVB_TYPE_C &&
567 deltaU32(rs->dmc.dmc_fe_freq, ((iptv_mux_t *)mux)->mm_iptv_satip_dvbc_freq) < 2000)
568 break;
569 if (rs->dmc.dmc_fe_type == DVB_TYPE_S &&
570 deltaU32(rs->dmc.dmc_fe_freq, ((iptv_mux_t *)mux)->mm_iptv_satip_dvbs_freq) < 2000)
571 break;
572 }
573 if (mux) {
574 dmc = rs->dmc;
575 rs->perm_lock = 1;
576 break;
577 }
578 }
579 #endif
580 }
581 if (mux == NULL && mn2 &&
582 (rtsp_muxcnf == MUXCNF_AUTO || rtsp_muxcnf == MUXCNF_KEEP)) {
583 dvb_mux_conf_str(&rs->dmc, buf, sizeof(buf));
584 tvhwarn(LS_SATIPS, "%i/%s/%i: create mux %s",
585 rs->frontend, rs->session, rs->stream, buf);
586 mux =
587 mn2->mn_create_mux(mn2, (void *)(intptr_t)rs->nsession,
588 MPEGTS_ONID_NONE, MPEGTS_TSID_NONE,
589 &rs->dmc, 1);
590 if (mux) {
591 created = 1;
592 dmc = ((dvb_mux_t *)mux)->lm_tuning;
593 rs->perm_lock = 1;
594 }
595 }
596 if (mux == NULL) {
597 dvb_mux_conf_str(&rs->dmc, buf, sizeof(buf));
598 tvhwarn(LS_SATIPS, "%i/%s/%i: unable to create mux %s%s",
599 rs->frontend, rs->session, rs->stream, buf,
600 (rtsp_muxcnf == MUXCNF_REJECT || rtsp_muxcnf == MUXCNF_REJECT_EXACT_MATCH ) ? " (configuration)" : "");
601 goto endclean;
602 }
603 if (rs->mux == mux && rs->subs) {
604 if (rs->no_data) {
605 tvhwarn(LS_SATIPS, "%i/%s/%i: subscription fails because mux %s can't tune",
606 rs->frontend, rs->session, rs->stream, buf);
607 goto endclean;
608 }
609 goto pids;
610 }
611 rtsp_clean(rs, 1);
612 rs->dmc_tuned = dmc;
613 rs->mux = mux;
614 rs->mux_created = created;
615 if (profile_chain_raw_open(&rs->prch, (mpegts_mux_t *)rs->mux, qsize, 0))
616 goto endclean;
617 rs->used_weight = weight;
618 rs->subs = subscription_create_from_mux(&rs->prch, NULL,
619 weight,
620 "SAT>IP",
621 rs->prch.prch_flags |
622 SUBSCRIPTION_STREAMING,
623 addrbuf, hc->hc_username,
624 http_arg_get(&hc->hc_args, "User-Agent"),
625 NULL);
626 if (!rs->subs)
627 goto endclean;
628 if (!rs->pids.all && rs->pids.count == 0)
629 mpegts_pid_add(&rs->pids, 0, MPS_WEIGHT_RAW);
630 } else {
631 pids:
632 if (!rs->subs)
633 goto endclean;
634 if (!rs->pids.all && rs->pids.count == 0)
635 mpegts_pid_add(&rs->pids, 0, MPS_WEIGHT_RAW);
636 svc = (mpegts_service_t *)rs->subs->ths_raw_service;
637 svc->s_update_pids(svc, &rs->pids);
638 satip_rtp_update_pids(rs->rtp_handle, &rs->pids);
639 if (rs->used_weight != weight && weight > 0) {
640 subscription_set_weight(rs->subs, rs->used_weight = weight);
641 LIST_FOREACH(sub, &rs->slaves, link)
642 subscription_set_weight(sub->ths, weight);
643 }
644 }
645 if (cmd != RTSP_CMD_DESCRIBE && rs->rtp_handle == NULL) {
646 if (rs->mux == NULL)
647 goto endclean;
648 rs->no_data = 0;
649 rs->rtp_handle =
650 satip_rtp_queue(rs->subs, &rs->prch.prch_sq,
651 hc, hc->hc_peer, rs->rtp_peer_port,
652 rs->udp_rtp ? rs->udp_rtp->fd : hc->hc_fd,
653 rs->udp_rtcp ? rs->udp_rtcp->fd : -1,
654 rs->findex, rs->src, &rs->dmc_tuned,
655 &rs->pids,
656 cmd == RTSP_CMD_PLAY || rs->playing,
657 rs->perm_lock, rtsp_no_data, rs);
658 if (rs->rtp_handle == NULL) {
659 res = HTTP_STATUS_INTERNAL;
660 goto endclean;
661 }
662 rs->tcp_data = rs->udp_rtp ? NULL : hc;
663 if (!rs->pids.all && rs->pids.count == 0)
664 mpegts_pid_add(&rs->pids, 0, MPS_WEIGHT_RAW);
665 svc = (mpegts_service_t *)rs->subs->ths_raw_service;
666 svc->s_update_pids(svc, &rs->pids);
667 rs->playing = cmd == RTSP_CMD_PLAY || rs->playing;
668 rs->state = STATE_PLAY;
669 } else if (cmd == RTSP_CMD_PLAY) {
670 rs->playing = 1;
671 if (rs->mux == NULL)
672 goto endclean;
673 satip_rtp_allow_data(rs->rtp_handle);
674 }
675 rtsp_manage_descramble(rs);
676 pthread_mutex_unlock(&global_lock);
677 return 0;
678
679 endclean:
680 rtsp_clean(rs, 0);
681 pthread_mutex_unlock(&global_lock);
682 return res;
683 }
684
685 /*
686 *
687 */
688 static inline int
msys_to_tvh(http_connection_t * hc)689 msys_to_tvh(http_connection_t *hc)
690 {
691 static struct strtab tab[] = {
692 { "dvbs", DVB_SYS_DVBS },
693 { "dvbs2", DVB_SYS_DVBS2 },
694 { "dvbt", DVB_SYS_DVBT },
695 { "dvbt2", DVB_SYS_DVBT2 },
696 { "dvbc", DVB_SYS_DVBC_ANNEX_A },
697 { "dvbc2", DVB_SYS_DVBC_ANNEX_C },
698 { "atsc", DVB_SYS_ATSC },
699 { "dvbcb", DVB_SYS_DVBC_ANNEX_B }
700 };
701 const char *s = http_arg_get_remove(&hc->hc_req_args, "msys");
702 return s && s[0] ? str2val(s, tab) : DVB_SYS_NONE;
703 }
704
705 static inline int
pol_to_tvh(http_connection_t * hc)706 pol_to_tvh(http_connection_t *hc)
707 {
708 static struct strtab tab[] = {
709 { "h", DVB_POLARISATION_HORIZONTAL },
710 { "v", DVB_POLARISATION_VERTICAL },
711 { "l", DVB_POLARISATION_CIRCULAR_LEFT },
712 { "r", DVB_POLARISATION_CIRCULAR_RIGHT },
713 };
714 const char *s = http_arg_get_remove(&hc->hc_req_args, "pol");
715 return s && s[0] ? str2val(s, tab) : -1;
716 }
717
718 static int
fec_to_tvh(http_connection_t * hc)719 fec_to_tvh(http_connection_t *hc)
720 {
721 switch (atoi(http_arg_get_remove(&hc->hc_req_args, "fec") ?: "0")) {
722 case 0: return DVB_FEC_AUTO;
723 case 12: return DVB_FEC_1_2;
724 case 13: return DVB_FEC_1_3;
725 case 15: return DVB_FEC_1_5;
726 case 23: return DVB_FEC_2_3;
727 case 25: return DVB_FEC_2_5;
728 case 29: return DVB_FEC_2_9;
729 case 34: return DVB_FEC_3_4;
730 case 35: return DVB_FEC_3_5;
731 case 45: return DVB_FEC_4_5;
732 case 415: return DVB_FEC_4_15;
733 case 56: return DVB_FEC_5_6;
734 case 59: return DVB_FEC_5_9;
735 case 67: return DVB_FEC_6_7;
736 case 78: return DVB_FEC_7_8;
737 case 79: return DVB_FEC_7_9;
738 case 715: return DVB_FEC_7_15;
739 case 89: return DVB_FEC_8_9;
740 case 815: return DVB_FEC_8_15;
741 case 910: return DVB_FEC_9_10;
742 case 920: return DVB_FEC_9_20;
743 default: return DVB_FEC_NONE;
744 }
745 }
746
747 static int
bw_to_tvh(http_connection_t * hc)748 bw_to_tvh(http_connection_t *hc)
749 {
750 int bw = atof(http_arg_get_remove(&hc->hc_req_args, "bw") ?: "0") * 1000;
751 switch (bw) {
752 case 0: return DVB_BANDWIDTH_AUTO;
753 case DVB_BANDWIDTH_1_712_MHZ:
754 case DVB_BANDWIDTH_5_MHZ:
755 case DVB_BANDWIDTH_6_MHZ:
756 case DVB_BANDWIDTH_7_MHZ:
757 case DVB_BANDWIDTH_8_MHZ:
758 case DVB_BANDWIDTH_10_MHZ:
759 return bw;
760 default:
761 return DVB_BANDWIDTH_NONE;
762 }
763 }
764
765 static int
rolloff_to_tvh(http_connection_t * hc)766 rolloff_to_tvh(http_connection_t *hc)
767 {
768 int ro = atof(http_arg_get_remove(&hc->hc_req_args, "ro") ?: "0") * 1000;
769 switch (ro) {
770 case 0:
771 return DVB_ROLLOFF_35;
772 case DVB_ROLLOFF_20:
773 case DVB_ROLLOFF_25:
774 case DVB_ROLLOFF_35:
775 return ro;
776 default:
777 return DVB_ROLLOFF_NONE;
778 }
779 }
780
781 static int
pilot_to_tvh(http_connection_t * hc)782 pilot_to_tvh(http_connection_t *hc)
783 {
784 const char *s = http_arg_get_remove(&hc->hc_req_args, "plts");
785 if (s && strcmp(s, "on") == 0)
786 return DVB_PILOT_ON;
787 if (s && strcmp(s, "off") == 0)
788 return DVB_PILOT_OFF;
789 if (s == NULL || s[0] == '\0' || strcmp(s, "auto") == 0)
790 return DVB_PILOT_AUTO;
791 return DVB_ROLLOFF_NONE;
792 }
793
794 static int
tmode_to_tvh(http_connection_t * hc)795 tmode_to_tvh(http_connection_t *hc)
796 {
797 static struct strtab tab[] = {
798 { "auto", DVB_TRANSMISSION_MODE_AUTO },
799 { "1k", DVB_TRANSMISSION_MODE_1K },
800 { "2k", DVB_TRANSMISSION_MODE_2K },
801 { "4k", DVB_TRANSMISSION_MODE_4K },
802 { "8k", DVB_TRANSMISSION_MODE_8K },
803 { "16k", DVB_TRANSMISSION_MODE_16K },
804 { "32k", DVB_TRANSMISSION_MODE_32K },
805 };
806 const char *s = http_arg_get_remove(&hc->hc_req_args, "tmode");
807 if (s && s[0]) {
808 int v = str2val(s, tab);
809 return v >= 0 ? v : DVB_TRANSMISSION_MODE_NONE;
810 }
811 return DVB_TRANSMISSION_MODE_AUTO;
812 }
813
814 static int
mtype_to_tvh(http_connection_t * hc)815 mtype_to_tvh(http_connection_t *hc)
816 {
817 static struct strtab tab[] = {
818 { "auto", DVB_MOD_AUTO },
819 { "qpsk", DVB_MOD_QPSK },
820 { "8psk", DVB_MOD_PSK_8 },
821 { "16qam", DVB_MOD_QAM_16 },
822 { "32qam", DVB_MOD_QAM_32 },
823 { "64qam", DVB_MOD_QAM_64 },
824 { "128qam", DVB_MOD_QAM_128 },
825 { "256qam", DVB_MOD_QAM_256 },
826 { "8vsb", DVB_MOD_VSB_8 },
827 };
828 const char *s = http_arg_get_remove(&hc->hc_req_args, "mtype");
829 if (s && s[0]) {
830 int v = str2val(s, tab);
831 return v >= 0 ? v : DVB_MOD_NONE;
832 }
833 return DVB_MOD_AUTO;
834 }
835
836 static int
gi_to_tvh(http_connection_t * hc)837 gi_to_tvh(http_connection_t *hc)
838 {
839 switch (atoi(http_arg_get_remove(&hc->hc_req_args, "gi") ?: "0")) {
840 case 0: return DVB_GUARD_INTERVAL_AUTO;
841 case 14: return DVB_GUARD_INTERVAL_1_4;
842 case 18: return DVB_GUARD_INTERVAL_1_8;
843 case 116: return DVB_GUARD_INTERVAL_1_16;
844 case 132: return DVB_GUARD_INTERVAL_1_32;
845 case 1128: return DVB_GUARD_INTERVAL_1_128;
846 case 19128: return DVB_GUARD_INTERVAL_19_128;
847 case 19256: return DVB_GUARD_INTERVAL_19_256;
848 default: return DVB_GUARD_INTERVAL_NONE;
849 }
850 }
851
852 static int
parse_pids(char * p,mpegts_apids_t * pids)853 parse_pids(char *p, mpegts_apids_t *pids)
854 {
855 char *x, *saveptr;
856 int i = 0, pid;
857
858 mpegts_pid_reset(pids);
859 if (p == NULL || *p == '\0')
860 return 0;
861 x = strtok_r(p, ",", &saveptr);
862 while (1) {
863 if (x == NULL)
864 break;
865 if (strcmp(x, "all") == 0) {
866 if (satip_server_conf.satip_restrict_pids_all) {
867 pids->all = 0;
868 for (pid = 1; pid <= 2; pid++) /* CAT, TSDT */
869 mpegts_pid_add(pids, pid, MPS_WEIGHT_RAW);
870 for (pid = 0x10; pid < 0x20; pid++) /* NIT ... SIT */
871 mpegts_pid_add(pids, pid, MPS_WEIGHT_RAW);
872 mpegts_pid_add(pids, 0x1ffb, MPS_WEIGHT_RAW); /* ATSC */
873 } else {
874 pids->all = 1;
875 }
876 } else {
877 pids->all = 0;
878 pid = atoi(x);
879 if (pid < 0 || pid > 8191)
880 return -1;
881 mpegts_pid_add(pids, pid, MPS_WEIGHT_RAW);
882 }
883 x = strtok_r(NULL, ",", &saveptr);
884 i++;
885 }
886 if (i == 0)
887 return -1;
888 return 0;
889 }
890
891 static int
parse_transport(http_connection_t * hc)892 parse_transport(http_connection_t *hc)
893 {
894 const char *s = http_arg_get(&hc->hc_args, "Transport");
895 const char *u;
896 int a, b;
897 if (!s)
898 return -1;
899 if (strncmp(s, "RTP/AVP;unicast;client_port=", 28) == 0) {
900 for (s += 28, u = s; isdigit(*u); u++);
901 if (*u != '-')
902 return -1;
903 a = atoi(s);
904 for (s = ++u; isdigit(*s); s++);
905 if (*s != '\0' && *s != ';')
906 return -1;
907 b = atoi(u);
908 if (a + 1 != b)
909 return -1;
910 return a;
911 } else if ((strncmp(s, "RTP/AVP/TCP;interleaved=0-1", 27) == 0) &&
912 !satip_server_conf.satip_notcp_mode) {
913 return RTSP_TCP_DATA;
914 }
915 return -1;
916 }
917
918 /*
919 *
920 */
921 static int
rtsp_parse_cmd(http_connection_t * hc,int stream,int cmd,session_t ** rrs,int * valid)922 rtsp_parse_cmd
923 (http_connection_t *hc, int stream, int cmd,
924 session_t **rrs, int *valid)
925 {
926 session_t *rs = NULL;
927 int errcode = HTTP_STATUS_BAD_REQUEST, r, findex = 1, has_args, weight = 0;
928 int delsys = DVB_SYS_NONE, msys, fe, src, freq, pol, sr;
929 int fec, ro, plts, bw, tmode, mtype, gi, plp, t2id, sm, c2tft, ds, specinv;
930 int alloc_stream_id = 0;
931 char *s;
932 const char *caller;
933 mpegts_apids_t pids, addpids, delpids;
934 dvb_mux_conf_t *dmc;
935 char buf[256];
936 http_arg_t *arg;
937
938 switch (cmd) {
939 case RTSP_CMD_DESCRIBE: caller = "DESCRIBE"; break;
940 case RTSP_CMD_PLAY: caller = "PLAY"; break;
941 case RTSP_CMD_SETUP: caller = "SETUP"; break;
942 default: caller = NULL; break;
943 }
944
945 *rrs = NULL;
946 mpegts_pid_init(&pids);
947 mpegts_pid_init(&addpids);
948 mpegts_pid_init(&delpids);
949
950 has_args = !TAILQ_EMPTY(&hc->hc_req_args);
951
952 fe = atoi(http_arg_get_remove(&hc->hc_req_args, "fe") ?: 0);
953 fe = satip_server_conf.satip_drop_fe ? 0 : fe;
954 s = http_arg_get_remove(&hc->hc_req_args, "addpids");
955 if (parse_pids(s, &addpids)) goto end;
956 s = http_arg_get_remove(&hc->hc_req_args, "delpids");
957 if (parse_pids(s, &delpids)) goto end;
958 s = http_arg_get_remove(&hc->hc_req_args, "pids");
959 if (parse_pids(s, &pids)) goto end;
960 msys = msys_to_tvh(hc);
961 freq = atof(http_arg_get_remove(&hc->hc_req_args, "freq")) * 1000;
962 *valid = freq >= 10000;
963 weight = atoi(http_arg_get_remove(&hc->hc_req_args, "tvhweight"));
964
965 if (addpids.count > 0 || delpids.count > 0) {
966 if (cmd == RTSP_CMD_SETUP)
967 goto end;
968 if (!stream)
969 goto end;
970 }
971
972 rs = rtsp_find_session(hc, stream);
973
974 if (fe > 0) {
975 delsys = satip_rtsp_delsys(fe, &findex, NULL);
976 if (delsys == DVB_SYS_NONE) {
977 tvherror(LS_SATIPS, "fe=%d does not exist", fe);
978 goto end;
979 }
980 } else {
981 delsys = msys;
982 }
983
984 if (cmd == RTSP_CMD_SETUP) {
985 if (!rs) {
986 rs = rtsp_new_session(hc->hc_peer_ipstr, msys, 0, -1);
987 if (delsys == DVB_SYS_NONE) goto end;
988 if (msys == DVB_SYS_NONE) goto end;
989 if (!(*valid)) goto end;
990 alloc_stream_id = 1;
991 } else if (stream != rs->stream) {
992 rs = rtsp_new_session(hc->hc_peer_ipstr, msys, rs->nsession, stream);
993 if (delsys == DVB_SYS_NONE) goto end;
994 if (msys == DVB_SYS_NONE) goto end;
995 if (!(*valid)) goto end;
996 alloc_stream_id = 1;
997 } else {
998 if (!has_args && rs->state == STATE_DESCRIBE) {
999 r = parse_transport(hc);
1000 if (r < 0) {
1001 errcode = HTTP_STATUS_BAD_TRANSFER;
1002 goto end;
1003 }
1004 rs->rtp_peer_port = r;
1005 *valid = 1;
1006 goto ok;
1007 }
1008 }
1009 r = parse_transport(hc);
1010 if (r < 0) {
1011 errcode = HTTP_STATUS_BAD_TRANSFER;
1012 goto end;
1013 }
1014 if (rs->state == STATE_PLAY && rs->rtp_peer_port != r) {
1015 errcode = HTTP_STATUS_METHOD_INVALID;
1016 goto end;
1017 }
1018 rs->rtp_peer_port = r;
1019 rs->frontend = fe > 0 ? fe : 1;
1020 } else {
1021 if (!rs || stream != rs->stream) {
1022 if (rs)
1023 errcode = HTTP_STATUS_NOT_FOUND;
1024 goto end;
1025 }
1026 if (!fe) {
1027 fe = rs->frontend;
1028 findex = rs->findex;
1029 }
1030 if (rs->frontend != fe)
1031 goto end;
1032 if (*valid) {
1033 if (delsys == DVB_SYS_NONE) goto end;
1034 if (msys == DVB_SYS_NONE) goto end;
1035 } else {
1036 if (!TAILQ_EMPTY(&hc->hc_req_args)) goto end;
1037 goto play;
1038 }
1039 }
1040
1041 dvb_mux_conf_init(NULL, dmc = &rs->dmc, msys);
1042
1043 mtype = mtype_to_tvh(hc);
1044 if (mtype == DVB_MOD_NONE) goto end;
1045
1046 src = 1;
1047
1048 if (msys == DVB_SYS_DVBS || msys == DVB_SYS_DVBS2) {
1049
1050 src = atoi(http_arg_get_remove(&hc->hc_req_args, "src") ?: "0");
1051 if (src < 1) goto end;
1052 pol = pol_to_tvh(hc);
1053 if (pol < 0) goto end;
1054 sr = atof(http_arg_get_remove(&hc->hc_req_args, "sr") ?: "0") * 1000;
1055 if (sr < 1000) goto end;
1056 fec = fec_to_tvh(hc);
1057 if (fec == DVB_FEC_NONE) goto end;
1058 ro = rolloff_to_tvh(hc);
1059 if (ro == DVB_ROLLOFF_NONE ||
1060 (ro != DVB_ROLLOFF_35 && msys == DVB_SYS_DVBS)) goto end;
1061 plts = pilot_to_tvh(hc);
1062 if (plts == DVB_PILOT_NONE) goto end;
1063
1064 if (!TAILQ_EMPTY(&hc->hc_req_args)) goto eargs;
1065
1066 dmc->dmc_fe_rolloff = ro;
1067 dmc->dmc_fe_pilot = plts;
1068 dmc->u.dmc_fe_qpsk.polarisation = pol;
1069 dmc->u.dmc_fe_qpsk.symbol_rate = sr;
1070 dmc->u.dmc_fe_qpsk.fec_inner = fec;
1071
1072 } else if (msys == DVB_SYS_DVBT || msys == DVB_SYS_DVBT2) {
1073
1074 freq *= 1000;
1075 if (freq < 0) goto end;
1076 bw = bw_to_tvh(hc);
1077 if (bw == DVB_BANDWIDTH_NONE) goto end;
1078 tmode = tmode_to_tvh(hc);
1079 if (tmode == DVB_TRANSMISSION_MODE_NONE) goto end;
1080 gi = gi_to_tvh(hc);
1081 if (gi == DVB_GUARD_INTERVAL_NONE) goto end;
1082 fec = fec_to_tvh(hc);
1083 if (fec == DVB_FEC_NONE) goto end;
1084 s = http_arg_get_remove(&hc->hc_req_args, "plp");
1085 if (s && s[0]) {
1086 plp = atoi(s);
1087 if (plp < 0 || plp > 255) goto end;
1088 } else {
1089 plp = DVB_NO_STREAM_ID_FILTER;
1090 }
1091 t2id = atoi(http_arg_get_remove(&hc->hc_req_args, "t2id") ?: "0");
1092 if (t2id < 0 || t2id > 65535) goto end;
1093 sm = atoi(http_arg_get_remove(&hc->hc_req_args, "sm") ?: "0");
1094 if (sm < 0 || sm > 1) goto end;
1095
1096 if (!TAILQ_EMPTY(&hc->hc_req_args)) goto eargs;
1097
1098 dmc->u.dmc_fe_ofdm.bandwidth = bw;
1099 dmc->u.dmc_fe_ofdm.code_rate_HP = fec;
1100 dmc->u.dmc_fe_ofdm.code_rate_LP = DVB_FEC_NONE;
1101 dmc->u.dmc_fe_ofdm.transmission_mode = tmode;
1102 dmc->u.dmc_fe_ofdm.guard_interval = gi;
1103 dmc->u.dmc_fe_ofdm.hierarchy_information = DVB_HIERARCHY_AUTO;
1104 dmc->dmc_fe_stream_id = plp;
1105 dmc->dmc_fe_pls_code = t2id;
1106 dmc->dmc_fe_pls_mode = sm; /* check */
1107
1108 } else if (msys == DVB_SYS_DVBC_ANNEX_A || msys == DVB_SYS_DVBC_ANNEX_C) {
1109
1110 freq *= 1000;
1111 if (freq < 0) goto end;
1112 c2tft = atoi(http_arg_get_remove(&hc->hc_req_args, "c2tft") ?: "0");
1113 if (c2tft < 0 || c2tft > 2) goto end;
1114 bw = bw_to_tvh(hc);
1115 if (bw == DVB_BANDWIDTH_NONE) goto end;
1116 sr = atof(http_arg_get_remove(&hc->hc_req_args, "sr") ?: "0") * 1000;
1117 if (sr < 1000) goto end;
1118 ds = atoi(http_arg_get_remove(&hc->hc_req_args, "ds") ?: "0");
1119 if (ds < 0 || ds > 255) goto end;
1120 s = http_arg_get_remove(&hc->hc_req_args, "plp");
1121 if (s && s[0]) {
1122 plp = atoi(http_arg_get_remove(&hc->hc_req_args, "plp"));
1123 if (plp < 0 || plp > 255) goto end;
1124 } else {
1125 plp = DVB_NO_STREAM_ID_FILTER;
1126 }
1127 specinv = atoi(http_arg_get_remove(&hc->hc_req_args, "specinv") ?: "0");
1128 if (specinv < 0 || specinv > 1) goto end;
1129 fec = fec_to_tvh(hc);
1130 if (fec == DVB_FEC_NONE) goto end;
1131
1132 if (!TAILQ_EMPTY(&hc->hc_req_args)) goto eargs;
1133
1134 dmc->u.dmc_fe_qam.symbol_rate = sr;
1135 dmc->u.dmc_fe_qam.fec_inner = fec;
1136 dmc->dmc_fe_inversion = specinv;
1137 dmc->dmc_fe_stream_id = plp;
1138 dmc->dmc_fe_pls_code = ds; /* check */
1139
1140 } else if (msys == DVB_SYS_ATSC || msys == DVB_SYS_DVBC_ANNEX_B) {
1141
1142 freq *= 1000;
1143 if (freq < 0) goto end;
1144 if (!TAILQ_EMPTY(&hc->hc_req_args)) goto eargs;
1145
1146 } else {
1147
1148 goto end;
1149
1150 }
1151
1152 dmc->dmc_fe_freq = freq;
1153 dmc->dmc_fe_modulation = mtype;
1154 dmc->dmc_fe_delsys = msys;
1155
1156 rs->frontend = fe;
1157 rs->findex = findex;
1158 rs->src = src;
1159 if (weight > 0)
1160 rs->weight = weight;
1161 else if (cmd == RTSP_CMD_SETUP)
1162 rs->weight = 0;
1163 rs->old_hc = hc;
1164
1165 if (alloc_stream_id) {
1166 stream_id++;
1167 if (stream_id == 0)
1168 stream_id++;
1169 rs->stream = stream_id % 0x7fff;
1170 } else {
1171 /* don't subscribe to the new mux, if it was already done */
1172 if (memcmp(dmc, &rs->dmc_tuned, sizeof(*dmc)) == 0 && !rs->no_data)
1173 *valid = 0;
1174 }
1175
1176 if (cmd == RTSP_CMD_DESCRIBE)
1177 rs->shutdown_on_close = hc;
1178
1179 play:
1180 if (pids.count > 0 || pids.all)
1181 mpegts_pid_copy(&rs->pids, &pids);
1182 if (delpids.count > 0)
1183 mpegts_pid_del_group(&rs->pids, &delpids);
1184 if (addpids.count > 0)
1185 mpegts_pid_add_group(&rs->pids, &addpids);
1186
1187 dvb_mux_conf_str(&rs->dmc, buf, sizeof(buf));
1188 r = strlen(buf);
1189 tvh_strlcatf(buf, sizeof(buf), r, " pids ");
1190 if (mpegts_pid_dump(&rs->pids, buf + r, sizeof(buf) - r, 0, 0) == 0)
1191 tvh_strlcatf(buf, sizeof(buf), r, "<none>");
1192
1193 tvhdebug(LS_SATIPS, "%i/%s/%d: %s from %s:%d %s",
1194 rs->frontend, rs->session, rs->stream,
1195 caller, hc->hc_peer_ipstr, ntohs(IP_PORT(*hc->hc_peer)), buf);
1196
1197 ok:
1198 errcode = 0;
1199 *rrs = rs;
1200
1201 end:
1202 if (rs)
1203 rtsp_rearm_session_timer(rs);
1204 mpegts_pid_done(&addpids);
1205 mpegts_pid_done(&delpids);
1206 mpegts_pid_done(&pids);
1207 return errcode;
1208
1209 eargs:
1210 TAILQ_FOREACH(arg, &hc->hc_req_args, link)
1211 tvhwarn(LS_SATIPS, "%i/%s/%i: extra parameter '%s'='%s'",
1212 rs->frontend, rs->session, rs->stream,
1213 arg->key, arg->val);
1214 goto end;
1215 }
1216
1217 /*
1218 *
1219 */
1220 static int
rtsp_process_options(http_connection_t * hc)1221 rtsp_process_options(http_connection_t *hc)
1222 {
1223 http_arg_list_t args;
1224 char *u = tvh_strdupa(hc->hc_url);
1225 session_t *rs;
1226 int found;
1227
1228 if (strcmp(u, "*") != 0 && (u = rtsp_check_urlbase(u)) == NULL)
1229 goto error;
1230
1231 if (hc->hc_session) {
1232 found = 0;
1233 pthread_mutex_lock(&rtsp_lock);
1234 TAILQ_FOREACH(rs, &rtsp_sessions, link)
1235 if (!strcmp(rs->session, hc->hc_session)) {
1236 rtsp_rearm_session_timer(rs);
1237 found = 1;
1238 }
1239 pthread_mutex_unlock(&rtsp_lock);
1240 if (!found) {
1241 http_error(hc, HTTP_STATUS_BAD_SESSION);
1242 return 0;
1243 }
1244 }
1245 http_arg_init(&args);
1246 http_arg_set(&args, "Public", "OPTIONS,DESCRIBE,SETUP,PLAY,TEARDOWN");
1247 if (hc->hc_session)
1248 http_arg_set(&args, "Session", hc->hc_session);
1249 http_send_begin(hc);
1250 http_send_header(hc, HTTP_STATUS_OK, NULL, 0, NULL, NULL, 0, NULL, NULL, &args);
1251 http_send_end(hc);
1252 http_arg_flush(&args);
1253 return 0;
1254
1255 error:
1256 http_error(hc, HTTP_STATUS_BAD_REQUEST);
1257 return 0;
1258 }
1259
1260 /*
1261 *
1262 */
1263 static void
rtsp_describe_header(session_t * rs,htsbuf_queue_t * q)1264 rtsp_describe_header(session_t *rs, htsbuf_queue_t *q)
1265 {
1266 unsigned long mono = mclk();
1267 int dvbt, dvbc;
1268
1269 htsbuf_append_str(q, "v=0\r\n");
1270 htsbuf_qprintf(q, "o=- %lu %lu IN %s %s\r\n",
1271 rs ? (unsigned long)rs->nsession : mono - 123,
1272 mono,
1273 strchr(rtsp_ip, ':') ? "IP6" : "IP4",
1274 rtsp_ip);
1275
1276 pthread_mutex_lock(&global_lock);
1277 htsbuf_qprintf(q, "s=SatIPServer:1 %d",
1278 satip_server_conf.satip_dvbs +
1279 satip_server_conf.satip_dvbs2);
1280 dvbt = satip_server_conf.satip_dvbt +
1281 satip_server_conf.satip_dvbt2;
1282 dvbc = satip_server_conf.satip_dvbc +
1283 satip_server_conf.satip_dvbc2;
1284 if (dvbc)
1285 htsbuf_qprintf(q, " %d %d\r\n", dvbt, dvbc);
1286 else if (dvbt)
1287 htsbuf_qprintf(q, " %d\r\n", dvbt);
1288 else
1289 htsbuf_append(q, "\r\n", 1);
1290 pthread_mutex_unlock(&global_lock);
1291
1292 htsbuf_append_str(q, "t=0 0\r\n");
1293 }
1294
1295 static void
rtsp_describe_session(session_t * rs,htsbuf_queue_t * q)1296 rtsp_describe_session(session_t *rs, htsbuf_queue_t *q)
1297 {
1298 char buf[4096];
1299
1300 htsbuf_qprintf(q, "a=control:stream=%d\r\n", rs->stream);
1301 htsbuf_append_str(q, "a=tool:tvheadend\r\n");
1302 htsbuf_append_str(q, "m=video 0 RTP/AVP 33\r\n");
1303 if (strchr(rtsp_ip, ':'))
1304 htsbuf_append_str(q, "c=IN IP6 ::0\r\n");
1305 else
1306 htsbuf_append_str(q, "c=IN IP4 0.0.0.0\r\n");
1307 if (rs->state == STATE_PLAY || rs->state == STATE_SETUP) {
1308 satip_rtp_status(rs->rtp_handle, buf, sizeof(buf));
1309 htsbuf_qprintf(q, "a=fmtp:33 %s\r\n", buf);
1310 htsbuf_qprintf(q, "a=%s\r\n", rs->state == STATE_SETUP ? "inactive" : "sendonly");
1311 } else {
1312 htsbuf_append_str(q, "a=fmtp:33\r\n");
1313 htsbuf_append_str(q, "a=inactive\r\n");
1314 }
1315 }
1316
1317 /*
1318 *
1319 */
1320 static int
rtsp_process_describe(http_connection_t * hc)1321 rtsp_process_describe(http_connection_t *hc)
1322 {
1323 http_arg_list_t args;
1324 const char *arg;
1325 char *u = tvh_strdupa(hc->hc_url);
1326 session_t *rs;
1327 htsbuf_queue_t q;
1328 char buf[96];
1329 int r = HTTP_STATUS_BAD_REQUEST;
1330 int stream, first = 1, valid;
1331
1332 htsbuf_queue_init(&q, 0);
1333
1334 arg = http_arg_get(&hc->hc_args, "Accept");
1335 if (arg == NULL || strcmp(arg, "application/sdp"))
1336 goto error;
1337
1338 if ((u = rtsp_check_urlbase(u)) == NULL)
1339 goto error;
1340
1341 stream = rtsp_parse_args(hc, u);
1342
1343 pthread_mutex_lock(&rtsp_lock);
1344
1345 if (TAILQ_FIRST(&hc->hc_req_args)) {
1346 if (stream < 0) {
1347 pthread_mutex_unlock(&rtsp_lock);
1348 goto error;
1349 }
1350 r = rtsp_parse_cmd(hc, stream, RTSP_CMD_DESCRIBE, &rs, &valid);
1351 if (r) {
1352 pthread_mutex_unlock(&rtsp_lock);
1353 goto error;
1354 }
1355 }
1356
1357 TAILQ_FOREACH(rs, &rtsp_sessions, link) {
1358 if (hc->hc_session) {
1359 if (strcmp(hc->hc_session, rs->session))
1360 continue;
1361 rtsp_rearm_session_timer(rs);
1362 }
1363 if (stream > 0 && rs->stream != stream)
1364 continue;
1365 if (satip_server_conf.satip_anonymize &&
1366 strcmp(hc->hc_peer_ipstr, rs->peer_ipstr))
1367 continue;
1368 if (first) {
1369 rtsp_describe_header(hc->hc_session ? rs : NULL, &q);
1370 first = 0;
1371 }
1372 rtsp_describe_session(rs, &q);
1373 }
1374 pthread_mutex_unlock(&rtsp_lock);
1375
1376 if (first) {
1377 if (hc->hc_session) {
1378 http_error(hc, HTTP_STATUS_BAD_SESSION);
1379 return 0;
1380 }
1381 rtsp_describe_header(NULL, &q);
1382 }
1383
1384 http_arg_init(&args);
1385 if (hc->hc_session)
1386 http_arg_set(&args, "Session", hc->hc_session);
1387 if (stream > 0)
1388 snprintf(buf, sizeof(buf), "rtsp://%s/stream=%i", rtsp_ip, stream);
1389 else
1390 snprintf(buf, sizeof(buf), "rtsp://%s", rtsp_ip);
1391 http_arg_set(&args, "Content-Base", buf);
1392 http_send_begin(hc);
1393 http_send_header(hc, HTTP_STATUS_OK, "application/sdp", q.hq_size,
1394 NULL, NULL, 0, NULL, NULL, &args);
1395 tcp_write_queue(hc->hc_fd, &q);
1396 http_send_end(hc);
1397 http_arg_flush(&args);
1398 htsbuf_queue_flush(&q);
1399 return 0;
1400
1401 error:
1402 htsbuf_queue_flush(&q);
1403 http_error(hc, HTTP_STATUS_BAD_REQUEST);
1404 return 0;
1405 }
1406
1407 /*
1408 *
1409 */
1410 static int
rtsp_process_play(http_connection_t * hc,int cmd)1411 rtsp_process_play(http_connection_t *hc, int cmd)
1412 {
1413 session_t *rs;
1414 int errcode = HTTP_STATUS_BAD_REQUEST, valid = 0, i, stream;
1415 char buf[256], *u = tvh_strdupa(hc->hc_url);
1416 http_arg_list_t args;
1417
1418 http_arg_init(&args);
1419
1420 if ((u = rtsp_check_urlbase(u)) == NULL)
1421 goto error2;
1422
1423 if ((stream = rtsp_parse_args(hc, u)) < 0)
1424 goto error2;
1425
1426 pthread_mutex_lock(&rtsp_lock);
1427
1428 errcode = rtsp_parse_cmd(hc, stream, cmd, &rs, &valid);
1429
1430 if (errcode) goto error;
1431
1432 if (cmd == RTSP_CMD_SETUP && rs->rtp_peer_port != RTSP_TCP_DATA &&
1433 !rs->rtp_udp_bound) {
1434 if (udp_bind_double(&rs->udp_rtp, &rs->udp_rtcp,
1435 LS_SATIPS, "rtsp", "rtcp",
1436 rtsp_ip, 0, NULL,
1437 4*1024, 4*1024,
1438 RTP_BUFSIZE, RTCP_BUFSIZE)) {
1439 errcode = HTTP_STATUS_INTERNAL;
1440 goto error;
1441 }
1442 if (udp_connect(rs->udp_rtp, "RTP", hc->hc_peer_ipstr, rs->rtp_peer_port) ||
1443 udp_connect(rs->udp_rtcp, "RTCP", hc->hc_peer_ipstr, rs->rtp_peer_port + 1)) {
1444 udp_close(rs->udp_rtp);
1445 rs->udp_rtp = NULL;
1446 udp_close(rs->udp_rtcp);
1447 rs->udp_rtcp = NULL;
1448 errcode = HTTP_STATUS_INTERNAL;
1449 goto error;
1450 }
1451 rs->rtp_udp_bound = 1;
1452 }
1453
1454 if (cmd == RTSP_CMD_SETUP && rs->rtp_peer_port == RTSP_TCP_DATA)
1455 rs->shutdown_on_close = hc;
1456
1457 if ((errcode = rtsp_start(hc, rs, hc->hc_peer_ipstr, valid, cmd)) != 0)
1458 goto error;
1459
1460 if (cmd == RTSP_CMD_SETUP) {
1461 snprintf(buf, sizeof(buf), "%s;timeout=%d", rs->session, RTSP_TIMEOUT);
1462 http_arg_set(&args, "Session", buf);
1463 i = rs->rtp_peer_port;
1464 if (i == RTSP_TCP_DATA) {
1465 snprintf(buf, sizeof(buf), "RTP/AVP/TCP;interleaved=0-1");
1466 } else {
1467 snprintf(buf, sizeof(buf), "RTP/AVP;unicast;client_port=%d-%d", i, i+1);
1468 }
1469 http_arg_set(&args, "Transport", buf);
1470 snprintf(buf, sizeof(buf), "%d", rs->stream);
1471 http_arg_set(&args, "com.ses.streamID", buf);
1472 } else {
1473 if (rtsp_port != 554)
1474 snprintf(buf, sizeof(buf), "url=rtsp://%s:%d/stream=%d", rtsp_ip, rtsp_port, rs->stream);
1475 else
1476 snprintf(buf, sizeof(buf), "url=rtsp://%s/stream=%d", rtsp_ip, rs->stream);
1477 http_arg_set(&args, "RTP-Info", buf);
1478 }
1479
1480 pthread_mutex_unlock(&rtsp_lock);
1481
1482 http_send_begin(hc);
1483 http_send_header(hc, HTTP_STATUS_OK, NULL, 0, NULL, NULL, 0, NULL, NULL, &args);
1484 http_send_end(hc);
1485
1486 goto end;
1487
1488 error:
1489 pthread_mutex_unlock(&rtsp_lock);
1490 error2:
1491 http_error(hc, errcode);
1492
1493 end:
1494 http_arg_flush(&args);
1495 return 0;
1496 }
1497
1498 /*
1499 *
1500 */
1501 static int
rtsp_process_teardown(http_connection_t * hc)1502 rtsp_process_teardown(http_connection_t *hc)
1503 {
1504 char *u = tvh_strdupa(hc->hc_url);
1505 struct session *rs = NULL;
1506 http_arg_list_t args;
1507 char session[16];
1508 int stream;
1509
1510 if ((u = rtsp_check_urlbase(u)) == NULL ||
1511 (stream = rtsp_parse_args(hc, u)) < 0) {
1512 http_error(hc, HTTP_STATUS_BAD_REQUEST);
1513 return 0;
1514 }
1515
1516 tvhdebug(LS_SATIPS, "-/%s/%i: teardown from %s:%d",
1517 hc->hc_session, stream, hc->hc_peer_ipstr, ntohs(IP_PORT(*hc->hc_peer)));
1518
1519 pthread_mutex_lock(&rtsp_lock);
1520 rs = rtsp_find_session(hc, stream);
1521 if (!rs || stream != rs->stream) {
1522 pthread_mutex_unlock(&rtsp_lock);
1523 http_error(hc, !rs ? HTTP_STATUS_BAD_SESSION : HTTP_STATUS_NOT_FOUND);
1524 } else {
1525 strlcpy(session, rs->session, sizeof(session));
1526 rtsp_close_session(rs);
1527 rtsp_free_session(rs);
1528 pthread_mutex_unlock(&rtsp_lock);
1529 http_arg_init(&args);
1530 http_arg_set(&args, "Session", session);
1531 http_send_begin(hc);
1532 http_send_header(hc, HTTP_STATUS_OK, NULL, 0, NULL, NULL, 0, NULL, NULL, NULL);
1533 http_send_end(hc);
1534 http_arg_flush(&args);
1535 }
1536 return 0;
1537 }
1538
1539 /**
1540 * Process a RTSP request
1541 */
1542 static int
rtsp_process_request(http_connection_t * hc,htsbuf_queue_t * spill)1543 rtsp_process_request(http_connection_t *hc, htsbuf_queue_t *spill)
1544 {
1545 switch (hc->hc_cmd) {
1546 case RTSP_CMD_OPTIONS:
1547 return rtsp_process_options(hc);
1548 case RTSP_CMD_DESCRIBE:
1549 return rtsp_process_describe(hc);
1550 case RTSP_CMD_SETUP:
1551 case RTSP_CMD_PLAY:
1552 return rtsp_process_play(hc, hc->hc_cmd);
1553 case RTSP_CMD_TEARDOWN:
1554 return rtsp_process_teardown(hc);
1555 default:
1556 http_error(hc, HTTP_STATUS_BAD_REQUEST);
1557 return 0;
1558 }
1559 }
1560
1561 /*
1562 *
1563 */
1564 static void
rtsp_flush_requests(http_connection_t * hc)1565 rtsp_flush_requests(http_connection_t *hc)
1566 {
1567 struct session *rs, *rs_next;
1568
1569 pthread_mutex_lock(&rtsp_lock);
1570 for (rs = TAILQ_FIRST(&rtsp_sessions); rs; rs = rs_next) {
1571 rs_next = TAILQ_NEXT(rs, link);
1572 if (rs->shutdown_on_close == hc) {
1573 rtsp_close_session(rs);
1574 rtsp_free_session(rs);
1575 } else if (rs->tcp_data == hc) {
1576 satip_rtp_close(rs->rtp_handle);
1577 rs->rtp_handle = NULL;
1578 rs->tcp_data = NULL;
1579 rs->state = STATE_SETUP;
1580 }
1581 }
1582 pthread_mutex_unlock(&rtsp_lock);
1583 }
1584
1585 /*
1586 *
1587 */
1588 static void
rtsp_stream_status(void * opaque,htsmsg_t * m)1589 rtsp_stream_status ( void *opaque, htsmsg_t *m )
1590 {
1591 http_connection_t *hc = opaque;
1592 htsmsg_add_str(m, "type", "SAT>IP");
1593 if (hc->hc_username)
1594 htsmsg_add_str(m, "user", hc->hc_username);
1595 }
1596
1597 /*
1598 *
1599 */
1600 static void
rtsp_serve(int fd,void ** opaque,struct sockaddr_storage * peer,struct sockaddr_storage * self)1601 rtsp_serve(int fd, void **opaque, struct sockaddr_storage *peer,
1602 struct sockaddr_storage *self)
1603 {
1604 http_connection_t hc;
1605 access_t aa;
1606 char buf[128];
1607 void *tcp;
1608
1609 memset(&hc, 0, sizeof(http_connection_t));
1610 *opaque = &hc;
1611
1612 memset(&aa, 0, sizeof(aa));
1613 strcpy(buf, "SAT>IP Client ");
1614 tcp_get_str_from_ip(peer, buf + strlen(buf), sizeof(buf) - strlen(buf));
1615 aa.aa_representative = buf;
1616
1617 tcp = tcp_connection_launch(fd, rtsp_stream_status, &aa);
1618
1619 /* Note: global_lock held on entry */
1620 pthread_mutex_unlock(&global_lock);
1621
1622 hc.hc_fd = fd;
1623 hc.hc_peer = peer;
1624 hc.hc_self = self;
1625 hc.hc_process = rtsp_process_request;
1626 hc.hc_cseq = 1;
1627
1628 http_serve_requests(&hc);
1629
1630 rtsp_flush_requests(&hc);
1631
1632 close(fd);
1633
1634 /* Note: leave global_lock held for parent */
1635 pthread_mutex_lock(&global_lock);
1636 *opaque = NULL;
1637
1638 tcp_connection_land(tcp);
1639 }
1640
1641 /*
1642 *
1643 */
1644 static void
rtsp_close_session(session_t * rs)1645 rtsp_close_session(session_t *rs)
1646 {
1647 satip_rtp_close(rs->rtp_handle);
1648 rs->rtp_handle = NULL;
1649 rs->playing = 0;
1650 rs->state = STATE_DESCRIBE;
1651 udp_close(rs->udp_rtp);
1652 rs->udp_rtp = NULL;
1653 udp_close(rs->udp_rtcp);
1654 rs->udp_rtcp = NULL;
1655 rs->rtp_udp_bound = 0;
1656 rs->shutdown_on_close = NULL;
1657 rs->tcp_data = NULL;
1658 pthread_mutex_lock(&global_lock);
1659 mpegts_pid_reset(&rs->pids);
1660 rtsp_clean(rs, 1);
1661 mtimer_disarm(&rs->timer);
1662 pthread_mutex_unlock(&global_lock);
1663 }
1664
1665 /*
1666 *
1667 */
1668 static void
rtsp_free_session(session_t * rs)1669 rtsp_free_session(session_t *rs)
1670 {
1671 TAILQ_REMOVE(&rtsp_sessions, rs, link);
1672 pthread_mutex_lock(&global_lock);
1673 mtimer_disarm(&rs->timer);
1674 pthread_mutex_unlock(&global_lock);
1675 mpegts_pid_done(&rs->pids);
1676 free(rs->peer_ipstr);
1677 free(rs);
1678 }
1679
1680 /*
1681 *
1682 */
1683 static void
rtsp_close_sessions(void)1684 rtsp_close_sessions(void)
1685 {
1686 session_t *rs;
1687 do {
1688 pthread_mutex_lock(&rtsp_lock);
1689 rs = TAILQ_FIRST(&rtsp_sessions);
1690 if (rs) {
1691 rtsp_close_session(rs);
1692 rtsp_free_session(rs);
1693 }
1694 pthread_mutex_unlock(&rtsp_lock);
1695 } while (rs != NULL);
1696 }
1697
1698 /*
1699 *
1700 */
satip_server_rtsp_init(const char * bindaddr,int port,int descramble,int rewrite_pmt,int muxcnf,const char * nat_ip,int nat_port)1701 void satip_server_rtsp_init
1702 (const char *bindaddr, int port, int descramble, int rewrite_pmt, int muxcnf,
1703 const char *nat_ip, int nat_port)
1704 {
1705 static tcp_server_ops_t ops = {
1706 .start = rtsp_serve,
1707 .stop = NULL,
1708 .cancel = http_cancel
1709 };
1710 int reg = 0;
1711 uint8_t rnd[4];
1712 char *s;
1713 if (!rtsp_server) {
1714 uuid_random(rnd, sizeof(rnd));
1715 session_number = *(uint32_t *)rnd;
1716 TAILQ_INIT(&rtsp_sessions);
1717 pthread_mutex_init(&rtsp_lock, NULL);
1718 satip_rtp_init(1);
1719 }
1720 if (rtsp_port != port && rtsp_server) {
1721 rtsp_close_sessions();
1722 tcp_server_delete(rtsp_server);
1723 rtsp_server = NULL;
1724 reg = 1;
1725 }
1726 s = rtsp_ip;
1727 rtsp_ip = strdup(bindaddr);
1728 free(s);
1729 rtsp_port = port;
1730 rtsp_descramble = descramble;
1731 rtsp_rewrite_pmt = rewrite_pmt;
1732 rtsp_muxcnf = muxcnf;
1733 s = rtsp_nat_ip;
1734 rtsp_nat_ip = nat_ip ? strdup(nat_ip) : NULL;
1735 free(s);
1736 rtsp_nat_port = nat_port;
1737 if (!rtsp_server)
1738 rtsp_server = tcp_server_create(LS_SATIPS, "SAT>IP RTSP", bindaddr, port, &ops, NULL);
1739 if (reg)
1740 tcp_server_register(rtsp_server);
1741 }
1742
satip_server_rtsp_register(void)1743 void satip_server_rtsp_register(void)
1744 {
1745 tcp_server_register(rtsp_server);
1746 satip_rtp_init(0);
1747 }
1748
satip_server_rtsp_done(void)1749 void satip_server_rtsp_done(void)
1750 {
1751 pthread_mutex_lock(&global_lock);
1752 if (rtsp_server)
1753 tcp_server_delete(rtsp_server);
1754 pthread_mutex_unlock(&global_lock);
1755 rtsp_close_sessions();
1756 pthread_mutex_lock(&global_lock);
1757 rtsp_server = NULL;
1758 rtsp_port = -1;
1759 rtsp_nat_port = -1;
1760 free(rtsp_ip);
1761 free(rtsp_nat_ip);
1762 rtsp_ip = rtsp_nat_ip = NULL;
1763 satip_rtp_done();
1764 pthread_mutex_unlock(&global_lock);
1765 }
1766