* Titlebar AJAX page
*/
static int
-ajax_page_titlebar(http_connection_t *hc, const char *remain, void *opaque)
+ajax_page_titlebar(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
- tcp_queue_t tq;
-
if(remain == NULL)
return HTTP_STATUS_NOT_FOUND;
- tcp_init_queue(&tq, -1);
- ajax_menu_bar_from_array(&tq, "top", ajax_tabnames, AJAX_TABS, atoi(remain));
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ ajax_menu_bar_from_array(&hr->hr_tq, "top",
+ ajax_tabnames, AJAX_TABS, atoi(remain));
+ http_output_html(hc, hr);
return 0;
}
* About
*/
static int
-ajax_about_tab(http_connection_t *hc)
+ajax_about_tab(http_connection_t *hc, http_reply_t *hr)
{
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
- tcp_init_queue(&tq, -1);
-
- tcp_qprintf(&tq, "<center>");
- tcp_qprintf(&tq, "<div style=\"padding: auto; width: 400px\">");
+ tcp_qprintf(tq, "<center>");
+ tcp_qprintf(tq, "<div style=\"padding: auto; width: 400px\">");
- ajax_box_begin(&tq, AJAX_BOX_SIDEBOX, NULL, NULL, "About");
+ ajax_box_begin(tq, AJAX_BOX_SIDEBOX, NULL, NULL, "About");
- tcp_qprintf(&tq, "<div style=\"text-align: center\">");
+ tcp_qprintf(tq, "<div style=\"text-align: center\">");
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<p>HTS / Tvheadend</p>"
"<p>(c) 2006-2008 Andreas \303\226man</p>"
"<p>Latest release and information is available at:</p>"
"<p><a href=\"http://www.ffmpeg.org/\">FFmpeg</a></p>"
);
- tcp_qprintf(&tq, "</div>");
- ajax_box_end(&tq, AJAX_BOX_SIDEBOX);
- tcp_qprintf(&tq, "</div>");
- tcp_qprintf(&tq, "</center>");
+ tcp_qprintf(tq, "</div>");
+ ajax_box_end(tq, AJAX_BOX_SIDEBOX);
+ tcp_qprintf(tq, "</div>");
+ tcp_qprintf(tq, "</center>");
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ http_output_html(hc, hr);
return 0;
}
* Find the 'tab' id and continue with tab specific code
*/
static int
-ajax_page_tab(http_connection_t *hc, const char *remain, void *opaque)
+ajax_page_tab(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
int tab;
switch(tab) {
case AJAX_TAB_CHANNELS:
- return ajax_channelgroup_tab(hc);
+ return ajax_channelgroup_tab(hc, hr);
case AJAX_TAB_CONFIGURATION:
- return ajax_config_tab(hc);
+ return ajax_config_tab(hc, hr);
case AJAX_TAB_ABOUT:
- return ajax_about_tab(hc);
+ return ajax_about_tab(hc, hr);
default:
return HTTP_STATUS_NOT_FOUND;
* Root page
*/
static int
-ajax_page_root(http_connection_t *hc, const char *remain, void *opaque)
+ajax_page_root(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
- tcp_init_queue(&tq, -1);
-
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\r\n"
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
/*
"content=\"text/html; charset=utf-8\">\r\n");
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<link href=\"/ajax/ajaxui.css\" rel=\"stylesheet\" "
"type=\"text/css\">\r\n");
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<script src=\"/ajax/prototype.js\" type=\"text/javascript\">"
"</script>\r\n");
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<script src=\"/ajax/effects.js\" type=\"text/javascript\">"
"</script>\r\n");
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<script src=\"/ajax/dragdrop.js\" type=\"text/javascript\">"
"</script>\r\n");
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<script src=\"/ajax/controls.js\" type=\"text/javascript\">"
"</script>\r\n");
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<script src=\"/ajax/tvheadend.js\" type=\"text/javascript\">"
"</script>\r\n");
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"</head>");
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<body>");
- ajax_box_begin(&tq, AJAX_BOX_FILLED, "topmenu", NULL, NULL);
- ajax_box_end(&tq, AJAX_BOX_FILLED);
+ ajax_box_begin(tq, AJAX_BOX_FILLED, "topmenu", NULL, NULL);
+ ajax_box_end(tq, AJAX_BOX_FILLED);
- tcp_qprintf(&tq, "<div id=\"topdeck\"></div>");
+ tcp_qprintf(tq, "<div id=\"topdeck\"></div>");
- ajax_js(&tq, "switchtab('top', '0')");
-
- tcp_qprintf(&tq, "</body></html>");
-
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
- return 0;
-}
-
-#if 0
-void blah(void) {
- tcp_qprintf(&tq,
- "<ul id=\"list\">"
- "<li id=\"item_1\">I'm number 1 <a href=\"/\">a link</a></li>"
- "<li id=\"item_2\">");
- ajax_box_top(&tq, NULL, NULL);
- tcp_qprintf(&tq,
- "I'm number 2");
-
- ajax_box_bottom(&tq);
-
- tcp_qprintf(&tq,
- "</li>"
- "<li id=\"item_3\">I'm number 3</li>"
- "<li id=\"item_4\">I'm number 4</li>"
- "</ul>"
- "\r\n"
- "<p id=\"list-info\"></p>\r\n");
-
-
- tcp_qprintf(&tq,
- "<script type=\"text/javascript\">\r\n"
- "//<![CDATA[\r\n"
- "Sortable.create(\"list\", {onUpdate:function(){new Ajax.Updater('list-info', '/ajax/order', {asynchronous:true, evalScripts:true, onComplete:function(request){new Effect.Highlight(\"list\",{});}, parameters:Sortable.serialize(\"list\")})}})\r\n"
- "//]]>\r\n"
- "</script>\r\n");
+ ajax_js(tq, "switchtab('top', '0')");
+ tcp_qprintf(tq, "</body></html>");
- tcp_qprintf(&tq,
- "<div id=\"updateDiv\"></div>\r\n"
- "<form id=\"testform\">\n"
- "<input name=\"name\" type=\"text\"><br>\r\n"
- "<textarea name=\"comment\" cols=\"20\" rows=\"3\">"
- "</textarea><br>\r\n"
- "<input name=\"sendbutton\" type=\"button\" value=\"Send\""
- " onClick=\"new Ajax.Updater('updateDiv', '/ajax/formupdate', "
- "{asynchronous:true, "
- " parameters:Form.serialize($('testform'))})\">\r\n"
- "</form>\r\n");
-
-
- for(i = 0; i < 40; i++) {
- tcp_qprintf(&tq,
- "<div style=\"float: left\" class=\"sidebox\">\r\n"
- " <div class=\"boxhead\"><h2>Discovery</h2></div>\r\n"
- " <div class=\"boxbody\">"
- " <p>Idag e det bra saker pa TV</p>"
- " <p>Imorgon vet vi inte</p>"
- "</div></div>");
- }
-
- tcp_qprintf(&tq,
- "</body></html>");
-
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ http_output_html(hc, hr);
return 0;
}
-#endif
/**
void ajax_a_jsfunc(tcp_queue_t *tq, const char *innerhtml, const char *func,
const char *trailer);
-int ajax_channelgroup_tab(http_connection_t *hc);
-int ajax_config_tab(http_connection_t *hc);
+int ajax_channelgroup_tab(http_connection_t *hc, http_reply_t *hr);
+int ajax_config_tab(http_connection_t *hc, http_reply_t *hr);
-int ajax_config_channels_tab(http_connection_t *hc);
+int ajax_config_channels_tab(http_connection_t *hc, http_reply_t *hr);
void ajax_config_channels_init(void);
-int ajax_config_dvb_tab(http_connection_t *hc);
+int ajax_config_dvb_tab(http_connection_t *hc, http_reply_t *hr);
void ajax_config_dvb_init(void);
void ajax_config_transport_init(void);
* Channelgroup menu bar
*/
static int
-ajax_channelgroup_menu(http_connection_t *hc, const char *remain, void *opaque)
+ajax_channelgroup_menu(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
if(remain == NULL)
return HTTP_STATUS_NOT_FOUND;
- tcp_init_queue(&tq, -1);
-
- ajax_channelgroupmenu_content(&tq, atoi(remain));
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ ajax_channelgroupmenu_content(tq, atoi(remain));
+ http_output_html(hc, hr);
return 0;
}
* Group is given by 'tag' as an ASCII string in remain
*/
int
-ajax_channel_tab(http_connection_t *hc, const char *remain, void *opaque)
+ajax_channel_tab(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
- tcp_queue_t tq;
+ // tcp_queue_t *tq = &hr->hr_tq;
th_channel_t *ch;
th_channel_group_t *tcg;
if((tcg = channel_group_by_tag(atoi(remain))) == NULL)
return HTTP_STATUS_NOT_FOUND;
- tcp_init_queue(&tq, -1);
-
TAILQ_FOREACH(ch, &tcg->tcg_channels, ch_group_link) {
if(LIST_FIRST(&ch->ch_transports) == NULL)
continue;
#endif
}
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ http_output_html(hc, hr);
return 0;
}
* This is the top level menu for this c-file
*/
int
-ajax_channelgroup_tab(http_connection_t *hc)
+ajax_channelgroup_tab(http_connection_t *hc, http_reply_t *hr)
{
- tcp_queue_t tq;
-
- tcp_init_queue(&tq, -1);
+ tcp_queue_t *tq = &hr->hr_tq;
- ajax_box_begin(&tq, AJAX_BOX_FILLED, "channelgroupmenu", NULL, NULL);
- ajax_box_end(&tq, AJAX_BOX_FILLED);
+ ajax_box_begin(tq, AJAX_BOX_FILLED, "channelgroupmenu", NULL, NULL);
+ ajax_box_end(tq, AJAX_BOX_FILLED);
- tcp_qprintf(&tq, "<div id=\"channelgroupdeck\"></div>");
+ tcp_qprintf(tq, "<div id=\"channelgroupdeck\"></div>");
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<script type=\"text/javascript\">"
"switchtab('channelgroup', '0')"
"</script>");
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ http_output_html(hc, hr);
return 0;
}
* Titlebar AJAX page
*/
static int
-ajax_config_menu(http_connection_t *hc, const char *remain, void *opaque)
+ajax_config_menu(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
if(remain == NULL)
return HTTP_STATUS_NOT_FOUND;
- tcp_init_queue(&tq, -1);
- ajax_menu_bar_from_array(&tq, "config",
+ ajax_menu_bar_from_array(tq, "config",
ajax_config_tabnames, AJAX_CONFIG_TABS,
atoi(remain));
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ http_output_html(hc, hr);
return 0;
}
* Switch to different tabs
*/
static int
-ajax_config_dispatch(http_connection_t *hc, const char *remain, void *opaque)
+ajax_config_dispatch(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
int tab;
switch(tab) {
case AJAX_CONFIG_TAB_CHANNELS:
- return ajax_config_channels_tab(hc);
+ return ajax_config_channels_tab(hc, hr);
case AJAX_CONFIG_TAB_DVB:
- return ajax_config_dvb_tab(hc);
+ return ajax_config_dvb_tab(hc, hr);
default:
return HTTP_STATUS_NOT_FOUND;
* This is the top level menu for this c-file
*/
int
-ajax_config_tab(http_connection_t *hc)
+ajax_config_tab(http_connection_t *hc, http_reply_t *hr)
{
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
- tcp_init_queue(&tq, -1);
+ ajax_box_begin(tq, AJAX_BOX_FILLED, "configmenu", NULL, NULL);
+ ajax_box_end(tq, AJAX_BOX_FILLED);
- ajax_box_begin(&tq, AJAX_BOX_FILLED, "configmenu", NULL, NULL);
- ajax_box_end(&tq, AJAX_BOX_FILLED);
+ tcp_qprintf(tq, "<div id=\"configdeck\"></div>");
- tcp_qprintf(&tq, "<div id=\"configdeck\"></div>");
-
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<script type=\"text/javascript\">"
"switchtab('config', '0')"
"</script>");
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ http_output_html(hc, hr);
return 0;
}
* Update order of channel groups
*/
static int
-ajax_chgroup_updateorder(http_connection_t *hc, const char *remain,
- void *opaque)
+ajax_chgroup_updateorder(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
th_channel_group_t *tcg;
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
http_arg_t *ra;
- tcp_init_queue(&tq, -1);
-
TAILQ_FOREACH(ra, &hc->hc_req_args, link) {
if(strcmp(ra->key, "channelgrouplist[]") ||
(tcg = channel_group_by_tag(atoi(ra->val))) == NULL)
channel_group_settings_write();
- tcp_qprintf(&tq, "<span id=\"updatedok\">Updated on server</span>");
- ajax_js(&tq, "Effect.Fade('updatedok')");
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ tcp_qprintf(tq, "<span id=\"updatedok\">Updated on server</span>");
+ ajax_js(tq, "Effect.Fade('updatedok')");
+ http_output_html(hc, hr);
return 0;
}
* Add a new channel group
*/
static int
-ajax_chgroup_add(http_connection_t *hc, const char *remain, void *opaque)
+ajax_chgroup_add(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
th_channel_group_t *tcg;
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
const char *name;
- tcp_init_queue(&tq, -1);
-
if((name = http_arg_get(&hc->hc_req_args, "name")) != NULL) {
TAILQ_FOREACH(tcg, &all_channel_groups, tcg_global_link)
if(tcg == NULL) {
tcg = channel_group_find(name, 1);
- ajax_chgroup_build(&tq, tcg);
+ ajax_chgroup_build(tq, tcg);
/* We must recreate the Sortable object */
- ajax_js(&tq, "Sortable.destroy(\"channelgrouplist\")");
+ ajax_js(tq, "Sortable.destroy(\"channelgrouplist\")");
- ajax_js(&tq, "Sortable.create(\"channelgrouplist\", "
+ ajax_js(tq, "Sortable.create(\"channelgrouplist\", "
"{onUpdate:function(){updatelistonserver("
"'channelgrouplist', "
"'/ajax/chgroup_updateorder', "
")}});");
}
}
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ http_output_html(hc, hr);
return 0;
}
* Delete a channel group
*/
static int
-ajax_chgroup_del(http_connection_t *hc, const char *remain, void *opaque)
+ajax_chgroup_del(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
th_channel_group_t *tcg;
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
const char *id;
if((id = http_arg_get(&hc->hc_req_args, "id")) == NULL)
if((tcg = channel_group_by_tag(atoi(id))) == NULL)
return HTTP_STATUS_BAD_REQUEST;
- tcp_init_queue(&tq, -1);
- tcp_qprintf(&tq, "$('chgrp_%d').remove();", tcg->tcg_tag);
- http_output_queue(hc, &tq, "text/javascript; charset=UTF-8", 0);
+ tcp_qprintf(tq, "$('chgrp_%d').remove();", tcg->tcg_tag);
+ http_output(hc, hr, "text/javascript; charset=UTF-8", NULL, 0);
channel_group_destroy(tcg);
-
return 0;
}
* Channel group & channel configuration
*/
int
-ajax_config_channels_tab(http_connection_t *hc)
+ajax_config_channels_tab(http_connection_t *hc, http_reply_t *hr)
{
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
th_channel_group_t *tcg;
- tcp_init_queue(&tq, -1);
-
- tcp_qprintf(&tq, "<div style=\"float: left; width: 40%\">");
+ tcp_qprintf(tq, "<div style=\"float: left; width: 40%\">");
- ajax_box_begin(&tq, AJAX_BOX_SIDEBOX, "channelgroups",
+ ajax_box_begin(tq, AJAX_BOX_SIDEBOX, "channelgroups",
NULL, "Channel groups");
- tcp_qprintf(&tq, "<div style=\"height:15px; text-align:center\" "
+ tcp_qprintf(tq, "<div style=\"height:15px; text-align:center\" "
"id=\"list-info\"></div>");
- tcp_qprintf(&tq, "<ul id=\"channelgrouplist\" class=\"draglist\">");
+ tcp_qprintf(tq, "<ul id=\"channelgrouplist\" class=\"draglist\">");
TAILQ_FOREACH(tcg, &all_channel_groups, tcg_global_link) {
if(tcg->tcg_hidden)
continue;
- ajax_chgroup_build(&tq, tcg);
+ ajax_chgroup_build(tq, tcg);
}
- tcp_qprintf(&tq, "</ul>");
+ tcp_qprintf(tq, "</ul>");
- ajax_js(&tq, "Sortable.create(\"channelgrouplist\", "
+ ajax_js(tq, "Sortable.create(\"channelgrouplist\", "
"{onUpdate:function(){updatelistonserver("
"'channelgrouplist', "
"'/ajax/chgroup_updateorder', "
/**
* Add new group
*/
- ajax_box_begin(&tq, AJAX_BOX_BORDER, NULL, NULL, NULL);
+ ajax_box_begin(tq, AJAX_BOX_BORDER, NULL, NULL, NULL);
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div style=\"height: 20px\">"
"<div style=\"float: left\">"
"<input class=\"textinput\" type=\"text\" id=\"newchgrp\">"
"Add</a></div>"
"</div>");
- ajax_box_end(&tq, AJAX_BOX_BORDER);
+ ajax_box_end(tq, AJAX_BOX_BORDER);
- ajax_box_end(&tq, AJAX_BOX_SIDEBOX);
- tcp_qprintf(&tq, "</div>");
+ ajax_box_end(tq, AJAX_BOX_SIDEBOX);
+ tcp_qprintf(tq, "</div>");
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div id=\"groupeditortab\" "
"style=\"height: 600px; overflow: auto; "
"float: left; width: 60%\">");
-
- tcp_qprintf(&tq, "</div>");
-
-
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ tcp_qprintf(tq, "</div>");
+ http_output_html(hc, hr);
return 0;
}
* Display all channels within the group
*/
static int
-ajax_chgroup_editor(http_connection_t *hc, const char *remain, void *opaque)
+ajax_chgroup_editor(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
th_channel_t *ch;
th_channel_group_t *tcg;
if(remain == NULL || (tcg = channel_group_by_tag(atoi(remain))) == NULL)
return HTTP_STATUS_BAD_REQUEST;
- tcp_init_queue(&tq, -1);
-
- ajax_box_begin(&tq, AJAX_BOX_SIDEBOX, NULL, NULL, tcg->tcg_name);
+ ajax_box_begin(tq, AJAX_BOX_SIDEBOX, NULL, NULL, tcg->tcg_name);
- tcp_qprintf(&tq, "<ul id=\"channellist\" class=\"draglist\">");
+ tcp_qprintf(tq, "<ul id=\"channellist\" class=\"draglist\">");
TAILQ_FOREACH(ch, &tcg->tcg_channels, ch_group_link) {
- tcp_qprintf(&tq, "<li id=\"ch_%d\">", ch->ch_tag);
+ tcp_qprintf(tq, "<li id=\"ch_%d\">", ch->ch_tag);
- ajax_box_begin(&tq, AJAX_BOX_BORDER, NULL, NULL, NULL);
+ ajax_box_begin(tq, AJAX_BOX_BORDER, NULL, NULL, NULL);
- tcp_qprintf(&tq, "<div style=\"overflow: auto; width: 100%\">");
+ tcp_qprintf(tq, "<div style=\"overflow: auto; width: 100%\">");
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div style=\"float: left; width: 100%\">"
"<a href=\"javascript:void(0)\" >"
"%s</a>"
"</div>",
ch->ch_name);
- tcp_qprintf(&tq, "</div>");
- ajax_box_end(&tq, AJAX_BOX_BORDER);
- tcp_qprintf(&tq, "</li>");
+ tcp_qprintf(tq, "</div>");
+ ajax_box_end(tq, AJAX_BOX_BORDER);
+ tcp_qprintf(tq, "</li>");
}
- tcp_qprintf(&tq, "</ul>");
+ tcp_qprintf(tq, "</ul>");
- ajax_box_end(&tq, AJAX_BOX_SIDEBOX);
+ ajax_box_end(tq, AJAX_BOX_SIDEBOX);
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ http_output_html(hc, hr);
return 0;
}
* Adapter summary
*/
static int
-ajax_adaptersummary(http_connection_t *hc, const char *remain, void *opaque)
+ajax_adaptersummary(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
th_dvb_adapter_t *tda;
char dispname[20];
if(remain == NULL || (tda = dvb_adapter_find_by_identifier(remain)) == NULL)
return HTTP_STATUS_NOT_FOUND;
- tcp_init_queue(&tq, -1);
-
snprintf(dispname, sizeof(dispname), "%s", tda->tda_displayname);
strcpy(dispname + sizeof(dispname) - 4, "...");
- ajax_box_begin(&tq, AJAX_BOX_SIDEBOX, NULL, NULL, dispname);
+ ajax_box_begin(tq, AJAX_BOX_SIDEBOX, NULL, NULL, dispname);
- tcp_qprintf(&tq, "<div class=\"infoprefix\">Status:</div>"
+ tcp_qprintf(tq, "<div class=\"infoprefix\">Status:</div>"
"<div>%s</div>",
val2str(tda->tda_state, adapterstatus) ?: "invalid");
- tcp_qprintf(&tq, "<div class=\"infoprefix\">Type:</div>"
+ tcp_qprintf(tq, "<div class=\"infoprefix\">Type:</div>"
"<div>%s</div>",
dvb_adaptertype_to_str(tda->tda_fe_info->type));
- tcp_qprintf(&tq, "<div style=\"text-align: center\">"
+ tcp_qprintf(tq, "<div style=\"text-align: center\">"
"<a href=\"javascript:void(0);\" "
"onClick=\"new Ajax.Updater('dvbadaptereditor', "
"'/ajax/dvbadaptereditor/%s', "
"{method: 'get', evalScripts: true})\""
"\">Edit</a></div>", tda->tda_identifier);
- ajax_box_end(&tq, AJAX_BOX_SIDEBOX);
+ ajax_box_end(tq, AJAX_BOX_SIDEBOX);
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ http_output_html(hc, hr);
return 0;
}
* DVB configuration
*/
int
-ajax_config_dvb_tab(http_connection_t *hc)
+ajax_config_dvb_tab(http_connection_t *hc, http_reply_t *hr)
{
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
th_dvb_adapter_t *tda;
- tcp_init_queue(&tq, -1);
-
- tcp_qprintf(&tq, "<div style=\"overflow: auto; width: 100%\">");
+ tcp_qprintf(tq, "<div style=\"overflow: auto; width: 100%\">");
LIST_FOREACH(tda, &dvb_adapters, tda_global_link) {
- tcp_qprintf(&tq, "<div id=\"summary_%s\" "
+ tcp_qprintf(tq, "<div id=\"summary_%s\" "
"style=\"float:left; width: 250px\"></div>",
tda->tda_identifier);
- ajax_js(&tq, "new Ajax.Updater('summary_%s', "
+ ajax_js(tq, "new Ajax.Updater('summary_%s', "
"'/ajax/dvbadaptersummary/%s', {method: 'get'})",
tda->tda_identifier, tda->tda_identifier);
}
- tcp_qprintf(&tq, "</div>");
- tcp_qprintf(&tq, "<div id=\"dvbadaptereditor\"></div>");
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ tcp_qprintf(tq, "</div>");
+ tcp_qprintf(tq, "<div id=\"dvbadaptereditor\"></div>");
+ http_output_html(hc, hr);
return 0;
}
* DVB adapter editor pane
*/
static int
-ajax_adaptereditor(http_connection_t *hc, const char *remain, void *opaque)
+ajax_adaptereditor(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
th_dvb_adapter_t *tda;
float a, b, c;
if(remain == NULL || (tda = dvb_adapter_find_by_identifier(remain)) == NULL)
return HTTP_STATUS_NOT_FOUND;
- tcp_init_queue(&tq, -1);
+ ajax_box_begin(tq, AJAX_BOX_FILLED, NULL, NULL, NULL);
- ajax_box_begin(&tq, AJAX_BOX_FILLED, NULL, NULL, NULL);
-
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div style=\"text-align: center; font-weight: bold\">%s</div>",
tda->tda_displayname);
- ajax_box_end(&tq, AJAX_BOX_FILLED);
+ ajax_box_end(tq, AJAX_BOX_FILLED);
/* Type */
- tcp_qprintf(&tq, "<div class=\"infoprefixwide\">Model:</div>"
+ tcp_qprintf(tq, "<div class=\"infoprefixwide\">Model:</div>"
"<div>%s (%s)</div>",
tda->tda_fe_info->name,
dvb_adaptertype_to_str(tda->tda_fe_info->type));
break;
}
- tcp_qprintf(&tq, "<div class=\"infoprefixwide\">Freq. Range:</div>"
+ tcp_qprintf(tq, "<div class=\"infoprefixwide\">Freq. Range:</div>"
"<div>%.2f - %.2f kHz, in steps of %.2f kHz</div>",
a, b, c);
if(tda->tda_fe_info->symbol_rate_min) {
- tcp_qprintf(&tq, "<div class=\"infoprefixwide\">Symbolrate:</div>"
+ tcp_qprintf(tq, "<div class=\"infoprefixwide\">Symbolrate:</div>"
"<div>%d - %d BAUD</div>",
tda->tda_fe_info->symbol_rate_min,
tda->tda_fe_info->symbol_rate_max);
/* Capabilities */
- // tcp_qprintf(&tq, "<div class=\"infoprefixwide\">Capabilities:</div>");
+ // tcp_qprintf(tq, "<div class=\"infoprefixwide\">Capabilities:</div>");
- tcp_qprintf(&tq, "<div style=\"float: left; width:45%\">");
+ tcp_qprintf(tq, "<div style=\"float: left; width:45%\">");
- ajax_box_begin(&tq, AJAX_BOX_SIDEBOX, NULL, NULL, "Multiplexes");
+ ajax_box_begin(tq, AJAX_BOX_SIDEBOX, NULL, NULL, "Multiplexes");
- tcp_qprintf(&tq, "<div id=\"dvbmuxlist%s\"></div>",
+ tcp_qprintf(tq, "<div id=\"dvbmuxlist%s\"></div>",
tda->tda_identifier);
- ajax_js(&tq,
+ ajax_js(tq,
"new Ajax.Updater('dvbmuxlist%s', "
"'/ajax/dvbadaptermuxlist/%s', {method: 'get'}) ",
tda->tda_identifier, tda->tda_identifier);
- tcp_qprintf(&tq, "<hr><div id=\"addmux\">");
- dvb_make_add_link(&tq, tda, NULL);
- tcp_qprintf(&tq, "</div>");
+ tcp_qprintf(tq, "<hr><div id=\"addmux\">");
+ dvb_make_add_link(tq, tda, NULL);
+ tcp_qprintf(tq, "</div>");
- ajax_box_end(&tq, AJAX_BOX_SIDEBOX);
- tcp_qprintf(&tq, "</div>");
+ ajax_box_end(tq, AJAX_BOX_SIDEBOX);
+ tcp_qprintf(tq, "</div>");
/* Div for displaying services */
- tcp_qprintf(&tq, "<div id=\"servicepane\" "
+ tcp_qprintf(tq, "<div id=\"servicepane\" "
"style=\"float: left; width:55%\">");
- tcp_qprintf(&tq, "</div>");
+ tcp_qprintf(tq, "</div>");
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ http_output_html(hc, hr);
return 0;
}
* DVB adapter add mux
*/
static int
-ajax_adapteraddmux(http_connection_t *hc, const char *remain, void *opaque)
+ajax_adapteraddmux(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
th_dvb_adapter_t *tda;
int caps;
int fetype;
caps = tda->tda_fe_info->caps;
fetype = tda->tda_fe_info->type;
- tcp_init_queue(&tq, -1);
-
- tcp_qprintf(&tq, "<div style=\"text-align: center; font-weight: bold\">"
+ tcp_qprintf(tq, "<div style=\"text-align: center; font-weight: bold\">"
"Add new %s mux</div>",
dvb_adaptertype_to_str(tda->tda_fe_info->type));
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div class=\"infoprefixwidefat\">Frequency (%s):</div>"
"<div>"
"<input class=\"textinput\" type=\"text\" id=\"freq\">"
if(fetype == FE_QAM || fetype == FE_QPSK) {
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div class=\"infoprefixwidefat\">Symbolrate:</div>"
"<div>"
"<input class=\"textinput\" type=\"text\" id=\"symrate\">"
/* Bandwidth */
if(fetype == FE_OFDM) {
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div class=\"infoprefixwidefat\">Bandwidth:</div>"
"<div><select id=\"bw\" class=\"textinput\">");
- add_option(&tq, caps & FE_CAN_BANDWIDTH_AUTO, "AUTO");
- add_option(&tq, 1 , "8MHz");
- add_option(&tq, 1 , "7MHz");
- add_option(&tq, 1 , "6MHz");
- tcp_qprintf(&tq, "</select></div>");
+ add_option(tq, caps & FE_CAN_BANDWIDTH_AUTO, "AUTO");
+ add_option(tq, 1 , "8MHz");
+ add_option(tq, 1 , "7MHz");
+ add_option(tq, 1 , "6MHz");
+ tcp_qprintf(tq, "</select></div>");
snprintf(params + strlen(params), sizeof(params) - strlen(params),
", bw: $F('bw')");
/* Constellation */
if(fetype == FE_QAM || fetype == FE_OFDM) {
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div class=\"infoprefixwidefat\">Constellation:</div>"
"<div><select id=\"const\" class=\"textinput\">");
- add_option(&tq, caps & FE_CAN_QAM_AUTO, "AUTO");
- add_option(&tq, caps & FE_CAN_QPSK, "QPSK");
- add_option(&tq, caps & FE_CAN_QAM_16, "QAM16");
- add_option(&tq, caps & FE_CAN_QAM_32, "QAM32");
- add_option(&tq, caps & FE_CAN_QAM_64, "QAM64");
- add_option(&tq, caps & FE_CAN_QAM_128, "QAM128");
- add_option(&tq, caps & FE_CAN_QAM_256, "QAM256");
+ add_option(tq, caps & FE_CAN_QAM_AUTO, "AUTO");
+ add_option(tq, caps & FE_CAN_QPSK, "QPSK");
+ add_option(tq, caps & FE_CAN_QAM_16, "QAM16");
+ add_option(tq, caps & FE_CAN_QAM_32, "QAM32");
+ add_option(tq, caps & FE_CAN_QAM_64, "QAM64");
+ add_option(tq, caps & FE_CAN_QAM_128, "QAM128");
+ add_option(tq, caps & FE_CAN_QAM_256, "QAM256");
- tcp_qprintf(&tq, "</select></div>");
+ tcp_qprintf(tq, "</select></div>");
snprintf(params + strlen(params), sizeof(params) - strlen(params),
", const: $F('const')");
/* FEC */
if(fetype == FE_QAM || fetype == FE_QPSK) {
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div class=\"infoprefixwidefat\">FEC:</div>"
"<div><select id=\"fec\" class=\"textinput\">");
- add_option(&tq, caps & FE_CAN_FEC_AUTO, "AUTO");
- add_option(&tq, caps & FE_CAN_FEC_1_2, "1/2");
- add_option(&tq, caps & FE_CAN_FEC_2_3, "2/3");
- add_option(&tq, caps & FE_CAN_FEC_3_4, "3/4");
- add_option(&tq, caps & FE_CAN_FEC_4_5, "4/5");
- add_option(&tq, caps & FE_CAN_FEC_5_6, "5/6");
- add_option(&tq, caps & FE_CAN_FEC_6_7, "6/7");
- add_option(&tq, caps & FE_CAN_FEC_7_8, "7/8");
- add_option(&tq, caps & FE_CAN_FEC_8_9, "8/9");
- tcp_qprintf(&tq, "</select></div>");
+ add_option(tq, caps & FE_CAN_FEC_AUTO, "AUTO");
+ add_option(tq, caps & FE_CAN_FEC_1_2, "1/2");
+ add_option(tq, caps & FE_CAN_FEC_2_3, "2/3");
+ add_option(tq, caps & FE_CAN_FEC_3_4, "3/4");
+ add_option(tq, caps & FE_CAN_FEC_4_5, "4/5");
+ add_option(tq, caps & FE_CAN_FEC_5_6, "5/6");
+ add_option(tq, caps & FE_CAN_FEC_6_7, "6/7");
+ add_option(tq, caps & FE_CAN_FEC_7_8, "7/8");
+ add_option(tq, caps & FE_CAN_FEC_8_9, "8/9");
+ tcp_qprintf(tq, "</select></div>");
snprintf(params + strlen(params), sizeof(params) - strlen(params),
", fec: $F('fec')");
}
if(fetype == FE_QPSK) {
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div class=\"infoprefixwidefat\">Polarisation:</div>"
"<div><select id=\"pol\" class=\"textinput\">");
- add_option(&tq, 1, "Vertical");
- add_option(&tq, 1, "Horizontal");
- tcp_qprintf(&tq, "</select></div>");
+ add_option(tq, 1, "Vertical");
+ add_option(tq, 1, "Horizontal");
+ tcp_qprintf(tq, "</select></div>");
snprintf(params + strlen(params), sizeof(params) - strlen(params),
", pol: $F('pol')");
if(fetype == FE_OFDM) {
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div class=\"infoprefixwidefat\">Transmission mode:</div>"
"<div><select id=\"tmode\" class=\"textinput\">");
- add_option(&tq, caps & FE_CAN_TRANSMISSION_MODE_AUTO, "AUTO");
- add_option(&tq, 1 , "2k");
- add_option(&tq, 1 , "8k");
- tcp_qprintf(&tq, "</select></div>");
+ add_option(tq, caps & FE_CAN_TRANSMISSION_MODE_AUTO, "AUTO");
+ add_option(tq, 1 , "2k");
+ add_option(tq, 1 , "8k");
+ tcp_qprintf(tq, "</select></div>");
snprintf(params + strlen(params), sizeof(params) - strlen(params),
", tmode: $F('tmode')");
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div class=\"infoprefixwidefat\">Guard interval:</div>"
"<div><select id=\"guard\" class=\"textinput\">");
- add_option(&tq, caps & FE_CAN_GUARD_INTERVAL_AUTO, "AUTO");
- add_option(&tq, 1 , "1/32");
- add_option(&tq, 1 , "1/16");
- add_option(&tq, 1 , "1/8");
- add_option(&tq, 1 , "1/4");
- tcp_qprintf(&tq, "</select></div>");
+ add_option(tq, caps & FE_CAN_GUARD_INTERVAL_AUTO, "AUTO");
+ add_option(tq, 1 , "1/32");
+ add_option(tq, 1 , "1/16");
+ add_option(tq, 1 , "1/8");
+ add_option(tq, 1 , "1/4");
+ tcp_qprintf(tq, "</select></div>");
snprintf(params + strlen(params), sizeof(params) - strlen(params),
", guard: $F('guard')");
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div class=\"infoprefixwidefat\">Hierarchy:</div>"
"<div><select id=\"hier\" class=\"textinput\">");
- add_option(&tq, caps & FE_CAN_HIERARCHY_AUTO, "AUTO");
- add_option(&tq, 1 , "1");
- add_option(&tq, 1 , "2");
- add_option(&tq, 1 , "4");
- add_option(&tq, 1 , "NONE");
- tcp_qprintf(&tq, "</select></div>");
+ add_option(tq, caps & FE_CAN_HIERARCHY_AUTO, "AUTO");
+ add_option(tq, 1 , "1");
+ add_option(tq, 1 , "2");
+ add_option(tq, 1 , "4");
+ add_option(tq, 1 , "NONE");
+ tcp_qprintf(tq, "</select></div>");
snprintf(params + strlen(params), sizeof(params) - strlen(params),
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div class=\"infoprefixwidefat\">FEC Hi:</div>"
"<div><select id=\"fechi\" class=\"textinput\">");
- add_option(&tq, caps & FE_CAN_FEC_AUTO, "AUTO");
- add_option(&tq, caps & FE_CAN_FEC_1_2, "1/2");
- add_option(&tq, caps & FE_CAN_FEC_2_3, "2/3");
- add_option(&tq, caps & FE_CAN_FEC_3_4, "3/4");
- add_option(&tq, caps & FE_CAN_FEC_4_5, "4/5");
- add_option(&tq, caps & FE_CAN_FEC_5_6, "5/6");
- add_option(&tq, caps & FE_CAN_FEC_6_7, "6/7");
- add_option(&tq, caps & FE_CAN_FEC_7_8, "7/8");
- add_option(&tq, caps & FE_CAN_FEC_8_9, "8/9");
- tcp_qprintf(&tq, "</select></div>");
+ add_option(tq, caps & FE_CAN_FEC_AUTO, "AUTO");
+ add_option(tq, caps & FE_CAN_FEC_1_2, "1/2");
+ add_option(tq, caps & FE_CAN_FEC_2_3, "2/3");
+ add_option(tq, caps & FE_CAN_FEC_3_4, "3/4");
+ add_option(tq, caps & FE_CAN_FEC_4_5, "4/5");
+ add_option(tq, caps & FE_CAN_FEC_5_6, "5/6");
+ add_option(tq, caps & FE_CAN_FEC_6_7, "6/7");
+ add_option(tq, caps & FE_CAN_FEC_7_8, "7/8");
+ add_option(tq, caps & FE_CAN_FEC_8_9, "8/9");
+ tcp_qprintf(tq, "</select></div>");
snprintf(params + strlen(params), sizeof(params) - strlen(params),
", fechi: $F('fechi')");
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div class=\"infoprefixwidefat\">FEC Low:</div>"
"<div><select id=\"feclo\" class=\"textinput\">");
- add_option(&tq, caps & FE_CAN_FEC_AUTO, "AUTO");
- add_option(&tq, caps & FE_CAN_FEC_1_2, "1/2");
- add_option(&tq, caps & FE_CAN_FEC_2_3, "2/3");
- add_option(&tq, caps & FE_CAN_FEC_3_4, "3/4");
- add_option(&tq, caps & FE_CAN_FEC_4_5, "4/5");
- add_option(&tq, caps & FE_CAN_FEC_5_6, "5/6");
- add_option(&tq, caps & FE_CAN_FEC_6_7, "6/7");
- add_option(&tq, caps & FE_CAN_FEC_7_8, "7/8");
- add_option(&tq, caps & FE_CAN_FEC_8_9, "8/9");
- tcp_qprintf(&tq, "</select></div>");
+ add_option(tq, caps & FE_CAN_FEC_AUTO, "AUTO");
+ add_option(tq, caps & FE_CAN_FEC_1_2, "1/2");
+ add_option(tq, caps & FE_CAN_FEC_2_3, "2/3");
+ add_option(tq, caps & FE_CAN_FEC_3_4, "3/4");
+ add_option(tq, caps & FE_CAN_FEC_4_5, "4/5");
+ add_option(tq, caps & FE_CAN_FEC_5_6, "5/6");
+ add_option(tq, caps & FE_CAN_FEC_6_7, "6/7");
+ add_option(tq, caps & FE_CAN_FEC_7_8, "7/8");
+ add_option(tq, caps & FE_CAN_FEC_8_9, "8/9");
+ tcp_qprintf(tq, "</select></div>");
snprintf(params + strlen(params), sizeof(params) - strlen(params),
", feclo: $F('feclo')");
}
- tcp_qprintf(&tq,
+ tcp_qprintf(tq,
"<div style=\"text-align: center\">"
"<input type=\"button\" value=\"Create\" "
"onClick=\"new Ajax.Updater('addmux', "
"\">"
"</div>", tda->tda_identifier, params);
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ http_output_html(hc, hr);
return 0;
}
*
*/
static int
-ajax_adaptercreatemux_fail(http_connection_t *hc, th_dvb_adapter_t *tda,
- const char *errmsg)
+ajax_adaptercreatemux_fail(http_connection_t *hc, http_reply_t *hr,
+ th_dvb_adapter_t *tda, const char *errmsg)
{
- tcp_queue_t tq;
- tcp_init_queue(&tq, -1);
- dvb_make_add_link(&tq, tda, errmsg);
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ tcp_queue_t *tq = &hr->hr_tq;
+ dvb_make_add_link(tq, tda, errmsg);
+ http_output_html(hc, hr);
return 0;
}
* DVB adapter create mux (come here on POST after addmux query)
*/
static int
-ajax_adaptercreatemux(http_connection_t *hc, const char *remain, void *opaque)
+ajax_adaptercreatemux(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
- tcp_queue_t tq;
+ tcp_queue_t *tq;
th_dvb_adapter_t *tda;
const char *v;
http_arg_get(&hc->hc_req_args, "port"), 1);
if(v != NULL)
- return ajax_adaptercreatemux_fail(hc, tda, v);
+ return ajax_adaptercreatemux_fail(hc, hr, tda, v);
- tcp_init_queue(&tq, -1);
- dvb_make_add_link(&tq, tda, "Successfully created");
+ tq = &hr->hr_tq;
+ dvb_make_add_link(tq, tda, "Successfully created");
- ajax_js(&tq,
+ ajax_js(tq,
"new Ajax.Updater('dvbmuxlist%s', "
"'/ajax/dvbadaptermuxlist/%s', {method: 'get'}) ",
tda->tda_identifier, tda->tda_identifier);
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ http_output_html(hc, hr);
return 0;
}
* Return a list of all muxes on the given adapter
*/
static int
-ajax_adaptermuxlist(http_connection_t *hc, const char *remain, void *opaque)
+ajax_adaptermuxlist(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
th_dvb_mux_instance_t *tdmi;
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
th_dvb_adapter_t *tda;
char buf[50], buf2[500], buf3[20];
const char *txt;
fetype = tda->tda_fe_info->type;
- tcp_init_queue(&tq, -1);
-
/* List of muxes */
LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link)
nmuxes++;
- ajax_table_header(hc, &tq,
+ ajax_table_header(hc, tq,
(const char *[])
{"Freq", "Status", "State", "Name", "Services", NULL},
(int[]){3,3,2,4,2},
nmuxes > displines,
csize);
- tcp_qprintf(&tq, "<hr>");
+ tcp_qprintf(tq, "<hr>");
v = displines;
if(nmuxes < displines)
v = nmuxes;
- tcp_qprintf(&tq, "<div id=\"dvbmuxlist%s\" "
+ tcp_qprintf(tq, "<div id=\"dvbmuxlist%s\" "
"style=\"height: %dpx; overflow: auto\" class=\"normallist\">",
tda->tda_identifier, v * 14);
if(nmuxes == 0) {
- tcp_qprintf(&tq, "<div style=\"text-align: center\">"
+ tcp_qprintf(tq, "<div style=\"text-align: center\">"
"No muxes configured</div>");
} else LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link) {
cells[4] = buf3;
cells[5] = NULL;
- ajax_table_row(&tq, cells, csize, &o);
+ ajax_table_row(tq, cells, csize, &o);
}
- tcp_qprintf(&tq, "</div>");
+ tcp_qprintf(tq, "</div>");
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ http_output_html(hc, hr);
return 0;
}
* Display detailes about a mux
*/
static int
-ajax_dvbmuxeditor(http_connection_t *hc, const char *remain, void *opaque)
+ajax_dvbmuxeditor(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
th_dvb_mux_instance_t *tdmi;
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
char buf[1000];
th_transport_t *t;
struct th_transport_list head;
if(remain == NULL || (tdmi = dvb_mux_find_by_identifier(remain)) == NULL)
return HTTP_STATUS_NOT_FOUND;
- tcp_init_queue(&tq, -1);
-
tdmi_displayname(tdmi, buf, sizeof(buf));
LIST_INIT(&head);
}
}
- ajax_box_begin(&tq, AJAX_BOX_SIDEBOX, NULL, NULL, buf);
- ajax_transport_build_list(hc, &tq, &head, n);
- ajax_box_end(&tq, AJAX_BOX_SIDEBOX);
+ ajax_box_begin(tq, AJAX_BOX_SIDEBOX, NULL, NULL, buf);
+ ajax_transport_build_list(hc, tq, &head, n);
+ ajax_box_end(tq, AJAX_BOX_SIDEBOX);
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ http_output_html(hc, hr);
return 0;
}
* Rename of unmapped channel
*/
static int
-ajax_transport_rename_channel(http_connection_t *hc,
+ajax_transport_rename_channel(http_connection_t *hc, http_reply_t *hr,
const char *remain, void *opaque)
{
th_transport_t *t;
const char *newname, *v;
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
char buf[1000];
if(remain == NULL || (t = transport_find_by_identifier(remain)) == NULL)
free((void *)t->tht_channelname);
t->tht_channelname = strdup(newname);
- tcp_init_queue(&tq, -1);
-
v = newname;
snprintf(buf, sizeof(buf),
"'/ajax/transport_rename_channel/%s', '%s')",
t->tht_identifier, t->tht_identifier, v);
- ajax_a_jsfunc(&tq, v, buf, "");
+ ajax_a_jsfunc(tq, v, buf, "");
- http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
+ http_output_html(hc, hr);
t->tht_config_change(t);
return 0;
}
*
*/
int
-ajax_transport_op(http_connection_t *hc, const char *remain, void *opaque)
+ajax_transport_op(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
th_transport_t *t;
- tcp_queue_t tq;
+ tcp_queue_t *tq = &hr->hr_tq;
const char *op;
if(remain == NULL || (t = transport_find_by_identifier(remain)) == NULL)
if((op = http_arg_get(&hc->hc_req_args, "action")) == NULL)
return HTTP_STATUS_BAD_REQUEST;
- tcp_init_queue(&tq, -1);
-
if(!strcmp(op, "toggle")) {
if(t->tht_channel)
- dvb_unmap_channel(t, &tq);
+ dvb_unmap_channel(t, tq);
else
- dvb_map_channel(t, &tq);
+ dvb_map_channel(t, tq);
} else if(!strcmp(op, "map") && t->tht_channel == NULL) {
- dvb_map_channel(t, &tq);
+ dvb_map_channel(t, tq);
} else if(!strcmp(op, "unmap") && t->tht_channel != NULL) {
- dvb_unmap_channel(t, &tq);
+ dvb_unmap_channel(t, tq);
}
- http_output_queue(hc, &tq, "text/javascript; charset=UTF-8", 0);
+ http_output(hc, hr, "text/javascript; charset=UTF8", NULL, 0);
t->tht_config_change(t);
return 0;
};
/**
- * If current version mandates it, send a HTTP reply header back
+ *
*/
static void
-http_output_reply_header(http_connection_t *hc, int rc, int maxage)
+http_destroy_reply(http_connection_t *hc, http_reply_t *hr)
+{
+ if(hr->hr_destroy != NULL)
+ hr->hr_destroy(hr, hr->hr_opaque);
+
+ TAILQ_REMOVE(&hc->hc_replies, hr, hr_link);
+ free(hr->hr_location);
+ tcp_flush_queue(&hr->hr_tq);
+ free(hr);
+}
+
+/**
+ * Transmit a HTTP reply
+ *
+ * Return non-zero if we should disconnect (no more keep-alive)
+ */
+static int
+http_send_reply(http_connection_t *hc, http_reply_t *hr)
{
struct tm tm0, *tm;
time_t t;
+ tcp_queue_t *tq = &hr->hr_tq;
+ int r;
- if(hc->hc_version < HTTP_VERSION_1_0)
- return;
-
- http_printf(hc, "%s %d %s\r\n", val2str(hc->hc_version, HTTP_versiontab),
- rc, http_rc2str(rc));
+ if(hr->hr_version > HTTP_VERSION_1_0) {
+ http_printf(hc, "%s %d %s\r\n", val2str(hr->hr_version, HTTP_versiontab),
+ hr->hr_rc, http_rc2str(hr->hr_rc));
- if(maxage == 0) {
- http_printf(hc, "Cache-Control: no-cache\r\n");
- } else {
- t = dispatch_clock;
+ http_printf(hc, "Server: HTS/tvheadend\r\n");
- tm = gmtime_r(&t, &tm0);
- http_printf(hc,
- "Last-Modified: %s, %02d %s %d %02d:%02d:%02d GMT\r\n",
- cachedays[tm->tm_wday], tm->tm_year + 1900,
- cachemonths[tm->tm_mon], tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ if(hr->hr_maxage == 0) {
+ http_printf(hc, "Cache-Control: no-cache\r\n");
+ } else {
+ t = dispatch_clock;
+
+ tm = gmtime_r(&t, &tm0);
+ http_printf(hc,
+ "Last-Modified: %s, %02d %s %d %02d:%02d:%02d GMT\r\n",
+ cachedays[tm->tm_wday], tm->tm_year + 1900,
+ cachemonths[tm->tm_mon], tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+ t += hr->hr_maxage;
+
+ tm = gmtime_r(&t, &tm0);
+ http_printf(hc,
+ "Expires: %s, %02d %s %d %02d:%02d:%02d GMT\r\n",
+ cachedays[tm->tm_wday], tm->tm_year + 1900,
+ cachemonths[tm->tm_mon], tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+ http_printf(hc, "Cache-Control: max-age=%d\r\n", hr->hr_maxage);
+ }
- t += maxage;
+ http_printf(hc, "Connection: %s\r\n",
+ hr->hr_keep_alive ? "Keep-Alive" : "Close");
- tm = gmtime_r(&t, &tm0);
- http_printf(hc,
- "Expires: %s, %02d %s %d %02d:%02d:%02d GMT\r\n",
- cachedays[tm->tm_wday], tm->tm_year + 1900,
- cachemonths[tm->tm_mon], tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+ if(hr->hr_rc == HTTP_STATUS_UNAUTHORIZED)
+ http_printf(hc, "WWW-Authenticate: Basic realm=\"tvheadend\"\r\n");
+
+ if(hr->hr_encoding != NULL)
+ http_printf(hc, "Content-Encoding: %s\r\n", hr->hr_encoding);
- http_printf(hc, "Cache-Control: max-age=%d\r\n", maxage);
+ if(hr->hr_location != NULL)
+ http_printf(hc, "Location: %s\r\n", hr->hr_location);
+
+ http_printf(hc,
+ "Content-Type: %s\r\n"
+ "Content-Length: %d\r\n"
+ "\r\n",
+ hr->hr_content, tq->tq_depth);
}
+ tcp_output_queue(&hc->hc_tcp_session, NULL, tq);
- http_printf(hc, "Server: HTS/tvheadend\r\n");
- http_printf(hc, "Connection: %s\r\n",
- hc->hc_keep_alive ? "Keep-Alive" : "Close");
+ r = !hr->hr_keep_alive;
+
+ http_destroy_reply(hc, hr);
+ return r;
}
/**
- * Send HTTP error back
+ * Send HTTP replies
+ *
+ * Return non-zero if we should disconnect
*/
-void
-http_error(http_connection_t *hc, int error)
+static int
+http_xmit_queue(http_connection_t *hc)
{
- char ret[300];
- const char *errtxt = http_rc2str(error);
+ http_reply_t *hr;
- http_output_reply_header(hc, error, 0);
+ while((hr = TAILQ_FIRST(&hc->hc_replies)) != NULL) {
+ if(hr->hr_destroy != NULL)
+ break; /* Pending reply, cannot send this yet */
+ if(http_send_reply(hc, hr))
+ return 1;
+ }
+ return 0;
+}
- snprintf(ret, sizeof(ret),
- "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
- "<HTML><HEAD>\r\n"
- "<TITLE>%d %s</TITLE>\r\n"
- "</HEAD><BODY>\r\n"
- "<H1>%d %s</H1>\r\n"
- "</BODY></HTML>\r\n",
- error, errtxt,
- error, errtxt);
- if(hc->hc_version >= HTTP_VERSION_1_0) {
- if(error == HTTP_STATUS_UNAUTHORIZED)
- http_printf(hc, "WWW-Authenticate: Basic realm=\"tvheadend\"\r\n");
- http_printf(hc, "Content-Type: text/html\r\n");
- http_printf(hc, "Content-Length: %d\r\n", strlen(ret));
- http_printf(hc, "\r\n");
- }
- http_printf(hc, "%s", ret);
+/**
+ * Send HTTP error back
+ */
+void
+http_error(http_connection_t *hc, http_reply_t *hr, int error)
+{
+ const char *errtxt = http_rc2str(error);
+ tcp_queue_t *tq = &hr->hr_tq;
+
+ tcp_flush_queue(tq);
+
+ tcp_qprintf(tq,
+ "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
+ "<HTML><HEAD>\r\n"
+ "<TITLE>%d %s</TITLE>\r\n"
+ "</HEAD><BODY>\r\n"
+ "<H1>%d %s</H1>\r\n"
+ "</BODY></HTML>\r\n",
+ error, errtxt, error, errtxt);
+
+ hr->hr_destroy = NULL;
+ hr->hr_rc = error;
+ hr->hr_content = "text/html";
}
/**
- * Send an HTTP OK and post data from a tcp queue
+ * Send an HTTP OK
*/
void
-http_output_queue(http_connection_t *hc, tcp_queue_t *tq, const char *content,
- int maxage)
+http_output(http_connection_t *hc, http_reply_t *hr, const char *content,
+ const char *encoding, int maxage)
{
- http_output_reply_header(hc, 200, maxage);
-
- if(hc->hc_version >= HTTP_VERSION_1_0) {
- http_printf(hc,
- "Content-Type: %s\r\n"
- "Content-Length: %d\r\n"
- "\r\n",
- content, tq->tq_depth);
- }
-
- tcp_output_queue(&hc->hc_tcp_session, NULL, tq);
+ hr->hr_encoding = encoding;
+ hr->hr_content = content;
+ hr->hr_maxage = maxage;
}
/**
- * Send an HTTP OK and post data from a tcp queue
+ * Send an HTTP OK, simple version for text/html
*/
-static void
-http_output_queue_encoding(http_connection_t *hc, tcp_queue_t *tq,
- const char *content, int maxage,
- const char *encoding)
+void
+http_output_html(http_connection_t *hc, http_reply_t *hr)
{
- http_output_reply_header(hc, 200, maxage);
+ hr->hr_content = "text/html; charset=UTF-8";
+}
- if(hc->hc_version >= HTTP_VERSION_1_0) {
- http_printf(hc,
- "Content-Encoding: %s\r\n"
- "Content-Type: %s\r\n"
- "Content-Length: %d\r\n"
- "\r\n",
- encoding, content, tq->tq_depth);
- }
- tcp_output_queue(&hc->hc_tcp_session, NULL, tq);
+
+/**
+ * Send an HTTP REDIRECT
+ */
+void
+http_redirect(http_connection_t *hc, http_reply_t *hr, const char *location)
+{
+ tcp_queue_t *tq = &hr->hr_tq;
+
+ tcp_qprintf(tq,
+ "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
+ "<HTML><HEAD>\r\n"
+ "<TITLE>Redirect</TITLE>\r\n"
+ "</HEAD><BODY>\r\n"
+ "Please follow <a href=\"%s\">%s</a>\r\n"
+ "</BODY></HTML>\r\n",
+ location, location);
+
+ hr->hr_location = strdup(location);
+ hr->hr_rc = 303;
+ hr->hr_content = "text/html";
}
/**
- * Send an HTTP REDIRECT
+ * Execute url callback
+ *
+ * Returns 1 if we should disconnect
+ *
*/
-int
-http_redirect(http_connection_t *hc, const char *location)
+static int
+http_exec(http_connection_t *hc, http_path_t *hp, char *remain, int err)
{
- tcp_queue_t tq;
+ http_reply_t *hr = calloc(1, sizeof(http_reply_t));
- http_output_reply_header(hc, 303, 0);
+ /* Insert reply in order */
+ TAILQ_INSERT_TAIL(&hc->hc_replies, hr, hr_link);
+
+ tcp_init_queue(&hr->hr_tq, -1);
+ hr->hr_version = hc->hc_version;
+ hr->hr_keep_alive = hc->hc_keep_alive;
- if(hc->hc_version < HTTP_VERSION_1_0)
- return -1;
+ if(!err)
+ err = hp->hp_callback(hc, hr, remain, hp->hp_opaque);
- tcp_init_queue(&tq, -1);
+ if(err)
+ http_error(hc, hr, err);
- tcp_qprintf(&tq, "Please follow <a href=\"%s\"\"></a>", location);
+ if(hr->hr_destroy != NULL)
+ return 0; /* New entry is delayed, do not transmit anything */
- http_printf(hc,
- "Location: %s\r\n"
- "Content-Type: text/html\r\n"
- "Content-Length: %d\r\n"
- "\r\n", location, tq.tq_depth);
- tcp_output_queue(&hc->hc_tcp_session, NULL, &tq);
- return 0;
+ return http_xmit_queue(hc);
}
+
/**
* HTTP GET
*/
-static void
+static int
http_cmd_get(http_connection_t *hc)
{
http_path_t *hp;
char *remain;
char *args;
- int err;
hp = http_resolve(hc, &remain, &args);
- if(hp == NULL) {
- http_error(hc, HTTP_STATUS_NOT_FOUND);
- return;
- }
+ if(hp == NULL)
+ return http_exec(hc, NULL, NULL, HTTP_STATUS_NOT_FOUND);
if(args != NULL)
http_parse_get_args(hc, args);
- err = hp->hp_callback(hc, remain, hp->hp_opaque);
- if(err)
- http_error(hc, err);
+ return http_exec(hc, hp, remain, 0);
}
/**
* Check if a HTTP POST is fully received, and if so, continue processing
+ *
+ * Return non-zero if we should disconnect
*/
-static void
+static int
http_post_check(http_connection_t *hc)
{
http_path_t *hp;
char *remain, *args, *v, *argv[2];
- int err, n;
+ int n;
if(hc->hc_post_ptr != hc->hc_post_len)
- return;
+ return 0;
hc->hc_state = HTTP_CON_WAIT_REQUEST;
/* Parse content-type */
v = http_arg_get(&hc->hc_args, "Content-Type");
- if(v == NULL) {
- http_error(hc, HTTP_STATUS_BAD_REQUEST);
- return;
- }
+ if(v == NULL)
+ return http_exec(hc, NULL, NULL, HTTP_STATUS_BAD_REQUEST);
n = http_tokenize(v, argv, 2, ';');
- if(n == 0) {
- http_error(hc, HTTP_STATUS_BAD_REQUEST);
- return;
- }
+ if(n == 0)
+ return http_exec(hc, NULL, NULL, HTTP_STATUS_BAD_REQUEST);
if(!strcmp(argv[0], "application/x-www-form-urlencoded"))
http_parse_get_args(hc, hc->hc_post_data);
hp = http_resolve(hc, &remain, &args);
- if(hp == NULL) {
- http_error(hc, HTTP_STATUS_NOT_FOUND);
- return;
- }
+ if(hp == NULL)
+ return http_exec(hc, NULL, NULL, HTTP_STATUS_NOT_FOUND);
- err = hp->hp_callback(hc, remain, hp->hp_opaque);
- if(err)
- http_error(hc, err);
+ return http_exec(hc, hp, remain, 0);
}
/**
- * HTTP POST
+ * Initial processing of HTTP POST
+ *
+ * Return non-zero if we should disconnect
*/
-static void
+static int
http_cmd_post(http_connection_t *hc)
{
char *v;
/* Set keep-alive status */
v = http_arg_get(&hc->hc_args, "Content-Length");
- if(v == NULL) {
- /* No content length in POST, make us disconnect */
- hc->hc_keep_alive = 0;
- return;
- }
+ if(v == NULL)
+ return 1; /* No content length in POST, make us disconnect */
hc->hc_post_len = atoi(v);
- if(hc->hc_post_len > 16 * 1024 * 1024) {
- /* Bail out if POST data > 16 Mb */
- hc->hc_keep_alive = 0;
- return;
- }
+ if(hc->hc_post_len > 16 * 1024 * 1024)
+ return 1; /* Bail out if POST data > 16 Mb */
hc->hc_state = HTTP_CON_POST_DATA;
hc->hc_post_ptr = tcp_line_drain(&hc->hc_tcp_session, hc->hc_post_data,
hc->hc_post_len);
-
- http_post_check(hc);
+ return http_post_check(hc);
}
}
hc->hc_post_ptr += r;
- http_post_check(hc);
+ if(http_post_check(hc))
+ tcp_disconnect(tcp, 0);
}
/**
* Process a HTTP request
*/
-static void
+static int
http_process_request(http_connection_t *hc)
{
switch(hc->hc_cmd) {
default:
- http_error(hc, HTTP_STATUS_BAD_REQUEST);
- break;
+ return http_exec(hc, NULL, NULL, HTTP_STATUS_BAD_REQUEST);
case HTTP_CMD_GET:
- http_cmd_get(hc);
- break;
+ return http_cmd_get(hc);
case HTTP_CMD_POST:
- http_cmd_post(hc);
- break;
+ return http_cmd_post(hc);
}
}
switch(hc->hc_version) {
case RTSP_VERSION_1_0:
rtsp_process_request(hc);
- break;
+ return 0;
case HTTP_VERSION_0_9:
case HTTP_VERSION_1_0:
case HTTP_VERSION_1_1:
- http_process_request(hc);
- break;
+ return http_process_request(hc) ? -1 : 0;
}
-
- return hc->hc_keep_alive == 0 ? -1 : 0;
+ return -1;
}
/*
* HTTP connection state machine & parser
+ *
+ * If we return non zero we will disconnect
*/
static int
http_con_parse(void *aux, char *buf)
static void
http_disconnect(http_connection_t *hc)
{
+ http_reply_t *hr;
+
+ while((hr = TAILQ_FIRST(&hc->hc_replies)) != NULL)
+ http_destroy_reply(hc, hr);
+
free(hc->hc_post_data);
free(hc->hc_username);
free(hc->hc_password);
switch(event) {
case TCP_CONNECT:
+ TAILQ_INIT(&hc->hc_replies);
TAILQ_INIT(&hc->hc_args);
TAILQ_INIT(&hc->hc_req_args);
break;
} http_resource_t;
static int
-deliver_resource(http_connection_t *hc, const char *remain, void *opaque)
+deliver_resource(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque)
{
http_resource_t *hres = opaque;
- tcp_queue_t tq;
- tcp_init_queue(&tq, -1);
- tcp_qput(&tq, hres->data, hres->len);
- http_output_queue_encoding(hc, &tq, hres->content, 15, hres->encoding);
+ tcp_qput(&hr->hr_tq, hres->data, hres->len);
+ http_output(hc, hr, hres->content, hres->encoding, 15);
return 0;
}
} http_arg_t;
+TAILQ_HEAD(http_reply_queue, http_reply);
+
+typedef struct http_reply {
+ TAILQ_ENTRY(http_reply) hr_link;
+
+ void *hr_opaque;
+
+ void (*hr_destroy)(struct http_reply *hr, void *opaque);
+
+ int hr_version; /* HTTP version */
+ int hr_keep_alive;
+
+ char *hr_location;
+
+ int hr_rc; /* Return code */
+ int hr_maxage;
+ const char *hr_encoding;
+ const char *hr_content;
+
+ tcp_queue_t hr_tq;
+
+} http_reply_t;
+
+
typedef struct http_connection {
tcp_session_t hc_tcp_session; /* Must be first */
char *hc_url;
int hc_keep_alive;
+ struct http_reply_queue hc_replies;
+
struct http_arg_list hc_args;
struct http_arg_list hc_req_args; /* Argumets from GET or POST request */
int http_tokenize(char *buf, char **vec, int vecsize, int delimiter);
-void http_error(http_connection_t *hc, int error);
+void http_error(http_connection_t *hc, http_reply_t *hr, int error);
+
+void http_output(http_connection_t *hc, http_reply_t *hr,
+ const char *content, const char *encoding, int maxage);
-void http_output_queue(http_connection_t *hc, tcp_queue_t *tq,
- const char *content, int maxage);
+void http_output_html(http_connection_t *hc, http_reply_t *hr);
-int http_redirect(http_connection_t *hc, const char *location);
+void http_redirect(http_connection_t *hc, http_reply_t *hr,
+ const char *location);
-typedef int (http_callback_t)(http_connection_t *hc, const char *remain,
- void *opaque);
+typedef int (http_callback_t)(http_connection_t *hc, http_reply_t *hr,
+ const char *remain, void *opaque);
typedef struct http_path {
LIST_ENTRY(http_path) hp_link;
dst->tq_depth += s;
}
- if(!ses->tcp_blocked)
+ if(ses != NULL && !ses->tcp_blocked)
tcp_transmit(ses);
src->tq_depth = 0;