diff --git a/ajaxui/ajaxui.h b/ajaxui/ajaxui.h index cb4f4801..ee416e8d 100644 --- a/ajaxui/ajaxui.h +++ b/ajaxui/ajaxui.h @@ -42,12 +42,10 @@ TAILQ_HEAD(ajax_menu_entry_queue, ajax_menu_entry); #define AJAX_TABS 4 +void ajax_mailbox_init(void); void ajaxui_start(void); void ajax_channels_init(void); void ajax_config_init(void); -void ajax_mailbox_init(void); -int ajax_mailbox_create(char *subscriptionid); - void ajax_menu_bar_from_array(tcp_queue_t *tq, const char *name, const char **vec, int num, int cur); diff --git a/ajaxui/ajaxui_config_dvb.c b/ajaxui/ajaxui_config_dvb.c index 1e20f4f1..c7950832 100644 --- a/ajaxui/ajaxui_config_dvb.c +++ b/ajaxui/ajaxui_config_dvb.c @@ -37,11 +37,14 @@ #include "psi.h" #include "transports.h" +#include "ajaxui_mailbox.h" +#if 0 static struct strtab adapterstatus[] = { { "Hardware detected", TDA_STATE_RUNNING }, { "Hardware not found", TDA_STATE_ZOMBIE }, }; +#endif static void add_option(tcp_queue_t *tq, int bol, const char *name) @@ -83,9 +86,9 @@ ajax_adaptersummary(http_connection_t *hc, http_reply_t *hr, ajax_box_begin(tq, AJAX_BOX_SIDEBOX, NULL, NULL, dispname); - tcp_qprintf(tq, "
Status:
" + tcp_qprintf(tq, "
Device:
" "
%s
", - val2str(tda->tda_state, adapterstatus) ?: "invalid"); + tda->tda_rootpath); tcp_qprintf(tq, "
Type:
" "
%s
", dvb_adaptertype_to_str(tda->tda_fe_info->type)); @@ -226,6 +229,9 @@ ajax_adaptereditor(http_connection_t *hc, http_reply_t *hr, "'/ajax/dvbadaptermuxlist/%s', {method: 'get', evalScripts: true})", tda->tda_identifier, tda->tda_identifier); + ajax_mailbox_start(tq, tda->tda_identifier); + + tcp_qprintf(tq, "
"); dvb_make_add_link(tq, tda, NULL); tcp_qprintf(tq, "
"); @@ -559,7 +565,7 @@ ajax_adaptermuxlist(http_connection_t *hc, http_reply_t *hr, ajax_table_header(hc, tq, (const char *[]) {"Freq", "Status", "State", "Name", "Services", NULL}, - (int[]){3,3,2,4,2}, + (int[]){4,3,2,4,2}, nmuxes > displines, csize); @@ -616,14 +622,11 @@ ajax_adaptermuxlist(http_connection_t *hc, http_reply_t *hr, cells[5] = NULL; ajax_table_row(tq, cells, csize, &o, - (const char *[]){NULL, "status", "state", "name", NULL}, + (const char *[]){NULL, "status", "state", "name", "nsvc"}, tdmi->tdmi_identifier); } tcp_qprintf(tq, ""); - ajax_js(tq, "new Ajax.Request('/ajax/mailbox/%d')", - ajax_mailbox_create(tda->tda_identifier)); - http_output_html(hc, hr); return 0; } diff --git a/ajaxui/ajaxui_mailbox.c b/ajaxui/ajaxui_mailbox.c index a4bdee7c..8f2cc588 100644 --- a/ajaxui/ajaxui_mailbox.c +++ b/ajaxui/ajaxui_mailbox.c @@ -27,6 +27,7 @@ #include "dispatch.h" #include "http.h" #include "ajaxui.h" +#include "transports.h" #define MAILBOX_UNUSED_TIMEOUT 15 #define MAILBOX_EMPTY_REPLY_TIMEOUT 10 @@ -40,7 +41,8 @@ TAILQ_HEAD(ajaxui_letter_queue, ajaxui_letter); typedef struct ajaxui_letter { TAILQ_ENTRY(ajaxui_letter) al_link; - char *al_payload; + char *al_payload_a; + char *al_payload_b; } ajaxui_letter_t; @@ -66,6 +68,8 @@ static void al_destroy(ajaxui_mailbox_t *amb, ajaxui_letter_t *al) { TAILQ_REMOVE(&amb->amb_letters, al, al_link); + free(al->al_payload_a); + free(al->al_payload_b); free(al); } @@ -119,7 +123,7 @@ ajax_mailbox_connection_lost(http_reply_t *hr, void *opaque) * */ int -ajax_mailbox_create(char *subscriptionid) +ajax_mailbox_create(const char *subscriptionid) { ajaxui_mailbox_t *amb = calloc(1, sizeof(ajaxui_mailbox_t)); @@ -137,6 +141,28 @@ ajax_mailbox_create(char *subscriptionid) return amb->amb_boxid; } +/** + * + */ +void +ajax_mailbox_start(tcp_queue_t *tq, const char *identifier) +{ + int boxid = ajax_mailbox_create(identifier); + + /* We need to keep a hidden element in a part of the document that + is directly mapped to this mailbox. + + This element is updated in every reply and if it fails, + there will be no more updates. + + This avoid getting stale updaters that keeps on going if parts + of the document is reloaded faster than the mailbox sees it */ + + tcp_qprintf(tq, "
", boxid); + + ajax_js(tq, "new Ajax.Request('/ajax/mailbox/%d')", boxid); +} + /** * @@ -146,8 +172,14 @@ ajax_mailbox_reply(ajaxui_mailbox_t *amb, http_reply_t *hr) { ajaxui_letter_t *al; + /* Modify the hidden element (as described in ajax_mailbox_start()), + if this div no longer exist, the rest of the javascript will bail + out and we will not be reloaded */ + + tcp_qprintf(&hr->hr_tq, "$('mbox_%d').innerHTML='';\r\n", amb->amb_boxid); + while((al = TAILQ_FIRST(&amb->amb_letters)) != NULL) { - tcp_qprintf(&hr->hr_tq, "%s", al->al_payload); + tcp_qprintf(&hr->hr_tq, "%s%s", al->al_payload_a, al->al_payload_b ?: ""); al_destroy(amb, al); } @@ -157,11 +189,14 @@ ajax_mailbox_reply(ajaxui_mailbox_t *amb, http_reply_t *hr) http_output(hr->hr_connection, hr, "text/javascript", NULL, 0); amb->amb_hr = NULL; + /* Arm a timer in case the browser won't call back */ dtimer_arm(&amb->amb_timer, ajax_mailbox_unused, amb, MAILBOX_UNUSED_TIMEOUT); } - +/** + * + */ static void ajax_mailbox_empty_reply(void *opaque, int64_t now) { @@ -225,29 +260,59 @@ ajax_mailbox_init(void) } +/** + * Delayed delivery of mailbox replies + */ +static void +ajax_mailbox_deliver(void *opaque, int64_t now) +{ + ajaxui_mailbox_t *amb = opaque; + http_connection_t *hc; + + hc = amb->amb_hr->hr_connection; + ajax_mailbox_reply(amb, amb->amb_hr); + http_continue(hc); +} + /** * */ static void -ajax_mailbox_add_to_subscription(const char *subscription, const char *content) +ajax_mailbox_add_to_subscription(const char *subscription, + const char *content_a, const char *content_b) { ajaxui_mailbox_t *amb; ajaxui_letter_t *al; - http_connection_t *hc; LIST_FOREACH(amb, &mailboxes, amb_link) { if(strcmp(subscription, amb->amb_subscriptionid)) continue; - al = malloc(sizeof(ajaxui_letter_t)); - al->al_payload = strdup(content); + /* Avoid inserting the same message twice */ + + TAILQ_FOREACH(al, &amb->amb_letters, al_link) { + if(!strcmp(al->al_payload_a, content_a)) + break; + } + + if(al == NULL) { + + al = malloc(sizeof(ajaxui_letter_t)); + al->al_payload_a = strdup(content_a); + } else { + /* Already exist, just move to tail */ + + TAILQ_REMOVE(&amb->amb_letters, al, al_link); + free(al->al_payload_b); + } + + al->al_payload_b = content_b ? strdup(content_b) : NULL; + TAILQ_INSERT_TAIL(&amb->amb_letters, al, al_link); - if(amb->amb_hr != NULL) { - hc = amb->amb_hr->hr_connection; - ajax_mailbox_reply(amb, amb->amb_hr); - http_continue(hc); - } + if(amb->amb_hr != NULL) + dtimer_arm_hires(&amb->amb_timer, ajax_mailbox_deliver, amb, + getclock_hires() + 100000); } } @@ -260,12 +325,13 @@ static void ajax_mailbox_update_div(const char *subscription, const char *prefix, const char *postfix, const char *content) { - char buf[1000]; + char buf_a[500]; + char buf_b[500]; - snprintf(buf, sizeof(buf), "$('%s_%s').innerHTML='%s';\r\n", - prefix, postfix, content); + snprintf(buf_a, sizeof(buf_a), "$('%s_%s').innerHTML=", prefix, postfix); + snprintf(buf_b, sizeof(buf_b), "'%s';\n\r", content); - ajax_mailbox_add_to_subscription(subscription, buf); + ajax_mailbox_add_to_subscription(subscription, buf_a, buf_b); } @@ -280,7 +346,7 @@ ajax_mailbox_reload_div(const char *subscription, const char *prefix, "{method: 'get', evalScripts: true});\r\n", prefix, postfix, url); - ajax_mailbox_add_to_subscription(subscription, buf); + ajax_mailbox_add_to_subscription(subscription, buf, NULL); } @@ -320,6 +386,26 @@ ajax_mailbox_tdmi_status_change(th_dvb_mux_instance_t *tdmi) tdmi->tdmi_last_status); } +void +ajax_mailbox_tdmi_services_change(th_dvb_mux_instance_t *tdmi) +{ + th_transport_t *t; + char buf[20]; + int n, m; + + n = m = 0; + LIST_FOREACH(t, &tdmi->tdmi_transports, tht_mux_link) { + n++; + if(transport_is_available(t)) + m++; + } + snprintf(buf, sizeof(buf), "%d / %d", m, n); + + ajax_mailbox_update_div(tdmi->tdmi_adapter->tda_identifier, + "nsvc", tdmi->tdmi_identifier, + buf); +} + void diff --git a/ajaxui/ajaxui_mailbox.h b/ajaxui/ajaxui_mailbox.h index 2a0ba5e5..2fc84b43 100644 --- a/ajaxui/ajaxui_mailbox.h +++ b/ajaxui/ajaxui_mailbox.h @@ -19,12 +19,20 @@ #ifndef AJAXUI_MAILBOX_H_ #define AJAXUI_MAILBOX_H_ +#include "tcp.h" + +int ajax_mailbox_create(const char *subscriptionid); + void ajax_mailbox_tdmi_state_change(th_dvb_mux_instance_t *tdmi); void ajax_mailbox_tdmi_name_change(th_dvb_mux_instance_t *tdmi); void ajax_mailbox_tdmi_status_change(th_dvb_mux_instance_t *tdmi); +void ajax_mailbox_tdmi_services_change(th_dvb_mux_instance_t *tdmi); + void ajax_mailbox_tda_change(th_dvb_adapter_t *tda); +void ajax_mailbox_start(tcp_queue_t *tq, const char *identifier); + #endif /* AJAXUI_MAILBOX_H_ */