Example #1
0
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"]
Example #2
0
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))
Example #3
0
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)
Example #4
0
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)
Example #5
0
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')
Example #6
0
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')
Example #7
0
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))
Example #8
0
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"))
Example #9
0
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"
Example #10
0
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"
Example #11
0
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"
Example #12
0
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'))
Example #13
0
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'))
Example #14
0
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"
Example #15
0
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'))
Example #16
0
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'))
Example #17
0
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%")))
Example #18
0
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"))
Example #19
0
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))
Example #20
0
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))
Example #21
0
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)
Example #22
0
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"
Example #23
0
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%")))