diff --git a/cmd_parser.c b/cmd_parser.c index 21137a5..fc98f1a 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -273,8 +273,37 @@ void parse_mirror(void) __xdata uint16_t rx_pmask = 0; __xdata uint16_t tx_pmask = 0; + if (cmd_words_b[1] > 0 && cmd_compare(1, "status")) { + reg_read_m(RTL837x_MIRROR_CTRL); + uint8_t mPort = sfr_data[3]; + if (mPort & 1) { + print_string("Enabled: "); + } else { + print_string("NOT Enabled: "); + } + print_string("Mirroring port: "); + if (!isRTL8373) + write_char('0' + log_to_phys_port[mPort >> 1]); + else + write_char('0' + (mPort >> 1) + 1); + reg_read_m(RTL837x_MIRROR_CONF); + uint16_t m = sfr_data[0]; + m = (m << 8) | sfr_data[1]; + print_string(", Port mask RX: "); + print_short(m); + m = sfr_data[2]; + m = (m << 8) | sfr_data[3]; + print_string(", Port mask TX: "); + print_short(m); + write_char('\n'); + return; + } else if (cmd_words_b[1] > 0 && cmd_compare(1, "off")) { + port_mirror_del(); + return; + } + if (!isnumber(cmd_buffer[cmd_words_b[1]])) { - print_string("Port missing: port [port][t/r]..."); + print_string("Port missing: mirror [port][t/r]..."); return; } diff --git a/html/eee.html b/html/eee.html index 5e2eb5e..d7c78c8 100644 --- a/html/eee.html +++ b/html/eee.html @@ -3,7 +3,7 @@ - FreeSwitchOS Port Statistics + EEE Configuration @@ -15,8 +15,8 @@

EEE Status

Port 2.5G 1G 100M 2.5G 1G 100M Active?
- - + +
diff --git a/html/mirror.html b/html/mirror.html new file mode 100644 index 0000000..1fba4e9 --- /dev/null +++ b/html/mirror.html @@ -0,0 +1,27 @@ + + + + + + Mirror Configuration + + + +
+
+

Mirror Configuration

+
+ +

Mirrored Ports (TX)

+
+
+

Mirrored Ports (RX)

