Added ADSL stats page to luci2 gui

This commit is contained in:
Martin Schröder 2015-04-15 13:18:08 +02:00 committed by Martin Schröder
parent 4d8c2d1214
commit d6dd3bec0c
8 changed files with 212 additions and 7 deletions

View file

@ -15,7 +15,7 @@
<script type="text/javascript" src="/luci2/jquery.peity.js"></script>
<script type="text/javascript" src="/luci2/bootstrap.js"></script>
<script type="text/javascript" src="/luci2/luci2.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
@ -28,8 +28,12 @@
});
});
</script>
<!-- not using angular right now. maybe later. -->
<!--<script type="text/javascript" src="/luci2/angular.js"></script>
<script type="text/javascript" src="/luci2/angular.app.js"></script>-->
</head>
<body>
<body >
<div class="navbar navbar-inverse navbar-fixed-top" role="banner">
<div class="container">
<div class="navbar-header">
@ -46,7 +50,7 @@
<div id="viewmenu"></div>
<div id="maincontent" class="container">
<div id="maincontent" class="container" luci2dynamic ng-app="inteno" ng-controller="dslstats">
</div>
<!--

View file

@ -0,0 +1,74 @@
<div id="dslstats">
<legend><span translate>DSL Connection</span></legend>
<table class="table table-condensed table-hover">
<tr>
<td class="col-md-6"><span ng-model="dslstats.ip"></span></td>
<td class="col-md-6"><span ng-model="dslstats.ipstate"></span></td>
</tr>
</table>
<legend><span translate>DSL Mode</span></legend>
<table class="table table-condensed table-hover">
<tr>
<td class="col-md-6"><span ng-model="dslstats.mode"></span></td>
<td class="col-md-6"><span ng-model="dslstats.mode_details"></span></td>
</tr>
</table>
<legend><span translate>DSL Status Information</span></legend>
<table class="table table-condensed table-hover">
<thead>
<tr>
<th class="col-md-4"></th>
<th class="col-md-4"><span translate>Configured</span></th>
<th class="col-md-4"><span translate>Current</span></th>
</tr>
</thead>
<tr><td><span translate>Line Status</span></td><td><span ng-model="dslstats.line_status_configured"></span></td><td><span ng-model="dslstats.status"></span></td></tr>
<tr><td><span translate>Link Type</span></td><td><span ng-model="dslstats.line_type_configured"></span></td><td><span ng-model="dslstats.line_type"></span></td></tr>
</table>
<legend><span translate>Bit Rate</span></legend>
<table class="table table-condensed table-hover">
<thead>
<tr>
<th class="col-md-4"></th>
<th class="col-md-4"><span translate>Downstream</span></th>
<th class="col-md-4"><span translate>Upstream</span></th>
</tr>
</thead>
<tr><td><span translate>Actual Data Rate</span></td><td><span ng-model="dslstats.bearers[0].rate_down"></span> (Kbps.)</td><td><span ng-model="dslstats.bearers[0].rate_up"></span> (Kbps.)</td></tr>
</table>
<legend><span translate>Operating Data</span></legend>
<table class="table table-condensed table-hover">
<thead>
<tr>
<th class="col-md-4"></th>
<th class="col-md-4"><span translate>Downstream</span></th>
<th class="col-md-4"><span translate>Upstream</span></th>
</tr>
</thead>
<tr><td><span translate>SNR Margin</span></td><td><span ng-model="dslstats.snr_down"></span> dB</td><td><span ng-model="dslstats.snr_up"></span> dB</td></tr>
<tr><td><span translate>Loop Attenuation</span></td><td><span ng-model="dslstats.attn_down"></span> dB</td><td><span ng-model="dslstats.attn_up"></span> dB</td></tr>
</table>
<legend><span translate>Error Counter</span></legend>
<table class="table table-condensed table-hover">
<thead>
<tr>
<th class="col-md-4"><span translate>Indicator Name</span></th>
<th class="col-md-4"><span translate>Downstream</span></th>
<th class="col-md-4"><span translate>Upstream</span></th>
</tr>
</thead>
<tr><td><span translate>FEC Corrections</span></td><td><span ng-model="dslstats.counters.totals.fec_down"></span></td><td><span ng-model="dslstats.counters.totals.fec_up"></span></td></tr>
<tr><td><span translate>CRC Errors</span></td><td><span ng-model="dslstats.counters.totals.crc_down"></span></td><td><span ng-model="dslstats.counters.totals.crc_up"></span></td></tr>
</table>
<legend><span translate>Statistics</span></legend>
<table class="table table-condensed table-hover">
<thead>
<tr>
<th class="col-md-4"></th>
<th class="col-md-4"><span translate>Transmitted Cells</span></th>
<th class="col-md-4"><span translate>Received Cells</span></th>
</tr>
</thead>
<tr><td><span translate>Cell Counter</span></td><td><span ng-model="dslstats.bearers[0].total_cells_down"></span></td><td><span ng-model="dslstats.bearers[0].total_cells_up"></span></td></tr>
</table>
</div>

