Skip to content

Commit

Permalink
first version of cli scanner tool
Browse files Browse the repository at this point in the history
  • Loading branch information
maxliu2001 committed May 24, 2023
1 parent 073f15c commit d38c12d
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 133 deletions.
28 changes: 14 additions & 14 deletions pscheduler-test-wifibssid/wifibssid/result-format
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ if format == 'text/plain':
print("")
print(entry["ssid"] + ":")
print(f' Signal: {entry["signal"]}')
print(f' Address: {entry["address"]}')
print(f' Frequency: {entry["frequency"]}')
print(f' Quality: {entry["quality"]}')
print(f' Bitrates: {entry["bitrates"]}')
print(f' Encrypted: {entry["encrypted"]}')
print(f' Channel: {entry["channel"]}')
print(f' Mode: {entry["mode"]}')
print(f' Address: {entry["bssid"]}')
print(f' Frequency: {entry["freq"]}')
# print(f' Quality: {entry["quality"]}')
# print(f' Bitrates: {entry["bitrates"]}')
# print(f' Encrypted: {entry["encrypted"]}')
# print(f' Channel: {entry["channel"]}')
print(f' Mode: {entry["flags"]}')
print("")

elif format == 'text/html':
Expand All @@ -68,13 +68,13 @@ elif format == 'text/html':
for entry in result['ssid_list']:
print(f' <tr><td><b>SSID</b></td> <td>{entry["ssid"]}</td></tr>')
print(f' <tr><td><b>Signal</b></td> <td>{entry["signal"]}</td></tr>')
print(f' <tr><td><b>Address</b></td> <td>{entry["address"]}</td></tr>')
print(f' <tr><td><b>Frequency</b></td> <td>{entry["frequency"]}</td></tr>')
print(f' <tr><td><b>Quality</b></td> <td>{entry["quality"]}</td></tr>')
print(f' <tr><td><b>Bitrates</b></td> <td>{entry["bitrates"]}</td></tr>')
print(f' <tr><td><b>Encrypted</b></td> <td>{entry["signal"]}</td></tr>')
print(f' <tr><td><b>Channel</b></td> <td>{entry["channel"]}</td></tr>')
print(f' <tr><td><b>Mode</b></td> <td>{entry["mode"]}</td></tr>')
print(f' <tr><td><b>Address</b></td> <td>{entry["bssid"]}</td></tr>')
print(f' <tr><td><b>Frequency</b></td> <td>{entry["freq"]}</td></tr>')
# print(f' <tr><td><b>Quality</b></td> <td>{entry["quality"]}</td></tr>')
# print(f' <tr><td><b>Bitrates</b></td> <td>{entry["bitrates"]}</td></tr>')
# print(f' <tr><td><b>Encrypted</b></td> <td>{entry["signal"]}</td></tr>')
# print(f' <tr><td><b>Channel</b></td> <td>{entry["channel"]}</td></tr>')
print(f' <tr><td><b>Mode</b></td> <td>{entry["flags"]}</td></tr>')
print('</table>')


Expand Down
3 changes: 1 addition & 2 deletions pscheduler-test-wifibssid/wifibssid/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@
},
# If listed here, these parameters MUST be in the test spec.
"required": [
"interface",
"ssid",
"interface"
],
# Treat other properties as acceptable. This should
# ALWAYS be false.
Expand Down
1 change: 1 addition & 0 deletions pscheduler-tool-bssidscanner/bssidscanner/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ FILES=\
merged-results \
participant-data \
run \
run-wrapped

install: $(FILES)
ifndef DESTDIR
Expand Down
119 changes: 2 additions & 117 deletions pscheduler-tool-bssidscanner/bssidscanner/run
Original file line number Diff line number Diff line change
@@ -1,119 +1,4 @@
#!/usr/bin/env python3
#!/bin/sh -e

#
# Development Order #5:
#
# This is the meat and bones of the tool, where the actual desired
# commands or operation will be run. The results are then recorded
# and added to the 'results' JSON data, which will then be sent
# back to the test. Both system and api are able to be used here.
#

import datetime
import subprocess
import json
import sys
import time
import argparse
import time
from wifi import Cell #make sure that you have pip installed wifi

import pscheduler

# from stdin
input = pscheduler.json_load(exit_on_error=True)

# Take input from test spec
try:
interface = input['test']['spec']['interface']
ssid = input['test']['spec']['ssid']
except KeyError:
pscheduler.fail('Missing data in input')

# convert the comma separated ssids to a list
ssid = list(ssid.split(','))

duration = input['test']['spec'].get('duration', 'PT5S')
duration = pscheduler.timedelta_as_seconds( pscheduler.iso8601_as_timedelta(duration) )
timeout_iso = input['test']['spec'].get('timeout', 'PT10S')
timeout = pscheduler.timedelta_as_seconds( pscheduler.iso8601_as_timedelta(timeout_iso) )
start_time = datetime.datetime.now()
succeeded = False
error = ''
diags = ''

# Run the actual task here:
def get_all_bssids(interface):
"""
Scan the given interface for all bssids
Return a list of all bssids
"""
start_time = time.time()
cells = Cell.all(interface) # Specify interface to scan on
wifi_list = []
for cell in cells:
bssid = {}
bssid['ssid'] = cell.ssid
bssid['signal'] = cell.signal
bssid['address'] = cell.address
bssid['frequency'] = pscheduler.si_as_number(cell.frequency[:-2])
quality_num,quality_denom = cell.quality.split('/')
bssid['quality'] = float(quality_num) / float(quality_denom)
bssid['bitrates'] = sorted(map(lambda v : pscheduler.si_as_number(v[:-3]), cell.bitrates))
bssid['encrypted'] = cell.encrypted
bssid['channel'] = cell.channel
bssid['mode'] = cell.mode
wifi_list.append(bssid)

