op-packages/luci-app-sms-tool-js/htdocs/luci-static/resources/view/modem/sendussd.js
github-actions[bot] 32600acc60 🌴 Sync 2026-03-05 23:51:42
2026-03-05 23:51:42 +08:00

386 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict';
'require dom';
'require form';
'require fs';
'require ui';
'require uci';
'require view';
/*
Copyright 2022-2025 Rafał Wabik - IceG - From eko.one.pl forum
Licensed to the GNU General Public License v3.0.
*/
return view.extend({
handleCommand: function(exec, args) {
let buttons = document.querySelectorAll('.cbi-button');
for (let i = 0; i < buttons.length; i++)
buttons[i].setAttribute('disabled', 'true');
return fs.exec(exec, args).then(function(res) {
let out = document.querySelector('.ussdcommand-output');
let fullhistory = document.getElementById('history-full')?.checked;
let reversereplies = document.getElementById('reverse-replies')?.checked;
out.style.display = '';
res.stdout = res.stdout?.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm, "") || '';
res.stderr = res.stderr?.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm, "") || '';
if (res.stdout === undefined || res.stderr === undefined || res.stderr.includes('undefined') || res.stdout.includes('undefined')) {
return;
} else {
let cut = res.stderr;
if ( cut.length > 2 ) {
if (cut.includes('error: 0'))
res.stdout = _('Phone/Modem failure.');
if (cut.includes('error: 1'))
res.stdout = _('No connection to phone.');
if (cut.includes('error: 2'))
res.stdout = _('Phone/Modem adapter link reserved.');
if (cut.includes('error: 3'))
res.stdout = _('Operation not allowed.');
if (cut.includes('error: 4'))
res.stdout = _('Operation not supported.');
if (cut.includes('error: 5'))
res.stdout = _('PH_SIM PIN required.');
if (cut.includes('error: 6'))
res.stdout = _('PH_FSIM PIN required.');
if (cut.includes('error: 7'))
res.stdout = _('PH_FSIM PUK required.');
if (cut.includes('error: 10'))
res.stdout = _('SIM not inserted.');
if (cut.includes('error: 11'))
res.stdout = _('SIM PIN required.');
if (cut.includes('error: 12'))
res.stdout = _('SIM PUK required.');
if (cut.includes('error: 13'))
res.stdout = _('SIM failure.');
if (cut.includes('error: 14'))
res.stdout = _('SIM busy.');
if (cut.includes('error: 15'))
res.stdout = _('SIM wrong.');
if (cut.includes('error: 16'))
res.stdout = _('Incorrect password.');
if (cut.includes('error: 17'))
res.stdout = _('SIM PIN2 required.');
if (cut.includes('error: 18'))
res.stdout = _('SIM PUK2 required.');
if (cut.includes('error: 20'))
res.stdout = _('Memory full.');
if (cut.includes('error: 21'))
res.stdout = _('Invalid index.');
if (cut.includes('error: 22'))
res.stdout = _('Not found.');
if (cut.includes('error: 23'))
res.stdout = _('Memory failure.');
if (cut.includes('error: 24'))
res.stdout = _('Text string too long.');
if (cut.includes('error: 25'))
res.stdout = _('Invalid characters in text string.');
if (cut.includes('error: 26'))
res.stdout = _('Dial string too long.');
if (cut.includes('error: 27'))
res.stdout = _('Invalid characters in dial string.');
if (cut.includes('error: 30'))
res.stdout = _('No network service.');
if (cut.includes('error: 31'))
res.stdout = _('Network timeout.');
if (cut.includes('error: 32'))
res.stdout = _('Network not allowed, emergency calls only.');
if (cut.includes('error: 40'))
res.stdout = _('Network personalization PIN required.');
if (cut.includes('error: 41'))
res.stdout = _('Network personalization PUK required.');
if (cut.includes('error: 42'))
res.stdout = _('Network subset personalization PIN required.');
if (cut.includes('error: 43'))
res.stdout = _('Network subset personalization PUK required.');
if (cut.includes('error: 44'))
res.stdout = _('Service provider personalization PIN required.');
if (cut.includes('error: 45'))
res.stdout = _('Service provider personalization PUK required.');
if (cut.includes('error: 46'))
res.stdout = _('Corporate personalization PIN required.');
if (cut.includes('error: 47'))
res.stdout = _('Corporate personalization PUK required.');
if (cut.includes('error: 48'))
res.stdout = _('PH-SIM PUK required.');
if (cut.includes('error: 100'))
res.stdout = _('Unknown error.');
if (cut.includes('error: 103'))
res.stdout = _('Illegal MS.');
if (cut.includes('error: 106'))
res.stdout = _('Illegal ME.');
if (cut.includes('error: 107'))
res.stdout = _('GPRS services not allowed.');
if (cut.includes('error: 111'))
res.stdout = _('PLMN not allowed.');
if (cut.includes('error: 112'))
res.stdout = _('Location area not allowed.');
if (cut.includes('error: 113'))
res.stdout = _('Roaming not allowed in this location area.');
if (cut.includes('error: 126'))
res.stdout = _('Operation temporary not allowed.');
if (cut.includes('error: 132'))
res.stdout = _('Service operation not supported.');
if (cut.includes('error: 133'))
res.stdout = _('Requested service option not subscribed.');
if (cut.includes('error: 134'))
res.stdout = _('Service option temporary out of order.');
if (cut.includes('error: 148'))
res.stdout = _('Unspecified GPRS error.');
if (cut.includes('error: 149'))
res.stdout = _('PDP authentication failure.');
if (cut.includes('error: 150'))
res.stdout = _('Invalid mobile class.');
if (cut.includes('error: 256'))
res.stdout = _('Operation temporarily not allowed.');
if (cut.includes('error: 257'))
res.stdout = _('Call barred.');
if (cut.includes('error: 258'))
res.stdout = _('Phone/Modem is busy.');
if (cut.includes('error: 259'))
res.stdout = _('User abort.');
if (cut.includes('error: 260'))
res.stdout = _('Invalid dial string.');
if (cut.includes('error: 261'))
res.stdout = _('SS not executed.');
if (cut.includes('error: 262'))
res.stdout = _('SIM Blocked.');
if (cut.includes('error: 263'))
res.stdout = _('Invalid block.');
if (cut.includes('error: 527'))
res.stdout = _('Please wait, and retry your selection later (Specific Modem Sierra).');
if (cut.includes('error: 528'))
res.stdout = _('Location update failure emergency calls only (Specific Modem Sierra).');
if (cut.includes('error: 529'))
res.stdout = _('Selection failure emergency calls only (Specific Modem Sierra).');
if (cut.includes('error: 772'))
res.stdout = _('SIM powered down.');
dom.content(out, [ res.stderr || '', res.stdout ? ' > ' + res.stdout : '' ]);
} else {
if ( fullhistory ) {
const ussdreply = (res.stdout + res.stderr).replace(/^\s*\n+/g, '');
let ussdv = document.getElementById('cmdvalue');
ussdv.value = '';
document.getElementById('cmdvalue').focus();
if (reversereplies) {
out.innerText = ussdreply + (out.innerText.trim() ? '\n\n' + out.innerText : '');
} else {
out.innerText += '\n\n' + res.stdout + res.stderr;
out.innerText = out.innerText.replace(/^\s*\n+/g, '');
}
} else {
dom.content(out, [ res.stdout || '', res.stderr || '' ]);
}
}
}
}).catch(function(err) {
if (res.stdout === undefined || res.stderr === undefined || res.stderr.includes('undefined') || res.stdout.includes('undefined')) {
return;
} else {
ui.addNotification(null, E('p', [ err ]));
}
}).finally(function() {
for (let i = 0; i < buttons.length; i++)
buttons[i].removeAttribute('disabled');
});
},
handleGo: function(ev) {
let ussd = document.getElementById('cmdvalue').value;
let sections = uci.sections('sms_tool_js');
let port = sections[0].ussdport;
let get_ussd = sections[0].ussd;
let get_pdu = sections[0].pdu;
let get_coding = sections[0].coding;
let tool_args = [];
if ( ussd.length < 1 ) {
ui.addNotification(null, E('p', _('Please specify the code to send')), 'info');
return false;
}
if ( !port ) {
ui.addNotification(null, E('p', _('Please set the port for communication with the modem')), 'info');
return false;
}
tool_args.push('-d', port);
if (get_ussd == '1')
tool_args.push('-R');
if (get_pdu == '1')
tool_args.push('-r');
if (get_coding && get_coding != 'auto')
tool_args.push('-c', get_coding);
tool_args.push('ussd', ussd);
return this.handleCommand('sms_tool', tool_args);
},
handleClear: function(ev) {
let out = document.querySelector('.ussdcommand-output');
out.style.display = '';
out.style.display = 'none';
let fullhistory = document.getElementById('history-full')?.checked;
if ( fullhistory ) {
dom.content(out, [ '' ]);
}
let ov = document.getElementById('cmdvalue');
ov.value = '';
document.getElementById('cmdvalue').focus();
},
handleClearOut: function(ev) {
let out = document.querySelector('.ussdcommand-output');
let fullhistory = document.getElementById('history-full')?.checked;
if ( fullhistory ) {
out.style.display = '';
out.style.display = 'none';
dom.content(out, [ '' ]);
document.getElementById("reverse-replies").disabled = false;
document.getElementById("reverse-replies").checked = true;
} else {
document.getElementById("reverse-replies").disabled = true;
document.getElementById("reverse-replies").checked = false;
}
},
handleCopy: function(ev) {
let out = document.querySelector('.ussdcommand-output');
let fullhistory = document.getElementById('history-full')?.checked;
if ( !fullhistory ) {
out.style.display = 'none';
}
let ov = document.getElementById('cmdvalue');
ov.value = '';
let x = document.getElementById('tk').value;
ov.value = x;
},
load: function() {
return Promise.all([
L.resolveDefault(fs.read_direct('/etc/modem/ussdcodes.user'), null),
uci.load('sms_tool_js')
]);
},
render: function (loadResults) {
let info = _('User interface for sending USSD codes using sms-tool. More information about the sms-tool on the %seko.one.pl forum%s.').format('<a href="https://eko.one.pl/?p=openwrt-sms_tool" target="_blank">', '</a>');
return E('div', { 'class': 'cbi-map', 'id': 'map' }, [
E('h2', {}, [ _('USSD Codes') ]),
E('div', { 'class': 'cbi-map-descr'}, info),
E('hr'),
E('div', { 'class': 'cbi-section' }, [
E('div', { 'class': 'cbi-section-node' }, [
E('div', { 'class': 'cbi-value' }, [
E('label', { 'class': 'cbi-value-title' }, [ _('User USSD codes') ]),
E('div', { 'class': 'cbi-value-field' }, [
E('select', { 'class': 'cbi-input-select',
'id': 'tk',
'style': 'margin:5px 0; width:100%;',
'change': ui.createHandlerFn(this, 'handleCopy'),
'mousedown': ui.createHandlerFn(this, 'handleCopy')
},
(loadResults[0] || "").trim().split("\n").map(function(cmd) {
let fields = cmd.split(/;/);
let name = fields[0];
let code = fields[1] || fields[0];
return E('option', { 'value': code }, name );
})
)
])
]),
E('div', { 'class': 'cbi-value' }, [
E('label', { 'class': 'cbi-value-title' }, [ _('Code to send') ]),
E('div', { 'class': 'cbi-value-field' }, [
E('input', {
'style': 'margin:5px 0; width:100%;',
'type': 'text',
'id': 'cmdvalue',
'data-tooltip': _('Press [Enter] to send the code, press [Delete] to delete the code'),
'keydown': function(ev) {
if (ev.keyCode === 13) {
let execBtn = document.getElementById('execute');
if (execBtn) {
execBtn.click();
}
}
if (ev.keyCode === 46) {
let del = document.getElementById('cmdvalue');
if (del) {
let ov = document.getElementById('cmdvalue');
ov.value = '';
document.getElementById('cmdvalue').focus();
}
}
}
}),
])
]),
])
]),
E('div', { 'class': 'right' }, [
E('label', { 'class': 'cbi-checkbox' }, [
E('input', {
'id': 'history-full',
'click': ui.createHandlerFn(this, 'handleClearOut'),
'data-tooltip': _('Check this option if you need to use the menu built on USSD codes'),
'type': 'checkbox',
'name': 'showhistory',
'disabled': null
}), ' ',
E('label', { 'for': 'history-full' }), ' ',
_('Keep the previous reply when sending a new USSD code.')
]),
'\xa0\xa0\xa0',
E('label', { 'class': 'cbi-checkbox' }, [
E('input', {
'id': 'reverse-replies',
'data-tooltip': _('View new reply from top'),
'type': 'checkbox',
'name': 'reversereplies',
'disabled': true
}), ' ',
E('label', { 'for': 'reverse-replies' }), ' ',
_('Turn over the replies.')
])
]),
E('hr'),
E('div', { 'class': 'right' }, [
E('button', {
'class': 'cbi-button cbi-button-remove',
'id': 'clr',
'click': ui.createHandlerFn(this, 'handleClear')
}, [ _('Clear form') ]),
'\xa0\xa0\xa0',
E('button', {
'class': 'cbi-button cbi-button-action important',
'id': 'execute',
'click': ui.createHandlerFn(this, 'handleGo')
}, [ _('Send code') ]),
]),
E('p', _('Reply')),
E('pre', { 'class': 'ussdcommand-output', 'style': 'display:none; border: 1px solid var(--border-color-medium); border-radius: 5px; font-family: monospace' }),
]);
},
handleSaveApply: null,
handleSave: null,
handleReset: null
})