View file

@ -0,0 +1,66 @@
L.ui.view.extend({
title: L.tr('ADSL Status'),
description: L.tr('Router ADSL status.'),
getDSLStatus: L.rpc.declare({
object: 'luci2.network',
method: 'dslstats',
expect: { data: '' }
}),
execute: function() {
return this.getDSLStatus().then(function(data){
var dslstats = {};
try { dslstats = JSON.parse(data); } catch(e){}
// todo fields
with({dslstats: dslstats.dslstats}){
dslstats.ip = "TODO";
dslstats.ipstate = "TODO";
dslstats.mode_details = "TODO";
dslstats.line_status_configured = "TODO";
dslstats.line_type_configured = "TODO";
dslstats.line_type = "TODO";
}
// compute floating point values (because ubus blobs do not support floats yet)
function reconstruct_floats(obj) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
reconstruct_floats(obj[property]);
} else {
var matches = property.match(/(.*)_x([\d]*)/);
if(matches && matches.length == 3){
try {
obj[matches[1]] = parseFloat(String(obj[property])) / parseFloat(matches[2]);
} catch(e) {
obj[matches[1]] = "Err";
}
}
}
}
}
}
reconstruct_floats(dslstats);
// translate labels
$("*[translate]").each(function(){
$(this).html(L.tr($(this).html()));
});
// update the view
$("span").each(function(){
var model = $(this).attr("ng-model");
try {
if(model) {
with({dslstats: dslstats.dslstats}) {
$(this).html(eval(model));
}
}
} catch(e) {}
});
});
}
});

View file

@ -51,7 +51,8 @@
"dhcp6_leases",
"arp_table",
"routes",
"routes6"
"routes6",
"dslstats"
],
"luci2.system": [
"diskfree",
@ -325,7 +326,8 @@
"switch_list",
"switch_info",
"switch_status",
"device_list"
"device_list",
"dslstats"
],
"luci2.network.bwmon": [
"devices",

View file

@ -32,5 +32,11 @@
"acls": [ "status" ],
"view": "status/processes",
"index": 50
}
},
"status/dsl": {
"title": "ADSL Status",
"acls": [ "status" ],
"view": "status/dsl",
"index": 60
}
}

View file

@ -1118,6 +1118,34 @@ backup_finish_list(struct blob_buf *blob, int status, void *priv)
return UBUS_STATUS_OK;
}
static int rpc_run_command(struct ubus_context *ctx, struct ubus_request_data *req, const char *cmd){
FILE *fd;
int buffer_size = 4096;
char *data = malloc(buffer_size);
char *pdata = data;
int c;
blob_buf_init(&buf, 0);
if ((fd = popen("ubus call router dslstats", "r"))) {
while((c = fgetc(fd)) != EOF){
*pdata = c;
pdata++;
if(pdata == (data + buffer_size)){
size_t size = buffer_size;
buffer_size += 4096;
data = realloc(data, buffer_size);
pdata = data + size;
}
}
pclose(fd);
}
blobmsg_add_string(&buf, "data", data);
free(data);
ubus_send_reply(ctx, req, buf.head);
return 0;
}
static int
rpc_luci2_backup_list(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
@ -1814,6 +1842,14 @@ rpc_luci2_network_sw_list(struct ubus_context *ctx, struct ubus_object *obj,
state, ctx, req);
}
static int
rpc_luci2_network_dslstats(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
return rpc_run_command(ctx, req, "ubus call router dslstats");
}
static int
swconfig_parse_help(struct blob_buf *blob, char *buf, int len, void *priv)
@ -2808,6 +2844,7 @@ rpc_luci2_api_init(const struct rpc_daemon_ops *o, struct ubus_context *ctx)
UBUS_METHOD_NOARG("routes", rpc_luci2_network_routes),
UBUS_METHOD_NOARG("routes6", rpc_luci2_network_routes6),
UBUS_METHOD_NOARG("switch_list", rpc_luci2_network_sw_list),
UBUS_METHOD_NOARG("dslstats", rpc_luci2_network_dslstats),
UBUS_METHOD("switch_info", rpc_luci2_network_sw_info,
rpc_switch_policy),
UBUS_METHOD("switch_status", rpc_luci2_network_sw_status,

View file

@ -103,7 +103,8 @@ void dslstats_load(struct dsl_stats *self){
else self->trellis.up = 0;
}
}
else if(strstr(name, "Status") == name) self->status = strdup(arg1);
else if(strstr(name, "Training Status") == name) self->status = strdup(arg1);
else if(strstr(name, "Line Status") == name) self->line_status = strdup(arg1);
else if(strstr(name, "Bearer") == name){
unsigned long id, up, down, ret;
if((ret = sscanf(arg1, "%d, Upstream rate = %lu Kbps, Downstream rate = %lu Kbps", &id, &up, &down)) == 3){
@ -229,6 +230,14 @@ void dslstats_load(struct dsl_stats *self){
counters->uas.down = atoll(arg1);
counters->uas.up = atoll(arg2);
}
else if(strstr(name, "FEC:") == name){
counters->fec.down = atoll(arg1);
counters->fec.up = atoll(arg2);
}
else if(strstr(name, "CRC:") == name){
counters->crc.down = atoll(arg1);
counters->crc.up = atoll(arg2);
}
DSLDEBUG("PARSED: name:%s, arg1:%s, arg2:%s\n", name, arg1, arg2);
} break;
default: {
@ -325,6 +334,7 @@ void dslstats_to_blob_buffer(struct dsl_stats *self, struct blob_buf *b){
blobmsg_add_string(b, "traffic", self->traffic);
blobmsg_add_string(b, "status", self->status);
blobmsg_add_string(b, "link_power_state", self->link_power_state);
blobmsg_add_string(b, "line_status", self->line_status);
blobmsg_add_u8(b, "trellis_up", self->trellis.up);
blobmsg_add_u8(b, "trellis_down", self->trellis.down);
blobmsg_add_u32(b, "snr_up_x100", self->snr.up * 100);
@ -390,6 +400,10 @@ void dslstats_to_blob_buffer(struct dsl_stats *self, struct blob_buf *b){
//counter = &self->counters[DSLSTATS_COUNTER_TOTALS];
array = blobmsg_open_table(b, "counters");
obj = blobmsg_open_table(b, "totals");
blobmsg_add_u64(b, "fec_down", counter->fec.down);
blobmsg_add_u64(b, "fec_up", counter->fec.up);
blobmsg_add_u64(b, "crc_down", counter->crc.down);
blobmsg_add_u64(b, "crc_up", counter->crc.up);
blobmsg_add_u64(b, "es_down", counter->es.down);
blobmsg_add_u64(b, "es_up", counter->es.up);
blobmsg_add_u64(b, "ses_down", counter->ses.down);

View file

@ -52,6 +52,7 @@ typedef struct dsl_bearer {
typedef struct dsl_counters {
UpDown es, ses, uas;
UpDown fec, crc;
} DSLCounters;
typedef struct dsl_stats {
@ -59,6 +60,7 @@ typedef struct dsl_stats {
char *traffic;
char *status;
char *link_power_state;
char *line_status;
char *vdsl2_profile;
UpDown trellis;
UpDown snr;