...
 
Commits (50)
......@@ -10,16 +10,157 @@ function M.section(form)
.. 'you can set an automatically localization of your router or enter its coordinates here. Also to enhance the network quallity. Specifying the altitude '
.. 'is optional and should only be done if a proper value is known.'))
local s = form:section(cbi.SimpleSection, nil,
[[
<!-- Beware: Ugly hacks ahead -->
<div id="locationPickerMap" style="width:100%; height:300px; display: none;"></div>
<script type="text/javascript">
/* Center coordinated if node has no position - adjust to your city */
var latitude = 52.9387073;
var longitude = 7.8620911;
var offline = 0;
function showMap() {
if (typeof OpenLayers === 'object' &amp;&amp; document.getElementById("cbid.wizard.1._longitude") !== null) {
document.getElementById("locationPickerMap").style.display="block";
offline = 0;
var proj4326 = new OpenLayers.Projection("EPSG:4326");
var projmerc = new OpenLayers.Projection("EPSG:900913");
var mapZoom = 7;
var markers = new OpenLayers.Layer.Markers( "Markers" );
OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {
defaultHandlerOptions: {
'single': true,
'double': false,
'pixelTolerance': 0,
'stopSingle': false,
'stopDouble': false
},
initialize: function(options) {
this.handlerOptions = OpenLayers.Util.extend(
{}, this.defaultHandlerOptions
);
OpenLayers.Control.prototype.initialize.apply(
this, arguments
);
this.handler = new OpenLayers.Handler.Click(
this, {
'click': this.trigger
}, this.handlerOptions
);
},
trigger: function(e) {
var lonlat = osmMap.getLonLatFromPixel(e.xy);
lonlat1 = new OpenLayers.LonLat(lonlat.lon,lonlat.lat).transform(projmerc,proj4326);
document.getElementById("cbid.wizard.1._longitude").value=lonlat1.lon;
document.getElementById("cbid.wizard.1._latitude").value=lonlat1.lat;
markers.clearMarkers();
markers.addMarker(new OpenLayers.Marker(lonlat));
document.getElementById("cbid.wizard.1._longitude").className = document.getElementById("cbid.wizard.1._longitude").className.replace(/ cbi-input-invalid/g, '');
document.getElementById("cbid.wizard.1._latitude").className = document.getElementById("cbid.wizard.1._latitude").className.replace(/ cbi-input-invalid/g, '');
cbi_d_update("cbid.wizard.1._longitude");
cbi_d_update("cbid.wizard.1._latitude");
}
});
osmMap = new OpenLayers.Map("locationPickerMap", {
controls: [
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoomBar(),
new OpenLayers.Control.MousePosition()
],
maxExtent:
new OpenLayers.Bounds(-20037508.34,-20037508.34, 20037508.34, 20037508.34),
numZoomLevels: 18,
maxResolution: 156543,
units: 'm',
projection: projmerc,
displayProjection: proj4326
} );
var osmLayer = new OpenLayers.Layer.OSM("OpenStreetMap");
osmMap.addLayer(osmLayer);
osmMap.addLayer(markers);
var temp_lon = longitude;
var temp_lat = latitude;
if(document.getElementById("cbid.wizard.1._longitude").value != "") temp_lon = document.getElementById("cbid.wizard.1._longitude").value;
if(document.getElementById("cbid.wizard.1._latitude").value != "") temp_lat = document.getElementById("cbid.wizard.1._latitude").value;
markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(temp_lon,temp_lat).transform(proj4326, projmerc)));
var mapCenterPositionAsLonLat = new OpenLayers.LonLat(temp_lon, temp_lat);
var mapCenterPositionAsMercator = mapCenterPositionAsLonLat.transform(proj4326, projmerc);
osmMap.setCenter(mapCenterPositionAsMercator, mapZoom);
var click = new OpenLayers.Control.Click();
osmMap.addControl(click);
click.activate();
}else{
offline = 1;
document.getElementById("locationPickerMap").style.display="none";
setTimeout(showMap, 1000);
}
}
var maindiv = document.getElementById("maincontainer");
/* Append script via DOM to the end of the document - this prevents the browser
from blocking the rendering if the OpenLayers-Server is unreachable */
var newcontent = document.createElement('script');
newcontent.setAttribute("type", "text/javascript");
newcontent.setAttribute("src", "http://www.openlayers.org/api/OpenLayers.js");
maindiv.appendChild(newcontent);
setTimeout(showMap, 1000);
setInterval(function() {
if(document.getElementById("cbid.wizard.1._static_disc") != null || document.getElementById("cbid.wizard.1._auto_static_disc") != null) {
if(offline == 0) {
document.getElementById("locationPickerMap").style.display="block";
}
}else{
document.getElementById("locationPickerMap").style.display="none";
}
}, 1000);
</script>
]])
local o
o = s:option(cbi.Flag, "_sharelocation", i18n.translate("Share your location to see your router on the map"))
o.default = uci:get_bool("gluon-node-info", "location", "share_location") and o.enabled or o.disabled
o:depends("_geolocation","_automatic")
o:depends("_geolocation","_static")
o:depends("_geolocation","_auto_static")
o.rmempty = false
o = s:option(cbi.ListValue, "_geolocation", i18n.translate("Geo-Location"))
o:value("_automatic", i18n.translate("Automatic (geolocator)"))
o:value("_static", i18n.translate("Static location"))
o:value("_auto_static", i18n.translate("Automatic & Static"))
o:value("_none", i18n.translate("Disabled"))
local auto_location = uci:get_bool("gluon-node-info", "location", "auto_location")
local static_location = uci:get_bool("gluon-node-info", "location", "static_location")
if auto_location == false and static_location == true then
o.default = "_static"
end
if auto_location == true and static_location == true then
o.default = "_auto_static"
end
if auto_location == false and static_location == false then
o.default = "_none"
end
o = s:option(cbi.DummyValue, "_automatic_disc", " ")
o:depends("_geolocation","_automatic")
......@@ -42,7 +183,7 @@ function M.section(form)
o:depends("_geolocation","_automatic")
o:depends("_geolocation","_auto_static")
o.rmempty = false
o.datatype = "integer"
o.datatype = "uinteger"
o.description = i18n.translatef("Set refresh interval, the default is once per day")
o = s:option(cbi.Value, "_latitude", i18n.translate("Latitude"))
......@@ -72,8 +213,11 @@ end
function M.handle(data)
local sname = uci:get_first("gluon-node-info", "location")
if data._sharelocation == '1' then
if data._geolocation ~= "_none" then
uci:set("gluon-node-info", sname, "share_location", data._sharelocation)
else
uci:set("gluon-node-info", sname, "share_location", 0)
end
if data._geolocation == "_automatic" or data._geolocation == "_auto_static" then
......@@ -83,6 +227,8 @@ function M.handle(data)
elseif tonumber(data._interval) > 43200 then
uci:set("gluon-node-info", sname, "refresh_interval", 43200)
end
else
uci:set("gluon-node-info", sname, "auto_location", 0)
end
if (data._geolocation == "_static" or data._geolocation == "_auto_static") and data._latitude ~= nil and data._longitude ~= nil then
......@@ -95,14 +241,12 @@ function M.handle(data)
uci:delete("gluon-node-info", sname, "altitude")
end
else
uci:set("gluon-node-info", sname, "static_location", 0)
uci:delete("gluon-node-info", sname, "latitude")
uci:delete("gluon-node-info", sname, "longitude")
end
if data._geolocation == "_none" then
uci:set("gluon-node-info", sname, "share_location", 0)
uci:set("gluon-node-info", sname, "auto_location", 0)
uci:set("gluon-node-info", sname, "static_location", 0)
uci:delete("gluon-node-info", sname, "altitude")
uci:delete("gluon-node-info", sname, "latitude")
uci:delete("gluon-node-info", sname, "longitude")
......
config location 'location'
option static_location '0'
option share_location '0'
option share_location '1'
config owner
......
......@@ -11,7 +11,7 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=networke
SECTION:=network
CATEGORY:=Freifunk Nordwest
TITLE:=Hoodjson file
endef
......
......@@ -5,16 +5,16 @@ PKG_VERSION:=1
PKG_RELEASE:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
PKG_BUILD_DEPENDS := lua/host luci-base/host respondd
PKG_BUILD_DEPENDS += lua/host luci-base/host
include $(GLUONDIR)/include/package.mk
include $(INCLUDE_DIR)/package.mk
define Package/ffnw-hoodselector
SECTION:=networke
SECTION:=network
CATEGORY:=Freifunk Nordwest
TITLE:=Select the hoods depending on the geo coordinate
DEPENDS:=+lwtrace +ffnw-hoods +luci-lib-jsonc gluon-mesh-batman-adv-15 +gluon-mesh-vpn-fastd
DEPENDS:=+lwtrace +ffnw-hoods +luci-lib-jsonc gluon-mesh-batman-adv-15 +gluon-mesh-vpn-fastd +respondd
endef
define Package/ffnw-hoodselector/description
......@@ -34,18 +34,22 @@ define Build/Prepare
$(CP) ./luasrc/* $(PKG_BUILD_DIR)/
$(call SrcDiet,$(PKG_BUILD_DIR),$(PKG_BUILD_DIR))
chmod +x -R $(PKG_BUILD_DIR)/
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Build/Configure
endef
define Build/Compile
$(call Build/Compile/Default)
endef
define Package/ffnw-hoodselector/install
$(CP) ./files/* $(1)/
$(INSTALL_DIR) $(1)/usr/sbin
$(CP) $(PKG_BUILD_DIR)/hoodselector $(1)/usr/sbin/hoodselector
$(INSTALL_DIR) $(1)/lib/gluon/respondd
$(CP) $(PKG_BUILD_DIR)/respondd.so $(1)/lib/gluon/respondd/hoodselector.so
endef
$(eval $(call BuildPackage,ffnw-hoodselector))
This diff is collapsed.
all: respondd.so
CFLAGS += -Wall
respondd.so: respondd.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -fPIC -D_GNU_SOURCE -o $@ $^ $(LDLIBS) -lgluonutil -luci
#include <respondd.h>
#include <json-c/json.h>
#include <libgluonutil.h>
#include <uci.h>
#include <string.h>
#include <net/if.h>
#define _STRINGIFY(s) #s
#define STRINGIFY(s) _STRINGIFY(s)
bool strstw(const char *pre, const char *str) {
size_t lenpre = strlen(pre);
return strlen(str) < lenpre ? false : strncmp(pre, str, lenpre) == 0;
}
bool strrmbs(char *line, int begin, int end) { // <- ist es hier sinvoller pointer auf die ints zu setzen??
size_t len = strlen(line);
if (len < begin)
return false;
memmove(line, line+begin, len - begin + 1);
if (len < end)
return false;
line[len-end] = 0; //remove val of end characters on the end
return true;
}
// extract hood informations
static struct json_object * get_hoodselector(void) {
FILE *f = fopen("/tmp/.hoodselector", "r");
if (!f)
return NULL;
struct json_object *ret = json_object_new_object();
char *line = NULL;
size_t len = 0;
while (getline(&line, &len, f) >= 0) {
//1. Get md5 hash from current selected hood.
if (strstw("\"md5hash\": ",line)) {
if (!strrmbs(line, 12, 14))
continue;
json_object_object_add(ret, "md5hash", gluonutil_wrap_string(line));
}
//2. Get true or false string for VPN Router.
if (strstw("\"vpnrouter\": ",line)) {
if (!strrmbs(line, 14, 16))
continue;
json_object_object_add(ret, "vpnrouter", gluonutil_wrap_string(line));
}
//3. Get hoodname
if (strstw("\"hoodname\": ",line)) {
if (!strrmbs(line, 13, 15))
continue;
json_object_object_add(ret, "hoodname", gluonutil_wrap_string(line));
}
}
free(line);
fclose(f);
return ret;
}
//Get currend selected BSSID
static struct json_object * get_current_selected_bssid(void){
struct uci_context *ctx = uci_alloc_context();
ctx->flags &= ~UCI_FLAG_STRICT;
struct uci_package *p;
if (uci_load(ctx, "wireless", &p))
goto end;
struct uci_element *e;
uci_foreach_element(&p->sections, e) {
struct uci_section *s = uci_to_section(e);
if (strcmp(s->type, "wifi-iface"))
continue;
if (strncmp(e->name, "ibss_", 5))
continue;
const char *bssid = uci_lookup_option_string(ctx, s, "bssid");
if (!bssid)
continue;
struct json_object *ret = json_object_new_object();
json_object_object_add(ret, "bssid", gluonutil_wrap_string(bssid));
free(bssid);
uci_free_context(ctx);
return ret;
}
end:
uci_free_context(ctx);
return NULL;
}
//Get uci mesh on lan wan
static struct json_object * get_mesh_on_lan_wan(void){
struct uci_context *ctx = uci_alloc_context();
ctx->flags &= ~UCI_FLAG_STRICT;
struct uci_package *p;
if (uci_load(ctx, "network", &p))
goto end;
struct uci_section *wan = uci_lookup_section(ctx, p, "mesh_wan");
struct uci_section *lan = uci_lookup_section(ctx, p, "mesh_lan");
if (!wan && !lan)
goto end;
struct json_object *ret = json_object_new_object();
if (wan) {
const char *wan_enabled = uci_lookup_option_string(ctx, wan, "auto");
json_object_object_add(ret, "wan", json_object_new_boolean(wan_enabled && !strcmp(wan_enabled, "1")));
}
if (lan) {
const char *lan_enabled = uci_lookup_option_string(ctx, lan, "auto");
json_object_object_add(ret, "lan", json_object_new_boolean(lan_enabled && !strcmp(lan_enabled, "1")));
}
uci_free_context(ctx);
return ret;
end:
uci_free_context(ctx);
return NULL;
}
// create final obj with logical structure
static struct json_object * respondd_provider_hoodselector(void) {
struct json_object *ret = json_object_new_object();
struct json_object *hoodinfo = get_hoodselector();
if(hoodinfo)
json_object_object_add(ret, "hoodinfo", hoodinfo);
struct json_object *selectedbssid = get_current_selected_bssid();
if(selectedbssid)
json_object_object_add(ret, "selectedbssid", selectedbssid);
struct json_object *mesh_on_lan_wan = get_mesh_on_lan_wan();
if(mesh_on_lan_wan)
json_object_object_add(ret, "mesh", mesh_on_lan_wan);
return ret;
}
// related to respondd_provider_hoodselector
const struct respondd_provider_info respondd_providers[] = {
{"hoodselector", respondd_provider_hoodselector},
{}
};