Home | History | Annotate | Download | only in examples
      1 #!/usr/bin/python
      2 #
      3 # Example Android logcat to wpa_supplicant wrapper for QR Code scans
      4 # Copyright (c) 2017, Qualcomm Atheros, Inc.
      5 #
      6 # This software may be distributed under the terms of the BSD license.
      7 # See README for more details.
      8 
      9 import os
     10 import sys
     11 import argparse
     12 import logging
     13 import qrcode
     14 
     15 scriptsdir = os.path.dirname(os.path.realpath(sys.modules[__name__].__file__))
     16 sys.path.append(os.path.join(scriptsdir, '..', '..', 'wpaspy'))
     17 
     18 import wpaspy
     19 
     20 wpas_ctrl = '/var/run/wpa_supplicant'
     21 
     22 def wpas_connect():
     23     ifaces = []
     24     if os.path.isdir(wpas_ctrl):
     25         try:
     26             ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
     27         except OSError, error:
     28             print "Could not find wpa_supplicant: ", error
     29             return None
     30 
     31     if len(ifaces) < 1:
     32         print "No wpa_supplicant control interface found"
     33         return None
     34 
     35     for ctrl in ifaces:
     36         try:
     37             wpas = wpaspy.Ctrl(ctrl)
     38             return wpas
     39         except Exception, e:
     40             pass
     41     return None
     42 
     43 def dpp_logcat():
     44     for line in iter(sys.stdin.readline, ''):
     45         if "ResultHandler: Launching intent: Intent" not in line:
     46             continue
     47         if "act=android.intent.action.VIEW" not in line:
     48             continue
     49         uri = None
     50         for val in line.split(' '):
     51             if val.startswith('dat='):
     52                 uri = val.split('=', 1)[1]
     53                 break
     54         if not uri:
     55             continue
     56         if not uri.startswith('DPP:'):
     57             continue
     58         print "Found DPP bootstrap info URI:"
     59         print uri
     60         wpas = wpas_connect()
     61         if not wpas:
     62             print "Could not connect to wpa_supplicant"
     63             print
     64             continue
     65         res = wpas.request("DPP_QR_CODE " + uri);
     66         try:
     67             id = int(res)
     68         except ValueError:
     69             print "QR Code URI rejected"
     70             continue
     71         print "QR Code URI accepted - ID=%d" % id
     72         print wpas.request("DPP_BOOTSTRAP_INFO %d" % id)
     73         del wpas
     74 
     75 def dpp_display(curve):
     76         wpas = wpas_connect()
     77         if not wpas:
     78             print "Could not connect to wpa_supplicant"
     79             return
     80         res = wpas.request("STATUS")
     81         addr = None
     82         for line in res.splitlines():
     83             if line.startswith("address="):
     84                 addr = line.split('=')[1]
     85                 break
     86         cmd = "DPP_BOOTSTRAP_GEN type=qrcode"
     87         cmd += " chan=81/1"
     88         if addr:
     89             cmd += " mac=" + addr.replace(':','')
     90         if curve:
     91             cmd += " curve=" + curve
     92         res = wpas.request(cmd)
     93         try:
     94             id = int(res)
     95         except ValueError:
     96             print "Failed to generate bootstrap info URI"
     97             return
     98         print "Bootstrap information - ID=%d" % id
     99         print wpas.request("DPP_BOOTSTRAP_INFO %d" % id)
    100         uri = wpas.request("DPP_BOOTSTRAP_GET_URI %d" % id)
    101         print uri
    102         print "ID=%d" % id
    103         qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_M,
    104                            border=3)
    105         qr.add_data(uri, optimize=5)
    106         qr.print_ascii(tty=True)
    107         print "ID=%d" % id
    108         del wpas
    109 
    110 def main():
    111     parser = argparse.ArgumentParser(description='Android logcat to wpa_supplicant integration for DPP QR Code operations')
    112     parser.add_argument('-d', const=logging.DEBUG, default=logging.INFO,
    113                         action='store_const', dest='loglevel',
    114                         help='verbose debug output')
    115     parser.add_argument('--curve', '-c',
    116                         help='set a specific curve (P-256, P-384, P-521, BP-256R1, BP-384R1, BP-512R1) for key generation')
    117     parser.add_argument('command', choices=['logcat',
    118                                             'display'],
    119                         nargs='?')
    120     args = parser.parse_args()
    121 
    122     logging.basicConfig(level=args.loglevel)
    123 
    124     if args.command == "logcat":
    125         dpp_logcat()
    126     elif args.command == "display":
    127         dpp_display(args.curve)
    128 
    129 if __name__ == '__main__':
    130     main()
    131