#!/usr/bin/lua function getConfig(configname) local uci=require("uci") local cur=uci.cursor() local config if configname then config=configname else config="beacon" end logging = cur.get(config,"logging","enabled") mqtt_host = cur.get(config,"mqtt","host") mqtt_port = cur.get(config,"mqtt","port") mqtt_id = cur.get(config,"mqtt","id") mqtt_topic = cur.get(config,"mqtt","topic") mqtt_user = cur.get(config,"mqtt","user") mqtt_passwd = cur.get(config,"mqtt","password") if mqtt_host and not mqtt_id then mqtt_id="beaconmon" end if mqtt_host and not mqtt_port then mqtt_port = 1883 end if mqtt_host and not mqtt_topic then mqtt_topic = 'beaconmon/{type}/{details}' end end function capture(cmd, raw) local f = assert(io.popen(cmd, 'r')) local s = assert(f:read('*a')) f:close() if raw then return s end s = string.gsub(s, '^%s+', '') s = string.gsub(s, '%s+$', '') s = string.gsub(s, '[\n\r]+', ' ') return s end function mqtt_encode(str) if (str) then str = string.gsub (str, "\n", "") str = string.gsub (str, "/", "-") end return str end function printLog(str) if logging=="on" then capture("logger -t beaconmon "..str) else print(str) end end function run_command(cmd) local file = assert(io.popen(cmd, 'r')) local output = file:read('*all') file:close() end function open_dump() run_command("/bin/kill `/usr/bin/pgrep hcidump`") run_command("/bin/kill `/usr/bin/pgrep hcitool`") f = assert(io.popen ("/usr/bin/hcidump --raw")) run_command("/usr/bin/hciconfig hci0 down") run_command("/usr/bin/hciconfig hci0 up") f_null = assert(io.popen ("/usr/bin/hcitool lescan --duplicates")) return f end function dump(o) if type(o) == 'table' then local s = '{ ' for k,v in pairs(o) do if type(k) ~= 'number' then k = '"'..k..'"' end s = s .. '['..k..'] = ' .. dump(v) .. ',' -- s = s .. dump(v) .. ',' end return s .. '} ' else return tostring(o) end end function trim(s) return (s:gsub("^%s*(.-)%s*$", "%1")) end function mqtt_pub(path,value) printLog("Pub "..path.." "..value) return mqtt_client:publish(path,value) end function process_packet(packet) local bytes={} local idx=1 local len local mac local flags local power local tx local type local paysublen local uuid local major local minor local details if packet:len()>1 then while packet:len()>2 do bytes[idx]=trim(packet:sub(1,3)) idx=idx+1 packet=packet:sub(4) end len = idx-1 if bytes[1]=='04' and bytes[2]=='3E' then -- BLE Beacon? type="" mac=bytes[13]..':'..bytes[12]..':'..bytes[11]..':'..bytes[10]..':'..bytes[9]..':'..bytes[8] flags=bytes[14] power=tonumber("0x"..bytes[len-1])-256 tx=tonumber("0x"..bytes[len])-256 local j = 15 while j" then line = trim(line:sub(2)) end if not (lchr == " ") then process_packet(packet) packet = "" end llen=line:len() if llen<59 then packet = packet .. " " .. line process_packet(packet) packet="" else packet = packet .. " " .. line end end end getConfig(arg[1]) if mqtt_host then MQTT = require "paho.mqtt" mqtt_client = MQTT.client.create(mqtt_host, mqtt_port) if mqtt_user then mqtt_client:auth(mqtt_user, mqtt_passwd) end mqtt_client:connect(mqtt_id) end inp = open_dump() read_loop()