Developing lightweight computation at the DSG edge

qmpinfo.lua 8.12 KB
Newer Older
1
#!/usr/bin/lua
2
3
4
5
6
7
local iwinfo = require "iwinfo"
local util = require "luci.util"
local sys = require "luci.sys"
local nixio = require "nixio"
local uci = luci.model.uci.cursor()
local qmpinfo = {}
p4u's avatar
p4u committed
8
9
local i,d

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

local function tableConcat(t1,t2)
	local _,i
	for _,i in ipairs(t2) do
		table.insert(t1,i)
	end
	return t1
end

local function isInTable(t,e)
	local yes = false
	local _,i
	for _,i in ipairs(t) do
		if i == e then
			yes = true
			break
		end
	end
	return yes
end

local function printr(t)
	local _,i
	for _,i in ipairs(t) do
		print(" " .. tostring(_) .. " -> " .. tostring(i))
35
	end
36
37
38
39
40
41
42
43
44
45
46
47
48
end

function qmpinfo.get_qmp_devices()
	local devs = {}
	local mesh = util.split( uci:get("qmp","interfaces","mesh_devices") or ""," ")
	local lan = util.split(uci:get("qmp","interfaces","lan_devices") or ""," ")
	local wan = util.split(uci:get("qmp","interfaces","wan_devices")or "", " ")
	tableConcat(devs,mesh)
	tableConcat(devs,lan)
	tableConcat(devs,wan)
	return devs
end

49

50
51
52
-- returns all the physical devices as a table
--  in table.wifi only the wifi ones
--  in table.eth only the non-wifi ones
53
54
55
56
function qmpinfo.get_devices()
	local d
	local phydevs = {}
	phydevs.wifi = {}
57
58
	phydevs.all = {}
	phydevs.eth = {}
59
	local ignored = util.split( uci:get("qmp","interfaces","ignore_devices") or ""," ")
60

61
62
	local sysnet = "/sys/class/net/"
	local qmp_devs = qmpinfo.get_qmp_devices()
63

64
	for d in nixio.fs.dir(sysnet) do
65
		local is_qmp_dev = isInTable(qmp_devs,d)
66
		if is_qmp_dev or nixio.fs.stat(sysnet..d..'/device',"type") ~= nil then
67
68
			if is_qmp_dev or (string.find(d,"%.") == nil and string.find(d,"ap") == nil) then
				local ignore = isInTable(ignored,d)
69

70
				if not ignore then
71
					local do_insert = false
72
					if nixio.fs.stat(sysnet..d..'/phy80211',"type") ~= nil then
73
						if string.sub(d, -1) ~= "a" then
74
75
76
77
							if string.sub(d, -2) ~= "ap" then
								table.insert(phydevs.wifi,d)
								do_insert = true
							end
78
						end
79
					else
80

81
82
            local toadd = true
						for e in nixio.fs.dir(sysnet) do
83
84
85
							-- if device e is a switched port of device d (e.g. if e=eth0.1 and d=eth0)
							-- but not if e=eth0_12 and d=eth0
							if toadd == true and string.match(e, d .. '%.') and nixio.fs.stat(sysnet..d..'/upper_'..e,"type") ~= nil then
86
87
								toadd = false
							end
88
						end
89
90

						if toadd == true then
91
							table.insert(phydevs.eth,d)
92
							do_insert = true
93
						end
94
					end
95

96
97
98
					if do_insert then
						table.insert(phydevs.all,d)
					end
99
100
101
102
				end
			end
		end
	end
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
  table.sort(phydevs)
	return phydevs
end


-- Get a sorted array with the wireless (IEEE 802.11) radio devices (e.g. radio0, radio1, radio2)
function qmpinfo.get_radios()

  local rdevices = {}
  local conn = ubus.connect()

  if conn then
    local status = conn:call("network.wireless", "status", {})

    -- Check all the devices returned by the Ubus call
    for k, v in pairs(status) do
      table.insert(rdevices, k)
    end

    conn:close()
  end

  table.sort(rdevices)

  return rdevices
