working!
This commit is contained in:
1 parent
50774bfbf7
commit
55eb4d0e4a
3 files changed
+84
-48
No files matched your search
+19
-25
@@ -3,6 +3,7 @@
|
||||
'require form';
|
||||
'require uci';
|
||||
'require fs';
|
||||
'require ui';
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
@@ -27,8 +28,9 @@ return view.extend({
|
||||
s.anonymous = true;
|
||||
s.addremove = false;
|
||||
|
||||
o = s.option(form.Flag, 'enabled', _('Enable USB Gadget'),
|
||||
_('Disable to use USB port in host mode'));
|
||||
o = s.option(form.Flag, 'enabled', _('Enable USB Gadget'));
|
||||
o.description = _('Disable to use USB port in host mode.') + '<br>' +
|
||||
'<strong>May disconnect USB. Ensure alternative access.</strong>';
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.Value, 'gadget_name', _('Gadget Name'));
|
||||
@@ -71,15 +73,10 @@ return view.extend({
|
||||
_('RNDIS (Windows Ethernet)'),
|
||||
_('Windows-compatible USB ethernet. Works on all Windows versions.'));
|
||||
|
||||
o = s.option(form.Flag, 'enabled', _('Enable RNDIS'));
|
||||
o = s.option(form.Flag, 'enabled', _('Enable RNDIS'),
|
||||
_('Plug-and-play on Windows. Automatically adds to LAN bridge.'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.DummyValue, '_desc', _('Description'));
|
||||
o.rawhtml = true;
|
||||
o.cfgvalue = function() {
|
||||
return _('Plug-and-play on Windows. Automatically adds to LAN bridge.');
|
||||
};
|
||||
|
||||
// =================================================================
|
||||
// ECM
|
||||
// =================================================================
|
||||
@@ -87,15 +84,10 @@ return view.extend({
|
||||
_('ECM (macOS/Linux Ethernet)'),
|
||||
_('For macOS ≤10.14 and Linux. Do not enable with NCM.'));
|
||||
|
||||
o = s.option(form.Flag, 'enabled', _('Enable ECM'));
|
||||
o = s.option(form.Flag, 'enabled', _('Enable ECM'),
|
||||
_('CDC Ethernet for macOS and Linux. Disable RNDIS when using.'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.DummyValue, '_desc', _('Description'));
|
||||
o.rawhtml = true;
|
||||
o.cfgvalue = function() {
|
||||
return _('CDC Ethernet for macOS and Linux. Disable RNDIS when using.');
|
||||
};
|
||||
|
||||
// =================================================================
|
||||
// NCM
|
||||
// =================================================================
|
||||
@@ -103,15 +95,10 @@ return view.extend({
|
||||
_('NCM (Modern Ethernet)'),
|
||||
_('Best performance. For Windows 11+, macOS ≥10.15, Linux.'));
|
||||
|
||||
o = s.option(form.Flag, 'enabled', _('Enable NCM'));
|
||||
o = s.option(form.Flag, 'enabled', _('Enable NCM'),
|
||||
_('Modern high-speed USB ethernet. Best choice for new systems.'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.DummyValue, '_desc', _('Description'));
|
||||
o.rawhtml = true;
|
||||
o.cfgvalue = function() {
|
||||
return _('Modern high-speed USB ethernet. Best choice for new systems.');
|
||||
};
|
||||
|
||||
// =================================================================
|
||||
// ACM Serial
|
||||
// =================================================================
|
||||
@@ -138,7 +125,7 @@ return view.extend({
|
||||
// =================================================================
|
||||
s = m.section(form.NamedSection, 'ums', 'function',
|
||||
_('Mass Storage'),
|
||||
_('Expose storage image as USB drive.'));
|
||||
_('Expose storage image as USB drive. Does not provide access to the device.'));
|
||||
|
||||
o = s.option(form.Flag, 'enabled', _('Enable Mass Storage'));
|
||||
o.rmempty = false;
|
||||
@@ -161,7 +148,14 @@ return view.extend({
|
||||
|
||||
handleSaveApply: function(ev, mode) {
|
||||
return this.super('handleSaveApply', [ev, mode]).then(function() {
|
||||
return fs.exec('/etc/init.d/usb-gadget', ['restart']);
|
||||
ui.addNotification(null,
|
||||
E('p', _('Configuration saved. Restarting USB Gadget service...')),
|
||||
'info');
|
||||
return fs.exec('/etc/init.d/usb-gadget', ['restart']).then(function() {
|
||||
ui.addNotification(null,
|
||||
E('p', _('USB Gadget service restarted successfully')),
|
||||
'info');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
+63
-20
@@ -4,19 +4,20 @@
|
||||
'require ui';
|
||||
'require uci';
|
||||
'require poll';
|
||||
'require network';
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
uci.load('usbgadget'),
|
||||
L.resolveDefault(fs.exec('/etc/init.d/usb-gadget', ['status']), null),
|
||||
L.resolveDefault(fs.list('/sys/class/udc'), [])
|
||||
L.resolveDefault(fs.list('/sys/class/udc'), []),
|
||||
network.getDevices()
|
||||
]);
|
||||
},
|
||||
|
||||
render: function(data) {
|
||||
var status_result = data[1];
|
||||
var udc_devices = data[2];
|
||||
var udc_devices = data[1];
|
||||
var net_devices = data[2];
|
||||
|
||||
var enabled = uci.get('usbgadget', 'usb', 'enabled');
|
||||
var gadget_name = uci.get('usbgadget', 'usb', 'gadget_name') || 'g1';
|
||||
@@ -31,6 +32,21 @@ return view.extend({
|
||||
}
|
||||
});
|
||||
|
||||
// Buscar interfaces USB y crear elementos con puntitos de colores
|
||||
var usb_interface_elements = [];
|
||||
net_devices.forEach(function(dev) {
|
||||
var name = dev.getName();
|
||||
if (name && name.match(/^usb\d+$/)) {
|
||||
var isUp = dev.isUp();
|
||||
usb_interface_elements.push(
|
||||
E('span', { 'style': 'margin-right: 10px;' }, [
|
||||
E('span', { 'style': 'color:' + (isUp ? 'green' : 'red') }, '● '),
|
||||
name
|
||||
])
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Construir array de filas de la tabla
|
||||
var tableRows = [
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
@@ -61,12 +77,20 @@ return view.extend({
|
||||
|
||||
// Añadir fila UDC solo si hay dispositivos
|
||||
if (udc_devices.length > 0) {
|
||||
tableRows.splice(3, 0, E('tr', { 'class': 'tr' }, [
|
||||
tableRows.push(E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left' }, E('strong', {}, _('USB Controller'))),
|
||||
E('td', { 'class': 'td left' }, udc_devices.map(function(d) { return d.name; }).join(', '))
|
||||
]));
|
||||
}
|
||||
|
||||
// Añadir interfaces de red USB con puntitos
|
||||
if (usb_interface_elements.length > 0) {
|
||||
tableRows.push(E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left' }, E('strong', {}, _('Network Interfaces'))),
|
||||
E('td', { 'class': 'td left', 'id': 'usb_interfaces' }, usb_interface_elements)
|
||||
]));
|
||||
}
|
||||
|
||||
var viewElements = [
|
||||
E('h2', {}, _('USB Gadget Status')),
|
||||
E('div', { 'class': 'cbi-map-descr' },
|
||||
@@ -77,11 +101,11 @@ return view.extend({
|
||||
E('table', { 'class': 'table' }, tableRows)
|
||||
]),
|
||||
|
||||
// Botón alineado a la derecha
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('div', { 'class': 'cbi-section-node' }, [
|
||||
E('div', { 'class': 'cbi-value' }, [
|
||||
E('label', { 'class': 'cbi-value-title' }, _('Service Control')),
|
||||
E('div', { 'class': 'cbi-value-field' }, [
|
||||
E('div', { 'class': 'cbi-value-field', 'style': 'text-align: right;' }, [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'click': function() {
|
||||
@@ -110,23 +134,14 @@ return view.extend({
|
||||
])
|
||||
];
|
||||
|
||||
// Añadir output detallado solo si existe
|
||||
if (status_result && status_result.stdout) {
|
||||
viewElements.push(
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('h3', {}, _('Detailed Output')),
|
||||
E('pre', {
|
||||
'style': 'background:#f9f9f9; padding:10px; overflow:auto; max-height:400px; border:1px solid #ddd'
|
||||
}, status_result.stdout)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
var view = E('div', { 'class': 'cbi-map' }, viewElements);
|
||||
|
||||
// Polling cada 5 segundos
|
||||
poll.add(function() {
|
||||
return uci.load('usbgadget').then(function() {
|
||||
return Promise.all([
|
||||
uci.load('usbgadget'),
|
||||
network.getDevices()
|
||||
]).then(function(pollData) {
|
||||
var newEnabled = uci.get('usbgadget', 'usb', 'enabled');
|
||||
var statusEl = document.getElementById('status_value');
|
||||
if (statusEl) {
|
||||
@@ -137,6 +152,34 @@ return view.extend({
|
||||
E('span', { 'style': 'color:red' }, '● ' + _('Disabled (Host Mode)'))
|
||||
);
|
||||
}
|
||||
|
||||
// Actualizar interfaces USB con puntitos
|
||||
var ifacesEl = document.getElementById('usb_interfaces');
|
||||
if (ifacesEl) {
|
||||
var newDevices = pollData[1];
|
||||
var newUsbElements = [];
|
||||
newDevices.forEach(function(dev) {
|
||||
var name = dev.getName();
|
||||
if (name && name.match(/^usb\d+$/)) {
|
||||
var isUp = dev.isUp();
|
||||
newUsbElements.push(
|
||||
E('span', { 'style': 'margin-right: 10px;' }, [
|
||||
E('span', { 'style': 'color:' + (isUp ? 'green' : 'red') }, '● '),
|
||||
name
|
||||
])
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
ifacesEl.innerHTML = '';
|
||||
if (newUsbElements.length > 0) {
|
||||
newUsbElements.forEach(function(el) {
|
||||
ifacesEl.appendChild(el);
|
||||
});
|
||||
} else {
|
||||
ifacesEl.appendChild(E('em', {}, _('None')));
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 5);
|
||||
|
||||
|
||||
@@ -26,11 +26,10 @@
|
||||
]
|
||||
},
|
||||
"file": {
|
||||
"/etc/config/usbgadget": ["write"]
|
||||
"/etc/config/usbgadget": ["write"],
|
||||
"/etc/init.d/usb-gadget": ["exec"]
|
||||
},
|
||||
"cgi-io": [
|
||||
"upload",
|
||||
"download",
|
||||
"exec"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user