fix: 优化断网处理
This commit is contained in:
+2
-2
@@ -115,7 +115,7 @@
|
||||
<article class="bento-control">
|
||||
<span class="eyebrow">mobile data</span>
|
||||
<h3 id="mobileDataState">--</h3>
|
||||
<p id="mobileDataHint">启动时会自动关闭移动数据。</p>
|
||||
<p id="mobileDataHint">启动时会自动断开应用层拨号。</p>
|
||||
<div class="bento-control__actions">
|
||||
<button class="button button--secondary button--compact" id="mobileDataToggle" type="button"
|
||||
data-action="disable">强制关闭流量</button>
|
||||
@@ -379,4 +379,4 @@
|
||||
<script src="/assets/admin.js" type="module"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
+11
-10
@@ -184,25 +184,26 @@ function renderMobileData(mobileData = {}) {
|
||||
const enabled = Boolean(mobileData.enabled || mobileData.anyActive);
|
||||
const cid = mobileData.cid || 1;
|
||||
const mode = formatMobileDataMode(mobileData.mode);
|
||||
const isMipcall = mobileData.mode === 'mipcall';
|
||||
const activeContexts = formatMobileDataContexts(mobileData.contexts || []);
|
||||
|
||||
if (unknown) {
|
||||
setText(elements.mobileDataSummary, '未知');
|
||||
setText(elements.mobileDataState, '状态未知');
|
||||
setText(elements.mobileDataHint, mobileData.error || '未能确认移动数据状态,可先强制关闭。');
|
||||
elements.mobileDataToggle.textContent = '强制关闭流量';
|
||||
setText(elements.mobileDataHint, mobileData.error || (isMipcall ? '未能确认应用层拨号状态,可先强制断开。' : '未能确认移动数据状态,可先强制关闭。'));
|
||||
elements.mobileDataToggle.textContent = isMipcall ? '强制断开拨号' : '强制关闭流量';
|
||||
elements.mobileDataToggle.dataset.action = 'disable';
|
||||
} else if (enabled) {
|
||||
setText(elements.mobileDataSummary, '已开启');
|
||||
setText(elements.mobileDataState, '流量已开启');
|
||||
setText(elements.mobileDataSummary, isMipcall ? '已连接' : '已开启');
|
||||
setText(elements.mobileDataState, isMipcall ? '应用拨号已连接' : '流量已开启');
|
||||
setText(elements.mobileDataHint, activeContexts ? `${mode} 检测到 ${activeContexts} 处于活动状态。` : `CID ${cid} 处于活动状态。`);
|
||||
elements.mobileDataToggle.textContent = '关闭流量';
|
||||
elements.mobileDataToggle.textContent = isMipcall ? '断开拨号' : '关闭流量';
|
||||
elements.mobileDataToggle.dataset.action = 'disable';
|
||||
} else {
|
||||
setText(elements.mobileDataSummary, '已关闭');
|
||||
setText(elements.mobileDataState, '流量已关闭');
|
||||
setText(elements.mobileDataHint, `${mode} CID ${cid} 未建立移动数据连接,重启后也会先保持关闭。`);
|
||||
elements.mobileDataToggle.textContent = '开启流量';
|
||||
setText(elements.mobileDataSummary, isMipcall ? '已断开' : '已关闭');
|
||||
setText(elements.mobileDataState, isMipcall ? '应用拨号已断开' : '流量已关闭');
|
||||
setText(elements.mobileDataHint, isMipcall ? `${mode} CID ${cid} 未建立应用层拨号连接;已保护性尝试停用PDP。` : `${mode} CID ${cid} 未建立移动数据连接,重启后也会先保持关闭。`);
|
||||
elements.mobileDataToggle.textContent = isMipcall ? '开启拨号' : '开启流量';
|
||||
elements.mobileDataToggle.dataset.action = 'enable';
|
||||
}
|
||||
|
||||
@@ -674,7 +675,7 @@ async function toggleMobileData() {
|
||||
body: JSON.stringify({ enabled })
|
||||
});
|
||||
renderMobileData(result.data || {});
|
||||
setStatusMessage(elements.mobileDataStatus, result.message || (enabled ? '移动数据已开启。' : '移动数据已关闭。'), 'success');
|
||||
setStatusMessage(elements.mobileDataStatus, result.message || (enabled ? '已开启。' : '已关闭。'), 'success');
|
||||
await refreshLogs();
|
||||
} catch (err) {
|
||||
setStatusMessage(elements.mobileDataStatus, err.message, 'error');
|
||||
|
||||
+5
-1
@@ -496,9 +496,13 @@ class APIServer {
|
||||
}
|
||||
|
||||
const mobileData = await this.modem.setMobileDataEnabled(req.body.enabled);
|
||||
const message = mobileData.mode === 'mipcall'
|
||||
? (req.body.enabled ? '应用层拨号已开启' : '应用层拨号已断开')
|
||||
: (req.body.enabled ? '移动数据已开启' : '移动数据已关闭');
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: req.body.enabled ? '移动数据已开启' : '移动数据已关闭',
|
||||
message,
|
||||
data: mobileData
|
||||
});
|
||||
} catch (err) {
|
||||
|
||||
+70
-8
@@ -544,19 +544,62 @@ class ModemManager extends EventEmitter {
|
||||
|
||||
async disableMobileData(options = {}) {
|
||||
const mode = this.getMobileDataMode();
|
||||
if (mode === 'mipcall') {
|
||||
return await this.disableMipcallMobileData(options);
|
||||
}
|
||||
|
||||
return await this.disableCgactMobileData(options);
|
||||
}
|
||||
|
||||
async disableMipcallMobileData(options = {}) {
|
||||
const before = await this.getMobileDataStatus();
|
||||
const cids = this.getMobileDataTargetCids(before);
|
||||
const label = mode === 'mipcall' ? '关闭移动数据拨号' : '停用PDP数据连接';
|
||||
let commandSucceeded = false;
|
||||
|
||||
logger.info(`${options.reason || '手动操作'}: 关闭移动数据,避免流量消耗`);
|
||||
logger.info(`${options.reason || '手动操作'}: 断开ML307应用层拨号连接,避免流量消耗`);
|
||||
|
||||
for (const cid of cids) {
|
||||
const command = this.getMobileDataCommand(mode, false, cid);
|
||||
const resp = await this.sendATWithRetry(command, {
|
||||
try {
|
||||
await this.sendATWithRetry(this.getMobileDataCommand('mipcall', false, cid), {
|
||||
timeout: 8000,
|
||||
retries: 1,
|
||||
label: `断开应用层拨号(CID ${cid})`,
|
||||
required: true
|
||||
});
|
||||
} catch (err) {
|
||||
err.mobileDataCritical = true;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
const status = await this.waitForMobileDataState(false, options.timeout || 8000);
|
||||
if (status.anyActive) {
|
||||
const err = new Error(`MIPCALL断开后仍检测到活动连接: ${this.formatMobileDataContexts(status.contexts)}`);
|
||||
err.mobileDataCritical = true;
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (status.status === 'unknown') {
|
||||
logger.warn('MIPCALL断开命令已成功发送,但状态未确认');
|
||||
}
|
||||
|
||||
await this.tryDeactivatePdpContexts(cids);
|
||||
|
||||
logger.info('✓ 应用层拨号连接已断开');
|
||||
return status;
|
||||
}
|
||||
|
||||
async disableCgactMobileData(options = {}) {
|
||||
const before = await this.getMobileDataStatus();
|
||||
const cids = this.getMobileDataTargetCids(before);
|
||||
let commandSucceeded = false;
|
||||
|
||||
logger.info(`${options.reason || '手动操作'}: 停用PDP数据连接,避免流量消耗`);
|
||||
|
||||
for (const cid of cids) {
|
||||
const resp = await this.sendATWithRetry(this.getMobileDataCommand('cgact', false, cid), {
|
||||
timeout: 8000,
|
||||
retries: 1,
|
||||
label: `${label}(CID ${cid})`,
|
||||
label: `停用PDP数据连接(CID ${cid})`,
|
||||
required: false
|
||||
});
|
||||
|
||||
@@ -592,6 +635,21 @@ class ModemManager extends EventEmitter {
|
||||
return status;
|
||||
}
|
||||
|
||||
async tryDeactivatePdpContexts(cids) {
|
||||
for (const cid of cids) {
|
||||
const resp = await this.sendATWithRetry(this.getMobileDataCommand('cgact', false, cid), {
|
||||
timeout: 8000,
|
||||
retries: 1,
|
||||
label: `保护性停用PDP(CID ${cid})`,
|
||||
required: false
|
||||
});
|
||||
|
||||
if (!resp) {
|
||||
logger.warn(`保护性停用PDP(CID ${cid})未成功,已按MIPCALL断开结果继续`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async forceMobileDataOff(stage) {
|
||||
this.mobileData.desiredEnabled = false;
|
||||
try {
|
||||
@@ -601,6 +659,10 @@ class ModemManager extends EventEmitter {
|
||||
timeout: 5000
|
||||
});
|
||||
} catch (err) {
|
||||
if (err.mobileDataCritical) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
logger.warn(`${stage}: 移动数据关闭未确认: ${err.message}`);
|
||||
return this.getCachedMobileDataStatus();
|
||||
}
|
||||
@@ -792,7 +854,7 @@ class ModemManager extends EventEmitter {
|
||||
await this.waitSIMReady();
|
||||
await this.ensureFullFunctionality();
|
||||
|
||||
// 4. 启动保护:先关闭移动数据拨号,再等待短信所需的网络注册。
|
||||
// 4. 启动保护:先断开应用层拨号,再等待短信所需的网络注册。
|
||||
await this.forceMobileDataOff('启动保护(CFUN=1后)');
|
||||
|
||||
// 5. 等待网络注册
|
||||
@@ -810,7 +872,7 @@ class ModemManager extends EventEmitter {
|
||||
this.ready = false;
|
||||
}
|
||||
|
||||
// 6. 驻网后再关一次,防止模组自动拨号在驻网完成后重新拉起。
|
||||
// 6. 驻网后再断开一次,防止模组自动拨号在驻网完成后重新拉起。
|
||||
await this.forceMobileDataOff('启动保护(驻网后)');
|
||||
|
||||
// 7. 按文档配置短信功能,并启用本项目需要的PDU模式
|
||||
|
||||
Reference in New Issue
Block a user