Refactor batctl calls into python class.

This drastically reduces the logic implement in mkmap.sh and also
supports multiple batman mesh interfaces.
alfred-data
Daniel Ehlers 2013-11-12 00:28:11 +01:00
parent e58d0baec3
commit 44c92ff65f
4 changed files with 85 additions and 30 deletions

View File

@ -4,6 +4,7 @@ import json
import fileinput import fileinput
import argparse import argparse
from batman import batman
from nodedb import NodeDB from nodedb import NodeDB
from d3mapbuilder import D3MapBuilder from d3mapbuilder import D3MapBuilder
@ -23,25 +24,30 @@ parser.add_argument('-a', '--aliases',
action='append', action='append',
metavar='FILE') metavar='FILE')
parser.add_argument('-g', '--gateway', action='append', parser.add_argument('-m', '--mesh', action='append',
help='MAC of a gateway') help='batman mesh interface')
parser.add_argument('batmanjson', help='output of batman vd json')
args = parser.parse_args() args = parser.parse_args()
options = vars(args) options = vars(args)
db = NodeDB() db = NodeDB()
db.import_batman(list(fileinput.input(options['batmanjson']))) if options['mesh']:
for mesh_interface in options['mesh']:
bm = batman(mesh_interface)
db.parse_vis_data(bm.vis_data())
for gw in bm.gateway_list():
db.mark_gateways(gw.mac)
else:
bm = batman()
db.parse_vis_data(bm.vis_data())
for gw in bm.gateway_list():
db.mark_gateways([gw['mac']])
if options['aliases']: if options['aliases']:
for aliases in options['aliases']: for aliases in options['aliases']:
db.import_aliases(json.load(open(aliases))) db.import_aliases(json.load(open(aliases)))
if options['gateway']:
db.mark_gateways(options['gateway'])
m = D3MapBuilder(db) m = D3MapBuilder(db)
print(m.build()) print(m.build())

65
batman.py Executable file
View File

@ -0,0 +1,65 @@
#!/usr/bin/env python3
import subprocess
import json
import re
class batman:
""" Bindings for B.A.T.M.A.N. advanced batctl tool
"""
def __init__(self, mesh_interface = "bat0"):
self.mesh_interface = mesh_interface
def vis_data(self):
""" Parse "batctl -m <mesh_interface> vd json -n" into an array of dictionaries.
"""
output = subprocess.check_output(["batctl","-m",self.mesh_interface,"vd","json","-n"])
lines = output.splitlines()
vd = []
for line in lines:
try:
utf8_line = line.decode("utf-8")
vd.append(json.loads(utf8_line))
except e:
pass
return vd
def gateway_list(self):
""" Parse "batctl -m <mesh_interface> gwl -n" into an array of dictionaries.
"""
output = subprocess.check_output(["batctl","-m",self.mesh_interface,"gwl","-n"])
output_utf8 = output.decode("utf-8")
# TODO Parse information
lines = output_utf8.splitlines()
own_mac = re.match(r"^.*MainIF/MAC: [^/]+/([0-9a-f:]+).*$",lines[0]).group(1)
# Remove header line
del lines[0]
# Fill gateway list
gw = []
gw_mode = self.gateway_mode()
if gw_mode['mode'] == 'server':
gw.append({'mac': own_mac, 'bandwidth': gw_mode['bandwidth']})
for line in lines:
gw_line = line.split()
# When in client gateway mode maybe gw_line[0] is not the right.
gw.append({'mac':gw_line[0], 'bandwidth': gw_line[-1]})
return gw
def gateway_mode(self):
""" Parse "batctl -m <mesh_interface> gw"
"""
output = subprocess.check_output(["batctl","-m",self.mesh_interface,"gw"])
elements = output.decode("utf-8").split()
mode = elements[0]
if mode == "server":
return {'mode': 'server', 'bandwidth': elements[3]}
else:
return {'mode': mode}
if __name__ == "__main__":
bc = batman()
vd = bc.vis_data()
gw = bc.gateway_list()
for x in vd:
print(x)
print(gw)
print(bc.gateway_mode())

View File

@ -7,20 +7,10 @@ DEST=$1
[ "$DEST" ] || exit 1 [ "$DEST" ] || exit 1
GWL=`batctl gwl -n`
SELF=`echo "$GWL" | head -n 1 | sed -r -e 's@^.*MainIF/MAC: [^/]+/([0-9a-f:]+).*$@\1@'`
GWS=`(echo "$GWL" | tail -n +2 | grep -v '^No' | sed 's/=>//' | awk '{ print $1 }') | while read a; do echo -n "-g $a "; done`
if [ `cat /sys/class/net/bat0/mesh/gw_mode` = server ]; then
GWS="$GWS -g $SELF"
fi
"$(dirname "$0")"/ffhlwiki.py http://freifunk.metameute.de/wiki/Knoten > "$(dirname "$0")"/aliases_hl.json "$(dirname "$0")"/ffhlwiki.py http://freifunk.metameute.de/wiki/Knoten > "$(dirname "$0")"/aliases_hl.json
"$(dirname "$0")"/ffhlwiki.py http://freifunk.metameute.de/wiki/Moelln:Knoten > "$(dirname "$0")"/aliases_moelln.json "$(dirname "$0")"/ffhlwiki.py http://freifunk.metameute.de/wiki/Moelln:Knoten > "$(dirname "$0")"/aliases_moelln.json
batctl vd json -n | "$(dirname "$0")"/bat2nodes.py -a "$(dirname "$0")"/aliases.json -a aliases_hl.json -a aliases_moelln.json $GWS - > $DEST/nodes.json.new "$(dirname "$0")"/bat2nodes.py -a "$(dirname "$0")"/aliases.json -a aliases_hl.json -a aliases_moelln.json > $DEST/nodes.json.new
mv $DEST/nodes.json.new $DEST/nodes.json mv $DEST/nodes.json.new $DEST/nodes.json

View File

@ -36,11 +36,8 @@ class NodeDB:
raise raise
# import_batman(list(fileinput.input(options['batmanjson']))) def parse_vis_data(self,vis_data):
def import_batman(self, lines): for x in vis_data:
for line in lines:
x = json.loads(line)
if 'of' in x: if 'of' in x:
try: try:
@ -53,8 +50,7 @@ class NodeDB:
node.add_mac(x['of']) node.add_mac(x['of'])
node.add_mac(x['secondary']) node.add_mac(x['secondary'])
for line in lines: for x in vis_data:
x = json.loads(line)
if 'router' in x: if 'router' in x:
try: try:
@ -95,8 +91,7 @@ class NodeDB:
node.add_mac(x['neighbor']) node.add_mac(x['neighbor'])
self._nodes.append(node) self._nodes.append(node)
for line in lines: for x in vis_data:
x = json.loads(line)
if 'router' in x: if 'router' in x:
try: try:
@ -127,8 +122,7 @@ class NodeDB:
self._links.append(link) self._links.append(link)
for line in lines: for x in vis_data:
x = json.loads(line)
if 'primary' in x: if 'primary' in x:
try: try: