1597 |
1597 |
return page_play_(hc, remain, opaque, URLAUTH_CODE);
|
1598 |
1598 |
}
|
1599 |
1599 |
|
|
1600 |
|
|
1601 |
/**
|
|
1602 |
* Return the discovery information for HDHomeRun to give clients
|
|
1603 |
* details of how to access the lineup.
|
|
1604 |
*
|
|
1605 |
* Our HDHomeRun server implementation uses a server configured
|
|
1606 |
* username to determine access rather than passing it through the
|
|
1607 |
* request. This is because HDHomeRun clients are usually configured
|
|
1608 |
* with only an IP address and port number and do not offer any input
|
|
1609 |
* for credentials.
|
|
1610 |
*/
|
|
1611 |
static int
|
|
1612 |
hdhomerun_server_discover(http_connection_t *hc, const char *remain, void *opaque)
|
|
1613 |
{
|
|
1614 |
const char *hdhr_user = config.hdhomerun_server_username ?: "";
|
|
1615 |
access_t *perm = access_get_by_username(hdhr_user);
|
|
1616 |
char http_ip[128];
|
|
1617 |
htsbuf_queue_t *hq;
|
|
1618 |
|
|
1619 |
if (access_verify2(perm, ACCESS_STREAMING))
|
|
1620 |
return http_noaccess_code(hc);
|
|
1621 |
|
|
1622 |
hq = &hc->hc_reply;
|
|
1623 |
tcp_get_str_from_ip(hc->hc_self, http_ip, sizeof(http_ip));
|
|
1624 |
|
|
1625 |
/* The contents below for the discovery message are based on tvhProxy */
|
|
1626 |
htsbuf_qprintf(hq, "{ " \
|
|
1627 |
"\"BaseURL\" : \"http://%s:%u\", " \
|
|
1628 |
"\"DeviceAuth\": \"none\", " \
|
|
1629 |
"\"DeviceID\": \"12345678\", " \
|
|
1630 |
"\"FirmwareName\": \"hdhomerun_atsc\", " \
|
|
1631 |
"\"FirmwareVersion\": \"20200101\", " \
|
|
1632 |
"\"FriendlyName\": \"tvheadend\", " \
|
|
1633 |
"\"LineupURL\": \"http://%s:%u/lineup.json\", " \
|
|
1634 |
"\"Manufacturer\": \"Silicondust\", " \
|
|
1635 |
"\"ModelNumber\": \"HDTC-2US\", " \
|
|
1636 |
"\"TunerCount\": 6 " \
|
|
1637 |
"}",
|
|
1638 |
http_ip, tvheadend_webui_port, http_ip, tvheadend_webui_port);
|
|
1639 |
http_output_content(hc, "application/json");
|
|
1640 |
return 0;
|
|
1641 |
}
|
|
1642 |
|
|
1643 |
/**
|
|
1644 |
* Dummy password verify callback for HDHomeRun. We need this to
|
|
1645 |
* ensure we can get the aa_auth information for the user in to the
|
|
1646 |
* access_t since it is not populated by an access_get_by_username.
|
|
1647 |
* Since the user is configured solely on the server, the "passwd" is
|
|
1648 |
* always valid.
|
|
1649 |
*/
|
|
1650 |
static int
|
|
1651 |
hdhomerun_server_verify_callback(void *aux, const char *passwd)
|
|
1652 |
{
|
|
1653 |
return 1;
|
|
1654 |
}
|
|
1655 |
|
|
1656 |
/**
|
|
1657 |
* Return the channel lineup for HDHomeRun
|
|
1658 |
*/
|
|
1659 |
static int
|
|
1660 |
hdhomerun_server_lineup(http_connection_t *hc, const char *remain, void *opaque)
|
|
1661 |
{
|
|
1662 |
const char *hdhr_user = config.hdhomerun_server_username ?: "";
|
|
1663 |
access_t *perm = access_get(hc->hc_peer, hdhr_user, hdhomerun_server_verify_callback, NULL);
|
|
1664 |
htsbuf_queue_t *hq;
|
|
1665 |
channel_t *ch;
|
|
1666 |
const char *name;
|
|
1667 |
const char *blank;
|
|
1668 |
const char *chnum_str;
|
|
1669 |
const int use_auth = perm && perm->aa_auth && !strempty(perm->aa_auth);
|
|
1670 |
char buf1[128], chnum[32], ubuf[UUID_HEX_SIZE];
|
|
1671 |
char url[1024];
|
|
1672 |
char http_ip[128];
|
|
1673 |
const int flags =
|
|
1674 |
(config.chname_num ? CHANNEL_ENAME_NUMBERS : 0) |
|
|
1675 |
(config.chname_src ? CHANNEL_ENAME_SOURCES : 0);
|
|
1676 |
int is_first = 1;
|
|
1677 |
|
|
1678 |
if (access_verify2(perm, ACCESS_STREAMING))
|
|
1679 |
return http_noaccess_code(hc);
|
|
1680 |
|
|
1681 |
tcp_get_str_from_ip(hc->hc_self, http_ip, sizeof(http_ip));
|
|
1682 |
blank = tvh_gettext_lang(perm->aa_lang_ui, channel_blank_name);
|
|
1683 |
hq = &hc->hc_reply;
|
|
1684 |
htsbuf_append_str(hq, "[");
|
|
1685 |
tvh_mutex_lock(&global_lock);
|
|
1686 |
CHANNEL_FOREACH(ch) {
|
|
1687 |
if (!channel_access(ch, perm, 0) || !ch->ch_enabled)
|
|
1688 |
continue;
|
|
1689 |
if (!is_first)
|
|
1690 |
htsbuf_append_str(hq, ", \n");
|
|
1691 |
name = channel_get_ename(ch, buf1, sizeof(buf1), blank, flags);
|
|
1692 |
htsbuf_append_str(hq, "{ \"GuideName\" : ");
|
|
1693 |
htsbuf_append_and_escape_jsonstr(hq, name);
|
|
1694 |
htsbuf_append_str(hq, ", \"GuideNumber\" : ");
|
|
1695 |
/* channel_get_number_as_str returns NULL if no channel number! */
|
|
1696 |
chnum_str = channel_get_number_as_str(ch, chnum, sizeof(chnum));
|
|
1697 |
htsbuf_append_and_escape_jsonstr(hq, chnum_str ? chnum_str : "0");
|
|
1698 |
htsbuf_append_str(hq, ", \"URL\" : ");
|
|
1699 |
sprintf(url, "http://%s:%u/stream/channel/%s?profile=pass%s%s",
|
|
1700 |
http_ip,
|
|
1701 |
tvheadend_webui_port,
|
|
1702 |
channel_get_uuid(ch, ubuf),
|
|
1703 |
use_auth? "&auth=" : "",
|
|
1704 |
use_auth ? perm->aa_auth : "");
|
|
1705 |
htsbuf_append_and_escape_jsonstr(hq, url);
|
|
1706 |
htsbuf_append_str(hq, "}");
|
|
1707 |
is_first = 0;
|
|
1708 |
}
|
|
1709 |
tvh_mutex_unlock(&global_lock);
|
|
1710 |
htsbuf_append_str(hq, "]");
|
|
1711 |
http_output_content(hc, "application/json");
|
|
1712 |
return 0;
|
|
1713 |
}
|
|
1714 |
|
1600 |
1715 |
/**
|
1601 |
1716 |
*
|
1602 |
1717 |
*/
|
... | ... | |
2133 |
2248 |
#if CONFIG_SATIP_SERVER
|
2134 |
2249 |
http_path_add("/satip_server", NULL, satip_server_http_page, ACCESS_ANONYMOUS);
|
2135 |
2250 |
#endif
|
|
2251 |
/* These names are specified in https://info.hdhomerun.com/info/http_api */
|
|
2252 |
http_path_add("/discover.json", NULL, hdhomerun_server_discover, ACCESS_ANONYMOUS);
|
|
2253 |
http_path_add("/lineup.json", NULL, hdhomerun_server_lineup, ACCESS_ANONYMOUS);
|
2136 |
2254 |
|
2137 |
2255 |
http_path_add_modify("/play", NULL, page_play, ACCESS_ANONYMOUS, page_play_path_modify5);
|
2138 |
2256 |
http_path_add_modify("/play/ticket", NULL, page_play_ticket, ACCESS_ANONYMOUS, page_play_path_modify12);
|
2139 |
|
-
|