summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAxel Neumann <axel@notmail.org>2019-03-05 00:52:11 +0100
committerGitHub <noreply@github.com>2019-03-05 00:52:11 +0100
commit2ad165c9545d6fb42a4abf51e5689e2b10ae94a0 (patch)
tree33fdf669c1d591288efa827d58b8a863fdb08420
parentea345d16a6e27c2a8fdf67bf543cc36a5f189131 (diff)
parent71f9aae5e4eb2ebf799384dcdd00915daceb94b9 (diff)
Merge pull request #452 from dangowrt/openwrt-18.06
bmx7: update to git snapshot as of 2018-12-29
-rw-r--r--bmx7/Makefile13
-rw-r--r--bmx7/patches/100-rename-list_add_tail-and-struct-list_head.patch461
-rw-r--r--luci-app-bmx6/bmx6/usr/lib/lua/luci/model/bmx6json.lua1
-rwxr-xr-xluci-app-bmx6/bmx6/www/cgi-bin/bmx6-info11
-rw-r--r--luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/js/bmx6-graph.js2
-rw-r--r--luci-app-bmx7/Makefile6
-rw-r--r--luci-app-bmx7/files/usr/lib/lua/luci/controller/bmx7.lua34
-rw-r--r--luci-app-bmx7/files/usr/lib/lua/luci/view/admin_status/index/bmx7_nodes.htm40
-rw-r--r--luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/nodes_j.htm76
-rw-r--r--luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/status_j.htm206
-rw-r--r--luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/topology.htm54
-rw-r--r--luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/tunnels_j.htm76
-rwxr-xr-xluci-app-bmx7/files/www/cgi-bin/bmx7-info29
-rw-r--r--luci-app-bmx7/files/www/luci-static/resources/bmx7/css/netjsongraph-theme.css59
-rw-r--r--luci-app-bmx7/files/www/luci-static/resources/bmx7/css/netjsongraph.css62
-rw-r--r--luci-app-bmx7/files/www/luci-static/resources/bmx7/js/netjsongraph.js568
-rw-r--r--luci-app-bmx7/files/www/luci-static/resources/bmx7/js/polling.js40
17 files changed, 1048 insertions, 690 deletions
diff --git a/bmx7/Makefile b/bmx7/Makefile
index 8f2a1ec..d9337e9 100644
--- a/bmx7/Makefile
+++ b/bmx7/Makefile
@@ -27,13 +27,12 @@ PKG_NAME:=bmx7
PKG_SOURCE_PROTO:=git
-PKG_SOURCE_URL:=git://github.com/bmx-routing/bmx7.git
-#PKG_SOURCE_URL:=file:///usr/src/bmx-routing/bmx7.git
+PKG_SOURCE_URL:=https://github.com/bmx-routing/bmx7.git
-PKG_REV:=9883383dc26df16da67b9ef7ba99efe62f79c4e7
-PKG_MIRROR_HASH:=012178aba42016d3e0961715f99bf1e322c2c6c22b1cc6635375468360cb4d68
-PKG_VERSION:=r2018042501
-PKG_RELEASE:=3
+PKG_REV:=7711e1f12b29e668f3090b5b94b783f4470a31ce
+PKG_MIRROR_HASH:=6269b210679fa391f92dfc66d2b629038f51201c93bb279fa55cd608c4f90827
+PKG_VERSION:=r2018122901
+PKG_RELEASE:=1
PKG_LICENSE:=GPL-2.0
PKG_SOURCE_VERSION:=$(PKG_REV)
@@ -45,7 +44,7 @@ include $(INCLUDE_DIR)/package.mk
TARGET_CFLAGS += $(FPIC)
-MAKE_ARGS += EXTRA_CFLAGS="$(TARGET_CFLAGS) -I. -I$(STAGING_DIR)/usr/include -DCRYPTLIB=MBEDTLS_2_4_0 -DCORE_LIMIT=20000 -DTRAFFIC_DUMP -DNO_TRACE_FUNCTION_CALLS -DBMX7_LIB_IWINFO"
+MAKE_ARGS += EXTRA_CFLAGS="$(TARGET_CFLAGS) -I. -I$(STAGING_DIR)/usr/include -DCRYPTLIB=MBEDTLS_2_8_0 -DCORE_LIMIT=20000 -DTRAFFIC_DUMP -DNO_TRACE_FUNCTION_CALLS -DBMX7_LIB_IWINFO"
MAKE_ARGS += \
EXTRA_LDFLAGS="$(TARGET_LDFLAGS) -L$(STAGING_DIR)/usr/lib -liwinfo" \
diff --git a/bmx7/patches/100-rename-list_add_tail-and-struct-list_head.patch b/bmx7/patches/100-rename-list_add_tail-and-struct-list_head.patch
deleted file mode 100644
index ffb4584..0000000
--- a/bmx7/patches/100-rename-list_add_tail-and-struct-list_head.patch
+++ /dev/null
@@ -1,461 +0,0 @@
-From 53f5a6ef74acff4c7294f4346a3d88fa04ad49c9 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 14 Aug 2018 12:19:49 +0200
-Subject: [PATCH] rename list_add_tail and struct list_head
-
-Rename some list stuff to avoid namespace collision with libubox
----
- control.c | 18 +++++++++---------
- control.h | 12 ++++++------
- lib/bmx7_tun/tun.c | 2 +-
- list.c | 26 +++++++++++++-------------
- list.h | 36 ++++++++++++++++++------------------
- msg.h | 2 +-
- plugin.c | 8 ++++----
- plugin.h | 2 +-
- schedule.c | 2 +-
- tun.h | 2 +-
- 10 files changed, 55 insertions(+), 55 deletions(-)
-
-diff --git a/control.c b/control.c
-index ee9df30..9ab778d 100644
---- a/control.c
-+++ b/control.c
-@@ -73,7 +73,7 @@ uint32_t My_pid = 0;
-
- LIST_SIMPEL(ctrl_list, struct ctrl_node, list, list);
-
--struct list_head dbgl_clients[DBGL_MAX + 1];
-+struct bmx_list_head dbgl_clients[DBGL_MAX + 1];
- static struct dbg_histogram dbgl_history[2][DBG_HIST_SIZE];
-
- static uint8_t debug_system_active = NO;
-@@ -136,7 +136,7 @@ void add_dbgl_node(struct ctrl_node *cn, int dbgl)
-
- dn->cn = cn;
- cn->dbgl = dbgl;
-- list_add_tail(&dbgl_clients[dbgl], &dn->list);
-+ bmx_list_add_tail(&dbgl_clients[dbgl], &dn->list);
-
- if (dbgl == DBGL_SYS || dbgl == DBGL_CHANGES) {
- dbgf_all(DBGT_INFO, "resetting muted dbg history");
-@@ -255,7 +255,7 @@ struct ctrl_node *create_ctrl_node(int fd, void (*cn_fd_handler) (struct ctrl_no
- {
- struct ctrl_node *cn = debugMallocReset(sizeof(struct ctrl_node), -300010);
-
-- list_add_tail(&ctrl_list, &cn->list);
-+ bmx_list_add_tail(&ctrl_list, &cn->list);
-
- cn->fd = fd;
- cn->cn_fd_handler = cn_fd_handler;
-@@ -571,7 +571,7 @@ void debug_output(uint32_t check_len, struct ctrl_node *cn, int8_t dbgl, int8_t
- if (level == DBGL_SYS && mute_dbgl_sys == DBG_HIST_MUTED)
- continue;
-
-- list_for_each(list_pos, /*(struct list_head *)*/&(dbgl_clients[level]))
-+ list_for_each(list_pos, /*(struct bmx_list_head *)*/&(dbgl_clients[level]))
- {
-
- struct dbgl_node *dn = list_entry(list_pos, struct dbgl_node, list);
-@@ -990,7 +990,7 @@ void register_option(struct opt_type *opt, const char * category_name)
-
- opt->d.parent_opt = tmp_opt;
-
-- list_add_tail(&tmp_opt->d.childs_type_list, &opt->d.list);
-+ bmx_list_add_tail(&tmp_opt->d.childs_type_list, &opt->d.list);
-
- } else {
-
-@@ -1017,7 +1017,7 @@ void register_option(struct opt_type *opt, const char * category_name)
- }
-
- if (!tmp_opt)
-- list_add_tail(&opt_list, &opt->d.list);
-+ bmx_list_add_tail(&opt_list, &opt->d.list);
-
- }
-
-@@ -1094,7 +1094,7 @@ struct opt_type *get_option(struct opt_type *parent_opt, uint8_t short_opt, char
-
- struct list_node *list_pos;
- int32_t len = 0;
-- struct list_head *list;
-+ struct bmx_list_head *list;
- struct opt_type *opt = NULL;
- char *equalp = NULL;
- char s[MAX_ARG_SIZE] = "";
-@@ -1305,7 +1305,7 @@ struct opt_child *add_opt_child(struct opt_type *opt, struct opt_parent *p)
-
- c->opt = opt;
- c->parent_instance = p;
-- list_add_tail(&p->childs_instance_list, &c->list);
-+ bmx_list_add_tail(&p->childs_instance_list, &c->list);
-
- return c;
- }
-@@ -1347,7 +1347,7 @@ struct opt_parent *add_opt_parent(struct opt_type *opt)
-
- LIST_INIT_HEAD(p->childs_instance_list, struct opt_child, list, list);
-
-- list_add_tail(&opt->d.parents_instance_list, &p->list);
-+ bmx_list_add_tail(&opt->d.parents_instance_list, &p->list);
-
- return p;
- }
-diff --git a/control.h b/control.h
-index df0176f..4ef0854 100644
---- a/control.h
-+++ b/control.h
-@@ -49,7 +49,7 @@ typedef uint32_t TIME_SEC_T;
-
- extern int unix_sock;
-
--extern struct list_head ctrl_list;
-+extern struct bmx_list_head ctrl_list;
-
- extern int32_t Client_mode;
-
-@@ -115,7 +115,7 @@ struct ctrl_node {
- int8_t dbgl;
- };
-
--extern struct list_head dbgl_clients[DBGL_MAX + 1];
-+extern struct bmx_list_head dbgl_clients[DBGL_MAX + 1];
-
- struct dbgl_node {
- struct list_node list;
-@@ -227,7 +227,7 @@ struct ctrl_node *create_ctrl_node(int fd, void (*cn_fd_handler) (struct ctrl_no
-
- #define MAX_UNIX_MSG_SIZE 2000
-
--extern struct list_head opt_list;
-+extern struct bmx_list_head opt_list;
-
-
- /* opt_t types:
-@@ -292,7 +292,7 @@ struct opt_child {
- struct opt_parent {
- struct list_node list;
-
-- struct list_head childs_instance_list;
-+ struct bmx_list_head childs_instance_list;
-
- char *val; //key
-
-@@ -311,9 +311,9 @@ struct opt_data {
-
- struct opt_type *parent_opt; //REMOVE THIS and use casting instead !
-
-- struct list_head childs_type_list; //if this opt is a section type, then further sub-opts types can be listed here
-+ struct bmx_list_head childs_type_list; //if this opt is a section type, then further sub-opts types can be listed here
-
-- struct list_head parents_instance_list; //
-+ struct bmx_list_head parents_instance_list; //
- };
-
- struct opt_type {
-diff --git a/lib/bmx7_tun/tun.c b/lib/bmx7_tun/tun.c
-index 2aa740c..265c47a 100644
---- a/lib/bmx7_tun/tun.c
-+++ b/lib/bmx7_tun/tun.c
-@@ -126,7 +126,7 @@ void set_tunXin6_net_adv_list_handl(uint8_t del, void **adv_list_ptr)
- n = debugMallocReset(sizeof( struct tunXin6_net_adv_list_node), -300517);
-
- n->adv_list = adv_list;
-- list_add_tail((&tunXin6_net_adv_list_list), &n->list);
-+ bmx_list_add_tail((&tunXin6_net_adv_list_list), &n->list);
- }
-
- STATIC_FUNC
-diff --git a/list.c b/list.c
-index 5e0665d..b698874 100644
---- a/list.c
-+++ b/list.c
-@@ -39,7 +39,7 @@
- * @head: list head of maintained nodes
- * @node: a node maintained in the list or NULL
- */
--void * list_iterate(struct list_head *head, void *node)
-+void * list_iterate(struct bmx_list_head *head, void *node)
- {
- struct list_node *ln = (node ?
- ((struct list_node*) (((char*) node) + head->list_node_offset)) :
-@@ -53,7 +53,7 @@ void * list_iterate(struct list_head *head, void *node)
- return(((char*) ln->next) - head->list_node_offset);
- }
-
--void *list_find_next(struct list_head *head, void* key, void *node)
-+void *list_find_next(struct bmx_list_head *head, void* key, void *node)
- {
- while ((node = list_iterate(head, node))) {
-
-@@ -68,7 +68,7 @@ void *list_find_next(struct list_head *head, void* key, void *node)
- * @head: list head to add it after
- * @new: new entry to be added
- */
--void list_add_head(struct list_head *head, struct list_node *new)
-+void list_add_head(struct bmx_list_head *head, struct list_node *new)
- {
-
- new->next = head->next;
-@@ -82,12 +82,12 @@ void list_add_head(struct list_head *head, struct list_node *new)
- }
-
- /**
-- * list_add_tail - add a new entry
-+ * bmx_list_add_tail - add a new entry
- * @head: list head to add it before
- * @new: new entry to be added
- */
-
--void list_add_tail(struct list_head *head, struct list_node *new)
-+void bmx_list_add_tail(struct bmx_list_head *head, struct list_node *new)
- {
- new->next = (struct list_node *) head;
- head->last->next = new;
-@@ -96,7 +96,7 @@ void list_add_tail(struct list_head *head, struct list_node *new)
- head->items++;
- }
-
--void list_add_after(struct list_head *head, struct list_node *ln, struct list_node *new)
-+void list_add_after(struct bmx_list_head *head, struct list_node *ln, struct list_node *new)
- {
- new->next = ln->next;
- ln->next = new;
-@@ -112,7 +112,7 @@ void list_add_after(struct list_head *head, struct list_node *ln, struct list_no
- * @entry: the element to delete from the list.
- * Note: list_empty on entry does not return true after this, the entry is in an undefined state.
- */
--void list_del_next(struct list_head *head, struct list_node *ln)
-+void list_del_next(struct bmx_list_head *head, struct list_node *ln)
- {
- assertion(-502641, (ln->next != (struct list_node*) head));
-
-@@ -126,7 +126,7 @@ void list_del_next(struct list_head *head, struct list_node *ln)
- head->items--;
- }
-
--void *list_del_head(struct list_head *head)
-+void *list_del_head(struct bmx_list_head *head)
- {
- if (LIST_EMPTY(head))
- return NULL;
-@@ -147,7 +147,7 @@ void *list_del_head(struct list_head *head)
- */
-
- /* UNTESTED
--void * plist_iterate(struct list_head *head, struct plist_node **pln)
-+void * plist_iterate(struct bmx_list_head *head, struct plist_node **pln)
- {
-
- if (head->last == (struct list_node*)
-@@ -169,17 +169,17 @@ static struct plist_node *plist_node_create(void *item)
- return plh;
- }
-
--void plist_add_head(struct list_head *head, void *item)
-+void plist_add_head(struct bmx_list_head *head, void *item)
- {
- list_add_head(head, &((plist_node_create(item))->list));
- }
-
--void plist_add_tail(struct list_head *head, void *item)
-+void plist_add_tail(struct bmx_list_head *head, void *item)
- {
-- list_add_tail(head, &((plist_node_create(item))->list));
-+ bmx_list_add_tail(head, &((plist_node_create(item))->list));
- }
-
--void * plist_del_head(struct list_head *head)
-+void * plist_del_head(struct bmx_list_head *head)
- {
- struct plist_node *pln = list_del_head(head);
-
-diff --git a/list.h b/list.h
-index d40306c..770dc9f 100644
---- a/list.h
-+++ b/list.h
-@@ -28,7 +28,7 @@
-
-
- #ifndef _LIST_H
--#define _LIST_H
-+#define _LIST_H_
-
- #include <stdint.h>
-
-@@ -36,7 +36,7 @@ struct list_node {
- struct list_node *next;
- };
-
--struct list_head {
-+struct bmx_list_head {
- struct list_node *next;
- struct list_node *last;
- uint16_t items;
-@@ -52,7 +52,7 @@ struct plist_node {
-
-
-
--#define LIST_SIMPEL(ptr, element_type, list_field, key_field ) struct list_head ptr = { \
-+#define LIST_SIMPEL(ptr, element_type, list_field, key_field ) struct bmx_list_head ptr = { \
- .next = (struct list_node *)&ptr, \
- .last = (struct list_node *)&ptr, \
- .items = 0, \
-@@ -75,14 +75,14 @@ struct plist_node {
- #define list_get_first(head) ((void*)((LIST_EMPTY(head)) ? NULL : (((char*) (head)->next) - (head)->list_node_offset) ))
- #define list_get_last(head) ((void*)((LIST_EMPTY(head)) ? NULL : (((char*) (head)->last) - (head)->list_node_offset) ))
-
--void *list_iterate(struct list_head *head, void *node);
--void *list_find_next(struct list_head *head, void* key, void *node);
-+void *list_iterate(struct bmx_list_head *head, void *node);
-+void *list_find_next(struct bmx_list_head *head, void* key, void *node);
-
--void list_add_head(struct list_head *head, struct list_node * new);
--void list_add_tail(struct list_head *head, struct list_node * new);
--void list_add_after(struct list_head *head, struct list_node *pos, struct list_node * new);
--void list_del_next(struct list_head *head, struct list_node *pos);
--void *list_del_head(struct list_head *head);
-+void list_add_head(struct bmx_list_head *head, struct list_node * new);
-+void bmx_list_add_tail(struct bmx_list_head *head, struct list_node * new);
-+void list_add_after(struct bmx_list_head *head, struct list_node *pos, struct list_node * new);
-+void list_del_next(struct bmx_list_head *head, struct list_node *pos);
-+void *list_del_head(struct bmx_list_head *head);
-
-
- #define plist_get_first(head) (LIST_EMPTY(head) ? NULL : \
-@@ -91,17 +91,17 @@ void *list_del_head(struct list_head *head);
- #define plist_get_last(head) (LIST_EMPTY(head) ? NULL : \
- ((struct plist_node*)(((char*) (head)->prev) - (head)->list_node_offset))-item )
-
--void * plist_iterate(struct list_head *head, struct plist_node **pln);
-+void * plist_iterate(struct bmx_list_head *head, struct plist_node **pln);
-
--void plist_add_head(struct list_head *head, void *item);
--void plist_add_tail(struct list_head *head, void *item);
--void *plist_del_head(struct list_head *head);
-+void plist_add_head(struct bmx_list_head *head, void *item);
-+void plist_add_tail(struct bmx_list_head *head, void *item);
-+void *plist_del_head(struct bmx_list_head *head);
-
-
-
- /**
- * list_entry - get the struct for this entry
-- * @ptr: the &struct list_head pointer.
-+ * @ptr: the &struct bmx_list_head pointer.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_struct within the struct.
- */
-@@ -109,7 +109,7 @@ void *plist_del_head(struct list_head *head);
-
- /**
- * list_for_each - iterate over a list
-- * @pos: the &struct list_head to use as a loop counter.
-+ * @pos: the &struct bmx_list_head to use as a loop counter.
- * @head: the head for your list.
- */
- #define list_for_each(pos, head) \
-@@ -123,8 +123,8 @@ void *plist_del_head(struct list_head *head);
-
- /**
- * list_for_each_safe - iterate over a list safe against removal of list entry
-- * @pos: the &struct list_head to use as a loop counter.
-- * @n: another &struct list_head to use as temporary storage
-+ * @pos: the &struct bmx_list_head to use as a loop counter.
-+ * @n: another &struct bmx_list_head to use as temporary storage
- * @head: the head for your list.
- */
- #define list_for_each_safe(pos, n, head) \
-diff --git a/msg.h b/msg.h
-index d36f6e2..b881cef 100644
---- a/msg.h
-+++ b/msg.h
-@@ -357,7 +357,7 @@ struct tx_frame_iterator {
- // MUST be initialized:
- // remains unchanged:
- const char *caller;
-- struct list_head *tx_task_list;
-+ struct bmx_list_head *tx_task_list;
- struct tx_task_node *ttn;
- // struct desc_contents *descContents;
- struct frame_db *db;
-diff --git a/plugin.c b/plugin.c
-index 5016956..102cdba 100644
---- a/plugin.c
-+++ b/plugin.c
-@@ -74,7 +74,7 @@ void _set_thread_hook(int32_t cb_type, void (*cb_handler) (void), int8_t del, st
- cleanup_all(-500143);
- }
-
-- list_for_each_safe(list_pos, tmp_pos, (struct list_head*) cb_list)
-+ list_for_each_safe(list_pos, tmp_pos, (struct bmx_list_head*) cb_list)
- {
- cbn = list_entry(list_pos, struct cb_node, list);
-
-@@ -82,7 +82,7 @@ void _set_thread_hook(int32_t cb_type, void (*cb_handler) (void), int8_t del, st
-
- if (del) {
-
-- list_del_next(((struct list_head*) cb_list), prev_pos);
-+ list_del_next(((struct bmx_list_head*) cb_list), prev_pos);
- debugFree(cbn, -300069);
- return;
-
-@@ -103,7 +103,7 @@ void _set_thread_hook(int32_t cb_type, void (*cb_handler) (void), int8_t del, st
-
- cbn->cb_type = cb_type;
- cbn->cb_handler = cb_handler;
-- list_add_tail(((struct list_head*) cb_list), &cbn->list);
-+ bmx_list_add_tail(((struct bmx_list_head*) cb_list), &cbn->list);
-
- }
-
-@@ -261,7 +261,7 @@ int activate_plugin(struct plugin *p, void *dlhandle, const char *dl_name)
- pn->plugin = p;
- pn->dlhandle = dlhandle;
-
-- list_add_tail(&plugin_list, &pn->list);
-+ bmx_list_add_tail(&plugin_list, &pn->list);
-
- dbgf_all(DBGT_INFO, "%s SUCCESS", pn->plugin->plugin_name);
-
-diff --git a/plugin.h b/plugin.h
-index 5028d4e..b5c9727 100644
---- a/plugin.h
-+++ b/plugin.h
-@@ -74,7 +74,7 @@ struct cb_fd_node {
- void (*cb_fd_handler) (int32_t fd);
- };
-
--extern struct list_head cb_fd_list;
-+extern struct bmx_list_head cb_fd_list;
- // cb_fd_handler is called when fd received data
- // called function may remove itself
- void set_fd_hook(int32_t fd, void (*cb_fd_handler) (int32_t fd), int8_t del);
-diff --git a/schedule.c b/schedule.c
-index 8e3f7a6..8868b01 100644
---- a/schedule.c
-+++ b/schedule.c
-@@ -205,7 +205,7 @@ void task_register(TIME_T timeout, void (* task) (void *), void *data, int32_t t
- }
-
- if ((tmp_tn == NULL) || (U32_LE(tmp_tn->expire, tn->expire)))
-- list_add_tail(&task_list, &tn->list);
-+ bmx_list_add_tail(&task_list, &tn->list);
-
- }
-
-diff --git a/tun.h b/tun.h
-index 06b8c6f..102ee87 100644
---- a/tun.h
-+++ b/tun.h
-@@ -309,7 +309,7 @@ struct tunXin6_net_adv_list_node {
- };
-
-
--extern struct list_head tunXin6_net_adv_list_list;
-+extern struct bmx_list_head tunXin6_net_adv_list_list;
-
- struct tun_bit_key_nodes {
- struct tun_search_node *tsn;
diff --git a/luci-app-bmx6/bmx6/usr/lib/lua/luci/model/bmx6json.lua b/luci-app-bmx6/bmx6/usr/lib/lua/luci/model/bmx6json.lua
index a4a8e43..a61362b 100644
--- a/luci-app-bmx6/bmx6/usr/lib/lua/luci/model/bmx6json.lua
+++ b/luci-app-bmx6/bmx6/usr/lib/lua/luci/model/bmx6json.lua
@@ -59,6 +59,7 @@ function get(field, host)
if json_url[1] == "http" then
raw,err = wget(url..field,1000)
+ sys.exec("")
else
if json_url[1] == "exec" then
diff --git a/luci-app-bmx6/bmx6/www/cgi-bin/bmx6-info b/luci-app-bmx6/bmx6/www/cgi-bin/bmx6-info
index 9c615e4..ceebbbb 100755
--- a/luci-app-bmx6/bmx6/www/cgi-bin/bmx6-info
+++ b/luci-app-bmx6/bmx6/www/cgi-bin/bmx6-info
@@ -43,7 +43,7 @@ print_query() {
i=$(( $i + 1 ))
done
echo -n " ] }"
-
+
# If /all has been specified, printing all the files together
} || {
comma=""
@@ -77,7 +77,7 @@ if [ "$QUERY" == 'myself' ]; then
echo -n "{\"myself\":{\"hostname\":\"$hostname\",\"ip6\":\"$ip6\",\"ip4\":\"$ip4\",\"net6\":\"$cidr6\",\"net4\":\"$cidr4\"}}"
exit 0
fi
-
+
if [ "$QUERY" == 'info' ]; then
echo -n '{ "info": [ '
print_query status
@@ -100,7 +100,12 @@ if [ "$QUERY" == 'neighbours' ]; then
fi
if [ "$QUERY" == 'tunnels' ]; then
- bmx6 -c --jshow tunnels /r=0
+ tunnels=$(bmx6 -c --jshow tunnels /r=0)
+ if [ -z $tunnels ]; then
+ echo '{ "tunnels" : [] }'
+ else
+ echo $tunnels
+ fi
exit 0
fi
diff --git a/luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/js/bmx6-graph.js b/luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/js/bmx6-graph.js
index 80233ff..e3ff009 100644
--- a/luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/js/bmx6-graph.js
+++ b/luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/js/bmx6-graph.js
@@ -48,7 +48,7 @@ function init() {
divwait = document.getElementById("wait");
- XHR.get('/cgi-bin/luci/status/bmx6/topology', null, function(nodesRequest, nodesData) {
+ XHR.get('/cgi-bin/luci/admin/network/BMX6/topology', null, function(nodesRequest, nodesData) {
nodes = nodesData;
XHR.get('/cgi-bin/bmx6-info?$myself&', null, function(myselfRequest, myselfData) {
diff --git a/luci-app-bmx7/Makefile b/luci-app-bmx7/Makefile
index a9e96f7..dbd71c8 100644
--- a/luci-app-bmx7/Makefile
+++ b/luci-app-bmx7/Makefile
@@ -21,7 +21,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-bmx7
-PKG_RELEASE:=0.0-alpha
+PKG_RELEASE:=0.1-alpha
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
PKG_LICENSE:=GPL-2.0+
@@ -33,8 +33,8 @@ define Package/luci-app-bmx7
CATEGORY:=LuCI
SUBMENU:=3. Applications
TITLE:= LuCI support for BMX7
- DEPENDS:=+luci-lib-json +luci-mod-admin-full +luci-lib-httpclient +bmx7
- MAINTAINER:= Roger Pueyo Centelles <roger.pueyo@guifi.net>
+ DEPENDS:=+luci-lib-json +luci-mod-admin-full +bmx7 +bmx7-json
+ MAINTAINER:= Roger Pueyo <roger.pueyo@guifi.net> and Pau Escrich <p4u@dabax.net>
endef
define Package/luci-app-bmx7/description
diff --git a/luci-app-bmx7/files/usr/lib/lua/luci/controller/bmx7.lua b/luci-app-bmx7/files/usr/lib/lua/luci/controller/bmx7.lua
index ed62628..482fb5d 100644
--- a/luci-app-bmx7/files/usr/lib/lua/luci/controller/bmx7.lua
+++ b/luci-app-bmx7/files/usr/lib/lua/luci/controller/bmx7.lua
@@ -59,10 +59,28 @@ function index()
entry(place,call("action_status_j"),"Status",0)
table.remove(place)
- -- Nodes list
+ -- Topology
+ table.insert(place,"Topology")
+ entry(place,call("topology"),"Topology",1)
+ table.remove(place)
+
+ -- Nodes
table.insert(place,"Nodes")
- entry(place,call("action_nodes_j"),"Nodes",1)
+ entry(place,call("action_nodes_j"),"Nodes",2)
+ table.remove(place)
+
+ -- Tunnels
+ table.insert(place,"Gateways")
+ entry(place,call("action_tunnels_j"),"Gateways",3)
table.remove(place)
+
+ -- Integrate bmx7-mdns if present
+ if nixio.fs.stat("/usr/lib/lua/luci/model/cbi/bmx7-mdns.lua","type") ~= nil then
+ table.insert(place,"mDNS")
+ entry(place, cbi("bmx7-mdns"), "mesh DNS", 1).dependent=false
+ table.remove(place)
+ end
+
end
@@ -70,8 +88,14 @@ function action_status_j()
luci.template.render("bmx7/status_j", {})
end
+function action_tunnels_j()
+ luci.template.render("bmx7/tunnels_j", {})
+end
+
+function topology()
+ luci.template.render("bmx7/topology", {})
+end
+
function action_nodes_j()
- local http = require "luci.http"
- local link_non_js = "/cgi-bin/luci" .. http.getenv("PATH_INFO") .. '/nodes_nojs'
- luci.template.render("bmx7/nodes_j", {link_non_js=link_non_js})
+ luci.template.render("bmx7/nodes_j", {})
end
diff --git a/luci-app-bmx7/files/usr/lib/lua/luci/view/admin_status/index/bmx7_nodes.htm b/luci-app-bmx7/files/usr/lib/lua/luci/view/admin_status/index/bmx7_nodes.htm
new file mode 100644
index 0000000..8a6aefa
--- /dev/null
+++ b/luci-app-bmx7/files/usr/lib/lua/luci/view/admin_status/index/bmx7_nodes.htm
@@ -0,0 +1,40 @@
+<div class="cbi-map">
+<div class="cbi-section">
+ <legend><%:Bmx7 mesh nodes%></legend>
+ <div class="cbi-section-node">
+ <div class="table" id="nodes_div">
+ <div class="tr table-titles">
+ <div class="th"><%:Name%></div>
+ <div class="th"><%:Short ID%></div>
+ <div class="th"><%:S/s/T/t%></div>
+ <div class="th"><%:Primary IPv6%></div>
+ <div class="th"><%:Via Neighbour%></div>
+ <div class="th"><%:Device%></div>
+ <div class="th"><%:Metric%></div>
+ <div class="th"><%:Last Ref%></div>
+ </div>
+ </div>
+ </div>
+</div>
+</div>
+
+<script type="text/javascript" src="<%=resource%>/bmx7/js/polling.js"></script>
+<script type="text/javascript">//<![CDATA[
+ new TablePooler(10,"/cgi-bin/bmx7-info", {'$originators':''}, "nodes_div", function(st){
+ var originators = st.originators;
+ var res = Array();
+ originators.forEach(function(originator,i){
+ var name = originator.name;
+ var shortId = originator.shortId;
+ var SsTt = originator.S+'/'+originator.s+'/'+originator.T+'/'+originator.t;
+ var primaryIp = originator.primaryIp;
+ var nbName = originator.nbName;
+ var dev = originator.dev;
+ var metric = originator.metric;
+ var lastRef = originator.lastRef;
+ res.push([name, shortId, SsTt, primaryIp,
+ nbName, dev, metric, lastRef]);
+ });
+ return res;
+ });
+//]]></script>
diff --git a/luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/nodes_j.htm b/luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/nodes_j.htm
index 347af42..a631c93 100644
--- a/luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/nodes_j.htm
+++ b/luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/nodes_j.htm
@@ -27,19 +27,16 @@
<style>
-
div.hideme{
display: none;
}
-
div.info{
background: #FFF;
border: solid 0px;
- height: 90px;
+ height: 190px;
display: block;
overflow: auto;
}
-
div.inforow{
text-align:left;
display:inline-block;
@@ -48,18 +45,15 @@
float: left;
white-space:nowrap;
}
-
div.inforow.newline{
clear: both;
}
-
u {
text-decoration: underline;
- }
-
+ }
#extra-info ul { list-style: none outside none; margin-left: 0em; }
-
</style>
+
<div class="cbi-map">
<h2>Mesh nodes</h2>
@@ -70,40 +64,38 @@
Tip: click the <img src="<%=resource%>/bmx7/world.png" /> icon to see individual node information.
</center>
</div>
-<fieldset class="cbi-section">
+
+
+<div class="cbi-section">
<legend><%:Originators%></legend>
- <table class="cbi-section-table" id="descriptions_table">
- <tr class="cbi-section-table-titles">
- <th class="cbi-section-table-cell"></th>
- <th class="cbi-section-table-cell"><%:Name%></th>
- <th class="cbi-section-table-cell"><%:Short ID%></th>
- <th class="cbi-section-table-cell"><%:S/s/T/t%></th>
- <th class="cbi-section-table-cell"><%:Primary IPv6 address%></th>
- <th class="cbi-section-table-cell"><%:Via neighbour%></th>
- <th class="cbi-section-table-cell"><%:Metric%></th>
- <th class="cbi-section-table-cell"><%:Last desc.%></th>
- <th class="cbi-section-table-cell"><%:Last ref.%></th>
- <th class="cbi-section-table-cell"><%: %></th>
- </tr>
- <tr class="cbi-section-table-row">
- <td colspan="11"><br /><center><em><%:Collecting data...%></em></center></td>
- </tr>
- </table>
-</fieldset>
+ <div class="cbi-section-node">
+ <div class="table" id="nodes_div">
+ <div class="tr table-titles">
+ <div class="th"></div>
+ <div class="th"><%:Name%></div>
+ <div class="th"><%:Short ID%></div>
+ <div class="th"><%:S/s/T/t%></div>
+ <div class="th"><%:Primary IPv6%></div>
+ <div class="th"><%:Via Neighbour%></div>
+ <div class="th"><%:Metric%></div>
+ <div class="th"><%:Last Desc%></div>
+ <div class="th"><%:Last Ref%></div>
+ <div class="th"><%: %></div>
+ </div>
+ </div>
+ </div>
+</div>
</div>
<script type="text/javascript">//<![CDATA[
var displayExtraInfo = function ( id ) {
- console.log('aaa'+id)
document.getElementById('extra-info').innerHTML = document.getElementById(id).innerHTML;
}
-
- new TablePooler(5,"/cgi-bin/bmx7-info", {'$originators':''}, "descriptions_table", function(st){
+ new TablePooler(5,"/cgi-bin/bmx7-info", {'$originators':''}, "nodes_div", function(st){
var infoicon = "<%=resource%>/bmx7/world_small.png";
var originators = st.originators;
var res = Array();
-
originators.forEach(function(originator,i){
var name = originator.name;
var shortId = originator.shortId;
@@ -119,57 +111,45 @@
var metric = originator.metric;
var lastDesc = originator.lastDesc;
var lastRef = originator.lastRef;
-
+
var extrainfo = '<a onclick="displayExtraInfo(\'ip-' + i + '\')"><img src="' + infoicon + '" / ></a>';
var extrainfo_link = '<a onclick="displayExtraInfo(\'ip-' + i + '\')">' + '<img src="' + infoicon + '" />' + '</a>';
-
- extrainfo = '<div id="ip-'+ i +'" class="hideme">'
+ extrainfo = '<div id="ip-'+ i +'" class="hideme">'
+ "<div class='inforow'>"
+ "<h4><u>" + name + '</u></h4>\n'
- + 'Node ID: ' + nodeId + "</div>"
-
+ + 'Node ID: ' + shortId + "</div>"
+ "<div class='inforow'>"
+ "<h5>Primary IPv6 address</h5>\n"
+ primaryIp + "</div>\n"
-
+ "<div class='inforow'>"
+ "<h5>Support & Trust</h5>\n"
+ SsTt + "</div>\n"
-
+ "<div class='inforow'>"
+ "<h5>Node key</h5>\n"
+ nodeKey + "</div>\n"
-
+ "<div class='inforow newline'>"
+ "<h5>Via neighbour</h5>\n"
+ nbName + "</div>\n"
-
+ "<div class='inforow'>"
+ "<h5>Via device</h5>\n"
+ dev + "</div>\n"
-
+ "<div class='inforow'>"
- + "<h5>Via remote link-local IPv6 address</h5>\n"
+ + "<h5>Via link-local IPv6</h5>\n"
+ nbLocalIp + "</div>\n"
-
+ "<div class='inforow'>"
+ "<h5>Route metric</h5>\n"
+ metric + "</div>\n"
-
+ "<div class='inforow'>"
+ "<h5>Desc. size</h5>\n"
+ descSize + "</div>\n"
-
+ "\n</div>";
res.push([extrainfo_link, name, shortId, SsTt, primaryIp,
nbName, metric, lastDesc, lastRef, extrainfo]);
-
});
return res;
});
//]]></script>
<%+footer%>
-
diff --git a/luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/status_j.htm b/luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/status_j.htm
index c6920f9..b7609d7 100644
--- a/luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/status_j.htm
+++ b/luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/status_j.htm
@@ -2,30 +2,6 @@
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript" src="<%=resource%>/bmx7/js/polling.js"></script>
-<style>
- div.hideme{
- display: none;
- }
-
- div.info{
- background: #FFF;
- border: solid 1px;
- height: 80px;
- display: block;
- overflow: auto;
- }
-
- div.inforow{
- text-align:left;
- display:inline-block;
- width:20%;
- margin:5px;
- vertical-align:top;
- }
-
- #extra-info ul { list-style: none outside none; margin-left: 0em; }
-</style>
-
<div class="cbi-map">
<center>
<img src="<%=resource%>/bmx7/bmx7logo.png" />
@@ -38,145 +14,117 @@
<div class="cbi-map-descr"></div>
-<fieldset class="cbi-section">
+<div class="cbi-section">
<legend><%:Node configuration%></legend>
- <table class="cbi-section-table" id="config_table">
- <tr class="cbi-section-table-titles">
- <th class="cbi-section-table-cell"><%:Short ID%></th>
- <th class="cbi-section-table-cell"><%:Node name%></th>
- <th class="cbi-section-table-cell"><%:Primary IPv6 address%></th>
- <th class="cbi-section-table-cell"><%:Node key%></th>
- <th class="cbi-section-table-cell"><%:BMX7 revision%></th>
- </tr>
- <tr class="cbi-section-table-row">
- <td colspan="5"><em><br /><%:Collecting data...%></em></td>
- </tr>
- </table>
-</fieldset>
-
-<fieldset class="cbi-section">
+ <div class="cbi-section-node">
+ <div class="table" id="config_div">
+ <div class="tr table-titles">
+ <div class="th"><%:Short ID%></div>
+ <div class="th"><%:Node name%></div>
+ <div class="th"><%:Primary IPv6 address%></div>
+ <div class="th"><%:Node key%></div>
+ <div class="th"><%:Short DHash%></div>
+ <div class="th"><%:BMX7 revision%></div>
+ </div>
+ </div>
+ </div>
+</div>
+
+
+<div class="cbi-section">
<legend><%:Node status%></legend>
- <table class="cbi-section-table" id="status_table">
- <tr class="cbi-section-table-titles">
- <th class="cbi-section-table-cell"><%:Nodes seen%></th>
- <th class="cbi-section-table-cell"><%:Neighbours%></th>
- <th class="cbi-section-table-cell"><%:Tunnelled IPv6 address%></th>
- <th class="cbi-section-table-cell"><%:Tunnelled IPv4 address%></th>
- <th class="cbi-section-table-cell"><%:Uptime%></th>
- <th class="cbi-section-table-cell"><%:CPU usage%></th>
- <th class="cbi-section-table-cell"><%:Memory usage%></th>
- <th class="cbi-section-table-cell"><%:Tx queue%></th>
-
- </tr>
- <tr class="cbi-section-table-row">
- <td colspan="8"><em><br /><%:Collecting data...%></em></td>
- </tr>
- </table>
-</fieldset>
-
-<fieldset class="cbi-section">
- <legend><%:Interfaces%></legend>
- <table class="cbi-section-table" id="ifaces_table">
- <tr class="cbi-section-table-titles">
- <th class="cbi-section-table-cell"><%:Interface%></th>
- <th class="cbi-section-table-cell"><%:State%></th>
- <th class="cbi-section-table-cell"><%:Type%></th>
- <th class="cbi-section-table-cell"><%:Max. rate%></th>
- <th class="cbi-section-table-cell"><%:Link-local IPv6 address%></th>
- <th class="cbi-section-table-cell"><%:Rx BpP%></th>
- <th class="cbi-section-table-cell"><%:Tx BpP%></th>
-
- </tr>
- <tr class="cbi-section-table-row">
- <td colspan="7"><em><br /><%:Collecting data...%></em></td>
- </tr>
- </table>
-</fieldset>
-
-<fieldset class="cbi-section">
- <legend><%:Links%></legend>
- <table class="cbi-section-table" id="links_table">
- <tr class="cbi-section-table-titles">
- <th class="cbi-section-table-cell"><%:Short ID%></th>
- <th class="cbi-section-table-cell"><%:Name%></th>
- <th class="cbi-section-table-cell"><%:Link key%></th>
- <th class="cbi-section-table-cell"><%:Remote link-local IPv6 address%></th>
- <th class="cbi-section-table-cell"><%:Device%></th>
- <th class="cbi-section-table-cell"><%:Rx rate%></th>
- <th class="cbi-section-table-cell"><%:Tx rate%></th>
- <th class="cbi-section-table-cell"><%:Routes%></th>
-
- </tr>
- <tr class="cbi-section-table-row">
- <td colspan="8"><em><br /><%:Collecting data...%></em></td>
- </tr>
- </table>
-</fieldset>
+ <div class="cbi-section-node">
+ <div class="table" id="status_div">
+ <div class="tr table-titles">
+ <div class="th"><%:Nodes seen%></div>
+ <div class="th"><%:Neighbours%></div>
+ <div class="th"><%:Tunnelled IPv6 address%></div>
+ <div class="th"><%:Tunnelled IPv4 address%></div>
+ <div class="th"><%:Uptime%></div>
+ <div class="th"><%:CPU usage%></div>
+ <div class="th"><%:Memory usage%></div>
+ <div class="th"><%:Tx queue%></div>
+ </div>
+ </div>
+ </div>
+</div>
+<div class="cbi-section">
+ <legend><%:Network interfaces%></legend>
+ <div class="cbi-section-node">
+ <div class="table" id="ifaces_div">
+ <div class="tr table-titles">
+ <div class="th"><%:Interface%></div>
+ <div class="th"><%:State%></div>
+ <div class="th"><%:Type%></div>
+ <div class="th"><%:Max rate%></div>
+ <div class="th"><%:LinkLocal Ipv6%></div>
+ <div class="th"><%:RX BpP%></div>
+ <div class="th"><%:TX BpP%></div>
+ </div>
+ </div>
+ </div>
+</div>
+
+
+<div class="cbi-section">
+ <legend><%:Links%></legend>
+ <div class="cbi-section-node">
+ <div class="table" id="links_div">
+ <div class="tr table-titles">
+ <div class="th"><%:Short ID%></div>
+ <div class="th"><%:Name%></div>
+ <div class="th"><%:Link key%></div>
+ <div class="th"><%:Remote linklocal IPv6%></div>
+ <div class="th"><%:Device%></div>
+ <div class="th"><%:RX rate%></div>
+ <div class="th"><%:TX rate%></div>
+ <div class="th"><%:Routes%></div>
+ </div>
+ </div>
+ </div>
+</div>
</div>
<script type="text/javascript">//<![CDATA[
- new TablePooler(1,"/cgi-bin/bmx7-info", {'$info':''}, "config_table", function(st){
+ new TablePooler(1,"/cgi-bin/bmx7-info", {'$info':''}, "config_div", function(st){
var res = Array();
var sta = st.info[0].status;
- var ifaces = st.info[1].interfaces;
-
- res.push([sta.shortId, sta.name, sta.primaryIp, sta.nodeKey, sta.revision]);
- res.push(['','','','',''])
- res.push(['','','','',''])
-
+ res.push([sta.shortId, sta.name, sta.primaryIp, sta.nodeKey, sta.shortDhash, sta.revision]);
return res;
});
-
- new TablePooler(1,"/cgi-bin/bmx7-info", {'$info':''}, "status_table", function(st){
+ new TablePooler(1,"/cgi-bin/bmx7-info", {'$info':''}, "status_div", function(st){
var res = Array();
var sta = st.info[0].status;
- var mem = st.info[3].memory;
-
+ var mem = st.info[3].memory.bmx7;
var txQ = sta.txQ.split('/');
- console.log(txQ)
-
var ptxQ = '<p style="color:rgb('+parseInt(255*txQ[0]/txQ[1])+','+parseInt(128*(txQ[1]-txQ[0])/txQ[1])+',0)")>'+sta.txQ+'</p>';
- console.log(ptxQ)
-
- res.push([sta.nodes, sta.nbs, sta.tun6Address, sta.tun4Address, sta.uptime, sta.cpu, mem.bmx7, ptxQ]);
-
- res.push(['','','','','','','',''])
- res.push(['','','','','','','',''])
-
+ res.push([sta.nodes, sta.nbs, sta.tun6Address, sta.tun4Address, sta.uptime, sta.cpu, mem, ptxQ]);
return res;
});
- new TablePooler(1,"/cgi-bin/bmx7-info", {'$info':''}, "ifaces_table", function(st){
+ new TablePooler(1,"/cgi-bin/bmx7-info", {'$info':''}, "ifaces_div", function(st){
var res = Array();
- var sta = st.info[0].status;
var ifaces = st.info[1].interfaces;
ifaces.forEach(function(iface){
res.push([iface.dev, iface.state, iface.type, iface.rateMax, iface.localIp, iface.rxBpP, iface.txBpP]);
});
- res.push(['','','','','','',''])
- if (ifaces.length % 2 == 0)
- res.push('')
- res.push(['','','','','','',''])
return res;
});
- new TablePooler(1,"/cgi-bin/bmx7-info", {'links':''}, "links_table", function(st){
+ new TablePooler(1,"/cgi-bin/bmx7-info", {'$info':''}, "links_div", function(st){
var res = Array();
- links = st.links;
+ links = st.info[2].links;
links.forEach(function(link){
- res.push([link.shortId, link.name, link.linkKey, link.nbLocalIp, link.dev, link.rxRate, link.txRate, link.routes]);
+ res.push([link.shortId, link.name, link.linkKey, link.nbLocalIp, link.dev, link.rxRate, link.txRate, link.rts]);
});
- res.push(['','','','','','','',''])
- if (links.length % 2 == 0)
- res.push([])
- res.push(['','','','','','','',''])
return res;
});
+
//]]></script>
<%+footer%>
diff --git a/luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/topology.htm b/luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/topology.htm
new file mode 100644
index 0000000..58ce9fd
--- /dev/null
+++ b/luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/topology.htm
@@ -0,0 +1,54 @@
+<%+header%>
+<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.12/d3.min.js"></script>
+<script type="text/javascript" src="<%=resource%>/bmx7/js/netjsongraph.js"></script>
+
+<link href="<%=resource%>/bmx7/css/netjsongraph.css" rel="stylesheet">
+ <style type="text/css">
+ body {
+ font-family: Arial, sans-serif;
+ font-size: 13px;
+ }
+
+ .njg-overlay{
+ width: auto;
+ height: auto;
+ min-width: 200px;
+ max-width: 400px;
+ border: 1px solid #000;
+ border-radius: 2px;
+ background: rgba(0, 0, 0, 0.7);
+ top: 10px;
+ right: 10px;
+ padding: 0 15px;
+ font-family: Arial, sans-serif;
+ font-size: 14px;
+ color: #fff
+ }
+
+ .njg-node {
+ fill: #008000;
+ fill-opacity: 0.8;
+ stroke: #008000;
+ stroke-width: 1px;
+ cursor: pointer;
+ }
+ .njg-node:hover,
+ .njg-node.njg-open{
+ fill-opacity: 1;
+ }
+
+ .njg-link {
+ stroke: #00ff00;
+ stroke-width: 2;
+ stroke-opacity: .5;
+ cursor: pointer;
+ }
+ .njg-link:hover,
+ .njg-link.njg-open{
+ stroke-width: 3;
+ stroke-opacity: 1
+ }
+</style>
+<script>d3.netJsonGraph("/cgi-bin/bmx7-info?netjson/network-graph.json", { defaultStyle: false });</script>
+<%+footer%>
+
diff --git a/luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/tunnels_j.htm b/luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/tunnels_j.htm
new file mode 100644
index 0000000..aaa79a8
--- /dev/null
+++ b/luci-app-bmx7/files/usr/lib/lua/luci/view/bmx7/tunnels_j.htm
@@ -0,0 +1,76 @@
+<%#
+ Copyright (C) 2011 Pau Escrich <pau@dabax.net>
+ Contributors Lluis Esquerda <eskerda@gmail.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+-%>
+
+
+<%+header%>
+<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
+<script type="text/javascript" src="<%=resource%>/bmx7/js/polling.js"></script>
+
+<div class="cbi-map">
+<h2>Gateway announcements</h2>
+<div class="cbi-map-descr">Networks announced by mesh nodes</div>
+
+<div class="cbi-section">
+ <legend><%:Announcements%></legend>
+ <div class="cbi-section-node">
+ <div class="table" id="tunnels_div">
+ <div class="tr table-titles">
+ <div class="th"><%:Status%></div>
+ <div class="th"><%:Name%></div>
+ <div class="th"><%:Node%></div>
+ <div class="th"><%:Network%></div>
+ <div class="th"><%:Bandwith%></div>
+ <div class="th"><%:Local net%></div>
+ <div class="th"><%:Path Metric%></div>
+ <div class="th"><%:Tun Metric%></div>
+ <div class="th"><%:Rating%></div>
+ </div>
+ </div>
+ </div>
+</div>
+
+</div>
+
+<script type="text/javascript">//<![CDATA[
+ new TablePooler(5,"/cgi-bin/bmx7-info", {'$tunnels':''}, "tunnels_div", function(st){
+ var tunicon = "<%=resource%>/icons/tunnel.png";
+ var tunicon_dis = "<%=resource%>/icons/tunnel_disabled.png";
+ var applyicon = "<%=resource%>/cbi/apply.gif";
+ var res = Array();
+ for ( var k in st.tunnels ) {
+ var tunnel = st.tunnels[k];
+ var nodename = tunnel.remoteName;
+ var advnet = tunnel.advNet;
+ var status = '<img src="'+tunicon_dis+'"/>';
+ if ( tunnel.tunName != "---" ) status = '<img src="'+tunicon+'"/>';
+ if ( advnet == "0.0.0.0/0" ) advnet = "<b>Internet IPv4</b>";
+ if ( advnet == "::/0" ) advnet = "<b>Internet IPv6</b>";
+ if (nodename != "---") {
+ res.push([status, tunnel.tunName, nodename, advnet, tunnel.advBw, tunnel.net,
+ tunnel.pathMtc, tunnel.tunMtc, tunnel.rating]);
+ }
+ }
+ return res;
+ });
+//]]></script>
+
+<%+footer%>
diff --git a/luci-app-bmx7/files/www/cgi-bin/bmx7-info b/luci-app-bmx7/files/www/cgi-bin/bmx7-info
index 8c501c5..7388ed1 100755
--- a/luci-app-bmx7/files/www/cgi-bin/bmx7-info
+++ b/luci-app-bmx7/files/www/cgi-bin/bmx7-info
@@ -1,7 +1,7 @@
#!/bin/sh
# Copyright © 2011 Pau Escrich
# Contributors Jo-Philipp Wich <xm@subsignal.org>
-# Roger Pueyo Centelles <roger.pueyo@guifi.net>
+# Roger Pueyo Centelles <roger.pueyo@guifi.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -34,13 +34,12 @@ else
QUERY="${QUERY_STRING%%=*}"
echo "Content-type: application/json"
echo ""
-
fi
check_path() {
- [ -d "$1" ] && path=$(cd $1; pwd)
- [ -f "$1" ] && path=$(cd $1/..; pwd)
- [ $(echo "$path" | grep -c "^$BMX7_DIR") -ne 1 ] && exit 1
+ [ -d "$1" ] && path=$(cd $1; pwd)
+ [ -f "$1" ] && path=$(cd $1/..; pwd)
+ [ $(echo "$path" | grep -c "^$BMX7_DIR") -ne 1 ] && exit 1
}
print_mem() {
@@ -52,19 +51,19 @@ print_mem() {
print_query() {
# If the query is a directory
[ -d "$BMX7_DIR/$1" ] &&
- {
+ {
# If /all has not been specified
[ -z "$QALL" ] &&
{
total=$(ls $BMX7_DIR/$1 | wc -w)
i=1
- echo -n "{ \"$1\": [ "
- for f in $(ls $BMX7_DIR/$1); do
+ echo -n "{ \"$1\": [ "
+ for f in $(ls $BMX7_DIR/$1); do
echo -n "{ \"name\": \"$f\" }"
[ $i -lt $total ] && echo -n ','
i=$(( $i + 1 ))
- done
- echo -n " ] }"
+ done
+ echo -n " ] }"
# If /all has been specified, printing all the files together
} || {
@@ -80,10 +79,10 @@ print_query() {
done
echo -n " ]"
}
- }
+ }
# If the query is a file, just printing the file
- [ -f "$BMX7_DIR/$1" ] && cat "$BMX7_DIR/$1";
+ [ -f "$BMX7_DIR/$1" ] && [ -s "$BMX7_DIR/$1" ] && cat "$BMX7_DIR/$1" && return 0 || return 1
}
if [ "${QUERY##*/}" == "all" ]; then
@@ -95,10 +94,8 @@ if [ "$QUERY" == '$info' ]; then
echo '{ "info": [ '
print_query status
echo -n ","
- print_query interfaces
- echo -n ","
- print_query links
- echo -n ","
+ print_query interfaces && echo -n "," || echo -n '{ "interfaces": "" },'
+ print_query links && echo -n "," || echo -n '{ "links": "" },'
print_mem
echo "] }"
fi
diff --git a/luci-app-bmx7/files/www/luci-static/resources/bmx7/css/netjsongraph-theme.css b/luci-app-bmx7/files/www/luci-static/resources/bmx7/css/netjsongraph-theme.css
new file mode 100644
index 0000000..276d362
--- /dev/null
+++ b/luci-app-bmx7/files/www/luci-static/resources/bmx7/css/netjsongraph-theme.css
@@ -0,0 +1,59 @@
+.njg-overlay{
+ background: #fbfbfb;
+ border-radius: 2px;
+ border: 1px solid #ccc;
+ color: #6d6357;
+ font-family: Arial, sans-serif;
+ font-family: sans-serif;
+ font-size: 14px;
+ line-height: 20px;
+ height: auto;
+ max-width: 400px;
+ min-width: 200px;
+ padding: 0 15px;
+ right: 10px;
+ top: 10px;
+ width: auto;
+}
+
+.njg-metadata{
+ background: #fbfbfb;
+ border-radius: 2px;
+ border: 1px solid #ccc;
+ color: #6d6357;
+ display: none;
+ font-family: Arial, sans-serif;
+ font-family: sans-serif;
+ font-size: 14px;
+ height: auto;
+ left: 10px;
+ max-width: 500px;
+ min-width: 200px;
+ padding: 0 15px;
+ top: 10px;
+ width: auto;
+}
+
+.njg-node{
+ stroke-opacity: 0.5;
+ stroke-width: 7px;
+ stroke: #fff;
+}
+
+.njg-node:hover,
+.njg-node.njg-open {
+ stroke: rgba(0, 0, 0, 0.2);
+}
+
+.njg-link{
+ cursor: pointer;
+ stroke: #999;
+ stroke-width: 2;
+ stroke-opacity: 0.25;
+}
+
+.njg-link:hover,
+.njg-link.njg-open{
+ stroke-width: 4 !important;
+ stroke-opacity: 0.5;
+}
diff --git a/luci-app-bmx7/files/www/luci-static/resources/bmx7/css/netjsongraph.css b/luci-app-bmx7/files/www/luci-static/resources/bmx7/css/netjsongraph.css
new file mode 100644
index 0000000..556c520
--- /dev/null
+++ b/luci-app-bmx7/files/www/luci-static/resources/bmx7/css/netjsongraph.css
@@ -0,0 +1,62 @@
+.njg-hidden {
+ display: none !important;
+ visibility: hidden !important;
+}
+
+.njg-tooltip{
+ font-family: sans-serif;
+ font-size: 10px;
+ fill: #000;
+ opacity: 0.5;
+ text-anchor: middle;
+}
+
+.njg-overlay{
+ display: none;
+ position: absolute;
+ z-index: 11;
+}
+
+.njg-close{
+ cursor: pointer;
+ position: absolute;
+ right: 10px;
+ top: 10px;
+}
+.njg-close:before { content: "\2716"; }
+
+.njg-metadata{
+ display: none;
+ position: absolute;
+ z-index: 12;
+}
+
+.njg-node{ cursor: pointer }
+.njg-link{ cursor: pointer }
+
+#njg-select-group {
+ text-align: center;
+ box-shadow: 0 0 10px #ccc;
+ position: fixed;
+ left: 50%;
+ top: 50%;
+ width: 50%;
+ margin-top: -7.5em;
+ margin-left: -25%;
+ padding: 5em 2em;
+}
+
+#njg-select-group select {
+ font-size: 2em;
+ padding: 10px 15px;
+ width: 50%;
+ cursor: pointer;
+}
+
+#njg-select-group option {
+ padding: 0.5em;
+}
+
+#njg-select-group option[value=""] {
+ color: #aaa;
+}
diff --git a/luci-app-bmx7/files/www/luci-static/resources/bmx7/js/netjsongraph.js b/luci-app-bmx7/files/www/luci-static/resources/bmx7/js/netjsongraph.js
new file mode 100644
index 0000000..66d0a5f
--- /dev/null
+++ b/luci-app-bmx7/files/www/luci-static/resources/bmx7/js/netjsongraph.js
@@ -0,0 +1,568 @@
+// version 0.1
+(function () {
+ /**
+ * vanilla JS implementation of jQuery.extend()
+ */
+ d3._extend = function(defaults, options) {
+ var extended = {},
+ prop;
+ for(prop in defaults) {
+ if(Object.prototype.hasOwnProperty.call(defaults, prop)) {
+ extended[prop] = defaults[prop];
+ }
+ }
+ for(prop in options) {
+ if(Object.prototype.hasOwnProperty.call(options, prop)) {
+ extended[prop] = options[prop];
+ }
+ }
+ return extended;
+ };
+
+ /**
+ * @function
+ * @name d3._pxToNumber
+ * Convert strings like "10px" to 10
+ *
+ * @param {string} val The value to convert
+ * @return {int} The converted integer
+ */
+ d3._pxToNumber = function(val) {
+ return parseFloat(val.replace('px'));
+ };
+
+ /**
+ * @function
+ * @name d3._windowHeight
+ *
+ * Get window height
+ *
+ * @return {int} The window innerHeight
+ */
+ d3._windowHeight = function() {
+ return window.innerHeight || document.documentElement.clientHeight || 600;
+ };
+
+ /**
+ * @function
+ * @name d3._getPosition
+ *
+ * Get the position of `element` relative to `container`
+ *
+ * @param {object} element
+ * @param {object} container
+ */
+ d3._getPosition = function(element, container) {
+ var n = element.node(),
+ nPos = n.getBoundingClientRect();
+ cPos = container.node().getBoundingClientRect();
+ return {
+ top: nPos.top - cPos.top,
+ left: nPos.left - cPos.left,
+ width: nPos.width,
+ bottom: nPos.bottom - cPos.top,
+ height: nPos.height,
+ right: nPos.right - cPos.left
+ };
+ };
+
+ /**
+ * netjsongraph.js main function
+ *
+ * @constructor
+ * @param {string} url The NetJSON file url
+ * @param {object} opts The object with parameters to override {@link d3.netJsonGraph.opts}
+ */
+ d3.netJsonGraph = function(url, opts) {
+ /**
+ * Default options
+ *
+ * @param {string} el "body" The container element el: "body" [description]
+ * @param {bool} metadata true Display NetJSON metadata at startup?
+ * @param {bool} defaultStyle true Use css style?
+ * @param {bool} animationAtStart false Animate nodes or not on load
+ * @param {array} scaleExtent [0.25, 5] The zoom scale's allowed range. @see {@link https://github.com/mbostock/d3/wiki/Zoom-Behavior#scaleExtent}
+ * @param {int} charge -130 The charge strength to the specified value. @see {@link https://github.com/mbostock/d3/wiki/Force-Layout#charge}
+ * @param {int} linkDistance 50 The target distance between linked nodes to the specified value. @see {@link https://github.com/mbostock/d3/wiki/Force-Layout#linkDistance}
+ * @param {float} linkStrength 0.2 The strength (rigidity) of links to the specified value in the range. @see {@link https://github.com/mbostock/d3/wiki/Force-Layout#linkStrength}
+ * @param {float} friction 0.9 The friction coefficient to the specified value. @see {@link https://github.com/mbostock/d3/wiki/Force-Layout#friction}
+ * @param {string} chargeDistance Infinity The maximum distance over which charge forces are applied. @see {@link https://github.com/mbostock/d3/wiki/Force-Layout#chargeDistance}
+ * @param {float} theta 0.8 The Barnes–Hut approximation criterion to the specified value. @see {@link https://github.com/mbostock/d3/wiki/Force-Layout#theta}
+ * @param {float} gravity 0.1 The gravitational strength to the specified numerical value. @see {@link https://github.com/mbostock/d3/wiki/Force-Layout#gravity}
+ * @param {int} circleRadius 8 The radius of circles (nodes) in pixel
+ * @param {string} labelDx "0" SVG dx (distance on x axis) attribute of node labels in graph
+ * @param {string} labelDy "-1.3em" SVG dy (distance on y axis) attribute of node labels in graph
+ * @param {function} onInit Callback function executed on initialization
+ * @param {function} onLoad Callback function executed after data has been loaded
+ * @param {function} onEnd Callback function executed when initial animation is complete
+ * @param {function} linkDistanceFunc By default high density areas have longer links
+ * @param {function} redraw Called when panning and zooming
+ * @param {function} prepareData Used to convert NetJSON NetworkGraph to the javascript data
+ * @param {function} onClickNode Called when a node is clicked
+ * @param {function} onClickLink Called when a link is clicked
+ */
+ opts = d3._extend({
+ el: "body",
+ metadata: true,
+ defaultStyle: true,
+ animationAtStart: true,
+ scaleExtent: [0.25, 5],
+ charge: -130,
+ linkDistance: 50,
+ linkStrength: 0.2,
+ friction: 0.9, // d3 default
+ chargeDistance: Infinity, // d3 default
+ theta: 0.8, // d3 default
+ gravity: 0.1,
+ circleRadius: 8,
+ labelDx: "0",
+ labelDy: "-1.3em",
+ nodeClassProperty: null,
+ linkClassProperty: null,
+ /**
+ * @function
+ * @name onInit
+ *
+ * Callback function executed on initialization
+ * @param {string|object} url The netJson remote url or object
+ * @param {object} opts The object of passed arguments
+ * @return {function}
+ */
+ onInit: function(url, opts) {},
+ /**
+ * @function
+ * @name onLoad
+ *
+ * Callback function executed after data has been loaded
+ * @param {string|object} url The netJson remote url or object
+ * @param {object} opts The object of passed arguments
+ * @return {function}
+ */
+ onLoad: function(url, opts) {},
+ /**
+ * @function
+ * @name onEnd
+ *
+ * Callback function executed when initial animation is complete
+ * @param {string|object} url The netJson remote url or object
+ * @param {object} opts The object of passed arguments
+ * @return {function}
+ */
+ onEnd: function(url, opts) {},
+ /**
+ * @function
+ * @name linkDistanceFunc
+ *
+ * By default, high density areas have longer links
+ */
+ linkDistanceFunc: function(d){
+ var val = opts.linkDistance;
+ if(d.source.linkCount >= 4 && d.target.linkCount >= 4) {
+ return val * 2;
+ }
+ return val;
+ },
+ /**
+ * @function
+ * @name redraw
+ *
+ * Called on zoom and pan
+ */
+ redraw: function() {
+ panner.attr("transform",
+ "translate(" + d3.event.translate + ") " +
+ "scale(" + d3.event.scale + ")"
+ );
+ },
+ /**
+ * @function
+ * @name prepareData
+ *
+ * Convert NetJSON NetworkGraph to the data structure consumed by d3
+ *
+ * @param graph {object}
+ */
+ prepareData: function(graph) {
+ var nodesMap = {},
+ nodes = graph.nodes.slice(), // copy
+ links = graph.links.slice(), // copy
+ nodes_length = graph.nodes.length,
+ links_length = graph.links.length;
+
+ for(var i = 0; i < nodes_length; i++) {
+ // count how many links every node has
+ nodes[i].linkCount = 0;
+ nodesMap[nodes[i].id] = i;
+ }
+ for(var c = 0; c < links_length; c++) {
+ var sourceIndex = nodesMap[links[c].source],
+ targetIndex = nodesMap[links[c].target];
+ // ensure source and target exist
+ if(!nodes[sourceIndex]) { throw("source '" + links[c].source + "' not found"); }
+ if(!nodes[targetIndex]) { throw("target '" + links[c].target + "' not found"); }
+ links[c].source = nodesMap[links[c].source];
+ links[c].target = nodesMap[links[c].target];
+ // add link count to both ends
+ nodes[sourceIndex].linkCount++;
+ nodes[targetIndex].linkCount++;
+ }
+ return { "nodes": nodes, "links": links };
+ },
+ /**
+ * @function
+ * @name onClickNode
+ *
+ * Called when a node is clicked
+ */
+ onClickNode: function(n) {
+ var overlay = d3.select(".njg-overlay"),
+ overlayInner = d3.select(".njg-overlay > .njg-inner"),
+ html = "<p><b>id</b>: " + n.id + "</p>";
+ if(n.label) { html += "<p><b>label</b>: " + n.label + "</p>"; }
+ if(n.properties) {
+ for(var key in n.properties) {
+ if(!n.properties.hasOwnProperty(key)) { continue; }
+ html += "<p><b>"+key.replace(/_/g, " ")+"</b>: " + n.properties[key] + "</p>";
+ }
+ }
+ if(n.linkCount) { html += "<p><b>links</b>: " + n.linkCount + "</p>"; }
+ if(n.local_addresses) {
+ html += "<p><b>local addresses</b>:<br>" + n.local_addresses.join('<br>') + "</p>";
+ }
+ overlayInner.html(html);
+ overlay.classed("njg-hidden", false);
+ overlay.style("display", "block");
+ // set "open" class to current node
+ removeOpenClass();
+ d3.select(this).classed("njg-open", true);
+ },
+ /**
+ * @function
+ * @name onClickLink
+ *
+ * Called when a node is clicked
+ */
+ onClickLink: function(l) {
+ var overlay = d3.select(".njg-overlay"),
+ overlayInner = d3.select(".njg-overlay > .njg-inner"),
+ html = "<p><b>source</b>: " + (l.source.label || l.source.id) + "</p>";
+ html += "<p><b>target</b>: " + (l.target.label || l.target.id) + "</p>";
+ html += "<p><b>cost</b>: " + l.cost + "</p>";
+ if(l.properties) {
+ for(var key in l.properties) {
+ if(!l.properties.hasOwnProperty(key)) { continue; }
+ html += "<p><b>"+ key.replace(/_/g, " ") +"</b>: " + l.properties[key] + "</p>";
+ }
+ }
+ overlayInner.html(html);
+ overlay.classed("njg-hidden", false);
+ overlay.style("display", "block");
+ // set "open" class to current link
+ removeOpenClass();
+ d3.select(this).classed("njg-open", true);
+ }
+ }, opts);
+
+ // init callback
+ opts.onInit(url, opts);
+
+ if(!opts.animationAtStart) {
+ opts.linkStrength = 2;
+ opts.friction = 0.3;
+ opts.gravity = 0;
+ }
+ if(opts.el == "body") {
+ var body = d3.select(opts.el),
+ rect = body.node().getBoundingClientRect();
+ if (d3._pxToNumber(d3.select("body").style("height")) < 60) {
+ body.style("height", d3._windowHeight() - rect.top - rect.bottom + "px");
+ }
+ }
+ var el = d3.select(opts.el).style("position", "relative"),
+ width = d3._pxToNumber(el.style('width')),
+ height = d3._pxToNumber(el.style('height')),
+ force = d3.layout.force()
+ .charge(opts.charge)
+ .linkStrength(opts.linkStrength)
+ .linkDistance(opts.linkDistanceFunc)
+ .friction(opts.friction)
+ .chargeDistance(opts.chargeDistance)
+ .theta(opts.theta)
+ .gravity(opts.gravity)
+ // width is easy to get, if height is 0 take the height of the body
+ .size([width, height]),
+ zoom = d3.behavior.zoom().scaleExtent(opts.scaleExtent),
+ // panner is the element that allows zooming and panning
+ panner = el.append("svg")
+ .attr("width", width)
+ .attr("height", height)
+ .call(zoom.on("zoom", opts.redraw))
+ .append("g")
+ .style("position", "absolute"),
+ svg = d3.select(opts.el + " svg"),
+ drag = force.drag(),
+ overlay = d3.select(opts.el).append("div").attr("class", "njg-overlay"),
+ closeOverlay = overlay.append("a").attr("class", "njg-close"),
+ overlayInner = overlay.append("div").attr("class", "njg-inner"),
+ metadata = d3.select(opts.el).append("div").attr("class", "njg-metadata"),
+ metadataInner = metadata.append("div").attr("class", "njg-inner"),
+ closeMetadata = metadata.append("a").attr("class", "njg-close"),
+ // container of ungrouped networks
+ str = [],
+ selected = [],
+ /**
+ * @function
+ * @name removeOpenClass
+ *
+ * Remove open classes from nodes and links
+ */
+ removeOpenClass = function () {
+ d3.selectAll("svg .njg-open").classed("njg-open", false);
+ };
+ processJson = function(graph) {
+ /**
+ * Init netJsonGraph
+ */
+ init = function(url, opts) {
+ d3.netJsonGraph(url, opts);
+ };
+ /**
+ * Remove all instances
+ */
+ destroy = function() {
+ force.stop();
+ d3.select("#selectGroup").remove();
+ d3.select(".njg-overlay").remove();
+ d3.select(".njg-metadata").remove();
+ overlay.remove();
+ overlayInner.remove();
+ metadata.remove();
+ svg.remove();
+ node.remove();
+ link.remove();
+ nodes = [];
+ links = [];
+ };
+ /**
+ * Destroy and e-init all instances
+ * @return {[type]} [description]
+ */
+ reInit = function() {
+ destroy();
+ init(url, opts);
+ };
+
+ var data = opts.prepareData(graph),
+ links = data.links,
+ nodes = data.nodes;
+
+ // disable some transitions while dragging
+ drag.on('dragstart', function(n){
+ d3.event.sourceEvent.stopPropagation();
+ zoom.on('zoom', null);
+ })
+ // re-enable transitions when dragging stops
+ .on('dragend', function(n){
+ zoom.on('zoom', opts.redraw);
+ })
+ .on("drag", function(d) {
+ // avoid pan & drag conflict
+ d3.select(this).attr("x", d.x = d3.event.x).attr("y", d.y = d3.event.y);
+ });
+
+ force.nodes(nodes).links(links).start();
+
+ var link = panner.selectAll(".link")
+ .data(links)
+ .enter().append("line")
+ .attr("class", function (link) {
+ var baseClass = "njg-link",
+ addClass = null;
+ value = link.properties && link.properties[opts.linkClassProperty];
+ if (opts.linkClassProperty && value) {
+ // if value is stirng use that as class
+ if (typeof(value) === "string") {
+ addClass = value;
+ }
+ else if (typeof(value) === "number") {
+ addClass = opts.linkClassProperty + value;
+ }
+ else if (value === true) {
+ addClass = opts.linkClassProperty;
+ }
+ return baseClass + " " + addClass;
+ }
+ return baseClass;
+ })
+ .on("click", opts.onClickLink),
+ groups = panner.selectAll(".node")
+ .data(nodes)
+ .enter()
+ .append("g");
+ node = groups.append("circle")
+ .attr("class", function (node) {
+ var baseClass = "njg-node",
+ addClass = null;
+ value = node.properties && node.properties[opts.nodeClassProperty];
+ if (opts.nodeClassProperty && value) {
+ // if value is stirng use that as class
+ if (typeof(value) === "string") {
+ addClass = value;
+ }
+ else if (typeof(value) === "number") {
+ addClass = opts.nodeClassProperty + value;
+ }
+ else if (value === true) {
+ addClass = opts.nodeClassProperty;
+ }
+ return baseClass + " " + addClass;
+ }
+ return baseClass;
+ })
+ .attr("r", opts.circleRadius)
+ .on("click", opts.onClickNode)
+ .call(drag);
+
+ var labels = groups.append('text')
+ .text(function(n){ return n.label || n.id })
+ .attr('dx', opts.labelDx)
+ .attr('dy', opts.labelDy)
+ .attr('class', 'njg-tooltip');
+
+ // Close overlay
+ closeOverlay.on("click", function() {
+ removeOpenClass();
+ overlay.classed("njg-hidden", true);
+ });
+ // Close Metadata panel
+ closeMetadata.on("click", function() {
+ // Reinitialize the page
+ if(graph.type === "NetworkCollection") {
+ reInit();
+ }
+ else {
+ removeOpenClass();
+ metadata.classed("njg-hidden", true);
+ }
+ });
+ // default style
+ // TODO: probably change defaultStyle
+ // into something else
+ if(opts.defaultStyle) {
+ var colors = d3.scale.category20c();
+ node.style({
+ "fill": function(d){ return colors(d.linkCount); },
+ "cursor": "pointer"
+ });
+ }
+ // Metadata style
+ if(opts.metadata) {
+ metadata.attr("class", "njg-metadata").style("display", "block");
+ }
+
+ var attrs = ["protocol",
+ "version",
+ "revision",
+ "metric",
+ "router_id",
+ "topology_id"],
+ html = "";
+ if(graph.label) {
+ html += "<h3>" + graph.label + "</h3>";
+ }
+ for(var i in attrs) {
+ var attr = attrs[i];
+ if(graph[attr]) {
+ html += "<p><b>" + attr + "</b>: <span>" + graph[attr] + "</span></p>";
+ }
+ }
+ // Add nodes and links count
+ html += "<p><b>nodes</b>: <span>" + graph.nodes.length + "</span></p>";
+ html += "<p><b>links</b>: <span>" + graph.links.length + "</span></p>";
+ metadataInner.html(html);
+ metadata.classed("njg-hidden", false);
+
+ // onLoad callback
+ opts.onLoad(url, opts);
+
+ force.on("tick", function() {
+ link.attr("x1", function(d) {
+ return d.source.x;
+ })
+ .attr("y1", function(d) {
+ return d.source.y;
+ })
+ .attr("x2", function(d) {
+ return d.target.x;
+ })
+ .attr("y2", function(d) {
+ return d.target.y;
+ });
+
+ node.attr("cx", function(d) {
+ return d.x;
+ })
+ .attr("cy", function(d) {
+ return d.y;
+ });
+
+ labels.attr("transform", function(d) {
+ return "translate(" + d.x + "," + d.y + ")";
+ });
+ })
+ .on("end", function(){
+ force.stop();
+ // onEnd callback
+ opts.onEnd(url, opts);
+ });
+
+ return force;
+ };
+
+ if(typeof(url) === "object") {
+ processJson(url);
+ }
+ else {
+ /**
+ * Parse the provided json file
+ * and call processJson() function
+ *
+ * @param {string} url The provided json file
+ * @param {function} error
+ */
+ d3.json(url, function(error, graph) {
+ if(error) { throw error; }
+ /**
+ * Check if the json contains a NetworkCollection
+ */
+ if(graph.type === "NetworkCollection") {
+ var selectGroup = body.append("div").attr("id", "njg-select-group"),
+ select = selectGroup.append("select")
+ .attr("id", "select");
+ str = graph;
+ select.append("option")
+ .attr({
+ "value": "",
+ "selected": "selected",
+ "name": "default",
+ "disabled": "disabled"
+ })
+ .html("Choose the network to display");
+ graph.collection.forEach(function(structure) {
+ select.append("option").attr("value", structure.type).html(structure.type);
+ // Collect each network json structure
+ selected[structure.type] = structure;
+ });
+ select.on("change", function() {
+ selectGroup.attr("class", "njg-hidden");
+ // Call selected json structure
+ processJson(selected[this.options[this.selectedIndex].value]);
+ });
+ }
+ else {
+ processJson(graph);
+ }
+ });
+ }
+ };
+})();
diff --git a/luci-app-bmx7/files/www/luci-static/resources/bmx7/js/polling.js b/luci-app-bmx7/files/www/luci-static/resources/bmx7/js/polling.js
index 4a382eb..234391a 100644
--- a/luci-app-bmx7/files/www/luci-static/resources/bmx7/js/polling.js
+++ b/luci-app-bmx7/files/www/luci-static/resources/bmx7/js/polling.js
@@ -41,35 +41,41 @@
In the code st is the data obtained from the json call
*/
-function TablePooler (time, jsonurl, getparams, table_id, callback) {
- this.table = document.getElementById(table_id);
+function TablePooler (time, jsonurl, getparams, div_id, callback) {
+ this.div_id = div_id;
+ this.div = document.getElementById(div_id);
this.callback = callback;
this.jsonurl = jsonurl;
this.getparams = getparams;
this.time = time;
- /* clear all rows */
- this.clear = function(){
- while( this.table.rows.length > 1 ) this.table.deleteRow(1);
- }
-
this.start = function(){
XHR.poll(this.time, this.jsonurl, this.getparams, function(x, st){
var data = this.callback(st);
- var content, tr, td;
- this.clear();
+ var content;
for (var i = 0; i < data.length; i++){
- tr = this.table.insertRow(-1);
- tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
-
+ rowId = "trDiv_" + this.div_id + i;
+ rowDiv = document.getElementById(rowId);
+ if (rowDiv === null) {
+ rowDiv = document.createElement("div");
+ rowDiv.id = rowId;
+ rowDiv.className = "tr";
+ this.div.appendChild(rowDiv);
+ }
for (var j = 0; j < data[i].length; j++){
- td = tr.insertCell(-1);
- if (data[i][j].length == 2) {
- td.colSpan = data[i][j][1];
- content = data[i][j][0];
+ cellId = "tdDiv_" + this.div_id + i + j;
+ cellDiv = document.getElementById(cellId);
+ if (cellDiv === null) {
+ cellDiv = document.createElement("div");
+ cellDiv.id = cellId;
+ cellDiv.className = "td";
+ rowDiv.appendChild(cellDiv);
+ }
+ if (typeof data[i][j] !== 'undefined' && data[i][j].length == 2) {
+ content = data[i][j][0] + "/" + data[i][j][1];
}
else content = data[i][j];
- td.innerHTML = content;
+ cellDiv.innerHTML = content;
}
}
}.bind(this));