+
+
+ + + +
+ + + diff --git a/html/mirror.js b/html/mirror.js new file mode 100644 index 0000000..b536405 --- /dev/null +++ b/html/mirror.js @@ -0,0 +1,59 @@ +var mirrorInterval = Number(); +const mirrors = ["mPortsTX", "mPortsRX"]; + +function mirrorForm() { + if (!numPorts) + return; + clearInterval(mirrorInterval); + for (let j=0; j < mirrors.length; j++) { + console.log("Adding Mirror " + j) + var m = document.getElementById(mirrors[j]); + for (let i = 1; i <= numPorts; i++) { + const d = document.createElement("div"); + d.classList.add("cbgroup"); + const l = document.createElement("label"); + l.innerHTML = "" + i; + l.classList.add("cbgroup"); + const inp = document.createElement("input"); + inp.type = "checkbox"; inp.setAttribute("class","psel"); + inp.id = mirrors[j] + i; + const o = document.createElement("img"); + if (pIsSFP[i - 1]) { + o.src = "sfp.svg"; o.width ="60"; o.height ="60"; + } else { + o.src = "port.svg"; o.width = "40"; o.height = "40"; + } + l.appendChild(inp); l.appendChild(o); + d.appendChild(l) + m.appendChild(d); + } + } + fetchMirror(); +} + +function setM(p, c){ + document.getElementById(p).checked=c; +} +window.addEventListener("load", function() { + mirrorInterval = setInterval(mirrorForm, 200); +}); + +function fetchMirror() { + var xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + const s = JSON.parse(xhttp.responseText); + console.log("MIRROR: ", JSON.stringify(s)); + document.getElementById('me').checked = s.enabled; + document.getElementById('mp').value = s.mPort; + let m_tx = parseInt(s.mirror_tx, 2); + let m_rx = parseInt(s.mirror_rx, 2); + for (let i = 1; i <= numPorts; i++) { + setM("mPortsTX"+i, m_tx&1); setM("mPortsRX"+i, m_rx&1); + m_tx = m_tx >> 1; m_rx = m_tx >> 1; + } + } + }; + xhttp.open("GET", `/mirror.json`, true); + xhttp.send(); +} diff --git a/html/mirror_sub.js b/html/mirror_sub.js new file mode 100644 index 0000000..7d8c0bb --- /dev/null +++ b/html/mirror_sub.js @@ -0,0 +1,43 @@ +async function mirrorSub() { + var cmd = "mirror "; + var mp=document.getElementById('mp').value + if (!mp) { + alert("Set Mirroring Port first"); + return; + } + document.getElementById(mirrors[0]+mp).checked=false;document.getElementById(mirrors[1]+mp).checked=false; + cmd = cmd + mp; + for (let i = 1; i <= numPorts; i++) { + if (document.getElementById(mirrors[0] + i).checked && document.getElementById(mirrors[1] + i).checked) + cmd = cmd + ` ${i}`; + else if (document.getElementById(mirrors[0] + i).checked) + cmd = cmd + ` ${i}t`; + else if (document.getElementById(mirrors[1] + i).checked) + cmd = cmd + ` ${i}r`; + } + if (cmd.length < 10) { + alert("Select Mirrored Ports"); + return; + } + try { + const response = await fetch('/cmd', { + method: 'POST', + body: cmd + }); + console.log('Completed!', response); + } catch(err) { + console.error(`Error: ${err}`); + } +} +async function mirrorDel() { + var cmd = "mirror off"; +try { + const response = await fetch('/cmd', { + method: 'POST', + body: cmd + }); + location.reload(); + } catch(err) { + console.error(`Error: ${err}`); + } +} diff --git a/html/style.css b/html/style.css index 0805ce9..b1cdecc 100644 --- a/html/style.css +++ b/html/style.css @@ -42,20 +42,19 @@ input[type=submit] { padding: 8px 16px;background-color:#aaf;color:#000; margin- input[type=submit]:hover { background-color: #226; color: white;} button {padding: 8px; background-color:#99f; color:#000;} button:hover { background-color: #226; color: white;} - -[type=checkbox] { +.psel { position: absolute; opacity: 0; width: 0; height: 0; margin-top: 1em; } -[type=checkbox] + img { +.psel + img { cursor: pointer; opacity: 0.4; padding: 8px; } -[type=checkbox]:checked + img { +.psel:checked + img { /* outline: 2px solid #f00;*/ opacity: 1.0; } @@ -74,3 +73,4 @@ object { .isSFP{ opacity: .4; background-color: #660;} .isNOK{ color: #900;} .isOK{ color: #090;} +.action{padding: 8px 16px;margin-top: 2em;margin-right: 3em; background-color: #aaf;color: #000;} diff --git a/html/vlan.html b/html/vlan.html index 27a40d1..8bc66f9 100644 --- a/html/vlan.html +++ b/html/vlan.html @@ -25,7 +25,7 @@

Tagged Ports

Untagged Ports

-
+
diff --git a/html/vlan.js b/html/vlan.js index 4377173..a6b0f9b 100644 --- a/html/vlan.js +++ b/html/vlan.js @@ -13,7 +13,7 @@ function vlanForm() { l.innerHTML = "" + i; l.classList.add("cbgroup"); const inp = document.createElement("input"); - inp.type = "checkbox"; + inp.type = "checkbox"; inp.setAttribute("class","psel"); inp.id = "tport" + i; inp.setAttribute('onclick', `setC("u", ${i}, false);`); const o = document.createElement("img"); diff --git a/httpd/httpd.c b/httpd/httpd.c index f6ae1a5..fb4d81a 100644 --- a/httpd/httpd.c +++ b/httpd/httpd.c @@ -441,6 +441,8 @@ void httpd_appcall(void) send_counters(q[19]-'0'); } else if (is_word(q, "/eee.json")) { send_eee(); + } else if (is_word(q, "/mirror.json")) { + send_mirror(); } else { send_not_found(); } diff --git a/httpd/page_impl.c b/httpd/page_impl.c index a7fcc35..b51ee21 100644 --- a/httpd/page_impl.c +++ b/httpd/page_impl.c @@ -217,7 +217,45 @@ void send_counters(char port) } -void send_eee() +void send_mirror(void) +{ + print_string("send_eee called\n"); + slen = strtox(outbuf, HTTP_RESPONCE_JSON); + print_string("sending EEE status\n"); + + reg_read_m(RTL837x_MIRROR_CTRL); + uint8_t mPort = sfr_data[3]; + if (mPort & 1) { + slen += strtox(outbuf + slen, "{\"enabled\":1,\"mPort\":"); + } else { + slen += strtox(outbuf + slen, "{\"enabled\":0,\"mPort\":"); + } + if (!isRTL8373) + itoa_html(log_to_phys_port[mPort >> 1]); + else + itoa_html((mPort >> 1) + 1); + + reg_read_m(RTL837x_MIRROR_CONF); + uint16_t m = sfr_data[0]; + m = (m << 8) | sfr_data[1]; + slen += strtox(outbuf + slen, ",\"mirror_rx\":\""); + for (uint8_t i = 0; i < 16; i++) { + bool_to_html(m & 0x8000); + m <<= 1; + } + m = sfr_data[2]; + m = (m << 8) | sfr_data[3]; + slen += strtox(outbuf + slen, "\",\"mirror_tx\":\""); + for (uint8_t i = 0; i < 16; i++) { + bool_to_html(m & 0x8000); + m <<= 1; + } + char_to_html('\"'); + char_to_html('}'); +} + + +void send_eee(void) { print_string("send_eee called\nsending EEE status\n"); slen = strtox(outbuf, HTTP_RESPONCE_JSON); diff --git a/httpd/page_impl.h b/httpd/page_impl.h index 9403023..9692989 100644 --- a/httpd/page_impl.h +++ b/httpd/page_impl.h @@ -6,5 +6,6 @@ void send_status(void); void send_vlan(register uint16_t vlan); void send_basic_info(void); void send_eee(void); +void send_mirror(void); #endif diff --git a/tools/httpd_sim.c b/tools/httpd_sim.c index 424921c..eb3a38c 100644 --- a/tools/httpd_sim.c +++ b/tools/httpd_sim.c @@ -146,9 +146,6 @@ void send_eee(int s) char *header = "HTTP/1.1 200 OK\r\n" "Content-Type: application/json; charset=UTF-8\r\n\r\n"; - time_t now = time(NULL); - now = last_called ? last_called + 1 : now; // Make sure we don't divide by 0 for rates - ports = json_object_new_array_ext(PORTS); for (int i = 1; i <= PORTS; i++) { v = json_object_new_object(); @@ -166,13 +163,41 @@ void send_eee(int s) json_object_object_add(v, "active", json_object_new_int((i % 2) ? 1 : 0)); json_object_array_add(ports, v); } - last_called = now; write(s, header, strlen(header)); jstring = json_object_to_json_string_ext(ports, JSON_C_TO_STRING_PLAIN); write(s, jstring, strlen(jstring)); - json_object_put(v); + json_object_put(ports); +} + + +void send_mirror(int s) +{ + uint16_t mirror_tx, mirror_rx = 0; + char mirror_tx_buf[20]; + char mirror_rx_buf[20]; + struct json_object *mirror; + const char *jstring; + char *header = "HTTP/1.1 200 OK\r\n" + "Content-Type: application/json; charset=UTF-8\r\n\r\n"; + + mirror = json_object_new_object(); + json_object_object_add(mirror, "mPort", json_object_new_int(1)); + json_object_object_add(mirror, "enabled", json_object_new_int(1)); + + mirror_tx = 0b000110; + mirror_rx = 0b000010; + sprintf(mirror_tx_buf, "%016b", mirror_tx); + sprintf(mirror_rx_buf, "%016b", mirror_rx); + json_object_object_add(mirror, "mirror_tx", json_object_new_string(mirror_tx_buf)); + json_object_object_add(mirror, "mirror_rx", json_object_new_string(mirror_rx_buf)); + + write(s, header, strlen(header)); + + jstring = json_object_to_json_string_ext(mirror, JSON_C_TO_STRING_PLAIN); + write(s, jstring, strlen(jstring)); + json_object_put(mirror); } @@ -303,6 +328,11 @@ void launch(struct Server *server) send_basic_info(new_socket); goto done; } + if (!strncmp(&buffer[4], "/mirror.json", 12)) { + printf("Mirror request\n"); + send_mirror(new_socket); + goto done; + } if (!strncmp(&buffer[4], "/vlan.json?vid=", 15)) { int vlan = atoi(&buffer[19]); printf("VLAN request for %d\n", vlan);