end_time = time.time()
elapsed_time = end_time - start_time
log_msg = "Scan finished in " + str(elapsed_time)
return wifi_list, elapsed_time

"""
Scan on the given interface
Output a list of all bssids in json format with the given ssid
"""
all_bssids, elapsed_time = get_all_bssids(interface)
ssid_list = []

# Check complete list for matching ssids
for bssid in all_bssids:
#if no ssids were given then append all the ssids
if not ssid:
ssid_list.append(bssid)
else:
#if ssid/ssids were given then only append those
if bssid['ssid'] in ssid:
ssid_list.append(bssid)

succeeded = True

# IMPORTANT NOTE: This code puts the process to sleep until the
# scheduled start time has arrived. It should be placed after all
# preparatory code has been executed and immediately before the tool
# is invoked (for plugins that run other programs) or any activity
# that does a measurement (for those that don't).

try:
pscheduler.sleep_until(input['schedule']['start'])
except KeyError:
pscheduler.fail("Unable to find start time in input")


end_time = datetime.datetime.now()

# Organize results into json data
results = {
'succeeded': succeeded,
'result': {
'schema': 1,
'time': pscheduler.timedelta_as_iso8601( end_time - start_time),
'succeeded': succeeded,
'ssid_list': ssid_list
},
'error': error,
'diags': diags }

pscheduler.succeed_json(results)
exec sudo "$(dirname $0)/run-wrapped"

125 changes: 125 additions & 0 deletions pscheduler-tool-bssidscanner/bssidscanner/run-wrapped
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#!/usr/bin/env python3

#
# Development Order #5:
#
# This is the meat and bones of the tool, where the actual desired
# commands or operation will be run. The results are then recorded
# and added to the 'results' JSON data, which will then be sent
# back to the test. Both system and api are able to be used here.
#

import select
from os import getpid, makedirs, unlink, access, R_OK, system, listdir, path
import datetime
import pscheduler
# import subprocess
import time

#temp file preserved between consecutive runs but not reboots
WPA_CONFIG_PATH = '/tmp/wpa_supplicant/wpa_supplicant.conf'
#initializes only when wpa_supplicant starts
WPA_CTRL_IFACE_BASE = '/var/run/wpa_supplicant'
ssid_set = set()

# parse config
pscheduler_input = pscheduler.json_load(exit_on_error=True)
interface = pscheduler_input['test']['spec'].get('interface')
get_ssid = pscheduler_input['test']['spec'].get('ssid', None)
ssid_set = set(get_ssid.split(',')) if get_ssid else None
duration_iso = pscheduler_input['test']['spec'].get('duration', 'PT5S')
timeout_iso = pscheduler_input['test']['spec'].get('timeout', 'PT10S')
timeout = pscheduler.timedelta_as_seconds(pscheduler.iso8601_as_timedelta(timeout_iso))
duration = pscheduler.timedelta_as_seconds(pscheduler.iso8601_as_timedelta(duration_iso))
start_time = datetime.datetime.now()
error = ''
diags = ''
ssid_list = []
dir_path = path.dirname(WPA_CONFIG_PATH)

# check if interface already exists
if not access(f'{WPA_CTRL_IFACE_BASE}/{interface}', R_OK):
#create config file and start wpa_supplicant
if not path.exists(dir_path):
makedirs(dir_path)
with open(WPA_CONFIG_PATH, 'w') as f:
f.write('ctrl_interface='+WPA_CTRL_IFACE_BASE+'\r\n')
f.write('update_config=1\r\n')
f.write('p2p_disabled=1\r\n')
status, out, err = pscheduler.run_program(['wpa_supplicant','-Dnl80211','-B','-i',interface,'-c',WPA_CONFIG_PATH])
if status:
pscheduler.succeed_json( {
'succeeded': False,
'diags': '',
'error': 'failed to initialize interface',
'result': None
} )

# run wpa_cli
start = datetime.datetime.now()
status, res, err = pscheduler.run_program(['wpa_cli', 'scan'])
if res.split('\n')[1] == 'OK':
status, res, err = pscheduler.run_program(['wpa_cli', 'scan_result'])
else:
pscheduler.succeed_json( {
'succeeded': False,
'diags': '',
'error': 'wpa_cli scan failed',
'result': None
} )


result = res.split('\n')

# account for automatic scanning interval of cli
while len(result) <= 3:
status, res, err = pscheduler.run_program(['wpa_cli', 'scan_result'])
result = res.split('\n')
time.sleep(0.3)

for i in range(2, len(result)):
line = result[i].split('\t')
if len(line) == 1:
break
elif len(line) == 4:
bssid, freq, signal, flags = line
elif len(line) == 5:
bssid, freq, signal, flags, ssid = line

if not ssid_set or ssid in ssid_set:
# retrieve prev ssid if ssid is empty
if ssid == '':
ssid = ssid_list[-1]['ssid']
ssid_list.append({
'ssid': ssid,
'bssid': bssid,
'freq': int(freq),
'signal': int(signal),
'flags': flags
})
end_time = datetime.datetime.now()

# Check for empty result
if len(ssid_list) == 0:
pscheduler.succeed_json( {
'succeeded': False,
'diags': '',
'error': 'scan completed but returned empty result',
'result': None
} )

# Organize results into json data
results = {
'succeeded': True,
'result': {
'schema': 1,
'time': pscheduler.timedelta_as_iso8601(end_time - start_time),
'succeeded': True,
'ssid_list': ssid_list
},
'error': error,
'diags': diags
}


pscheduler.succeed_json(results)
Empty file.

0 comments on commit d38c12d

Please sign in to comment.