From: Roman Bazalevskiy <rvb@rvb.name> Date: Sun, 19 Mar 2017 19:15:40 +0000 (+0300) Subject: BLE beacon scan added (initial commit, still too many TODOs) X-Git-Url: https://git.rvb.name/openhab-process.git/commitdiff_plain/254111f3712b8ac6dceeffe2518340e8ada36888?ds=sidebyside;hp=-c BLE beacon scan added (initial commit, still too many TODOs) --- 254111f3712b8ac6dceeffe2518340e8ada36888 diff --git a/mqtt-bt/scan-beacons b/mqtt-bt/scan-beacons new file mode 100644 index 0000000..747c295 --- /dev/null +++ b/mqtt-bt/scan-beacons @@ -0,0 +1,123 @@ +#!/usr/bin/env lua + +function run_command(cmd) + + local file = assert(io.popen(cmd, 'r')) + local output = file:read('*all') + file:close() + +end + +function open_dump() + + f = assert(io.popen ("hcidump --raw")) + run_command("kill `pgrep hcitool`") + run_command("hciconfig hci0 down") + run_command("hciconfig hci0 up") + f_null = assert(io.popen ("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 process_packet(packet) + + bytes={} + idx=1 + + 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 + j = 15 + while j<len-2 do + paysublen=tonumber('0x'..bytes[j]) + 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 + -- Standard UUID iBeacon + type="ibeacon" + uuid1=bytes[j+6]..bytes[j+7]..bytes[j+8]..bytes[j+9] + uuid2=bytes[j+10]..bytes[j+11] + uuid3=bytes[j+12]..bytes[j+13] + uuid4=bytes[j+14]..bytes[j+15] + uuid5=bytes[j+16]..bytes[j+17]..bytes[j+18]..bytes[j+19]..bytes[j+20]..bytes[j+21] + uuid=string.lower(uuid1..'-'..uuid2..'-'..uuid3..'-'..uuid4..'-'..uuid5) + major=bytes[j+23]..bytes[j+22] + minor=bytes[j+25]..bytes[j+24] + end + j=j+1+paysublen + end + if type=="ibeacon" then + print(string.format("{type:'ibeacon',mac:'%s',uuid:'%s',major:'%s',minor:'%s',power:%d,tx:%d}",mac,uuid,major,minor,power,tx)) + else + print(dump(bytes)) + end + end + end + +end + +function read_loop() + + packet = "" + + for line in inp:lines() do + + lchr=line:sub(1,1) + line=trim(line) + + if lchr=="<" or lchr==">" 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 + +inp = open_dump() + +read_loop()