Facebook
From Bitty Hedgehog, 7 Years ago, written in Python.
Embed
Download Paste or View Raw
Hits: 223
  1. #!/usr/bin/python3.4
  2. # -*- coding: utf-8 -*-
  3. # from typing import List
  4. import asyncio
  5.  
  6. from jinja2 import Environment, PackageLoader
  7. from flask import Flask
  8. import flask
  9. import os
  10. import sys
  11. import errno
  12. import logging
  13. #import subprocess
  14. from subprocess import Popen,call,PIPE
  15. import shlex
  16. import time
  17. import threading
  18. import json
  19. from collections import namedtuple
  20. import sqlite3
  21.  
  22. from jinja2 import FileSystemLoader
  23.  
  24. FileInfo = namedtuple('FileInfo', ['relative_path', 'target_path', 'filename', 'context'], verbose=True)
  25.  
  26. app = Flask(__name__)
  27. # env = Environment(loader=FileSystemLoader('.'))
  28. # env = Environment(loader=PackageLoader('yourapplication', 'templates'))
  29.  
  30.  
  31. script_lock = threading.Lock()
  32.  
  33. class clientThread(threading.Thread):
  34.     def __init__(self, ssid, passwd):
  35.         threading.Thread.__init__(self)
  36.         self.ssid = ssid
  37.         self.passwd = passwd
  38.     def run(self):
  39.         if not is_associated() :
  40.             run_script('config_client')
  41.         connect_to_network(self.ssid,self.passwd)
  42.  
  43. class apThread(threading.Thread):
  44.     def __init__(self):
  45.         threading.Thread.__init__(self)
  46.     def run(self):
  47.         configure('config_ap', dict())
  48.  
  49. class checkUSBThread(threading.Thread):
  50.     def __init__(self):
  51.         threading.Thread.__init__(self)
  52.     def run(self):
  53.         cmd ="su pi -c 'mono /home/pi/yodiwo/wisperFactoryReset/wisperFactoryReset.exe > /home/pi/yodiwo/wisperFactoryReset.log' &"
  54.         run_wpa_cli_cmd(cmd)
  55.  
  56. class WiFiNet:
  57.      def __init__(self, essid, mac,encryption,authsuites):
  58.          self.essid = essid
  59.          self.mac= mac
  60.          self.encryption = encryption
  61.          self.authsuites = authsuites
  62.  
  63.  
  64.  
  65.  
  66.  
  67. @app.route("/")
  68. def hello():
  69.     return "Hello World!"
  70.  
  71. @app.route("/render")
  72. def render():
  73.     return "Hello World!"
  74.  
  75. @app.route('/config_client', methods=['GET', 'POST'])
  76. def config_client():
  77.     ssid = flask.request.args.get('config_wifi_ssid')
  78.     password = flask.request.args.get('config_wifi_password')
  79.  
  80.     if not password:
  81.         password = ""
  82.     if not ssid:
  83.         return "Invalid parameters", 400
  84.     else:
  85.         thread1 = clientThread(ssid,password)
  86.         thread1.start()
  87.         return "Ok"
  88.  
  89. @app.route('/client_mode', methods=['GET', 'POST'])
  90. def client_mode():
  91.     run_script('config_client')
  92.     return "Ok"
  93.  
  94. @app.route('/config_ap', methods=['GET', 'POST'])
  95. def config_ap():
  96.     thread1 = apThread()
  97.     thread1.start()
  98.     return "Ok"
  99.  
  100.    # vars = {
  101.    # }
  102.    # configure('config_ap', vars)
  103.  
  104. @app.route('/purge_wifi_settings', methods=['GET', 'POST'])
  105. def purge_wifi_settings():
  106.     configure('config_ap', dict(), 1)
  107.     return "Ok"
  108.  
  109. @app.route('/scan', methods=['GET', 'POST'])
  110. def scan():
  111.     essid_list = []
  112.     j = 0
  113.     cmd = "sudo iwlist wlan0 scan"
  114.     res = run_wpa_cli_cmd(cmd)
  115.     res = res.strip()
  116.     cells= res.decode("utf-8").split('Cell')
  117.     print (cells[1])
  118.     foundessid= False
  119.     foundaddress= False
  120.     foundencryption=False
  121.     foundauthsuites= False;
  122.     authenticationsuites=[]
  123.     cells.pop(0)
  124.     for cell in cells:
  125.         lines= cell.split('\n')
  126.         for line in lines:
  127.             if "ESSID" in line:
  128.                 essid = line.strip().split(':')[1]
  129.             elif "Encryption" in line:
  130.                 encryption = line.strip().split(':')[1]
  131.             elif "Address" in line:
  132.                 address = line.strip().split(': ')[1]
  133.             elif "Authentication Suites" in line:
  134.                 auth = line.strip().split(': ')[1]
  135.                 authenticationsuites.append(auth)
  136.         print ("Construct wifi net")
  137.         authsuites = ",".join(authenticationsuites)
  138.         wifinet= WiFiNet(essid,address,encryption,authsuites)
  139.         authenticationsuites=[]
  140.         authsuites=''
  141.         essid_list.append(wifinet)
  142.     res_json = json.dumps([ob.__dict__ for ob in essid_list])
  143.     return (res_json)
  144.  
  145.  
  146. @app.route('/check_usb')
  147. def check_usb():
  148.     thread1 = checkUSBThread()
  149.     thread1.start()
  150.     return "Ok"
  151.  
  152. @app.route('/connectinfo',methods=['GET', 'POST'])
  153. def connectinfo():
  154.     try:
  155.         cmd = "sudo iwconfig wlan0"
  156.         res = run_wpa_cli_cmd(cmd)
  157.         print(res)
  158.         #res = res.strip()
  159.         lines = res.decode("utf-8").split('\n')
  160.         for line in lines:
  161.             if ("ESSID" in line):
  162.                 essid = line.strip().split('ESSID:')[1]
  163.                 return  essid
  164.         return "None"
  165.     except:
  166.         return "Unexpected Error"
  167.  
  168. @app.route('/reboot')
  169. def reboot():
  170.     cmd = "sudo reboot"
  171.     run_wpa_cli_cmd(cmd)
  172.     return "Ok"
  173.  
  174. @app.route('/removeflic', methods=['GET', 'POST'])
  175. def removeflic():
  176.     try:
  177.         bdaddr = flask.request.args.get('bdaddr')
  178.         print(bdaddr)
  179.         if bdaddr is None:
  180.             removeallflics()
  181.             res=stopflicd()
  182.             print(res)
  183.             time.sleep(3)
  184.             res=startflicd()
  185.             print(res)
  186.         else:
  187.             removesingleflic(bdaddr)
  188.             res=stopflicd()
  189.             print(res)
  190.             time.sleep(3)
  191.             startflicd()
  192.             print(res)
  193.         return "OK"
  194.     except Exception as e:
  195.         print ("Oops, exception while removing flic buttons")
  196.         print(str(e))
  197.         return "Bad Request"
  198.  
  199. def stopflicd():
  200.     try:
  201.         print ("Stop Flicd")
  202.         run_wpa_cli_cmd("sudo killall flicd")
  203.         #os.system("sudo killall flicd")
  204.         return "OK"
  205.     except Exception as e:
  206.         print ("Oops, exception while stopping flicd ")
  207.         print(str(e))
  208.         return "Bad Request"
  209.  
  210. def startflicd():
  211.     try:
  212.         print ("StartFlicd")
  213.         run_wpa_cli_cmd("sudo /home/pi/extools/flic/flicd -d -f /home/pi/extools/flic/flic.sqlite3 -s 0.0.0.0 -l /tmp/log_flicd &")
  214.         #os.system("sudo /home/pi/extools/flic/flicd -d -f /home/pi/extools/flic/flic.sqlite3 -s 0.0.0.0 -l /tmp/log_flicd &")
  215.         return "OK"
  216.     except Exception as e:
  217.         print ("Oops, exception while stopping flicd ")
  218.         print(str(e))
  219.         return "Bad Request"
  220.  
  221.  
  222. def removeallflics():
  223.     print("Remove All Flics")
  224.     try:
  225.         conn=sqlite3.connect('/home/pi/extools/flic/flic.sqlite3')
  226.         curs=conn.cursor()
  227.         curs.execute("DELETE FROM buttons")
  228.         conn.commit()
  229.     except Exception as e:
  230.         print (str(e))
  231.  
  232.  
  233. def removesingleflic(bdaddr):
  234.     print("Remove Single Flic")
  235.     try:
  236.         conn=sqlite3.connect('/home/pi/extools/flic/flic.sqlite3')
  237.         curs=conn.cursor()
  238.         query = 'DELETE FROM buttons WHERE bdaddr=?'
  239.         curs.execute(query, (bdaddr.strip(),))
  240.         #curs.execute("DELETE FROM buttons WHERE bdaddr='" + bdaddr +"'")
  241.         conn.commit()
  242.     except Exception as e:
  243.         print (str(e))
  244.  
  245.  
  246. def configure(context, vars = None, flag = None):
  247.     make_config(context, vars, flag)
  248.     run_script(context)
  249.  
  250. def make_config(context, vars = None, flag = None):
  251.     file_infos = get_files(context)
  252.     for info in file_infos:
  253.         """
  254.        do nothing with wpa_supplicant.conf
  255.        """
  256.         if info.relative_path == "config_ap/etc/wpa_supplicant" and flag!=1:
  257.             continue
  258.         else:
  259.             # processed = render_file(os.path.join(info.relative_path, info.filename), vars)
  260.             processed = render_file(info.relative_path, info.filename, vars)
  261.             print (info.relative_path)
  262.             with open(os.path.join(info.target_path, info.filename), 'w') as f:
  263.                 f.write(processed)
  264.  
  265.  
  266. # @asyncio.coroutine
  267. def run_script(context):
  268.     script = os.path.join('.', context + '.sh')
  269.     print (script)
  270.     call([script])
  271.     #Popen([script])
  272.     #t1 = threading.Thread(target=run_script_inner, args=[script])
  273.     #t1.start()
  274.  
  275. #def run_script_inner(filename):
  276. #    with script_lock:
  277. #        subprocess.call([filename])
  278.  
  279.  
  280. def get_files(context):# -> List[FileInfo]:
  281.     dirs = os.walk(context)
  282.     files = []
  283.     for d in dirs:
  284.         targetpath = d[0].split(context, 1)[1]
  285.         new = [FileInfo(d[0], targetpath, f, context) for f in d[2]]
  286.         files.extend(new)
  287.     return files
  288.  
  289.  
  290. def render_file(path, filename, vars = None):
  291.     # with open(filename, 'r') as f:
  292.     #     template_string = f.read()
  293.     # template = Environment().from_string(template_string)
  294.     template = Environment(loader=FileSystemLoader(path)).get_template(filename)
  295.     return template.render(**vars)
  296.  
  297. def run_wpa_cli_cmd(rcmd):
  298.     """
  299.    Runs a program, and it's paramters (e.g. rcmd="ls -lh /var/www")
  300.    Returns output if successful, or None and logs error if not.
  301.    """
  302.  
  303.     cmd = shlex.split(rcmd)
  304.     executable = cmd[0]
  305.     executable_options=cmd[1:]
  306.  
  307.     try:
  308.         proc  = Popen(([executable] + executable_options), stdout=PIPE, stderr=PIPE)
  309.         response = proc.communicate()
  310.         response_stdout, response_stderr = response[0], response[1]
  311.     except OSError(e):
  312.         if e.errno == errno.ENOENT:
  313.             logging.debug( "Unable to locate '%s' program. Is it in your path?" % executable )
  314.         else:
  315.             logging.error( "O/S error occured when trying to run '%s': \"%s\"" % (executable, str(e)) )
  316.     except ValueError(e):
  317.         logging.debug( "Value error occured. Check your parameters." )
  318.     else:
  319.         if proc.wait() != 0:
  320.             logging.debug( "Executable '%s' returned with the error: \"%s\"" %(executable,response_stderr) )
  321.             return response
  322.         else:
  323.             logging.debug( "Executable '%s' returned successfully. First line of response was \"%s\"" %(executable, response_stdout.decode("utf-8").split('\n')[0] ))
  324.             return response_stdout
  325.  
  326. def get_net_number(ssid):
  327.     """
  328.    Returns the number of existing network
  329.    """
  330.     cmd = "wpa_cli -i wlan0 list_net"
  331.     res = run_wpa_cli_cmd(cmd)
  332.     nets = res.decode("utf-8").split('\n')
  333.     print(len(nets))
  334.  
  335.     for i in range(1, (len(nets)-1)) :
  336.         found = nets[i].count(ssid)
  337.         if found:
  338.             break
  339.     return i
  340.  
  341.  
  342. def check_network_exist(ssid):
  343.     """
  344.    Check if a network already exists, in order to avoid duplicate entry
  345.    in wpa_supplicant.conf
  346.    """
  347.     try:
  348.         cmd = "wpa_cli -i wlan0 list_net"
  349.         res = run_wpa_cli_cmd(cmd)
  350.         tmp = res.decode("utf-8").find(ssid)
  351.         if ( tmp == -1 ):
  352.             return tmp
  353.         else:
  354.             net_no = get_net_number(ssid)
  355.             return net_no
  356.     except:
  357.         return -1
  358. '''
  359. For future use in order to implement temporary disable nets
  360. '''
  361. # def check_enabled_net():
  362. #     """
  363. #     Check if active networks exist
  364. #     """
  365. #     try:
  366. #         cmd = "wpa_cli -i wlan0 list_net"
  367. #         res = run_wpa_cli_cmd(cmd)
  368. #         nets = res.decode("utf-8").split('\n')
  369. #         print(len(nets))
  370. #
  371. #         for i in range(1, (len(nets)-1)) :
  372. #             found = nets[i].count("CURRENT")
  373. #             if found:
  374. #                 return i
  375. #     except:
  376. #         return -1
  377.  
  378. def connect_to_network(ssid, password):
  379.  
  380.     netw = check_network_exist(ssid)
  381.  
  382.     if netw == -1 :
  383.         print ("Network is NOT found , add it to conf")
  384.         cmd_add_net = "wpa_cli -i wlan0 add_network"
  385.         res = run_wpa_cli_cmd(cmd_add_net)
  386.         print (cmd_add_net)
  387.         print (res.strip())
  388.         cmd_set_ssid = "wpa_cli -i wlan0 set_network %d ssid \\\"%s\\\"" % (int(res),ssid)
  389.         resp = run_wpa_cli_cmd(cmd_set_ssid)
  390.         print(cmd_set_ssid)
  391.         print(resp.strip())
  392.         if password != "":
  393.             cmd_set_mgmt = "wpa_cli -i wlan0 set_network %d key_mgmt WPA-PSK" % (int(res))
  394.             resp = run_wpa_cli_cmd(cmd_set_mgmt)
  395.             print(cmd_set_mgmt)
  396.             print(resp.strip())
  397.             cmd_set_key = "wpa_cli -i wlan0 set_network %d psk \\\"%s\\\"" % (int(res),password)
  398.             resp = run_wpa_cli_cmd(cmd_set_key)
  399.             print(cmd_set_key)
  400.             print(resp.strip())
  401.         else:
  402.             cmd_set_mgmt = "wpa_cli -i wlan0 set_network %d key_mgmt NONE" % (int(res))
  403.             resp = run_wpa_cli_cmd(cmd_set_mgmt)
  404.             print(cmd_set_mgmt)
  405.             print(resp.strip())
  406.         # active_net = check_enabled_net()
  407.         # if(active_net):
  408.         #     cmd_disable = "wpa_cli -i wlan0 disable_network %d" % (int(active_net)-1)
  409.         #     resp = run_wpa_cli_cmd(cmd_disable)
  410.  
  411.         cmd_enable = "wpa_cli -i wlan0 enable_network %d" % (int(res))
  412.         resp = run_wpa_cli_cmd(cmd_enable)
  413.         time.sleep(5)
  414.         print (cmd_enable)
  415.         print(resp.strip())
  416.         #cmd_save = "wpa_cli -i wlan0 save_config"
  417.         #resp = run_wpa_cli_cmd(cmd_save)
  418.         #print (cmd_save)
  419.         #print(resp.strip())
  420.     else:
  421.  
  422.         # active_net = check_enabled_net()
  423.         # if active_net :
  424.         #     cmd_disable = "wpa_cli -i wlan0 disable_network %d" % (int(active_net)-1)
  425.         #     resp = run_wpa_cli_cmd(cmd_disable)
  426.         #     print (cmd_disable)
  427.         #     print(resp.strip())
  428.         cmd_enable = "wpa_cli -i wlan0 enable_network %d" % (int(netw)-1)
  429.         resp = run_wpa_cli_cmd(cmd_enable)
  430.         time.sleep(5)
  431.         print (cmd_enable)
  432.         print(resp.strip())
  433.  
  434.     #time.sleep(10)
  435.     cnt = 0
  436.     while not is_associated():
  437.          if cnt < 60 :
  438.              time.sleep(1)
  439.              print("*")
  440.              cnt = cnt + 1
  441.          else :
  442.              break
  443.     if cnt == 60 :
  444.         configure('config_ap',dict())
  445.     else :
  446.         cmd_save = "wpa_cli -i wlan0 save_config"
  447.         resp = run_wpa_cli_cmd(cmd_save)
  448.         print (cmd_save)
  449.         print(resp.strip())
  450.  
  451.     return True
  452.  
  453.  
  454. def is_associated():
  455.     """
  456.    Check if we're associated to a network.
  457.    """
  458.     try:
  459.         res = run_wpa_cli_cmd("wpa_cli -i wlan0 status | grep wpa_state")
  460.         #print (res)
  461.         tmp = res.decode("utf-8").find('COMPLETED')
  462.         #tmp = res.strip().decode("utf-8").split('=')[1]
  463.         print(tmp)
  464.         if tmp != -1:
  465.             print ("Connected !!!!!!!!!!!!!!!!!!!!!!!")
  466.             return True
  467.     except:
  468.         return False
  469.  
  470. if __name__ == "__main__":
  471.     # make_config('config_client', {'config_wifi_ssid': 'asdf', 'config_wifi_password': 'zxcv'})
  472.     # files = get_files('config_ap')
  473.  
  474.     if len(sys.argv) == 1:
  475.         app.run(host="0.0.0.0", port=8080, debug=True)
  476.  
  477.     else:
  478.         if 'config_client' in sys.argv[1] and len(sys.argv) >= 4:
  479.             print('configuring client')
  480.             thread1 = clientThread(sys.argv[2],sys.argv[3])
  481.             thread1.start()
  482.             # if not is_associated() :
  483.             #     run_script('config_client')
  484.             # connect_to_network(sys.argv[2],sys.argv[3])
  485.         elif 'config_ap' in sys.argv[1] :
  486.             print('configuring ap')
  487.             configure('config_ap', dict())
  488.         elif 'scan' in sys.argv[1] :
  489.             essid_list = []
  490.             print("Start scanning")
  491.             cmd = "sudo iwlist wlan0 scan"
  492.             res = run_wpa_cli_cmd(cmd)
  493.             resp = res.decode("utf-8").split('\n')
  494.             j = 0
  495.             for i in range(1, len(resp)):
  496.                 if "ESSID" in resp[i]:
  497.                     essid_list.insert(j,resp[i].strip().split(':')[1])
  498.                     j = j + 1
  499.  
  500.             res_json = json.dumps(essid_list)
  501.             print(res_json)
  502.  
  503.         elif 'purge_wifi_settings' in sys.argv[1] :
  504.             configure('config_ap',dict(),1)
  505.  
  506.