3 function getConfig(configname)
 
   5   local uci=require("uci")
 
  14   logging = cur.get(config,"logging","enabled") 
 
  16   mqtt_host = cur.get(config,"mqtt","host")
 
  17   mqtt_port = cur.get(config,"mqtt","port")
 
  18   mqtt_id = cur.get(config,"mqtt","id")
 
  19   mqtt_topic = cur.get(config,"mqtt","topic")
 
  21   mqtt_user = cur.get(config,"mqtt","user")
 
  22   mqtt_passwd = cur.get(config,"mqtt","password")
 
  24   if mqtt_host and not mqtt_id then
 
  28   if mqtt_host and not mqtt_port then
 
  32   if mqtt_host and not mqtt_topic then
 
  33     mqtt_topic = 'beaconmon/{type}/{details}'
 
  38 function capture(cmd, raw)
 
  39   local f = assert(io.popen(cmd, 'r'))
 
  40   local s = assert(f:read('*a'))
 
  42   if raw then return s end
 
  43   s = string.gsub(s, '^%s+', '')
 
  44   s = string.gsub(s, '%s+$', '')
 
  45   s = string.gsub(s, '[\n\r]+', ' ')
 
  49 function mqtt_encode(str)
 
  51     str = string.gsub (str, "\n", "")
 
  52     str = string.gsub (str, "/", "-")
 
  57 function printLog(str)
 
  59     capture("logger -t beaconmon "..str)
 
  65 function run_command(cmd)
 
  67   local file = assert(io.popen(cmd, 'r'))
 
  68   local output = file:read('*all')
 
  75   f = assert(io.popen ("hcidump --raw"))
 
  76   run_command("kill `pgrep hcitool`")
 
  77   run_command("hciconfig hci0 down")
 
  78   run_command("hciconfig hci0 up")
 
  79   f_null = assert(io.popen ("hcitool lescan --duplicates"))
 
  86    if type(o) == 'table' then
 
  88       for k,v in pairs(o) do
 
  89          if type(k) ~= 'number' then k = '"'..k..'"' end
 
  90          s = s .. '['..k..'] = ' .. dump(v) .. ','
 
  91 --         s = s .. dump(v) .. ','
 
 100   return (s:gsub("^%s*(.-)%s*$", "%1"))
 
 103 function mqtt_pub(path,value)
 
 104   printLog("Pub "..path.." "..value)
 
 105   return mqtt_client:publish(path,value)
 
 108 function process_packet(packet)
 
 124   if packet:len()>1 then
 
 126     while packet:len()>2 do
 
 127       bytes[idx]=trim(packet:sub(1,3))
 
 133     if bytes[1]=='04' and bytes[2]=='3E' then
 
 136       mac=bytes[13]..':'..bytes[12]..':'..bytes[11]..':'..bytes[10]..':'..bytes[9]..':'..bytes[8]
 
 138       power=tonumber("0x"..bytes[len-1])-256
 
 139       tx=tonumber("0x"..bytes[len])-256
 
 142         paysublen=tonumber('0x'..bytes[j])
 
 143         if bytes[j+1]=="FF" and bytes[j+2]=="4C" and bytes[j+3]=="00" and bytes[j+4]=="02" and bytes[j+5]=="15" then
 
 144           -- Standard UUID iBeacon
 
 146           local uuid1=bytes[j+6]..bytes[j+7]..bytes[j+8]..bytes[j+9]
 
 147           local uuid2=bytes[j+10]..bytes[j+11]
 
 148           local uuid3=bytes[j+12]..bytes[j+13]
 
 149           local uuid4=bytes[j+14]..bytes[j+15]
 
 150           local uuid5=bytes[j+16]..bytes[j+17]..bytes[j+18]..bytes[j+19]..bytes[j+20]..bytes[j+21]
 
 151           uuid=string.lower(uuid1..'-'..uuid2..'-'..uuid3..'-'..uuid4..'-'..uuid5)
 
 152           major=bytes[j+23]..bytes[j+22]
 
 153           minor=bytes[j+25]..bytes[j+24]
 
 157       if type=="ibeacon" then
 
 158         printLog(string.format("{type:'ibeacon',mac:'%s',uuid:'%s',major:'%s',minor:'%s',power:%d,tx:%d}",mac,uuid,major,minor,power,tx))
 
 159         details=uuid..'/'..major..'/'..minor
 
 165       if not (type=="unknown") then
 
 166         mqtt_path=string.gsub(mqtt_topic,"{(.-)}", 
 
 169               return mqtt_encode(type)
 
 170             elseif name=="details" then
 
 171               return mqtt_encode(details)
 
 173               return '{'..name..'}'
 
 177         if not pcall(mqtt_pub,mqtt_path,tx) then
 
 178           printLog('Reconnecting MQTT...')
 
 179           mqtt_client:connect(mqtt_id)
 
 192   for line in inp:lines() do
 
 197     if lchr=="<" or lchr==">" then
 
 198       line = trim(line:sub(2))
 
 201     if not (lchr == " ") then
 
 202       process_packet(packet)
 
 209       packet = packet .. " " .. line
 
 210       process_packet(packet)
 
 213       packet = packet .. " " .. line
 
 223   MQTT = require "paho.mqtt"
 
 224   mqtt_client = MQTT.client.create(mqtt_host, mqtt_port)
 
 226     mqtt_client:auth(mqtt_user, mqtt_passwd)
 
 228   mqtt_client:connect(mqtt_id)