92 |
92 |
static void rtsp_close_session(session_t *rs);
|
93 |
93 |
static void rtsp_free_session(session_t *rs);
|
94 |
94 |
|
|
95 |
/*
|
|
96 |
*
|
|
97 |
*/
|
|
98 |
static inline int rtsp_is_nat_active(void)
|
|
99 |
{
|
|
100 |
return rtsp_nat_ip[0] != '\0';
|
|
101 |
}
|
95 |
102 |
|
96 |
103 |
/*
|
97 |
104 |
*
|
... | ... | |
280 |
287 |
if (strcmp(u, rtsp_ip)) {
|
281 |
288 |
if (rtsp_nat_ip == NULL)
|
282 |
289 |
return NULL;
|
283 |
|
if (rtsp_nat_ip[0] != '*')
|
284 |
|
if (rtsp_nat_ip[0] == '\0' || strcmp(u, rtsp_nat_ip))
|
|
290 |
if (rtsp_is_nat_active()) {
|
|
291 |
if (rtsp_nat_ip[0] != '*' && strcmp(u, rtsp_nat_ip))
|
285 |
292 |
return NULL;
|
|
293 |
}
|
286 |
294 |
}
|
287 |
295 |
return p ? p + 1 : u + strlen(u);
|
288 |
296 |
}
|
... | ... | |
455 |
463 |
rtsp_manage_descramble(session_t *rs)
|
456 |
464 |
{
|
457 |
465 |
idnode_set_t *found;
|
458 |
|
mpegts_service_t *s, *snext;
|
459 |
|
mpegts_service_t *master = (mpegts_service_t *)rs->subs->ths_raw_service;
|
|
466 |
mpegts_service_t *s, *master, *snext;
|
460 |
467 |
slave_subscription_t *sub;
|
461 |
468 |
mpegts_apids_t pmt_pids;
|
462 |
469 |
size_t si;
|
... | ... | |
470 |
477 |
if (rs->mux == NULL || rs->subs == NULL)
|
471 |
478 |
goto end;
|
472 |
479 |
|
|
480 |
master = (mpegts_service_t *)rs->subs->ths_raw_service;
|
|
481 |
|
473 |
482 |
if (rs->pids.all) {
|
474 |
483 |
LIST_FOREACH(s, &rs->mux->mm_services, s_dvb_mux_link)
|
475 |
484 |
if (rtsp_validate_service(s, NULL))
|
... | ... | |
861 |
870 |
while (1) {
|
862 |
871 |
if (x == NULL)
|
863 |
872 |
break;
|
864 |
|
if (strcmp(x, "all") == 0) {
|
|
873 |
if (strcmp(x, "all") == 0 || strcmp(x, "8192") == 0) {
|
865 |
874 |
if (satip_server_conf.satip_restrict_pids_all) {
|
866 |
875 |
pids->all = 0;
|
867 |
876 |
for (pid = 1; pid <= 2; pid++) /* CAT, TSDT */
|
... | ... | |
907 |
916 |
if (a + 1 != b)
|
908 |
917 |
return -1;
|
909 |
918 |
return a;
|
910 |
|
} else if ((strncmp(s, "RTP/AVP/TCP;interleaved=0-1", 27) == 0) &&
|
|
919 |
} else if (strncmp(s, "RTP/AVP/UDP;unicast;client_port=", 32) == 0) {
|
|
920 |
for (s += 32, u = s; isdigit(*u); u++);
|
|
921 |
if (*u != '-')
|
|
922 |
return -1;
|
|
923 |
a = atoi(s);
|
|
924 |
for (s = ++u; isdigit(*s); s++);
|
|
925 |
if (*s != '\0' && *s != ';')
|
|
926 |
return -1;
|
|
927 |
b = atoi(u);
|
|
928 |
if (a + 1 != b)
|
|
929 |
return -1;
|
|
930 |
return a;
|
|
931 |
} else if ((strncmp(s, "RTP/AVP/TCP;unicast;interleaved=0-1", 27) == 0) &&
|
|
932 |
!satip_server_conf.satip_notcp_mode) {
|
|
933 |
return RTSP_TCP_DATA;
|
|
934 |
} else if ((strncmp(s, "RTP/AVP/TCP;interleaved=0-1", 35) == 0) &&
|
911 |
935 |
!satip_server_conf.satip_notcp_mode) {
|
912 |
936 |
return RTSP_TCP_DATA;
|
913 |
937 |
}
|
... | ... | |
983 |
1007 |
if (cmd == RTSP_CMD_SETUP) {
|
984 |
1008 |
if (!rs) {
|
985 |
1009 |
rs = rtsp_new_session(hc->hc_peer_ipstr, msys, 0, -1);
|
|
1010 |
if (rs == NULL) goto end;
|
986 |
1011 |
if (delsys == DVB_SYS_NONE) goto end;
|
987 |
1012 |
if (msys == DVB_SYS_NONE) goto end;
|
988 |
1013 |
if (!(*valid)) goto end;
|
989 |
1014 |
alloc_stream_id = 1;
|
990 |
1015 |
} else if (stream != rs->stream) {
|
991 |
1016 |
rs = rtsp_new_session(hc->hc_peer_ipstr, msys, rs->nsession, stream);
|
|
1017 |
if (rs == NULL) goto end;
|
992 |
1018 |
if (delsys == DVB_SYS_NONE) goto end;
|
993 |
1019 |
if (msys == DVB_SYS_NONE) goto end;
|
994 |
1020 |
if (!(*valid)) goto end;
|
... | ... | |
1017 |
1043 |
rs->rtp_peer_port = r;
|
1018 |
1044 |
rs->frontend = fe > 0 ? fe : 1;
|
1019 |
1045 |
} else {
|
|
1046 |
if (!rs && !stream && cmd == RTSP_CMD_DESCRIBE)
|
|
1047 |
rs = rtsp_new_session(hc->hc_peer_ipstr, msys, 0, -1);
|
1020 |
1048 |
if (!rs || stream != rs->stream) {
|
1021 |
1049 |
if (rs)
|
1022 |
1050 |
errcode = HTTP_STATUS_NOT_FOUND;
|
... | ... | |
1187 |
1215 |
if (mpegts_pid_dump(&rs->pids, buf + r, sizeof(buf) - r, 0, 0) == 0)
|
1188 |
1216 |
tvh_strlcatf(buf, sizeof(buf), r, "<none>");
|
1189 |
1217 |
|
|
1218 |
if (cmd == RTSP_CMD_DESCRIBE) {
|
|
1219 |
hc->hc_session = rs->session;
|
|
1220 |
if (!rs->stream)
|
|
1221 |
rs->stream = 1;
|
|
1222 |
hc->hc_stream = rs->stream;
|
|
1223 |
}
|
1190 |
1224 |
tvhdebug(LS_SATIPS, "%i/%s/%d: %s from %s:%d %s",
|
1191 |
1225 |
rs->frontend, rs->session, rs->stream,
|
1192 |
1226 |
caller, hc->hc_peer_ipstr, ntohs(IP_PORT(*hc->hc_peer)), buf);
|
... | ... | |
1294 |
1328 |
{
|
1295 |
1329 |
char buf[4096];
|
1296 |
1330 |
|
1297 |
|
htsbuf_qprintf(q, "a=control:stream=%d\r\n", rs->stream);
|
|
1331 |
if (rs->stream > 0)
|
|
1332 |
htsbuf_qprintf(q, "a=control:stream=%d\r\n", rs->stream);
|
1298 |
1333 |
htsbuf_append_str(q, "a=tool:tvheadend\r\n");
|
1299 |
1334 |
htsbuf_append_str(q, "m=video 0 RTP/AVP 33\r\n");
|
1300 |
1335 |
if (strchr(rtsp_ip, ':'))
|
... | ... | |
1311 |
1346 |
}
|
1312 |
1347 |
}
|
1313 |
1348 |
|
|
1349 |
static inline const char *
|
|
1350 |
rtsp_conn_ip(http_connection_t *hc, char *buf, size_t buflen, int *port)
|
|
1351 |
{
|
|
1352 |
const char *used_ip = rtsp_ip;
|
|
1353 |
int used_port = rtsp_port;
|
|
1354 |
|
|
1355 |
if (hc && hc->hc_self)
|
|
1356 |
used_ip = tcp_get_str_from_ip(hc->hc_self, buf, buflen);
|
|
1357 |
|
|
1358 |
*port = used_port > 0 ? used_port : 554;
|
|
1359 |
|
|
1360 |
return used_ip;
|
|
1361 |
}
|
|
1362 |
|
1314 |
1363 |
/*
|
1315 |
1364 |
*
|
1316 |
1365 |
*/
|
... | ... | |
1322 |
1371 |
char *u = tvh_strdupa(hc->hc_url);
|
1323 |
1372 |
session_t *rs;
|
1324 |
1373 |
htsbuf_queue_t q;
|
1325 |
|
char buf[96];
|
|
1374 |
char buf[96], buf1[46];
|
|
1375 |
const char *used_ip = NULL;
|
1326 |
1376 |
int r = HTTP_STATUS_BAD_REQUEST;
|
1327 |
|
int stream, first = 1, valid;
|
|
1377 |
int stream, first = 1, valid, used_port;
|
1328 |
1378 |
|
1329 |
1379 |
htsbuf_queue_init(&q, 0);
|
1330 |
1380 |
|
... | ... | |
1381 |
1431 |
http_arg_init(&args);
|
1382 |
1432 |
if (hc->hc_session)
|
1383 |
1433 |
http_arg_set(&args, "Session", hc->hc_session);
|
1384 |
|
if (stream > 0)
|
1385 |
|
snprintf(buf, sizeof(buf), "rtsp://%s/stream=%i", rtsp_ip, stream);
|
|
1434 |
used_ip = rtsp_conn_ip(hc, buf1, sizeof(buf1), &used_port);
|
|
1435 |
if ((stream > 0) && (used_port != 554))
|
|
1436 |
snprintf(buf, sizeof(buf), "rtsp://%s:%d/stream=%i", used_ip, used_port, stream);
|
|
1437 |
else if ((stream > 0) && (used_port == 554))
|
|
1438 |
snprintf(buf, sizeof(buf), "rtsp://%s/stream=%i", used_ip, stream);
|
|
1439 |
else if (used_port != 554)
|
|
1440 |
snprintf(buf, sizeof(buf), "rtsp://%s:%d", used_ip, used_port);
|
1386 |
1441 |
else
|
1387 |
|
snprintf(buf, sizeof(buf), "rtsp://%s", rtsp_ip);
|
|
1442 |
snprintf(buf, sizeof(buf), "rtsp://%s", used_ip);
|
1388 |
1443 |
http_arg_set(&args, "Content-Base", buf);
|
1389 |
1444 |
http_send_begin(hc);
|
1390 |
1445 |
http_send_header(hc, HTTP_STATUS_OK, "application/sdp", q.hq_size,
|
... | ... | |
1408 |
1463 |
rtsp_process_play(http_connection_t *hc, int cmd)
|
1409 |
1464 |
{
|
1410 |
1465 |
session_t *rs;
|
1411 |
|
int errcode = HTTP_STATUS_BAD_REQUEST, valid = 0, i, stream;
|
1412 |
|
char buf[256], *u = tvh_strdupa(hc->hc_url);
|
|
1466 |
int errcode = HTTP_STATUS_BAD_REQUEST, valid = 0, i, stream, used_port;
|
|
1467 |
char buf[256], buf1[46], *u = tvh_strdupa(hc->hc_url);
|
|
1468 |
const char *used_ip = NULL;
|
1413 |
1469 |
http_arg_list_t args;
|
1414 |
1470 |
|
1415 |
1471 |
http_arg_init(&args);
|
... | ... | |
1417 |
1473 |
if ((u = rtsp_check_urlbase(u)) == NULL)
|
1418 |
1474 |
goto error2;
|
1419 |
1475 |
|
1420 |
|
if ((stream = rtsp_parse_args(hc, u)) < 0)
|
|
1476 |
/* if ((stream = rtsp_parse_args(hc, u)) < 0) */
|
|
1477 |
stream = hc->hc_stream;
|
|
1478 |
if (stream < 0)
|
1421 |
1479 |
goto error2;
|
1422 |
1480 |
|
1423 |
1481 |
pthread_mutex_lock(&rtsp_lock);
|
... | ... | |
1467 |
1525 |
snprintf(buf, sizeof(buf), "%d", rs->stream);
|
1468 |
1526 |
http_arg_set(&args, "com.ses.streamID", buf);
|
1469 |
1527 |
} else {
|
1470 |
|
if (rtsp_port != 554)
|
1471 |
|
snprintf(buf, sizeof(buf), "url=rtsp://%s:%d/stream=%d", rtsp_ip, rtsp_port, rs->stream);
|
|
1528 |
used_ip = rtsp_conn_ip(hc, buf1, sizeof(buf1), &used_port);
|
|
1529 |
if (used_port != 554)
|
|
1530 |
snprintf(buf, sizeof(buf), "url=rtsp://%s:%d/stream=%d", used_ip, used_port, rs->stream);
|
1472 |
1531 |
else
|
1473 |
|
snprintf(buf, sizeof(buf), "url=rtsp://%s/stream=%d", rtsp_ip, rs->stream);
|
|
1532 |
snprintf(buf, sizeof(buf), "url=rtsp://%s/stream=%d", used_ip, rs->stream);
|
1474 |
1533 |
http_arg_set(&args, "RTP-Info", buf);
|
1475 |
1534 |
}
|
1476 |
1535 |
|
... | ... | |
1587 |
1646 |
rtsp_stream_status ( void *opaque, htsmsg_t *m )
|
1588 |
1647 |
{
|
1589 |
1648 |
http_connection_t *hc = opaque;
|
|
1649 |
struct session *rs = NULL;
|
|
1650 |
htsmsg_t *c, *tcp = NULL, *udp = NULL;
|
|
1651 |
int udpport, s32;
|
|
1652 |
|
1590 |
1653 |
htsmsg_add_str(m, "type", "SAT>IP");
|
|
1654 |
|
1591 |
1655 |
if (hc->hc_username)
|
1592 |
1656 |
htsmsg_add_str(m, "user", hc->hc_username);
|
|
1657 |
|
|
1658 |
TAILQ_FOREACH(rs, &rtsp_sessions, link) {
|
|
1659 |
if (hc->hc_session &&
|
|
1660 |
strcmp(rs->session, hc->hc_session) == 0 &&
|
|
1661 |
strcmp(rs->peer_ipstr, hc->hc_peer_ipstr) == 0 &&
|
|
1662 |
(udpport = rs->rtp_peer_port) > 0) {
|
|
1663 |
if (udpport == RTSP_TCP_DATA) {
|
|
1664 |
if (rs->tcp_data == hc) {
|
|
1665 |
s32 = htsmsg_get_s32_or_default(m, "peer_port", -1);
|
|
1666 |
if (!tcp) tcp = htsmsg_create_list();
|
|
1667 |
htsmsg_add_s32(tcp, NULL, s32);
|
|
1668 |
}
|
|
1669 |
} else {
|
|
1670 |
if (!udp) udp = htsmsg_create_list();
|
|
1671 |
htsmsg_add_s32(udp, NULL, udpport);
|
|
1672 |
htsmsg_add_s32(udp, NULL, udpport+1);
|
|
1673 |
}
|
|
1674 |
}
|
|
1675 |
}
|
|
1676 |
if (tcp || udp) {
|
|
1677 |
c = htsmsg_create_map();
|
|
1678 |
if (tcp) htsmsg_add_msg(c, "tcp", tcp);
|
|
1679 |
if (udp) htsmsg_add_msg(c, "udp", udp);
|
|
1680 |
htsmsg_add_msg(m, "peer_extra_ports", c);
|
|
1681 |
}
|
1593 |
1682 |
}
|
1594 |
1683 |
|
1595 |
1684 |
/*
|
... | ... | |
1621 |
1710 |
hc.hc_peer = peer;
|
1622 |
1711 |
hc.hc_self = self;
|
1623 |
1712 |
hc.hc_process = rtsp_process_request;
|
|
1713 |
hc.hc_stream = -1;
|
1624 |
1714 |
hc.hc_cseq = 1;
|
1625 |
1715 |
|
1626 |
1716 |
http_serve_requests(&hc);
|
... | ... | |
1655 |
1745 |
rs->tcp_data = NULL;
|
1656 |
1746 |
pthread_mutex_lock(&global_lock);
|
1657 |
1747 |
mpegts_pid_reset(&rs->pids);
|
1658 |
|
rtsp_clean(rs, 1);
|
|
1748 |
rtsp_clean(rs, 0);
|
1659 |
1749 |
mtimer_disarm(&rs->timer);
|
1660 |
1750 |
pthread_mutex_unlock(&global_lock);
|
1661 |
1751 |
}
|