import JsonRpc from 'node-jsonrpc-client' import esMain from 'es-main' import Debug from 'debug' const debug = Debug('rut950') const defaultOpts = () => ({ url: process.env.RUT950_UBUS_URL || 'http://192.168.1.1/ubus', username: process.env.RUT950_USERNAME || 'admin', password: process.env.RUT950_PASSWORD || 'admin01' }) const EMPTY_SESSID = '00000000000000000000000000000000' const UBUS_STATUS_CODE = [ 'UBUS_STATUS_OK', 'UBUS_STATUS_INVALID_COMMAND', 'UBUS_STATUS_INVALID_ARGUMENT', 'UBUS_STATUS_METHOD_NOT_FOUND', 'UBUS_STATUS_NOT_FOUND', 'UBUS_STATUS_NO_DATA', 'UBUS_STATUS_PERMISSION_DENIED', 'UBUS_STATUS_TIMEOUT', 'UBUS_STATUS_NOT_SUPPORTED', 'UBUS_STATUS_UNKNOWN_ERROR', 'UBUS_STATUS_CONNECTION_FAILED', 'UBUS_STATUS_NO_MEMORY', 'UBUS_STATUS_PARSE_ERROR', 'UBUS_STATUS_SYSTEM_ERROR', ] export class Rut950 { constructor (opts = {}) { opts = { ...defaultOpts(), ...opts } this.client = new JsonRpc(opts.url) this.opts = opts } async init () { debug('call', 'session.login') const res = await this.client.call('call', [ EMPTY_SESSID, 'session', 'login', { username: this.opts.username, password: this.opts.password } ]) if (!res.result || !res.result.length === 2) { throw new Error('received invalid response') } debug('res', res) const [code, data] = res.result if (code !== 0) { throw new Error('Error: ' + UBUS_STATUS_CODE[code]) } this.sessid = data.ubus_rpc_session } async call (...params) { if (!this.sessid) await this.init() debug('call', this.sessid, params) const res = await this.client.call('call', [ this.sessid, ...params ]) debug('res', res) if (res.error) { const err = new Error('RUT950 error: ' + res.error.message) err.code = res.error.code throw err } const result = res.result if (!result) throw new Error('Received invalid response') const [code, data] = result if (code !== 0 || !data) { throw new Error('received error: ' + UBUS_STATUS_CODE[code]) } return res.result[1] } } export async function demo() { const rut = new Rut950() let iwinfo = await rut.call('iwinfo', 'info', { device: 'wlan0' }) console.log('IWINFO', iwinfo) //let uci = await rut.call('uci', 'show') console.log('call uci show') let uci = await rut.call('file', 'exec', { command: 'uci', params: ['show'] }) const res = uci.stdout const data = {} const lines = res.split('\n') for (const line of lines) { const [key, value] = line.split('=') data[key] = value //const keyParts = key.split('.') //let part = data //let last = keyParts.pop() //console.log(keyParts, last, value) //for (const keyPart of keyParts) { // if (!part[keyPart]) part[keyPart] = {} // part = part[keyPart] //} } console.log('UCI', data) //console.log('UCI', JSON.stringify(uci)) }