1182 lines
31 KiB
HTML
1182 lines
31 KiB
HTML
<%+header%>
|
|
<script>
|
|
class ModemConfig {
|
|
constructor(cfg_id,title){
|
|
this.cfg_id = cfg_id;
|
|
this.init_view = false;
|
|
this.cbi_map = document.querySelector('.cbi-map');
|
|
this.fieldset = this.create_fieldset(title);
|
|
this.cbi_map.appendChild(this.fieldset);
|
|
}
|
|
|
|
update(){
|
|
console.log("update");
|
|
if (this.cb_update) {
|
|
this.cb_update();
|
|
}
|
|
}
|
|
|
|
pause(){
|
|
console.log("pause");
|
|
}
|
|
|
|
get_config(){
|
|
XHR.get('<%=luci.dispatcher.build_url("admin", "modem", "qmodem", "modem_ctrl")%>',
|
|
{
|
|
"cfg": this.cfg_id,
|
|
"action": this.get_action
|
|
},
|
|
(x, data) => {
|
|
this.config = data[this.config_name];
|
|
if (this.cb_get) {
|
|
this.cb_get(data);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
set_config(config){
|
|
XHR.get('<%=luci.dispatcher.build_url("admin", "modem", "qmodem", "modem_ctrl")%>',
|
|
{
|
|
"cfg": this.cfg_id,
|
|
"action": this.set_action,
|
|
"params": JSON.stringify(config)
|
|
},
|
|
(x, data) => {
|
|
this.config = data[this.config_name];
|
|
if (this.cb_set) {
|
|
this.cb_set(data);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
create_fieldset(title){
|
|
var fieldset = document.createElement('fieldset');
|
|
fieldset.className = "cbi-section";
|
|
var legend = document.createElement('legend');
|
|
legend.innerHTML = title;
|
|
fieldset.appendChild(legend);
|
|
return fieldset;
|
|
}
|
|
|
|
createInput(name,value){
|
|
var input = document.createElement('input');
|
|
input.type = "text";
|
|
input.name = name;
|
|
input.value = value;
|
|
return input;
|
|
}
|
|
|
|
createBTN(name,cb){
|
|
var btn = document.createElement('input');
|
|
btn.type = "button";
|
|
btn.value = name;
|
|
btn.addEventListener('click',cb);
|
|
return btn;
|
|
}
|
|
|
|
createRadio(name,value){
|
|
var radio = document.createElement('input');
|
|
radio.type = "radio";
|
|
radio.name = name;
|
|
radio.value = value;
|
|
return radio;
|
|
}
|
|
|
|
createCheckbox(value){
|
|
var checkbox = document.createElement('input');
|
|
checkbox.type = "checkbox";
|
|
checkbox.value = value;
|
|
return checkbox;
|
|
}
|
|
|
|
createTable(){
|
|
let table,tbody;
|
|
table = document.createElement('table');
|
|
table.classList.add("cbi-section-table");
|
|
table.classList.add("table");
|
|
tbody = document.createElement('tbody');
|
|
table.appendChild(tbody);
|
|
return table;
|
|
}
|
|
|
|
createDroplist(dict){
|
|
var select = document.createElement('select');
|
|
for (let key in dict) {
|
|
var option = document.createElement('option');
|
|
option.value = key;
|
|
option.innerHTML = dict[key];
|
|
select.appendChild(option);
|
|
}
|
|
return select;
|
|
}
|
|
|
|
createInputWithDatalist(name,hint,dict) {
|
|
// 创建输入框
|
|
var input = document.createElement('input');
|
|
input.setAttribute('list', name); // 设置 list 属性以关联 datalist
|
|
input.name = name;
|
|
input.placeholder = hint;
|
|
|
|
// 创建 datalist
|
|
var datalist = document.createElement('datalist');
|
|
datalist.id = name;
|
|
|
|
// 添加选项到 datalist
|
|
for (let key in dict) {
|
|
var option = document.createElement('option');
|
|
option.value = key;
|
|
datalist.appendChild(option);
|
|
}
|
|
|
|
// 返回包含输入框和 datalist 的文档片段
|
|
var fragment = document.createDocumentFragment();
|
|
fragment.appendChild(input);
|
|
fragment.appendChild(datalist);
|
|
|
|
return { input, datalist }; // 返回包含输入框和 datalist 的对象
|
|
}
|
|
|
|
createTD(innerHTML){
|
|
var td = document.createElement('td');
|
|
td.classList.add("cbi-section-table-cell");
|
|
td.classList.add("td");
|
|
td.classList.add("left");
|
|
if (innerHTML) {
|
|
td.innerHTML = innerHTML;
|
|
}
|
|
return td;
|
|
}
|
|
|
|
createTH(innerHTML){
|
|
var th = document.createElement('th');
|
|
th.classList.add("cbi-section-table-cell");
|
|
th.classList.add("th");
|
|
if (innerHTML) {
|
|
th.innerHTML = innerHTML;
|
|
}
|
|
return th;
|
|
}
|
|
|
|
createTR(){
|
|
var tr = document.createElement('tr');
|
|
tr.classList.add("cbi-section-table-row");
|
|
tr.classList.add("tr");
|
|
return tr;
|
|
}
|
|
|
|
createTRHeader(){
|
|
var tr = document.createElement('div');
|
|
tr.classList.add("tr");
|
|
tr.classList.add("cbi-section-table-titles");
|
|
tr.classList.add("anonymous");
|
|
return tr;
|
|
}
|
|
|
|
init_table(){
|
|
var table = this.createTable();
|
|
this.fieldset.appendChild(table);
|
|
this.tbody = table.querySelector('tbody');
|
|
}
|
|
|
|
hide(){
|
|
this.fieldset.style.display = "none";
|
|
this.pause();
|
|
}
|
|
|
|
show(){
|
|
this.fieldset.style.display = "block";
|
|
console.log("show");
|
|
this.update();
|
|
}
|
|
}
|
|
|
|
//锁频功能
|
|
class Lockband extends ModemConfig{
|
|
constructor(cfg_id){
|
|
super(cfg_id,"<%:Lock Band%>");
|
|
this.config_name = "lockband";
|
|
this.get_action = "get_lockband";
|
|
this.set_action = "set_lockband";
|
|
this.lockband_config = {};
|
|
this.checkboxes = {};
|
|
this.available_bandid = {};
|
|
this.band_class_map = {};
|
|
this.init_table();
|
|
this.cb_get = (data) => {
|
|
this.render();
|
|
}
|
|
this.cb_set = (data) => {
|
|
this.get_config();
|
|
}
|
|
this.get_config();
|
|
}
|
|
|
|
set lock(config){
|
|
var band_class = config.band_class;
|
|
var band_id = config.band_id;
|
|
if (!this.lockband_config[band_class].includes(band_id)){
|
|
this.lockband_config[band_class].push(band_id)
|
|
|
|
}
|
|
this.checkboxes[band_class][band_id].checked = true;
|
|
}
|
|
|
|
set unlock(config){
|
|
var band_class = config.band_class;
|
|
var band_id = config.band_id;
|
|
this.lockband_config[band_class] = this.lockband_config[band_class].filter(x => x != band_id);
|
|
//set checkbox
|
|
this.checkboxes[band_class][band_id].checked = false;
|
|
}
|
|
|
|
createCheckbox(band_class,band_name,band_id){
|
|
let checkbox = document.createElement('input');
|
|
checkbox.type = "checkbox";
|
|
checkbox.className = "cbi-input-checkbox";
|
|
checkbox.value = band_id;
|
|
checkbox.setAttribute("display-band",band_name);
|
|
checkbox.addEventListener("change",() => {
|
|
if (checkbox.checked){
|
|
this.lock = { "band_class": band_class, "band_id": band_id };
|
|
}
|
|
else{
|
|
this.unlock = { "band_class": band_class, "band_id": band_id };
|
|
}
|
|
});
|
|
|
|
this.checkboxes[band_class][band_id] = checkbox;
|
|
if (this.lockband_config[band_class].includes(band_id)) {
|
|
this.lock = { "band_class": band_class, "band_id": band_id };
|
|
}
|
|
}
|
|
|
|
createcheckboxes(band_class){
|
|
var band = this.config[band_class];
|
|
var available_band = band.available_band;
|
|
var lock_band = band.lock_band;
|
|
this.lockband_config[band_class] = lock_band;
|
|
if ( available_band.length == 0) {
|
|
return;
|
|
}
|
|
if (this.checkboxes[band_class] == undefined) {
|
|
this.checkboxes[band_class] = {};
|
|
}
|
|
if (this.available_bandid[band_class] == undefined) {
|
|
this.available_bandid[band_class] = [];
|
|
}
|
|
|
|
for (let band_cfg of available_band) {
|
|
let band_name = band_cfg.band_name;
|
|
let band_id = band_cfg.band_id;
|
|
if (this.available_bandid[band_class].includes(band_id) == false) {
|
|
this.available_bandid[band_class].push(band_id);
|
|
}
|
|
this.createCheckbox(band_class,band_name,band_id);
|
|
}
|
|
}
|
|
|
|
submit(band_class)
|
|
{
|
|
var sorted = this.lockband_config[band_class].sort();
|
|
var config = '';
|
|
for (let band_id of sorted) {
|
|
config += band_id + ",";
|
|
}
|
|
var lockband_cfg = {
|
|
"band_class": band_class,
|
|
"lock_band": config.slice(0,-1)
|
|
}
|
|
var cfg_string = JSON.stringify(lockband_cfg);
|
|
this.set_config(cfg_string);
|
|
}
|
|
|
|
select_all(band_class){
|
|
//if all selected, then unselect all
|
|
let lockall = this.lockband_config[band_class].length != this.available_bandid[band_class].length;
|
|
for (let band_id of this.available_bandid[band_class]) {
|
|
if (lockall) {
|
|
this.lock = { "band_class": band_class, "band_id": band_id };
|
|
}
|
|
else{
|
|
this.unlock = { "band_class": band_class, "band_id": band_id };
|
|
}
|
|
}
|
|
}
|
|
|
|
render() {
|
|
for (let band_class in this.band_class_map){
|
|
if (this.config[band_class] == undefined) {
|
|
this.band_class_map[band_class].header.style.display = "none";
|
|
this.band_class_map[band_class].tr.style.display = "none";
|
|
this.band_class_map[band_class].select_all_btn.style.display = "none";
|
|
this.band_class_map[band_class].submit_btn.style.display = "none";
|
|
}
|
|
else{
|
|
this.band_class_map[band_class].header.style.display = "";
|
|
this.band_class_map[band_class].tr.style.display = "";
|
|
this.band_class_map[band_class].select_all_btn.style.display = "";
|
|
this.band_class_map[band_class].submit_btn
|
|
}
|
|
}
|
|
for (let band_class in this.config) {
|
|
let header, tr, td, select_all_btn, submit_btn;
|
|
this.createcheckboxes(band_class);
|
|
if (this.band_class_map[band_class] == undefined)
|
|
{
|
|
this.createBandTable(band_class);
|
|
}
|
|
header = this.band_class_map[band_class].header;
|
|
tr = this.band_class_map[band_class].tr;
|
|
select_all_btn = this.band_class_map[band_class].select_all_btn;
|
|
submit_btn = this.band_class_map[band_class].submit_btn
|
|
td = document.createElement('td');
|
|
td.classList.add("cbi-section-table-cell");
|
|
td.classList.add("td")
|
|
td.style.display = "flex";
|
|
td.style.flexWrap = "wrap";
|
|
//clear tr
|
|
while (tr.firstChild) {
|
|
tr.removeChild(tr.firstChild);
|
|
}
|
|
tr.appendChild(td);
|
|
for (let checkbox in this.checkboxes[band_class]) {
|
|
let display_value = this.checkboxes[band_class][checkbox].getAttribute("display-band");
|
|
let span = document.createElement('span');
|
|
span.innerHTML = display_value;
|
|
td.appendChild(this.checkboxes[band_class][checkbox]);
|
|
td.appendChild(span);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
createBandTable(band_class){
|
|
let tr_header, th, tr, td, select_all_btn, submit_btn;
|
|
tr_header = document.createElement('div');
|
|
tr_header.className = "tr cbi-section-table-titles anonymous";
|
|
th = document.createElement('div');
|
|
th.className = "th cbi-section-table-cell";
|
|
th.innerHTML = band_class;
|
|
tr_header.appendChild(th);
|
|
tr = document.createElement('tr');
|
|
tr.className = "tr cbi-section-table-row";
|
|
select_all_btn = this.createBTN("<%:Select All%>", () => {
|
|
this.select_all(band_class);
|
|
});
|
|
submit_btn = this.createBTN("<%:Submit%>", () => {
|
|
this.submit(band_class);
|
|
});
|
|
this.band_class_map[band_class] = {
|
|
"header": tr_header,
|
|
"tr": tr,
|
|
"select_all_btn": select_all_btn,
|
|
"submit_btn": submit_btn
|
|
}
|
|
this.tbody.appendChild(tr_header);
|
|
this.tbody.appendChild(tr);
|
|
this.tbody.appendChild(select_all_btn);
|
|
this.tbody.appendChild(submit_btn);
|
|
|
|
}
|
|
|
|
update() {
|
|
console.log(JSON.stringify(this.lockband_config));
|
|
console.log(JSON.stringify(this.available_bandid));
|
|
console.log(JSON.stringify(this.band_class_map));
|
|
console.log(JSON.stringify(this.config));
|
|
this.get_config();
|
|
}
|
|
|
|
}
|
|
|
|
class RatPrefer extends ModemConfig {
|
|
constructor(cfg_id){
|
|
super(cfg_id,"<%:Rat Prefer%>");
|
|
this.config_name = "network_prefer";
|
|
this.get_action = "get_network_prefer";
|
|
this.set_action = "set_network_prefer";
|
|
this.selected_rat = [];
|
|
this.available_rat = [];
|
|
this.init_table();
|
|
this.create_submit_btn();
|
|
}
|
|
|
|
cb_get(data){
|
|
//clear selected_rat
|
|
this.selected_rat = [];
|
|
//clear available_rat
|
|
this.available_rat = [];
|
|
for (let key in this.config){
|
|
|
|
if (this.config[key] == 1) {
|
|
this.selected_rat.push(key);
|
|
}
|
|
this.available_rat.push(key);
|
|
|
|
}
|
|
|
|
this.render_checkbox();
|
|
this.render_current_mode();
|
|
}
|
|
cb_set(data){
|
|
this.get_config();
|
|
}
|
|
|
|
render_current_mode(){
|
|
let selected_mode = []
|
|
for (let rat in this.config) {
|
|
if (this.config[rat] == 1) {
|
|
selected_mode.push(rat);
|
|
}
|
|
}
|
|
this.current_mode = selected_mode.join(',');
|
|
this.current_mode_td.innerHTML = this.current_mode;
|
|
}
|
|
|
|
render_checkbox(){
|
|
if (this.init_view == false) {
|
|
this.init_ele();
|
|
this.init_view = true;
|
|
}
|
|
this.createCheckboxes();
|
|
}
|
|
|
|
create_submit_btn(){
|
|
var submit_btn = this.createBTN("<%:Submit%>",() => {
|
|
this.submit();
|
|
});
|
|
this.fieldset.appendChild(submit_btn);
|
|
}
|
|
|
|
createCheckbox(rat){
|
|
var checkbox = document.createElement('input');
|
|
checkbox.type = "checkbox";
|
|
checkbox.value = rat;
|
|
checkbox.addEventListener('change',() => {
|
|
if (checkbox.checked) {
|
|
this.selected_rat.push(rat);
|
|
}
|
|
else{
|
|
this.selected_rat = this.selected_rat.filter(x => x != rat);
|
|
}
|
|
});
|
|
return checkbox;
|
|
}
|
|
|
|
createCheckboxes(){
|
|
//clear select_td
|
|
while (this.select_td.firstChild) {
|
|
this.select_td.removeChild(this.select_td.firstChild);
|
|
}
|
|
var network_prefer = this.config;
|
|
for (let rat of this.available_rat) {
|
|
var checkbox = this.createCheckbox(rat);
|
|
if (this.selected_rat.includes(rat)) {
|
|
checkbox.checked = true;
|
|
}
|
|
var span = document.createElement('span');
|
|
span.innerHTML = rat;
|
|
this.select_td.appendChild(checkbox);
|
|
this.select_td.appendChild(span);
|
|
}
|
|
}
|
|
|
|
update(){
|
|
this.get_config();
|
|
}
|
|
|
|
submit(){
|
|
this.set_config(JSON.stringify(this.selected_rat));
|
|
}
|
|
|
|
init_ele(){
|
|
var header_tr,current_mode_th,select_th,setting_tr,current_mode_td,select_td;
|
|
header_tr = this.createTRHeader();
|
|
current_mode_th = this.createTH("<%:Current Mode%>");
|
|
select_th = this.createTH("<%:Setting%>");
|
|
setting_tr = this.createTR();
|
|
current_mode_td = this.createTD();
|
|
select_td = this.createTD();
|
|
header_tr.appendChild(current_mode_th);
|
|
header_tr.appendChild(select_th);
|
|
setting_tr.appendChild(current_mode_td);
|
|
setting_tr.appendChild(select_td);
|
|
this.tbody.appendChild(header_tr);
|
|
this.tbody.appendChild(setting_tr);
|
|
this.current_mode_td = current_mode_td;
|
|
this.select_td = select_td;
|
|
|
|
}
|
|
}
|
|
|
|
class DialMode extends ModemConfig {
|
|
constructor(cfg_id){
|
|
super(cfg_id,"<%:Dial Mode%>");
|
|
this.config_name = "mode";
|
|
this.get_action = "get_mode";
|
|
this.set_action = "set_mode";
|
|
this.avalibale_mode = [];
|
|
this.selected_mode = null;
|
|
this.init_table();
|
|
this.td_map = {
|
|
"current_mode": null,
|
|
"radio_div": null,
|
|
}
|
|
this.cb_get = (data) => {
|
|
this.render();
|
|
}
|
|
this.cb_set = (data) => {
|
|
this.get_config();
|
|
}
|
|
this.get_config();
|
|
|
|
}
|
|
|
|
render(){
|
|
if (this.td_map["current_mode"] == null) {
|
|
this.init_ele();
|
|
}
|
|
|
|
for (let key in this.config){
|
|
if (this.avalibale_mode.includes(key) == false)
|
|
{
|
|
this.avalibale_mode.push(key);
|
|
}
|
|
if (this.config[key] == 1) {
|
|
this.selected_mode = key;
|
|
this.td_map.current_mode.innerHTML = key;
|
|
}
|
|
}
|
|
this.create_mode_radio();
|
|
|
|
}
|
|
|
|
init_ele(){
|
|
var radio_div_th, current_mode_th, radio_div, current_mode, header_tr, setting_tr;
|
|
header_tr = document.createElement('div');
|
|
header_tr.className = "tr cbi-section-table-titles anonymous";
|
|
radio_div_th = document.createElement('div');
|
|
radio_div_th.className = "th cbi-section-table-cell";
|
|
radio_div_th.innerHTML = "<%:Dial Mode%>";
|
|
current_mode_th = document.createElement('div');
|
|
current_mode_th.className = "th cbi-section-table-cell";
|
|
current_mode_th.innerHTML = "<%:Current Mode%>";
|
|
setting_tr = document.createElement('div');
|
|
setting_tr.className = "tr cbi-section-table-row";
|
|
radio_div = document.createElement('div');
|
|
radio_div.className = "td cbi-section-table-cell left";
|
|
current_mode = document.createElement('div');
|
|
current_mode.className = "td cbi-section-table-cell left";
|
|
header_tr.appendChild(current_mode_th);
|
|
header_tr.appendChild(radio_div_th);
|
|
|
|
setting_tr.appendChild(current_mode);
|
|
setting_tr.appendChild(radio_div);
|
|
|
|
this.tbody.appendChild(header_tr);
|
|
this.tbody.appendChild(setting_tr);
|
|
this.td_map["radio_div"] = radio_div;
|
|
this.td_map["current_mode"] = current_mode;
|
|
this.mode_btn = this.createBTN("<%:Submit%>",() => {
|
|
this.set_config(this.selected_mode);
|
|
});
|
|
this.tbody.appendChild(this.mode_btn);
|
|
}
|
|
|
|
create_mode_radio(){
|
|
while (this.td_map.radio_div.firstChild) {
|
|
this.td_map.radio_div.removeChild(this.td_map.radio_div.firstChild);
|
|
}
|
|
for (let mode of this.avalibale_mode) {
|
|
let radio = this.createRadio("mode",mode);
|
|
if (mode == this.selected_mode) {
|
|
radio.checked = true;
|
|
}
|
|
radio.addEventListener('change',() => {
|
|
this.selected_mode = mode;
|
|
});
|
|
|
|
let span = document.createElement('span');
|
|
span.innerHTML = mode;
|
|
//clear radio_div
|
|
|
|
this.td_map.radio_div.appendChild(radio);
|
|
this.td_map.radio_div.appendChild(span);
|
|
}
|
|
|
|
}
|
|
|
|
update(){
|
|
this.get_config();
|
|
}
|
|
}
|
|
|
|
class NeighborCell extends ModemConfig {
|
|
constructor(cfg_id){
|
|
super(cfg_id,"<%:Neighbor Cell%>");
|
|
this.config_name = "neighborcell";
|
|
this.get_action = "get_neighborcell";
|
|
this.set_action = "set_neighborcell";
|
|
this.task = null;
|
|
this.init_nc_table();
|
|
this.get_config();
|
|
|
|
}
|
|
|
|
pause(){
|
|
if (this.task != null) {
|
|
clearInterval(this.task);
|
|
}
|
|
}
|
|
|
|
update(){
|
|
this.task = setInterval(() => {
|
|
this.get_config();
|
|
},10000);
|
|
}
|
|
|
|
nr_options(){
|
|
if (this.rat_input.selectedIndex == 0) {
|
|
this.band_tr.style.display = "none";
|
|
this.scs_tr.style.display = "none";
|
|
}
|
|
else{
|
|
this.band_tr.style.display = "";
|
|
this.scs_tr.style.display = "";
|
|
}
|
|
}
|
|
|
|
init_nc_table(){
|
|
var neighborcell_table,setting_table,status_table ;
|
|
neighborcell_table = this.createTable();
|
|
status_table = this.createTable();
|
|
setting_table = this.createTable();
|
|
|
|
this.fieldset.appendChild(neighborcell_table);
|
|
this.fieldset.appendChild(status_table);
|
|
this.fieldset.appendChild(setting_table);
|
|
|
|
this.neighborcell_table = neighborcell_table.querySelector('tbody');
|
|
this.status_table = status_table.querySelector('tbody');
|
|
this.setting_table = setting_table.querySelector('tbody');
|
|
|
|
var pci_tr,arfcn_tr,band_tr,scs_tr,header,td,td1,th,pci_input,arfcn_input,band_input,scs_input,rat_input,rat_tr;
|
|
var status_th,status_trh;
|
|
header = this.createTRHeader();
|
|
th = this.createTH("<%:Lock Cell Setting%>");
|
|
header.appendChild(th);
|
|
|
|
rat_input = this.createDroplist({0:"LTE",1:"NR"});
|
|
rat_tr = this.createTR();
|
|
td = this.createTD("<%:RAT%>");
|
|
td1 = this.createTD();
|
|
td1.appendChild(rat_input);
|
|
rat_tr.appendChild(td);
|
|
rat_tr.appendChild(td1);
|
|
|
|
|
|
pci_tr = this.createTR();
|
|
td = this.createTD("<%:PCI%>");
|
|
pci_input = this.createInput("pci","");
|
|
td1 = this.createTD();
|
|
td1.appendChild(pci_input);
|
|
pci_tr.appendChild(td);
|
|
pci_tr.appendChild(td1);
|
|
|
|
arfcn_tr = this.createTR();
|
|
td = this.createTD("<%:ARFCN%>");
|
|
arfcn_input = this.createInput("arfcn","");
|
|
td1 = this.createTD();
|
|
td1.appendChild(arfcn_input);
|
|
arfcn_tr.appendChild(td);
|
|
arfcn_tr.appendChild(td1);
|
|
|
|
band_tr = this.createTR();
|
|
td = this.createTD("<%:Band%>");
|
|
band_input = this.createInput("band","");
|
|
td1 = this.createTD();
|
|
td1.appendChild(band_input);
|
|
band_tr.appendChild(td);
|
|
band_tr.appendChild(td1);
|
|
|
|
scs_tr = this.createTR();
|
|
td = this.createTD("<%:SCS%>");
|
|
scs_input = this.createDroplist({0:"15KHZ",1:"30KHZ"});
|
|
td1 = this.createTD();
|
|
td1.appendChild(scs_input);
|
|
scs_tr.appendChild(td);
|
|
scs_tr.appendChild(td1);
|
|
|
|
|
|
status_th = this.createTH("<%:Status%>");
|
|
status_trh = this.createTRHeader();
|
|
status_trh.appendChild(status_th);
|
|
this.status_table.appendChild(status_trh);
|
|
|
|
this.pci_input = pci_input;
|
|
this.arfcn_input = arfcn_input;
|
|
this.band_input = band_input;
|
|
this.scs_input = scs_input;
|
|
this.rat_input = rat_input;
|
|
this.band_tr = band_tr;
|
|
this.scs_tr = scs_tr;
|
|
this.band_tr.style.display = "none";
|
|
this.scs_tr.style.display = "none";
|
|
this.rat_input.addEventListener('change',()=>{
|
|
this.nr_options();
|
|
});
|
|
|
|
var submit_btn = this.createBTN("<%:Submit%>",() => {
|
|
var config = {
|
|
"rat": this.rat_input.selectedIndex,
|
|
"pci": this.pci_input.value,
|
|
"arfcn": this.arfcn_input.value,
|
|
"band": this.band_input.value,
|
|
"scs": this.scs_input.selectedIndex
|
|
}
|
|
this.set_config(JSON.stringify(config));
|
|
});
|
|
|
|
this.setting_table.appendChild(header);
|
|
this.setting_table.appendChild(rat_tr);
|
|
this.setting_table.appendChild(pci_tr);
|
|
this.setting_table.appendChild(arfcn_tr);
|
|
this.setting_table.appendChild(band_tr);
|
|
this.setting_table.appendChild(scs_tr);
|
|
this.setting_table.appendChild(submit_btn);
|
|
}
|
|
|
|
render_neighborcell(){
|
|
//clear neighborcell_table
|
|
while (this.neighborcell_table.querySelector("tr")) {
|
|
let remove = this.neighborcell_table.querySelector("tr")
|
|
this.neighborcell_table.removeChild(remove);
|
|
}
|
|
var nr,lte,tr_left
|
|
nr = this.config.NR;
|
|
lte = this.config.LTE;
|
|
for (let cell_info of nr) {
|
|
this.create_nc_tr(1,cell_info);
|
|
}
|
|
for (let cell_info of lte) {
|
|
this.create_nc_tr(0,cell_info);
|
|
}
|
|
|
|
}
|
|
|
|
render_status(){
|
|
//clear status_table
|
|
while (this.status_table.querySelector("tr")) {
|
|
this.status_table.removeChild(this.status_table.querySelector("tr"));
|
|
}
|
|
var status = this.config.lockcell_status;
|
|
for (let key in status) {
|
|
if (status[key] != ""){
|
|
this.create_status_tr(key + ":" + status[key].toUpperCase());
|
|
}
|
|
}
|
|
}
|
|
|
|
create_status_tr(status){
|
|
var tr = this.createTR();
|
|
var td = this.createTD(status);
|
|
tr.appendChild(td);
|
|
this.status_table.appendChild(tr);
|
|
}
|
|
|
|
create_nc_tr(rat,cell_info){
|
|
if (rat == 0) {
|
|
var text = "LTE:";
|
|
}
|
|
else{
|
|
var text = "NR:";
|
|
}
|
|
for (let key in cell_info) {
|
|
if (cell_info[key] != ""){
|
|
text += key + ":" + cell_info[key] + " ";
|
|
}
|
|
}
|
|
let tr_left = this.createTD(text);
|
|
let tr_right = this.create_copy_btn_td(rat,cell_info.pci,cell_info.arfcn);
|
|
let tr = this.createTR();
|
|
tr.appendChild(tr_left);
|
|
tr.appendChild(tr_right);
|
|
this.neighborcell_table.appendChild(tr);
|
|
}
|
|
|
|
create_copy_btn_td(rat,pci,arfcn){
|
|
var copy_btn = this.createBTN("<%:Copy%>",() => {
|
|
this.pci_input.value = pci;
|
|
this.arfcn_input.value = arfcn;
|
|
this.rat_input.selectedIndex = rat;
|
|
this.nr_options()
|
|
});
|
|
var td = document.createElement('td');
|
|
td.className = "td cbi-section-table-cell left";
|
|
td.setAttribute("width","10%");
|
|
td.appendChild(copy_btn);
|
|
|
|
return td;
|
|
}
|
|
|
|
cb_get(){
|
|
this.render_neighborcell();
|
|
this.render_status();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
class IMEI extends ModemConfig {
|
|
constructor(cfg_id){
|
|
super(cfg_id,"<%:Set IMEI%>");
|
|
this.config_name = "imei";
|
|
this.get_action = "get_imei";
|
|
this.set_action = "set_imei";
|
|
this.get_config();
|
|
this.render();
|
|
}
|
|
|
|
render(){
|
|
this.imei_input = this.createInput("imei",this.config);
|
|
this.imei_btn = this.createBTN("<%:Submit%>",() => {
|
|
this.set_config(this.imei_input.value);
|
|
});
|
|
this.fieldset.appendChild(this.imei_input);
|
|
this.fieldset.appendChild(this.imei_btn);
|
|
}
|
|
|
|
cb_get(){
|
|
this.imei_input.value = this.config;
|
|
}
|
|
|
|
cb_set(){
|
|
this.imei_input.value = this.config;
|
|
}
|
|
|
|
update(){
|
|
this.get_config();
|
|
}
|
|
|
|
}
|
|
|
|
class RebootModem extends ModemConfig {
|
|
constructor(cfg_id){
|
|
super(cfg_id,"<%:Reboot Modem%>");
|
|
this.config_name = "reboot_caps";
|
|
this.get_action = "get_reboot_caps";
|
|
this.set_action = "do_reboot";
|
|
this.get_config();
|
|
this.render();
|
|
}
|
|
|
|
cb_get(){
|
|
this.soft_reboot_btn.disabled = !this.config.soft_reboot_caps;
|
|
this.hard_reboot_btn.disabled = !this.config.hard_reboot_caps;
|
|
}
|
|
|
|
|
|
render(){
|
|
this.soft_reboot_btn = this.createBTN("<%:Soft Reboot%>",() => {
|
|
this.set_config('{"method":"soft"}');
|
|
});
|
|
this.hard_reboot_btn = this.createBTN("<%:Hard Reboot%>",() => {
|
|
this.set_config('{"method":"hard"}');
|
|
});
|
|
this.fieldset.appendChild(this.soft_reboot_btn);
|
|
this.fieldset.appendChild(document.createElement("br"));
|
|
this.fieldset.appendChild(this.hard_reboot_btn);
|
|
}
|
|
update(){
|
|
this.get_config();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
class AtDebug extends ModemConfig {
|
|
constructor(cfg_id){
|
|
super(cfg_id,"<%:AT Debug%>");
|
|
this.config_name = "at_cfg";
|
|
this.get_action = "get_at_cfg";
|
|
this.set_action = "send_at";
|
|
this.at_port=null;
|
|
this.last_choice_cmd = null;
|
|
this.get_config();
|
|
this.render();
|
|
}
|
|
|
|
render(){
|
|
this.textarea = document.createElement('textarea');
|
|
this.textarea.style.width = "100%";
|
|
this.textarea.style.height = "600px";
|
|
this.textarea.readOnly = true;
|
|
this.at_btn = this.createBTN("<%:Send%>",() => {
|
|
let payload = {
|
|
"at": this.at_input,
|
|
"port": this.at_port
|
|
}
|
|
this.set_config(JSON.stringify(payload));
|
|
//append input to textarea
|
|
this.textarea.value += "INPUT>> " + this.at_input + "\n";
|
|
});
|
|
this.clear_btn = this.createBTN("<%:Clear%>",() => {
|
|
this.textarea.value = "";
|
|
});
|
|
this.clear_input_btn = this.createBTN("<%:Clear%>",() => {
|
|
this.cmd_prompt.value = "";
|
|
this.at_port_selector.value = "";
|
|
});
|
|
//this.at_port_selector = this.createDroplist();
|
|
var { input, datalist } = this.createInputWithDatalist("select_port","<%:Select Port%>" );
|
|
this.at_port_selector=input;
|
|
this.at_port_selector_datalist = datalist;
|
|
var { input, datalist } = this.createInputWithDatalist("cmd_prompt","<%:Input AT Command%>" );
|
|
//this.cmd_prompt = this.createDroplist();
|
|
this.cmd_prompt = input;
|
|
this.cmd_prompt_datalist = datalist;
|
|
this.fieldset.appendChild(this.at_port_selector);
|
|
this.fieldset.appendChild(this.at_port_selector_datalist);
|
|
//add br
|
|
this.fieldset.appendChild(document.createElement("br"));
|
|
|
|
this.fieldset.appendChild(this.cmd_prompt);
|
|
this.fieldset.appendChild(this.cmd_prompt_datalist);
|
|
this.fieldset.appendChild(document.createElement("br"));
|
|
this.fieldset.appendChild(this.at_btn);
|
|
this.fieldset.appendChild(this.clear_input_btn);
|
|
this.fieldset.appendChild(this.textarea);
|
|
this.fieldset.appendChild(this.clear_btn);
|
|
this.at_port_selector.addEventListener('change',(event) => {
|
|
this.at_port = event.target.value;
|
|
});
|
|
this.cmd_prompt.addEventListener('change',(event) => {
|
|
this.at_input = event.target.value;
|
|
});
|
|
}
|
|
|
|
cb_get(){
|
|
//clear ports
|
|
while (this.at_port_selector_datalist.firstChild) {
|
|
this.at_port_selector_datalist.removeChild(this.at_port_selector_datalist.firstChild);
|
|
}
|
|
var ports=this.config.ports;
|
|
var valid_ports=this.config.valid_ports;
|
|
var using_port=this.config.using_port;
|
|
var cmds = this.config.cmds;
|
|
for (let port of ports) {
|
|
let select;
|
|
let displayport = port;
|
|
if (valid_ports.includes(port) == false) {
|
|
displayport += "<%:(invalid)%>";
|
|
}
|
|
else{
|
|
displayport += "<%:(valid)%>";
|
|
}
|
|
if (port == using_port) {
|
|
displayport += "<%:(using)%>";
|
|
select = true;
|
|
}
|
|
|
|
var option = document.createElement('option');
|
|
option.value = port;
|
|
option.innerHTML = displayport;
|
|
if (select) {
|
|
option.selected = true;
|
|
this.at_port = port;
|
|
}
|
|
this.at_port_selector_datalist.appendChild(option);
|
|
}
|
|
//clear cmds
|
|
while (this.cmd_prompt_datalist.firstChild) {
|
|
this.cmd_prompt_datalist.removeChild(this.cmd_prompt_datalist.firstChild);
|
|
}
|
|
for (let cmd of cmds) {
|
|
var option = document.createElement('option');
|
|
option.value = cmd.value;
|
|
option.innerHTML = cmd.name;
|
|
this.cmd_prompt_datalist.appendChild(option);
|
|
}
|
|
|
|
}
|
|
|
|
cb_update(){
|
|
//clear 2 input
|
|
this.at_port_selector.value = "";
|
|
this.cmd_prompt.value = "";
|
|
this.get_config();
|
|
}
|
|
|
|
cb_set(){
|
|
//append response to textarea
|
|
this.textarea.value += this.config.res + "<<END\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
class Select_Modem {
|
|
constructor(){
|
|
this.modem_selector = document.getElementById('modem_selector');
|
|
this.cfg_id = null;
|
|
this.modem_cfg_list = [];
|
|
this.create_modem_cfg_selector();
|
|
this.update_modem_cfg_list();
|
|
}
|
|
|
|
create_modem_cfg_selector() {
|
|
var selector = document.createElement('select');
|
|
selector.addEventListener('change', (event) => {
|
|
this.cfg_id = event.target.value;
|
|
this.update_cfg_id(this.cfg_id);
|
|
});
|
|
this.modem_selector.appendChild(selector);
|
|
this.selector = selector;
|
|
}
|
|
|
|
update_modem_cfg_list() {
|
|
XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "modem", "qmodem", "get_modem_cfg")%>', {}, (x, data) => {
|
|
var new_cfg_list = [];
|
|
var cfgs = data.cfgs;
|
|
for (let i = 0; i < cfgs.length; i++) {
|
|
var cfg = cfgs[i];
|
|
var name = cfg.name;
|
|
var value = cfg.cfg;
|
|
new_cfg_list.push({ "value": value, "name": name });
|
|
}
|
|
if (JSON.stringify(new_cfg_list) != JSON.stringify(this.modem_cfg_list)) {
|
|
this.cfg_options = new_cfg_list;
|
|
}
|
|
});
|
|
}
|
|
|
|
set cfg_options(value) {
|
|
var longger = this.modem_cfg_list.length > value.length ? this.modem_cfg_list : value;
|
|
if (longger.length == 0) {
|
|
return;
|
|
}
|
|
for (let i = 0; i < longger.length; i++) {
|
|
var option = this.selector.options[i];
|
|
if (i < value.length) {
|
|
if (i >= this.selector.options.length) {
|
|
option = document.createElement('option');
|
|
this.selector.appendChild(option);
|
|
}
|
|
option.value = value[i].value;
|
|
option.innerHTML = value[i].name;
|
|
|
|
}
|
|
else {
|
|
this.selector.removeChild(option);
|
|
}
|
|
}
|
|
this.cfg_id = this.selector.value;
|
|
this.modem_cfg_list = value;
|
|
this.update_cfg_id(this.cfg_id);
|
|
}
|
|
}
|
|
|
|
class TabMenu extends Select_Modem {
|
|
functions = {
|
|
"DialMode": {"class": DialMode, "name":"<%:Dial Mode%>"},
|
|
"RatPrefer": {"class": RatPrefer, "name":"<%:Rat Prefer%>"},
|
|
"IMEI": {"class": IMEI, "name": "<%:Set IMEI%>"},
|
|
"NeighborCell": {"class": NeighborCell, "name": "<%:Neighbor Cell%>"},
|
|
"LockBand": {"class": Lockband, "name":"<%:Lock Band%>"},
|
|
"RebootModem": {"class": RebootModem, "name":"<%:Reboot Modem%>"},
|
|
"AtDebug": {"class": AtDebug, "name":"<%:AT Debug%>"}
|
|
}
|
|
constructor(){
|
|
super();
|
|
this.cbi_map = document.querySelector('.cbi-map');
|
|
this.class_map = {};
|
|
this.datatabs = [];
|
|
this.create_tabmenu();
|
|
|
|
}
|
|
|
|
update_cfg_id(cfg_id){
|
|
for (let key in this.class_map) {
|
|
this.class_map[key].cfg_id = cfg_id;
|
|
this.class_map[key].get_config();
|
|
}
|
|
//check if all datatab not selected
|
|
for (let tab of this.datatabs) {
|
|
if (tab.className == "cbi-tab") {
|
|
this.switch_tab(tab);
|
|
return;
|
|
}
|
|
}
|
|
this.switch_tab(this.datatabs[0]);
|
|
}
|
|
|
|
create_tabmenu(){
|
|
//add support function to tabmenu
|
|
var tabmenu = document.createElement('ul');
|
|
tabmenu.className = "cbi-tabmenu";
|
|
for (let key in this.functions) {
|
|
var li = document.createElement('li');
|
|
li.className = "cbi-tab-disabled";
|
|
li.innerHTML = this.functions[key].name;
|
|
li.setAttribute("data-tab", key);
|
|
li.addEventListener('click', (event) => {
|
|
this.switch_tab(event.target)
|
|
});
|
|
tabmenu.appendChild(li);
|
|
this.datatabs.push(li);
|
|
}
|
|
this.cbi_map.appendChild(tabmenu);
|
|
this.tabmenu = tabmenu;
|
|
}
|
|
|
|
switch_tab(target){
|
|
target.className = "cbi-tab";
|
|
target.style.display = "";
|
|
var datatab = target.getAttribute("data-tab");
|
|
for (let i = 0; i < this.datatabs.length; i++) {
|
|
if (this.datatabs[i] != target) {
|
|
this.datatabs[i].className = "cbi-tab-disabled";
|
|
}
|
|
}
|
|
|
|
if (this.class_map[datatab] == undefined) {
|
|
this.class_map[datatab] = new this.functions[datatab].class(this.cfg_id);
|
|
}
|
|
for (let key in this.class_map) {
|
|
this.class_map[key].hide();
|
|
}
|
|
this.class_map[datatab].show();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
window.onload = function(){
|
|
var tabmenu = new TabMenu();
|
|
}
|
|
|
|
</script>
|
|
<style>
|
|
.cbi-tabmenu li {
|
|
padding: 0.5rem;
|
|
}
|
|
</style>
|
|
<div class="cbi-map">
|
|
<fieldset class="cbi-section">
|
|
<table class="table">
|
|
<tbody>
|
|
<tr class="tr">
|
|
<td class="td" width="33%"><%:Modem Name%></td>
|
|
<td class="td" id="modem_selector">
|
|
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</fieldset>
|
|
</div>
|
|
<%+footer%>
|