diff --git a/hoodselector/files/usr/sbin/hoodselector b/hoodselector/files/usr/sbin/hoodselector index cbe5c590061e7a6c5040ed3d750f477dcac68e00..1813e6dce5f881c64db492f4f7189dd2758225a6 100755 --- a/hoodselector/files/usr/sbin/hoodselector +++ b/hoodselector/files/usr/sbin/hoodselector @@ -35,21 +35,23 @@ -- PID file to ensure the hoodselector isn't running parallel local pidPath="/var/run/hoodselector.pid" -if io.open(pidPath, "r") ~=nil then +if io.open(pidPath, 'r') ~= nil then io.stderr:write("The hoodselector is still running.\n") os.exit(1) else - io.close(io.open(pidPath, "w")) + io.close(io.open(pidPath, 'w')) end -local json = require ("dkjson") +local json = require ('dkjson') local uci = require('luci.model.uci').cursor() -local file = '/lib/ffnw/hoods/hoods.json' +local file = "/lib/ffnw/hoods/hoods.json" -- initialization done -- Read the full hoodfile. Return nil for wrong format or no such file local function readHoodfile(file) - local obj, pos, err = json.decode (io.popen(string.format("cat %s",file), 'r'):read('*a'), 1, nil) + local jhood = io.open(file, 'r') + if not jhood then return nil end + local obj, pos, err = json.decode (jhood:read('*a'), 1, nil) if err then return nil else @@ -59,75 +61,13 @@ end -- Program terminating function including removing of PID file local function exit() - if io.open(pidPath, "r") ~=nil then + if io.open(pidPath, 'r') ~= nil then os.remove(pidPath) end os.exit(0) end -function trim(s) - -- from PiL2 20.4 - return (s:gsub("^%s*(.-)%s*$", "%1")) -end - -function sleep(n) - os.execute("sleep " .. tonumber(n)) -end - ---- --- Function to retrieve console output --- -function os.capture(cmd, raw) - local handle = assert(io.popen(cmd, 'r')) - local output = assert(handle:read('*a')) - - handle:close() - - if raw then - return output - end - - output = string.gsub( - string.gsub( - string.gsub(output, '^%s+', ''), - '%s+$', - '' - ), - '[\n\r]+', - ' ' - ) - - return output -end - - -local function vpn_stop() - os.execute('/etc/init.d/fastd stop') - io.stderr:write('VPN stopped.\n') -end - -local function vpn_start() - os.execute('/etc/init.d/fastd start') - io.stderr:write('VPN started.\n') -end - -local function vpn_disable() - -- disable VPN if not already disabled - os.execute('/etc/init.d/fastd disable') - io.stderr:write('VPN disabled.\n') -end - -local function vpn_enable() - -- enable VPN if not already enabled - os.execute('/etc/init.d/fastd enable') -end - -local function wireless_restart() - os.execute('wifi') - io.stderr:write('Wireless restarted.\n') -end - --- Return a wifi device list +-- Get a list of wifi devices return an emty table for no divices local function getWifiDevices() local radios = {} uci:foreach('wireless', 'wifi-device', @@ -138,205 +78,16 @@ local function getWifiDevices() return radios end --- This method returns an one dimensional array containing the SSIDs for the --- Freifunk mesh network configured in the site.conf (on dualband routers --- one can have two mesh SSIDs. One for 2,4Ghz and one for 5Ghz). -local function get_mesh_ssids() - local site_src = "/lib/gluon/site.json" - local site, pos, err = json.decode (io.popen(string.format("cat %s",site_src), 'r'):read('*a'), 1, nil) - if err then - io.stderr:write("Error reading file " .. site_src .. "\n") - io.stderr:write("Existing...\n") - exit() - end - - local ssids = {} - if(site.wifi24.ibss.ssid ~= nil) then - table.insert(ssids, site.wifi24.ibss.ssid) - end - - if(site.wifi5.ibss.ssid ~= nil) then - table.insert(ssids, site.wifi5.ibss.ssid) - end - - return ssids -end - --- Scans for wireless networks and returns a two dimensional array containing --- wireless networks and their properties. --- The array is sorted descending by signal strength (strongest signal --- first, usually the local signal of the wireless chip of the router) -local function wlan_list_sorted(radios) - local networks = {} - for index, radio in ipairs(radios) do - local ifname = uci:get('wireless', 'ibss_' .. radio, 'ifname') - if(ifname ~= nil) then - local wireless_scan = string.format( "iw %s scan", ifname) - local row = {} - row["encryption"] = "open" - row["radio"] = radio - -- loop through each line in the output of iw - for wifiscan in io.popen(wireless_scan, 'r'):lines() do - -- the following line matches a new network in the output of iw - if wifiscan:match("BSS (%w+:%w+:%w+:%w+:%w+:%w+)") then - if(row["bssid"] ~= nil and row["quality"] ~= nil - and row["ssid"] ~= nil and row["capability"] ~= nil) then - table.insert(networks, row) - row = {} - row["encryption"] = "open" - row["radio"] = radio - end - end - - -- get encryption - if wifiscan:match("WPA:") then - row["encryption"] = "WPA" - end - if wifiscan:match("WEP:") then - row["encryption"] = "WEP" - end - if wifiscan:match("RSN:") then - row["encryption"] = "RSN" - end - - -- get ssid - if wifiscan:match("SSID:") then - row["ssid"] = wifiscan:split(":") - row["ssid"] = row["ssid"][2] - if(row["ssid"] ~= nil) then - row["ssid"] = trim(row["ssid"]) - end - end - - -- get frequency - if wifiscan:match("freq:") then - row["frequency"] = wifiscan:split(":") - row["frequency"] = row["frequency"][2] - if(row["frequency"] ~= nil) then - row["frequency"] = trim(row["frequency"]) - end - end - - -- get client/adhoc mode - if wifiscan:match("capability:") then - row["capability"] = wifiscan:split(":") - row["capability"] = row["capability"][2] - if(row["capability"] ~= nil) then - row["capability"] = trim(row["capability"]) - end - end - - -- get bssid - if wifiscan:match("(%w+:%w+:%w+:%w+:%w+:%w+)") then - row["bssid"] = wifiscan:match("(%w+:%w+:%w+:%w+:%w+:%w+)"):upper() - end - - -- get signal strength - if wifiscan:match("signal:") then - row["quality"] = wifiscan:split(" ") - row["quality"] = row["quality"][2]:split(".") - if row["quality"][1]:match("-") then - row["quality"] = row["quality"][1]:split("-") - end - row["quality"] = tonumber(row["quality"][2]:match("(%d%d)")) - end - end - end - end - - table.sort(networks, function(a,b) return a["quality"] < b["quality"] end) - return networks -end - -local function get_wlan_mesh_networks(wlan_list) - local mesh_wlan_list = {} - local mesh_ssids = get_mesh_ssids() - - for n,wlan in pairs(wlan_list) do - for i,ssid in pairs(mesh_ssids) do - if(string.match(wlan["ssid"], ssid)) then - table.insert(mesh_wlan_list, wlan) - break - end - end - end - - return mesh_wlan_list -end - --- this method removes the wireless network of the router itself --- from the wlan_list -local function filter_my_wlan_network(wlan_list) - local filtered_wlan_list = {} - - for n,wlan in pairs(wlan_list) do - if(wlan.quality ~= 0) then - table.insert(filtered_wlan_list, wlan) - end - end - - return filtered_wlan_list -end - -local function filter_default_hood_wlan_networks(default_hood, wlan_list) - local filtered_wlan_list = {} - - for n,wlan in pairs(wlan_list) do - if(default_hood.bssid ~= wlan.bssid) then - table.insert(filtered_wlan_list, wlan) - end - end - - return filtered_wlan_list -end - --- bool if direct VPN +-- bool if direct VPN. The detection is realaise by searching the fastd network interface inside the originator table local function directVPN() - local uci_vpn_net = uci:get('fastd', 'mesh_vpn_backbone', 'net') - local uci_vpn_ifname = uci:get('network', uci_vpn_net, 'ifname') - -- escape special chars "[]-" - uci_vpn_ifname = uci_vpn_ifname:gsub("%-", "%%-") - local testString = '%[ '..uci_vpn_ifname..'%]' - for outgoingIF in io.popen(string.format("cat /sys/kernel/debug/batman_adv/bat0/originators"), 'r'):lines() do - if outgoingIF:match(testString) then + for outgoingIF in io.open("/sys/kernel/debug/batman_adv/bat0/originators", 'r'):lines() do + if outgoingIF:match(string.gsub("%[ " .. uci:get('fastd', 'mesh_vpn_backbone', 'net') .. "%]","%_",'-'):gsub("%-", "%%-")) then return true end end return false end --- Retun a table of current peers from /etc/config/fastd -local function getCurrentPeers() - local configPeername = {} - local configPeers = {} - uci:foreach('fastd', 'peer', - function(s) - if s['.name'] then - table.insert(configPeername,s) - end - end - ) - for _,index in pairs(configPeername) do - for prefix,peer in pairs(index) do - local tmpPeer = {} - if prefix:match(".name") then - if peer:match("mesh_vpn_backbone_peer_") then - local tmpRemote = uci:get('fastd', peer, 'remote') - tmpRemote = tmpRemote[1]:split(" ") - local remote = {} - remote['host'] = tmpRemote[1] - remote[tmpRemote[2]] = tmpRemote[3] - tmpPeer['key'] = tostring(uci:get('fastd', peer, 'key')) - tmpPeer['remote'] = remote - configPeers[peer] = tmpPeer - end - end - end - end - return configPeers -end - - -- Get Geoposition if no static position present try lwtrace. Return nil for no position local function getGeolocation() local lat = uci:get('gluon-node-info', uci:get_first('gluon-node-info', 'location'), 'latitude') @@ -346,10 +97,10 @@ local function getGeolocation() if string.find(scan,"(lat)") then local last_val = nil for geo in string.gmatch(scan,"[^%s]+") do - if geo == '(lat)' then + if geo == "(lat)" then lat = last_val end - if geo == '(lon)' then + if geo == "(lon)" then lng = last_val end last_val = geo @@ -375,142 +126,141 @@ local function getHoodByGeo(jhood,geo) return nil end --- This method checks if the VPN configuration needs to be rewritten from the --- hoodfile. Therefore the method performs 3 checks and returns false if all --- checks fail. If one of the checks results to true the method returns true: --- 1. Check if the local VPN configuratin has a server that does not exist --- in the hoodfile. --- 2. Check if a server that does exist in the local VPN configuration AND --- in the hoodfile has a configuration change. --- 3. Check if the hoodfile contains a server that does not exist in the --- local VPN configuration. -local function vpn_reconfiguration_needed(hood_serverlist) - local local_serverlist = getCurrentPeers() - - -- Checks 1. and 2. - for local_server_config_name, local_server in pairs(local_serverlist) do - local local_server_exists_in_hoodfile = false - for hood_server_index,hood_server in pairs(hood_serverlist) do - if (local_server_config_name == 'mesh_vpn_backbone_peer_'.. hood_server["host"]:split('.')[1]) then - local_server_exists_in_hoodfile = true - if ( local_server.key ~= hood_server['publickey'] ) then - return true - end - local hood_server_host = '\"'..hood_server["host"]..'\"' - if ( local_server.remote.host ~= hood_server_host ) then - return true - end - if ( local_server.remote.port ~= hood_server['port'] ) then - return true - end - end - end - if not(local_server_exists_in_hoodfile) then return true end - end - - -- Check 3. - for hood_server_index,hood_server in pairs(hood_serverlist) do - local hood_server_exists_locally = false - for local_server_config_name, local_server in pairs(local_serverlist) do - if (local_server_config_name == 'mesh_vpn_backbone_peer_'.. hood_server["host"]:split('.')[1]) then - hood_server_exists_locally = true - end - end - if not(hood_server_exists_locally) then return true end - end - - return false -end - --- Reconfigure fastd -local function vpn_reconfigure(hood_serverlist) - -- remove all servers - local local_serverlist = getCurrentPeers() - for config_index, local_server in pairs(local_serverlist) do - uci:delete('fastd',config_index) - end - - -- add servers from hoodfile - local group = 'mesh_vpn_backbone' - for i,hood_server in pairs(hood_serverlist) do - uci:section('fastd', 'peer', group .. '_peer_' .. hood_server.host:split('.')[1], - { - enabled = 1, - net = 'mesh_vpn', - group = group, - key = hood_server.publickey, - remote = {'\"'..hood_server.host..'\"'..' port '..hood_server.port} - } - ) - end - - uci:save('fastd') - uci:commit('fastd') - io.stderr:write('Fastd needed reconfiguration. Stopped and applied new settings.\n') -end - --- Checks if wireless needs a reconfiguration. Returns true if any of the checks --- passes. Otherwise the method returns false. -local function wireless_reconfiguration_needed(radios, hood_bssid) - for index, radio in ipairs(radios) do - if ( uci:get('wireless', 'ibss_' .. radio, 'bssid') ~= hood_bssid ) then - return true - end - end - - return false +-- reconfigures the bssid if needed +-- returns true +-- returns false for error while setting bssid via UCI +local function setHoodWifi(hoodBssid,radios) + local ret = true + local change = false + for index, radio in ipairs(radios) do + if not ( uci:get('wireless', 'ibss_' .. radio, 'bssid') == hoodBssid) then + ret = uci:section('wireless', 'wifi-iface', 'ibss_' .. radio, + { + bssid = hoodBssid + } + ) + change = true + end + end + if change then + uci:save('wireless') + uci:commit('wireless') + os.execute('wifi') + end + return ret end --- Reconfigure wireless -local function wireless_reconfigure(radios, hood_bssid) - for index, radio in ipairs(radios) do - if not ( uci:get('wireless', 'ibss_' .. radio, 'bssid') == hood_bssid ) then - uci:section('wireless', 'wifi-iface', 'ibss_' .. radio, { - bssid = hood_bssid - }) - end +-- Retun a table of current peers from /etc/config/fastd +local function getCurrentPeers() + local configPeername = {} + local configPeers = {} + uci:foreach('fastd', 'peer', + function(s) + if s['.name'] then + table.insert(configPeername,s) + end + end + ) + for _,index in pairs(configPeername) do + for prefix,peer in pairs(index) do + local tmpPeer = {} + if prefix:match(".name") then + if peer:match("mesh_vpn_backbone_peer_") then + local tmpRemote = uci:get('fastd', peer, 'remote') + tmpRemote = tmpRemote[1]:split(' ') + local remote = {} + remote['host'] = tmpRemote[1] + remote[tmpRemote[2]] = tmpRemote[3] + tmpPeer['key'] = tostring(uci:get('fastd', peer, 'key')) + tmpPeer['remote'] = remote + configPeers[peer] = tmpPeer end - - uci:save('wireless') - uci:commit('wireless') + end + end + end + return configPeers end --- This method sets a new hoodconfig and takes care that services are only +-- This method sets a new fastd config and takes care that services are only -- stopped or restarted if reconfiguration is needed. --- Process: --- * Check if wireless needs reconfiguration and prepare reconfiguration --- * Check if fastd needs reconfiguration and prepare reconfiguration --- * If fastd needs reconfiguration, stop fastd and apply new settings but --- dont restart it before wireless has been reconfigured --- * If wireless needs reconfiguration apply new settings and restart wireless --- * If fastd needed reconfiguration start fastd now -local function set_hoodconfig(hood, radios) - -- Check if VPN needs reconfiguration because in case of reconfiguration we - -- need to stop VPN before we can reconfigure any other connection. - local vpn_reconfiguration_needed = vpn_reconfiguration_needed(hood["servers"]); - if(vpn_reconfiguration_needed) then - vpn_stop() - end - - -- reconfigure wireless - if(wireless_reconfiguration_needed(radios, hood["bssid"])) then - wireless_reconfigure(radios, hood["bssid"]) - wireless_restart() - io.stderr:write('Wireless needed reconfiguration. Applied new settings and restarted.\n') - end - - -- reconfigure fastd - if (vpn_reconfiguration_needed) then - vpn_reconfigure(hood["servers"]) - -- scan mode can disable VPN so we need to make shure that VPN is enabled - -- if the router selects a hood - vpn_enable() - vpn_start() - io.stderr:write('VPN needed reconfiguration. Applied new settings and restarted.\n') +-- return true +-- return false for getting error while setting config via UCI +local function setHoodVPN(hood) + local change = false + local uciError = false + local configPeers = getCurrentPeers() + for configIndex, configPeer in pairs(configPeers) do + local remove = true + local hoodserver0 = nil + for index0,serverlist in pairs(hood.servers) do + for index1,server in pairs(serverlist) do + if index1:match("host") then + local hoodserver1 = server:split('.') + if configIndex == "mesh_vpn_backbone_peer_" .. hoodserver1[1] then + remove = false + hoodserver0 = index0 + if not ( configPeer.key == serverlist['publickey'] ) then + if not uci:set('fastd', configIndex, 'key', serverlist['publickey']) then + uciError = true + end + change = true + end + server = '\"'..server..'\"' + if not ( configPeer.remote.host == server ) then + local hoodRemote = {} + table.insert(hoodRemote, server .. ' port ' .. configPeer.remote.port) + if not uci:set('fastd', configIndex, 'remote', hoodRemote) then + uciError = true + end + change = true + end + if not ( configPeer.remote.port == serverlist['port'] ) then + local hoodRemote = {} + table.insert(hoodRemote, configPeer.remote.host .. ' port ' .. serverlist['port']) + if not uci:set('fastd', configIndex, 'remote', hoodRemote) then + uciError = true + end + change = true + end + end end - io.stderr:write("Set hood \""..hood["name"].."\"\n") - - return true + end + end + if remove then + uci:delete('fastd',configIndex) + change = true + else + if hoodserver0 ~= nil then + table.remove(hood.servers,hoodserver0) + end + end + end + for index0,serverlist in pairs(hood.servers) do + local group = 'mesh_vpn_backbone' + local name = serverlist.host:split('.') + name = name[1] + local remote = {} + table.insert(remote, '\"'..serverlist.host..'\"'..' port '..serverlist.port) + uci:section('fastd', 'peer', group .. '_peer_' .. name, + { + enabled = 1, + net = 'mesh_vpn', + group = group, + key = serverlist.publickey, + remote = remote + } + ) + change = true + end + if change then + uci:save('fastd') + uci:commit('fastd') + os.execute('/etc/init.d/fastd restart 2> /dev/null') + end + if uciError then + return false + end + return true end -- Return the default hood in the hood list. @@ -526,9 +276,77 @@ local function getDefaultHood(jhood) return nil end +-- This functions "Load bssid history" and "Save bssid history" will stored a +-- history list of tryed nighbour BSSIDs over the cron intervall + +-- Load bssid history +local function bssid_hist_load(sfile) + local bssid_his = {} + local sfileO = io.open(sfile, r) + if not sfileO then return bssid_his end + for line in sfileO:lines() do + if line:match("(%w+:%w+:%w+:%w+:%w+:%w+)") then + table.insert(bssid_his,line) + end + end + sfileO:close() + return bssid_his +end + +-- Save bssid history +local function bssid_hist_save(tbl,filename) + local file = io.open( filename, "wb" ) + if not file then return nil end + for idx,str in ipairs( tbl ) do + file:write(str) + end + file:close() +end + +-- Return the BSSID from the next freifunk router with the best signal quality and with has a difference to the actual used BSSID +local function getNeigbourBssid(radios) + local hoodbssid = nil + local bssid_leases = bssid_hist_load("/tmp/hoodselector.leases") + for index, radio in ipairs(radios) do + hoodbssid = uci:get('wireless', 'ibss_' .. radio, 'bssid') + local bssid_his = '' + if bssid_leases[index] ~= nil then + bssid_his = bssid_leases[index] + end + bssid_his = bssid_his..' '..hoodbssid + local lastQuality = 255 + local tmphoodbssid = nil + for wifiscan in io.popen(string.format("iw %s scan | grep \"%s\" -B8", uci:get('wireless', 'ibss_' .. radio, 'ifname'), uci:get('wireless', 'ibss_' ..radio, 'ssid')),'r'):lines() do + if wifiscan:match("(%w+:%w+:%w+:%w+:%w+:%w+)") then + tmphoodbssid = wifiscan:match("(%w+:%w+:%w+:%w+:%w+:%w+)"):upper() + end + if wifiscan:match("signal:") then + local quallity = wifiscan:split(' ') + quallity = quallity[2]:split('.') + if quallity[1]:match('-') then + quallity = quallity[1]:split('-') + end + quallity = tonumber(quallity[2]:match("(%d%d)")) + if not bssid_his:match(tmphoodbssid) then + if ( lastQuality > quallity ) then + lastQuality = quallity + hoodbssid = tmphoodbssid + end + end + end + end + if ( lastQuality == 255 ) then + bssid_his = '' + end + bssid_leases[index] = bssid_his + end + bssid_hist_save(bssid_leases,"/tmp/hoodselector.leases") + return hoodbssid +end + -- boolean check if batman-adv has gateways -local function batmanHasGateway() - for gw in io.popen(string.format("cat /sys/kernel/debug/batman_adv/bat0/gateways"), 'r'):lines() do +local function getGwRange() + for gw in io.open("/sys/kernel/debug/batman_adv/bat0/gateways", 'r'):lines() do if gw:match("Bit") then return true end @@ -546,147 +364,73 @@ local function gethoodByBssid(jhood, scan_bssid) return nil end -local function get_batman_mesh_network(sorted_wlan_list, defaultHood) - io.stderr:write('Testing neighboring adhoc networks for batman advanced gw connection.\n') - io.stderr:write('The following wireless networks have been found:\n') - for n, network in pairs(sorted_wlan_list) do - print(network["quality"].."\t"..network["frequency"].."\t"..network["bssid"].."\t"..network["ssid"]) - end - - -- we only want to test adhoc networks with freifunk ssid - sorted_wlan_list = get_wlan_mesh_networks(sorted_wlan_list) - -- we dont want to get tricked by our our signal - sorted_wlan_list = filter_my_wlan_network(sorted_wlan_list) - -- we dont want to test the default hood because if there is no other - -- hood present we will connect to the default hood anyway - sorted_wlan_list = filter_default_hood_wlan_networks(defaultHood, sorted_wlan_list) - - io.stderr:write('After filtering we will test the following wireless networks:\n') - for n, network in pairs(sorted_wlan_list) do - print(network["quality"].."\t"..network["frequency"].."\t"..network["bssid"].."\t"..network["ssid"]) - end - - local bssid = nil - if(next(sorted_wlan_list)) then - io.stderr:write("Prepare configuration for testing wireless networks...\n") - -- Notice: - -- we will use iw for testing the wireless networks because using iw does - -- not need any changes inside the uci config. This approach allows the - -- router to automatically reset to previous configuration in case - -- someone disconnects the router from power during test. - - -- stop vpn to prevent two hoods from beeing connected in case - -- the router gets internet unexpectedly during test. - vpn_stop() - -- remove the ap network because we cannot change - -- the settings of the adhoc network if the ap network is still operating - os.execute("iw dev client0 del") - for n, wireless in pairs(sorted_wlan_list) do - io.stderr:write("Testing "..wireless["bssid"].."...") - -- leave the current adhoc network - os.execute("iw dev ibss0 ibss leave") - -- setup the adhoc network we want to test - os.execute("iw dev ibss0 ibss join "..wireless["ssid"].." "..wireless["frequency"].." "..wireless["bssid"]) - -- sleep 30 seconds till the connection is fully setup - sleep(30) --- os.execute("logread") --- os.execute("batctl o") - - if batmanHasGateway() then - bssid = wireless["bssid"] - break; - end - end - vpn_start() - wireless_restart() - io.stderr:write("Finished testing wireless networks, restored previous configuration\n") - end - - return bssid -end - --- INITIALIZE AND PREPARE DATA -- --- read hoodfile, exit if reading the hoodfile fails +--Start +--Read hoods json file local jhood = readHoodfile(file) if jhood == nil then - io.stderr:write('There seems to have gone something wrong while reading hoodfile from ' .. file .. '\n') + io.stderr:write("There seems to have gone something wrong while reading hoodfile from " .. file .. '\n') exit() end - --- check if a default hood has been defined and exit if none has been defined -local defaultHood = getDefaultHood(jhood) -if defaultHood == nil then - io.stderr:write('No defaulthood defined.\n') - exit() -end - -- Get list of wifi devices local radios = getWifiDevices() --- VPN MODE --- If we have a VPN connection then we will try to get the routers location and --- select the hood coresponding to our location. --- If no hood for the location has been defined, we will select --- the default hood. --- If we can not get our routers location, we will fallback to scan mode. +--If direct vpn, sed hood by geo. if directVPN() then - io.stderr:write('VPN connection found.\n') local geo = getGeolocation() if geo[1] ~= nil and geo[2] ~= nil then - io.stderr:write('Position found.\n') local geoHood = getHoodByGeo(jhood, geo) if geoHood ~= nil then - set_hoodconfig(geoHood, radios) - io.stderr:write('Hood set by VPN mode.\n') - exit() + if setHoodWifi(geoHood.bssid,radios) and setHoodVPN(geoHood) then + io.stderr:write('Setting hood getting from position.\n') + exit() + end + io.stderr:write('Error while setting new hood getting by geoposition.\n') + exit() end io.stderr:write('No hood has been defined for current position.\n') - set_hoodconfig(defaultHood, radios) - io.stderr:write('Defaulthood set.\n') - exit() + local defaultHood = getDefaultHood(jhood) + if defaultHood ~= nil then + if setHoodWifi(defaultHood.bssid,radios) and setHoodVPN(defaultHood) then + io.stderr:write('Setting defaulthood.\n') + exit() + end + io.stderr:write('Error while setting defaulthood.\n') + exit() + end end - io.stderr:write('No position found\n') -else - io.stderr:write('No VPN connection found\n') -end - -if batmanHasGateway() then - io.stderr:write('Batman gateways found, everything seems to be ok - doing nothing\n') - exit() + io.stderr:write('Router dont have a position.\n') end --- SCAN MODE if next(radios) then - -- check if there exist a neighboring freifunk batman advanced mesh - -- network with an active connection to a batman advanced gateway - local sortedWlanList = wlan_list_sorted(radios) - local meshBSSID = get_batman_mesh_network(sortedWlanList, defaultHood) - if meshBSSID ~= nil then - io.stderr:write("Neighoring freifunk batman advanced mesh with BSSID "..meshBSSID.." found\n") - local bssidHood = gethoodByBssid(jhood, meshBSSID) + -- If no direct VPN and batman GWs not in range set scanned bssid + local scanBssid = getNeigbourBssid(radios) + if scanBssid ~= nil then + if not getGwRange() then + if setHoodWifi(scanBssid,radios) then + io.stderr:write('Setting Bssid getting from Scan.\n') + else + io.stderr:write('Error while setting Bssid getting from Scan.\n') + exit() + end + end + + -- Set VPN config getting by BSSID + local bssidHood = gethoodByBssid(jhood, scanBssid) if bssidHood ~= nil then - set_hoodconfig(bssidHood, radios) - io.stderr:write('Hood set by scan mode\n') + if setHoodVPN(bssidHood) then + io.stderr:write('Setting hood getting from bssid.\n') + os.execute('/etc/init.d/fastd start 2> /dev/null') + os.execute('/etc/init.d/fastd enable') + exit() + end + io.stderr:write('Error while setting new hood getting by bssid.\n') exit() end - - -- if the bssid does not corespond to any hood, we disable vpn and - -- just establish a wireless connection to the mesh without any vpn or - -- mesh on lan (TODO) connectivity - vpn_stop() - vpn_disable() - wireless_reconfigure(radios, meshBSSID) - wireless_restart() - io.stderr:write('Could not select a hood but established a connection via wireless mesh.\n') - io.stderr:write('Disabled all connections except connections via wireless mesh.\n') + io.stderr:write('No hood has been defined for scanned bssid.\n') + os.execute('/etc/init.d/fastd stop 2> /dev/null') + os.execute('/etc/init.d/fastd disable') exit() end - io.stderr:write('No neighboring freifunk batman advanced mesh found.\n') + io.stderr:write('Error while scanning wifi.\n') end - --- DEFAULT-HOOD MODE --- If we do NOT have a VPN connection AND found no freifunk mesh network while --- scanning then we set the default hood -set_hoodconfig(defaultHood, radios) -io.stderr:write('Set defaulthood.\n') exit()