def syncConfig(): """ get BR information from Lowpan """ lowpanConf = json.loads(db.get('conf/lowpan')) oldbrConf = json.loads(db.get('conf/br')) response = urllib2.urlopen( lowpanConf['url'] + '?apikey=' + lowpanConf['password'] ) brConf = None if response.getcode() != 200: raise LowpanAPIError("bad HTTP response from Lowpan") fromLowpan = json.loads(response.read()) if 'status' in fromLowpan and fromLowpan['status'] != 'ok': raise LowpanAPIError("bad return value from Lowpan") else: brConf = fromLowpan # if our tunnel is different, update gogoc config and restart if 'tunnel' in oldbrConf and \ (set(oldbrConf['tunnel'].items()) == set(brConf['device']['tunnel'].items())): return ["no change"] else: print "new lowpan tunnel found; updating gogoc configuration" oldbrConf['tunnel'] = brConf['device']['tunnel'] db.store('conf/br', json.dumps(oldbrConf, sort_keys=True, indent=4)) updateGogoc() return ["new tunnel"]
def createDefaultConf(): lowpanConf = { "url" : None, "password" : None, "realm" : "lowpan", "gogo-conf": "/etc/gogoc" } db.store('conf/lowpan', json.dumps(lowpanConf, sort_keys=True, indent=4))
def settings(): release = {} try: release = json.loads(db.get("conf/release")) except IOError: release = {"distro": "br12", "release": "testing", "url": "distro.lowpan.com/distro"} db.store("conf/release", json.dumps(release)) return render_mako("settings.html", release=release)
def settings(): release = {} try: release = json.loads(db.get('conf/release')) except IOError: release = { "distro": "br12", "release": "testing", "url": "distro.lowpan.com/distro" } db.store('conf/release', json.dumps(release)) return render_mako('settings.html', release=release)
def jsonGetSet(dbFile, request): """Get/Set a database entry by passing the json """ if request.method == 'GET': return db.get(dbFile) elif request.method == 'POST': try: d = json.loads(db.get(dbFile)) except IOError: d = {} for a in request.json: d[a] = request.json[a] db.store(dbFile, json.dumps(d, sort_keys=True, indent=4)) return jsonify(status='ok')
def jsonGetSet(dbFile, request): """Get/Set a database entry by passing the json """ if request.method == 'GET': return db.get(dbFile) elif request.method == 'POST': try: d = json.loads(db.get(dbFile)) except IOError: d = {} for a in request.json: d[a] = request.json[a] db.store(dbFile, json.dumps(d, sort_keys=True, indent=4)) return jsonify(status = 'ok')
def load_radio(): subprocess.call(['killall', 'tunslip6']) radio = json.loads(db.get('conf/radio')) tunslip = json.loads(db.get('conf/tunslip')) try: subprocess.call(['systemctl', 'stop', '*****@*****.**']) except OSError: print "error disabling serial-getty ttyS0" try: subprocess.call(['uartsel', 'mc']) except OSError: print "error calling uartsel mc" subprocess.call(['killall', '-9', 'mc1322x-load']) time.sleep(.5) subprocess.call(['mc1322x-load', '-e', '-r', 'none', '-f', os.path.join(app.config['CACHE_ROOT'],'br.bin'), '-t', tunslip['device'], '-c', radio['resetcmd']]) devnull = open('/dev/null', 'w') now = time.time() result = None while result is None and time.time() - now < 5: try: result = subprocess.check_output(["ip", "-f", "inet6", "addr", "show", "tun", "scope", "global"], stderr=devnull) except subprocess.CalledProcessError: pass time.sleep(1) # save the radio ip addr radio['ips'] = get_radio_ip()['addrs'] print "Radio ips are %s" % (radio['ips']) if result is None: print "Using fallback address %s/64" % (tunslip['address']) os.system("tunslip6 -v3 -s %s %s > %s &" % (tunslip['device'], tunslip['address'], os.path.join(app.config['CACHE_ROOT'],'tunslip6.log'))) else: ipv6 = subprocess.check_output(["getbripv6.sh"]).rstrip(); print "Using tunnel address %s/64" % (ipv6) time.sleep(1) os.system("tunslip6 -v3 -s %s %s > %s &" % (tunslip['device'], ipv6 + '/64', os.path.join(app.config['CACHE_ROOT'],'tunslip6.log'))) os.system("for i in /proc/sys/net/ipv6/conf/*; do echo 1 > $i/forwarding; done") # get the current channel radio['channel'] = coap.get('coap://[%s]/config?param=channel' % (radio['ips'][0])).rstrip() print "Radio set to channel %s" % (radio['channel']) db.store('conf/radio', json.dumps(radio))
def distroUpdate(): print "do distro update" print request.json # get the update script up = urllib2.urlopen(unicode(request.json["script"])) script = up.read() print script # write out the script out = open(app.config["CACHE_ROOT"] + "/distro-update-script", "w") out.write(script) out.close() # and run it os.system("chmod 755 %s" % (app.config["CACHE_ROOT"] + "/distro-update-script")) os.system(app.config["CACHE_ROOT"] + "/distro-update-script") release = json.loads(db.get("conf/release")) release["distro"] = request.json["name"] release["release"] = request.json["release"] db.store("conf/release", json.dumps(release)) return json.dumps(dict(status="ok"))
def brSetup(): if request.method == 'GET': return render_mako('brSetup.html') elif request.method == 'POST': br = lowpan.getBRInfo(request.form['eui'], request.form['brkey']) lowpan.createDefaultConf() lowpanConf = json.loads(db.get('conf/lowpan')) lowpanConf['eui'] = request.form['eui'] lowpanConf['password'] = request.form['brkey'] lowpanConf['url'] = BASE_URL + request.form['eui'] db.store('conf/lowpan', json.dumps(lowpanConf)) db.store('conf/br', json.dumps(br)) # change root password os.system('echo "root:%s" | chpasswd' % (br['pin'])) # also set login password to pin conf['password'] = bcrypt.generate_password_hash(br['pin']) db.store('conf/bradmin', json.dumps(conf, sort_keys=True, indent=4)) # set the hostname os.system('hostnamectl set-hostname br12-%s' % (lowpanConf['eui'])) os.system('sleep 3 && systemctl restart bramble') return "Now you need to restart BRamble"
def load_radio(): try: radio = json.loads(db.get('conf/radio')) except IOError: # configure for zolertia Z1 as default radio = {"device": "/dev/ttyUSB0", "resetcmd": "make z1-reset"} db.store('conf/radio', json.dumps(radio)) # save the radio ip addr try: radio['ips'] = grep_radio_ip()['addrs'] db.store('conf/radio', json.dumps(radio)) print "Radio ips are %s" % (radio['ips']) except RadioError: broadcastStatus( "radio", json.dumps(dict(err="failed to get the radio IP address"))) print "Couldn't get radio IP addresses" # broadcastStatus("radio", json.dumps(dict(loadRadioProgress = "95%"))) # get the current channel try: radio['channel'] = get_radio_channel() db.store('conf/radio', json.dumps(radio)) print "Radio set to channel %s" % (radio['channel']) except ValueError: broadcastStatus( "radio", json.dumps(dict(err="failed to get the radio channel"))) print "failed to get the radio channel"
def init(): print "lowpan init" # make a default lowpan config lowpanConf = None try: lowpanConf = json.loads(db.get('conf/lowpan')) except IOError: # load default config lowpanConf = { "url" : None, "password" : None, "realm" : "lowpan", "gogo-conf": "/etc/gogoc" } db.store('conf/lowpan', json.dumps(lowpanConf, sort_keys=True, indent=4)) if (lowpanConf['url'] != None) and (lowpanConf['password'] != None): try: syncConfig() except urllib2.HTTPError: print "Couldn't connect to lowpan"
def distroUpdate(): print "do distro update" print request.json # get the update script up = urllib2.urlopen(unicode(request.json['script'])) script = up.read() # write out the script out = open(app.config['CACHE_ROOT'] + '/distro-update-script', 'w') out.write(script) out.close() os.system('chmod 755 %s' % (app.config['CACHE_ROOT'] + '/distro-update-script')) subprocess.Popen([app.config['CACHE_ROOT'] + '/distro-update-script']) release = json.loads(db.get('conf/release')) release['distro'] = request.json['name'] release['release'] = request.json['release'] db.store('conf/release', json.dumps(release)) return json.dumps(dict(status = 'ok'))
def distroUpdate(): print "do distro update" print request.json # get the update script up = urllib2.urlopen(unicode(request.json['script'])) script = up.read() # write out the script out = open(app.config['CACHE_ROOT'] + '/distro-update-script', 'w') out.write(script) out.close() os.system('chmod 755 %s' % (app.config['CACHE_ROOT'] + '/distro-update-script')) subprocess.Popen([app.config['CACHE_ROOT'] + '/distro-update-script']) release = json.loads(db.get('conf/release')) release['distro'] = request.json['name'] release['release'] = request.json['release'] db.store('conf/release', json.dumps(release)) return json.dumps(dict(status='ok'))
def brSetup(): if request.method == 'GET': return render_mako('brSetup.html', url=BASE_URL) elif request.method == 'POST': baseurl = BASE_URL br = {} if request.form['url'] != '': baseurl = request.form['url'] if baseurl[-1] != '/': baseurl = baseurl + '/' br = lowpan.getBRInfo(request.form['eui'], request.form['brkey'], baseurl) else: br = lowpan.getBRInfo(request.form['eui'], request.form['brkey']) lowpan.createDefaultConf() lowpanConf = json.loads(db.get('conf/lowpan')) lowpanConf['eui'] = request.form['eui'] lowpanConf['password'] = request.form['brkey'] lowpanConf['url'] = baseurl + request.form['eui'] db.store('conf/lowpan', json.dumps(lowpanConf)) db.store('conf/lowpan.factory', json.dumps(lowpanConf)) db.store('conf/br', json.dumps(br)) db.store('conf/br.factory', json.dumps(br)) lowpan.syncConfig() lowpan.updateGogoc() # set the radio's serial (which also sets the eui) try: radio.setSerial(br['m12serial']) except KeyError: print "Warning: no m12 serial number set" # change root password os.system('echo "root:%s" | chpasswd' % (br['pin'])) # also set login password to pin conf['password'] = bcrypt.generate_password_hash(br['pin']) db.store('conf/bradmin', json.dumps(conf, sort_keys=True, indent=4)) db.store('conf/bradmin.factory', json.dumps(conf, sort_keys=True, indent=4)) # set the hostname os.system('hostnamectl set-hostname br12-%s' % (lowpanConf['eui'])) return "Now you need to restart BRamble"
def newpass(): conf['password'] = bcrypt.generate_password_hash(request.json['password']) db.store('conf/bradmin', json.dumps(conf, sort_keys=True, indent=4)) return json.dumps(dict(status = 'ok'))
def newpass(): conf['password'] = bcrypt.generate_password_hash(request.json['password']) db.store('conf/bradmin', json.dumps(conf, sort_keys=True, indent=4)) return json.dumps(dict(status='ok'))
def load_radio(): broadcastStatus("radio", json.dumps(dict(loadRadioProgress="0%"))) subprocess.call(['killall', 'tunslip6']) try: radio = json.loads(db.get('conf/radio')) except IOError: # configure for econotag as default radio = { "device": "/dev/ttyUSB1", "resetcmd": "bbmc -l redbee-econotag reset" } db.store('conf/radio', json.dumps(radio)) try: tunslip = json.loads(db.get('conf/tunslip')) except IOError: # configure for econotag default # generate a random ULA in the fd space # XXX debug: tunslip gives this with a ULA assignment; not sure about this # sticking with aaaa::1/64 for now... # fdc8:12db:60b1:1dfd:1: Resolver Error 0 (no error) # *** Address:fdc8:12db:60b1:1dfd:1 => 20b1:f762:ff7f:0000 # Radio ips are [u'20b1:f762:ff7f::205:c2a:8cf4:5d24', u'fe80::205:c2a:8cf4:5d24'] # tunslip = { "device": "/dev/ttyUSB1", # "baud": 115200, # "address": "fd%x:%x:%x:%x:1/64" % (randint(0,0xff), randint(0, 0xffff), randint(0, 0xffff), randint(0,0xffff))} tunslip = { "device": "/dev/ttyUSB1", "baud": 115200, "address": "aaaa::1/64" } db.store('conf/tunslip', json.dumps(tunslip)) try: subprocess.call(['systemctl', 'stop', '*****@*****.**']) except OSError: print "error disabling serial-getty ttyS0" broadcastStatus("radio", json.dumps(dict(loadRadioProgress="5%"))) try: subprocess.call(['uartsel', 'mc']) except OSError: print "error calling uartsel mc" subprocess.call(['killall', '-9', 'mc1322x-load']) broadcastStatus("radio", json.dumps(dict(loadRadioProgress="15%"))) time.sleep(.5) subprocess.call([ 'mc1322x-load', '-e', '-r', 'none', '-f', os.path.join(app.config['CACHE_ROOT'], 'br.bin'), '-t', tunslip['device'], '-c', radio['resetcmd'] ]) broadcastStatus("radio", json.dumps(dict(loadRadioProgress="65%"))) devnull = open('/dev/null', 'w') now = time.time() result = None while result is None and time.time() - now < 5: try: result = subprocess.check_output([ "ip", "-f", "inet6", "addr", "show", "tun", "scope", "global" ], stderr=devnull) except subprocess.CalledProcessError: pass if result is None: radio['prefix-used'] = 'fallback' print "Using fallback address %s/64" % (tunslip['address']) os.system("tunslip6 -v3 -s %s %s > %s &" % (tunslip['device'], tunslip['address'], os.path.join(app.config['CACHE_ROOT'], 'tunslip6.log'))) else: radio['prefix-used'] = 'tunnel' ipv6 = subprocess.check_output(["getbripv6.sh"]).rstrip() print "Using tunnel address %s/64" % (ipv6) time.sleep(1) os.system("tunslip6 -v3 -s %s %s > %s &" % (tunslip['device'], ipv6 + '/64', os.path.join(app.config['CACHE_ROOT'], 'tunslip6.log'))) os.system( "for i in /proc/sys/net/ipv6/conf/*; do echo 1 > $i/forwarding; done") broadcastStatus("radio", json.dumps(dict(loadRadioProgress="75%"))) time.sleep(5) broadcastStatus("radio", json.dumps(dict(loadRadioProgress="85%"))) # save the radio ip addr try: radio['ips'] = grep_radio_ip()['addrs'] db.store('conf/radio', json.dumps(radio)) print "Radio ips are %s" % (radio['ips']) except RadioError: broadcastStatus( "radio", json.dumps(dict(err="failed to get the radio IP address"))) print "Couldn't get radio IP addresses" broadcastStatus("radio", json.dumps(dict(loadRadioProgress="95%"))) # get the current channel try: radio['channel'] = get_radio_channel() db.store('conf/radio', json.dumps(radio)) print "Radio set to channel %s" % (radio['channel']) except ValueError: broadcastStatus( "radio", json.dumps(dict(err="failed to get the radio channel"))) print "failed to get the radio channel" broadcastStatus("radio", json.dumps(dict(loadRadioProgress="100%")))
def newpass(): conf["password"] = bcrypt.generate_password_hash(request.json["password"]) db.store("conf/bradmin", json.dumps(conf, sort_keys=True, indent=4)) return json.dumps(dict(status="ok"))
def kwSet(dbFile, **kwargs): """ Set attributes in kword args to target file """ d = json.loads(db.get(dbFile)) for a in kwargs: d[a] = kwargs[a] db.store(dbFile, json.dumps(d, sort_keys=True, indent=4))
def syncConfig(): """ get BR information from Lowpan """ lowpanConf = json.loads(db.get('conf/lowpan')) try: response = urllib2.urlopen( lowpanConf['url'] + '?apikey=' + lowpanConf['password'] ) brConf = json.loads(response.read()) except: print "couldn't connect to lowpan" return db.store('conf/br', json.dumps(brConf, sort_keys=True, indent=4)) # create gogoc.conf distro = 'arch' try: with open('/etc/apt/sources.list') as f: distro = 'debian' except IOError as e: pass # search for lowpan.json config file search = ['/etc/gogoc', '/var/cache/bradmin', '/etc/lowpan', '/usr/local/etc/lowpan', '.'] gogotmpl = None for s in search: try: gogotmpl = open(s + '/gogoc.conf.tmpl.' + distro, 'r') except IOError: pass if gogotmpl is None: print "couldn't open gogoc template" return # generate a tunnel password chars = string.letters + string.digits length = 24 tunpassword = ''.join(choice(chars) for _ in range(length)) m = md5.new() try: m.update(brConf['device']['eui']) m.update(':' + lowpanConf['realm'] + ':') except KeyError: print "invalid config" return m.update(tunpassword) tunpasshash = m.hexdigest() data = json.dumps( { "passhash": tunpasshash } ) headers = { "Content-type": "application/json" } req = urllib2.Request(lowpanConf['url'] + '/tunnel/passhash?apikey=' + lowpanConf['password'], data, headers) resp = urllib2.urlopen(req) #print "sending passhash " + tunpasshash + " for password " + tunpassword gogo = '' gogo = gogo + "userid=%s\n" % (brConf['device']['eui']) gogo = gogo + "passwd=%s\n" % (tunpassword) gogo = gogo + "server=%s\n" % (brConf['device']['tunnel']['uri']) gogo = gogo + "\n" gogo = gogo + gogotmpl.read() os.system('mkdir -p %s' % (lowpanConf['gogo-conf'])) out = open(lowpanConf['gogo-conf'] + '/gogoc.conf', 'w') out.write(gogo) os.system('killall -HUP gogoc') os.system('gogoc -n > %s &' % (os.path.join(app.config['CACHE_ROOT'],'gogoc.log'))) time.sleep(5)
def load_radio(): broadcastStatus("radio", json.dumps(dict(loadRadioProgress = "0%"))) subprocess.call(['killall', 'tunslip6']) try: radio = json.loads(db.get('conf/radio')) except IOError: # configure for econotag as default radio = { "device": "/dev/ttyUSB1", "resetcmd": "bbmc -l redbee-econotag reset"} db.store('conf/radio', json.dumps(radio)) try: tunslip = json.loads(db.get('conf/tunslip')) except IOError: # configure for econotag default # generate a random ULA in the fd space # XXX debug: tunslip gives this with a ULA assignment; not sure about this # sticking with aaaa::1/64 for now... # fdc8:12db:60b1:1dfd:1: Resolver Error 0 (no error) # *** Address:fdc8:12db:60b1:1dfd:1 => 20b1:f762:ff7f:0000 # Radio ips are [u'20b1:f762:ff7f::205:c2a:8cf4:5d24', u'fe80::205:c2a:8cf4:5d24'] # tunslip = { "device": "/dev/ttyUSB1", # "baud": 115200, # "address": "fd%x:%x:%x:%x:1/64" % (randint(0,0xff), randint(0, 0xffff), randint(0, 0xffff), randint(0,0xffff))} tunslip = { "device": "/dev/ttyUSB1", "baud": 115200, "address": "aaaa::1/64" } db.store('conf/tunslip', json.dumps(tunslip)) try: subprocess.call(['systemctl', 'stop', '*****@*****.**']) except OSError: print "error disabling serial-getty ttyS0" broadcastStatus("radio", json.dumps(dict(loadRadioProgress = "5%"))) try: subprocess.call(['uartsel', 'mc']) except OSError: print "error calling uartsel mc" subprocess.call(['killall', '-9', 'mc1322x-load']) broadcastStatus("radio", json.dumps(dict(loadRadioProgress = "15%"))) time.sleep(.5) subprocess.call(['mc1322x-load', '-e', '-r', 'none', '-f', os.path.join(app.config['CACHE_ROOT'],'br.bin'), '-t', tunslip['device'], '-c', radio['resetcmd']]) broadcastStatus("radio", json.dumps(dict(loadRadioProgress = "65%"))) devnull = open('/dev/null', 'w') now = time.time() result = None while result is None and time.time() - now < 5: try: result = subprocess.check_output(["ip", "-f", "inet6", "addr", "show", "tun", "scope", "global"], stderr=devnull) except subprocess.CalledProcessError: pass if result is None: radio['prefix-used'] = 'fallback' print "Using fallback address %s/64" % (tunslip['address']) os.system("tunslip6 -v3 -s %s %s > %s &" % (tunslip['device'], tunslip['address'], os.path.join(app.config['CACHE_ROOT'],'tunslip6.log'))) else: radio['prefix-used'] = 'tunnel' ipv6 = subprocess.check_output(["getbripv6.sh"]).rstrip() print "Using tunnel address %s/64" % (ipv6) time.sleep(1) os.system("tunslip6 -v3 -s %s %s > %s &" % (tunslip['device'], ipv6 + '/64', os.path.join(app.config['CACHE_ROOT'],'tunslip6.log'))) os.system("for i in /proc/sys/net/ipv6/conf/*; do echo 1 > $i/forwarding; done") broadcastStatus("radio", json.dumps(dict(loadRadioProgress = "75%"))) time.sleep(5) broadcastStatus("radio", json.dumps(dict(loadRadioProgress = "85%"))) # save the radio ip addr try: radio['ips'] = grep_radio_ip()['addrs'] db.store('conf/radio', json.dumps(radio)) print "Radio ips are %s" % (radio['ips']) except RadioError: broadcastStatus("radio", json.dumps(dict(err = "failed to get the radio IP address"))) print "Couldn't get radio IP addresses" broadcastStatus("radio", json.dumps(dict(loadRadioProgress = "95%"))) # get the current channel try: radio['channel'] = get_radio_channel() db.store('conf/radio', json.dumps(radio)) print "Radio set to channel %s" % (radio['channel']) except ValueError: broadcastStatus("radio", json.dumps(dict(err = "failed to get the radio channel"))) print "failed to get the radio channel" broadcastStatus("radio", json.dumps(dict(loadRadioProgress = "100%")))