129
130
end

131
-- deprecated
132
function qmpinfo.get_devices_old()
p4u's avatar
p4u committed
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

	ethernet_interfaces = { 'eth' }
	wireless_interfaces = { 'ath', 'wlan' }

	local eth_int = {}
	for i,d in ipairs(sys.net.devices()) do
		for i,r in ipairs(ethernet_interfaces) do
			if string.find(d,r) ~= nil then
				if string.find(d,"%.") == nil  then
					table.insert(eth_int,d)
				end
			end
		end
	end

	local wl_int = {}
	for i,d in ipairs(luci.sys.net.devices()) do
		for i,r in ipairs(wireless_interfaces) do
			if string.find(d,r) ~= nil then
				if string.find(d,"%.") == nil  then
					table.insert(wl_int,d)
				end
			end
		end
	end

	return {eth_int,wl_int}

end
162
163

function qmpinfo.get_modes(dev)
164
	local modes = {}
165
	local iw = iwinfo[iwinfo.type(dev)]
166
167
	if iw ~= nil then modes = iw.hwmodelist(dev) end
	return modes
168

169
170
end

171
172
173
174

function qmpinfo.get_txpower(dev)
	local iw = iwinfo[iwinfo.type(dev)]
	local txpower_supported = {}
175
	if iw ~= nil then
176
		local txp = iw.txpwrlist(dev) or {}
177
178
179
		for _,v in ipairs(txp) do
			table.insert(txpower_supported,v.dbm)
		end
180
	end
181

182
	return txpower_supported
183

184
185
end

186
function qmpinfo.get_channels(dev)
187
188
189
190
191
192
193
194
195
196
197
198
199
200
	local clist = {} -- output channel list
	local iw = iwinfo[iwinfo.type(dev)]
	local ch = {}

	-- if there are not wireless cards, returning a dummy value
	if iw == nil then
		ch.channel=0
		ch.adhoc=false
		ch.ht40p=false
		ch.ht40m=false
		table.insert(clist,ch)
		return clist
	end

201
202
203
204
205
	local freqs = iw.freqlist(dev) --freqs list
	local c -- current channel
	local nc = 0 -- next channel
	local pc = 0 -- previous channel
	local adhoc
206
	local ht40_support = qmpinfo.get_modes(dev).n
207

208
209
210
211
212
213
214

	for i,f in ipairs(freqs) do
		c = f.channel
		ch = {}
		ch.channel = c
		ch.ht40p = false
		ch.ht40m = false
215
216
217
218
219
220

		if not f.restricted then
			ch.adhoc = true
		else
			ch.adhoc = false
		end
221

222
223
		ch.s80211 = true

224
225
		-- 2.4Ghz band
		if c < 15 then
226
			if c < 4 then
227
				ch.ht40p = true
228
229
230

			elseif c < 10 then
				ch.ht40m = true
231
				ch.ht40p = true
232
			else
233
234
				ch.ht40m = true
			end
235

236
237
238
		-- 5Ghz band
		elseif c > 14 then

239
240
241
242
			if #freqs == i then
				nc = nil
			else
				nc = freqs[i+1].channel
243
244
			end

245
246
247
248
249
250
			-- Channels 36 to 140
			if c <= 140 then
				if c % 8 == 0 then
					ch.ht40m = true
				elseif nc ~= nil and nc-c == 4 then
					ch.ht40p = true
251
			end
252

253
254
255
256
257
258
259
			-- Channels 149 to 165
			elseif c >=149 then
				if (c-1) % 8 == 0 then
					ch.ht40m = true
				elseif nc ~= nil and nc-c == 4 then
					ch.ht40p = true
				end
260
261
262
			end

		end
263
264
265
266
267
268
269

		-- If the device does not support ht40, both vars (+/-) are false
		if not ht40_support then
			ch.ht40p = false
			ch.ht40m = false
		end

270
		table.insert(clist,ch)
271

272
	end
273
274
275
	return clist
end

276
277
278

function qmpinfo.get_ipv4()
	local ipv4 = {}
279
	local ipv4_raw = util.exec("ip -4 a | awk '/inet/{print $2}'")
280
	for _,v in ipairs(util.split(ipv4_raw)) do
281
282
283
284
285
286
287
		local match = false
		local i = 1
		while i <= #ipv4 and not match do
			match = string.match(util.trim(v),util.trim(ipv4[i]))
			i = i + 1
		end
		if not match and #util.trim(v) > 1 then
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
			table.insert(ipv4,util.trim(v))
		end
	end
	return ipv4
end

function qmpinfo.get_hostname()
	local hostname = util.exec("cat /proc/sys/kernel/hostname")
	return hostname
end

function qmpinfo.get_uname()
	local uname = util.exec("uname -a")
	return uname
end

304
function qmpinfo.bandwidth_test(ip)
305
        local bwtest = util.trim(util.exec("netperf -6 -p 12865 -H "..ip.." -fm -v0 -P0"))
306
307
308
309
310
311
312
        local result = nil
        if #bwtest < 10 then
                result = bwtest
        end

        return result
end
313

314
315
316
317
318
319
320
321
function qmpinfo.get_wifi_index()
	local k,v
	local windex = {}
	for k,v in pairs(uci:get_all("qmp")) do
			if v.device ~= nil and v.mac ~= nil then
				table.insert(windex,k)
			end
	end
322

323
324
325
	return windex
end

326
327
328
329
330
331
332
333
334
335
336
337
338
339
function qmpinfo.nodes()
	local nodes = util.split(util.exec('bmx6 -c --originators | awk \'{print $1 "|" $3}\' | grep -e ".*:.*:"'))
	local ni
	result = {}
	for _,n in ipairs(nodes) do
		if n ~= "" then
		 ni = util.split(n,"|")
		 ni[1] = util.split(ni[1],".")[1]
		 table.insert(result,ni)
		end
	end
	return result
end

p4u's avatar
p4u committed
340
341
342
343
344
345
346
347
348
349
350
351
352
353
function qmpinfo.links()
	local nodes = util.split(util.exec('bmx6 -c --links | awk \'{print $1 "|" $2}\' |  grep -e ".*:.*:"'))
	local ni
	result = {}
	for _,n in ipairs(nodes) do
		if n ~= "" then
		ni = util.split(n,"|")
		ni[1] = util.split(ni[1],".")[1]
		table.insert(result,ni)
		end
	end
	return result
end

354
function qmpinfo.get_version(option)
355
356
357
358
359
360
361
362
363
364
	local version = nil
	if option == nil or option == "full" then version = util.exec("cat /etc/qmp/qmp.release | grep DESCRIPTION | cut -d= -f2")
	elseif option == "build" then version = util.exec("cat /etc/qmp/qmp.release | grep BUILDDATE | cut -d= -f2")
	elseif option == "branch" then version = util.exec("cat /etc/qmp/qmp.release | grep BRANCH | cut -d= -f2")
	elseif option == "codename" then version = util.exec("cat /etc/qmp/qmp.release | grep CODENAME | cut -d= -f2")
	elseif option == "release" then version = util.exec("cat /etc/qmp/qmp.release | grep RELEASE | cut -d= -f2")
	elseif option == "revision" then version = util.exec("cat /etc/qmp/qmp.release | grep REVISION | cut -d= -f2")
	else version = nil
	end
	return version
365
end
p4u's avatar
p4u committed
366

367
368
369
370
371
372
373
374
375
function qmpinfo.get_key()
	local keyf = util.exec("uci get qmp.node.key")
	if #keyf < 2 then
		keyf = "/tmp/qmp_key"
	end
	local key = util.split(util.exec("cat "..keyf))[1]
	return key
end

376
return qmpinfo