diff --git a/index.ts b/index.ts index b9f2981..8caacc5 100644 --- a/index.ts +++ b/index.ts @@ -11,8 +11,14 @@ import { sendMessage } from "./src/ListSMS"; import {controlMobileData, reconnect, status} from "./src/MobileData"; +import {getSignalInfo, lteBand} from "./src/Signal"; + const huawei = require('./jslib/public'); +async function delay(ms: number) { + return new Promise(res => setTimeout(res, ms)); +} + // @ts-ignore yargs(hideBin(process.argv)) .command('sendSMS', 'send SMS to contact or group of contacts', (yargs) => { @@ -37,7 +43,7 @@ yargs(hideBin(process.argv)) type: "string", }) }, async (argv) => { - huawei.publicKey.rsapadingtype=argv.rsapadingtype||"1"; + huawei.publicKey.rsapadingtype = argv.rsapadingtype || "1"; await login(argv.url, argv.username, argv.password); try { const sessionData = await startSession(argv.url); @@ -51,7 +57,7 @@ yargs(hideBin(process.argv)) } }).command('contacts', 'get contact list with the latest sms messages', (yargs) => { // @ts-ignore - return yargs + return yargs .positional('url', { describe: 'huawei host', default: '192.168.8.1' @@ -74,8 +80,8 @@ yargs(hideBin(process.argv)) default: 'none' }) }, async (argv) => { - huawei.publicKey.rsapadingtype=argv.rsapadingtype||"1"; - await login(argv.url, argv.username, argv.password); + huawei.publicKey.rsapadingtype = argv.rsapadingtype || "1"; + await login(argv.url, argv.username, argv.password); try { const sessionData = await startSession(argv.url); switch (argv.exportFormat) { @@ -162,7 +168,7 @@ yargs(hideBin(process.argv)) default: 'none' }) }, async (argv) => { - huawei.publicKey.rsapadingtype=argv.rsapadingtype||"1"; + huawei.publicKey.rsapadingtype = argv.rsapadingtype || "1"; await login(argv.url, argv.username, argv.password); try { const sessionData = await startSession(argv.url); @@ -216,7 +222,7 @@ yargs(hideBin(process.argv)) default: false }) }, async (argv) => { - huawei.publicKey.rsapadingtype=argv.rsapadingtype||"1"; + huawei.publicKey.rsapadingtype = argv.rsapadingtype || "1"; await login(argv.url, argv.username, argv.password); try { const sessionData = await startSession(argv.url); @@ -266,7 +272,7 @@ yargs(hideBin(process.argv)) default: 'none' }) }, async (argv) => { - huawei.publicKey.rsapadingtype=argv.rsapadingtype||"1"; + huawei.publicKey.rsapadingtype = argv.rsapadingtype || "1"; await login(argv.url, argv.username, argv.password); try { const sessionData = await startSession(argv.url); @@ -310,7 +316,7 @@ yargs(hideBin(process.argv)) type: 'string' }) }, async (argv: any) => { - huawei.publicKey.rsapadingtype=argv.rsapadingtype||"1"; + huawei.publicKey.rsapadingtype = argv.rsapadingtype || "1"; await login(argv.url, argv.username, argv.password); try { const sessionData = await startSession(argv.url); @@ -338,7 +344,7 @@ yargs(hideBin(process.argv)) describe: 'change mobile data to on,off or reconnect', }) }, async (argv: any) => { - huawei.publicKey.rsapadingtype=argv.rsapadingtype||"1"; + huawei.publicKey.rsapadingtype = argv.rsapadingtype || "1"; await login(argv.url, argv.username, argv.password); try { const sessionData = await startSession(argv.url); @@ -382,7 +388,7 @@ yargs(hideBin(process.argv)) default: 'none' }) }, async (argv: any) => { - huawei.publicKey.rsapadingtype=argv.rsapadingtype||"1"; + huawei.publicKey.rsapadingtype = argv.rsapadingtype || "1"; await login(argv.url, argv.username, argv.password); try { const sessionData = await startSession(argv.url); @@ -404,10 +410,73 @@ yargs(hideBin(process.argv)) } finally { await logout(argv.url); } +}).command('signalInfo', 'current device signal status', (yargs: any) => { +// @ts-ignore + return yargs + .positional('url', { + describe: 'huawei host', + default: '192.168.8.1' + }).positional('username', { + describe: 'huawei username', + default: 'admin' + }) + .positional('password', { + describe: 'huawei password', + type: 'string' + }).positional('turn', { + alias: 't', + describe: 'Request Signal info until interrupted', + default: false, + }) +}, async (argv: any) => { + huawei.publicKey.rsapadingtype = argv.rsapadingtype || "1"; + await login(argv.url, argv.username, argv.password); + try { + const sessionData = await startSession(argv.url); + if (argv.turn) { + while (true) { + await getSignalInfo(sessionData); + await delay(2500) + } + } else { + await getSignalInfo(sessionData); + } + } finally { + await logout(argv.url); + } +}).command('changeLteBand', 'change LTE band', (yargs: any) => { +// @ts-ignore + return yargs + .positional('url', { + describe: 'huawei host', + default: '192.168.8.1' + }).positional('username', { + describe: 'huawei username', + default: 'admin' + }) + .positional('password', { + describe: 'huawei password', + type: 'string' + }).positional('band', { + alias: 'band', + describe: 'desirable LTE band number, separated by + char (example 1+3+20).If you want to use every supported bands, write \'AUTO\'.", "AUTO"', + default: 'AUTO', + }) +}, async (argv: any) => { + if (!argv.band){ + throw new Error('Band is empty') + } + huawei.publicKey.rsapadingtype = argv.rsapadingtype || "1"; + await login(argv.url, argv.username, argv.password); + try { + await lteBand(await startSession(argv.url),argv.band); + } finally { + await logout(argv.url); + } }) .option('rsapadingtype', { type: 'string', description: 'rsapadingtype, to check your run in web-console: MUI.LoginStateController.rsapadingtype', - default:'1' + default: '1' }) .parse() diff --git a/package.json b/package.json index c9c6441..a0d9b55 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "huawei-hilink", - "version": "1.1.4", + "version": "1.1.5", "description": "huawei-hilink client", "main": "index.js", "scripts": { @@ -14,6 +14,9 @@ "reconnected": "node index.js mobileData --mode=reconnect --url=192.168.89.1 --password=testPassword", "monitoring": "node index.js monitoring --url=192.168.89.1 --password=testPassword", "messages": "node index.js messages --url=192.168.89.1 --deleteAfter=true --password=testPassword", + "signalInfo": "node index.js signalInfo --url=192.168.89.1 --password=testPassword", + "signalInfoLoop": "node index.js signalInfo --turn=true --url=192.168.89.1 --password=testPassword", + "changeLteBand": "node index.js changeLteBand --url=192.168.89.1 --band=\"AUTO\" --password=testPassword", "lint": "eslint src --ext .ts src", "build": "tsc --build", "lint:fix": "eslint --fix src --ext .ts" diff --git a/src/Signal.ts b/src/Signal.ts new file mode 100644 index 0000000..7fa96c7 --- /dev/null +++ b/src/Signal.ts @@ -0,0 +1,73 @@ +import parser from "xml2js"; + +import {SessionData} from "./startSession"; +import {restCalls} from "./utils/DefaultRestCalls"; +import {getSessionHeaders} from "./utils/HuaweiUtils"; + +const huawei = require('../jslib/public'); + +function _4GType(data:string):string { + if ((data === '20880800C5') || (data === '20000800C5')) { return "AUTO"; } + let dataOut = ""; + if ((parseInt(data, 16) & 0x1) === 0x1) { + dataOut = "B1+"; + } + if ((parseInt(data, 16) & 0x4) === 0x4) { + dataOut += "B3+"; + } + if ((parseInt(data, 16) & 0x40) === 0x40) { + dataOut += "B7+"; + } + if ((parseInt(data, 16) & 0x80000) === 0x80000) { + dataOut += "B20"; + } + dataOut = dataOut.replace(/\++$/, ""); + return dataOut; +} + +export async function getSignalInfo(sessionData: SessionData) { + const mode = await lteMode(sessionData); + const resp = await restCalls.fetchDataRaw(`http://${sessionData.url}/api/device/signal`, 'GET', await getSessionHeaders(sessionData.url)); + if (resp.headers.__requestverificationtoken) { + huawei.publicSession.token2 = resp.headers.__requestverificationtoken; + } + const json = await parser.parseStringPromise(resp.data); + const vars = ['rssi', 'rsrp', 'rsrq', 'sinr', 'dlbandwidth', 'ulbandwidth', 'band', 'cell_id', 'plmn']; + let resultString = ''; + const response = json.response; + for (let i = 0; i < vars.length; i++) { + resultString += ` ${vars[i]}: ${response[vars[i]][0]}`; + } + console.log(`LTE Band: ${_4GType(mode.LTEBand[0])}${resultString}`); +} + +export async function lteMode(sessionData: SessionData) { + const resp = await restCalls.fetchDataRaw(`http://${sessionData.url}/api/net/net-mode`, 'GET', await getSessionHeaders(sessionData.url)); + if (resp.headers.__requestverificationtoken) { + huawei.publicSession.token2 = resp.headers.__requestverificationtoken; + } + const json = await parser.parseStringPromise(resp.data); + return json.response; +} + +export async function lteBand(sessionData: SessionData, band: string) { + let ltesum:string; + if (band.toUpperCase() === "AUTO") { + ltesum = "7FFFFFFFFFFFFFFF"; + } else { + const bs:string[] = band.split("+"); + let ltesum0 = 0; + for (let i = 0; i < bs.length; i++) { + ltesum0 += 2 ** (parseInt(bs[i], 10) - 1); + } + ltesum = ltesum0.toString(16); + } + const data = await huawei.doRSAEncrypt(sessionData, `033FFFFFFF${ltesum}`); + const resp = await restCalls.sendDataRaw(`http://${sessionData.url}/api/net/net-mode`, 'POST', data, await getSessionHeaders(sessionData.url)); + huawei.publicSession.token2 = resp.headers.__requestverificationtoken; + const json = await parser.parseStringPromise(resp.data); + if (json.response !== 'OK') { + throw new Error(`LTEBand changing error: ${JSON.stringify(json)}`); + } + console.log(`LTEBand changed to ${_4GType((await lteMode(sessionData)).LTEBand[0])}`); +} diff --git a/src/startSession.ts b/src/startSession.ts index f09bc76..110c3da 100644 --- a/src/startSession.ts +++ b/src/startSession.ts @@ -48,7 +48,7 @@ export async function logout(url: string) { huawei.publicSession.token2 = resp.headers.__requestverificationtoken; const message = await parser.parseStringPromise(resp.data); if (message.response !== 'OK') { - throw new Error(`Logout error: ${resp}`); + throw new Error(`Logout error: ${resp.data}`); } } }