Add the thing and a reader for the "Aruba Instant"
This commit is contained in:
parent
e586ce62ea
commit
8cd62b46ed
2 changed files with 174 additions and 0 deletions
74
access_points.d/aruba_instant.php
Executable file
74
access_points.d/aruba_instant.php
Executable file
|
@ -0,0 +1,74 @@
|
|||
#!/usr/bin/php5
|
||||
<?php
|
||||
|
||||
// Report all errors. Errors should never be ignored, it means that our
|
||||
// application is broken and we need to fix it.
|
||||
error_reporting(-1);
|
||||
|
||||
// Transform PHP's super weird error system to comprehensible exceptions.
|
||||
set_error_handler(function($errno, $errstr, $errfile, $errline) {
|
||||
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
|
||||
// Don't execute PHP internal error handler.
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
try {
|
||||
|
||||
//$radio = [
|
||||
// "802.11g/n (IAP)",
|
||||
// "802.11a/n (IAP)",
|
||||
//];
|
||||
$ip = "IP";
|
||||
$snmp = "SNMP"; // Keep this secret :)
|
||||
|
||||
|
||||
$ssid = array();
|
||||
//$radio = array();
|
||||
$wlanTable = snmprealwalk($ip, $snmp, ".1.3.6.1.4.1.14823.2.3.3.1.2.3.1");
|
||||
foreach ($wlanTable as $index => $value) {
|
||||
$index = str_replace("iso.3.6.1.4.1.14823.2.3.3.1.2.3.1.", "", $index);
|
||||
$index2 = explode(".", $index);
|
||||
$index3 = array();
|
||||
|
||||
for ($i = 1; $i < 8; $i++) {
|
||||
$index3[] = $index2[$i];
|
||||
}
|
||||
$index3 = implode(".", $index3);
|
||||
|
||||
if ($index2[0] == 4) {
|
||||
$mac = str_replace(" ",":", trim(str_replace("Hex-STRING: ", "", $value)));
|
||||
$ssid[$mac] = $wlanTable["iso.3.6.1.4.1.14823.2.3.3.1.2.3.1.3.".$index3];
|
||||
// $radio[$mac] = trim(str_replace("INTEGER: ", "", $wlanTable["iso.3.6.1.4.1.14823.2.3.3.1.2.3.1.2.".$index3]));
|
||||
}
|
||||
}
|
||||
|
||||
$macs = array();
|
||||
$clientTable = snmprealwalk($ip, $snmp, ".1.3.6.1.4.1.14823.2.3.3.1.2.4.1");
|
||||
foreach($clientTable as $index => $value) {
|
||||
$index = str_replace("iso.3.6.1.4.1.14823.2.3.3.1.2.4.1.", "", $index);
|
||||
$index2 = explode(".", $index);
|
||||
$index3 = array();
|
||||
|
||||
for ($i = 1; $i <= 6; $i++) {
|
||||
$index3[] = $index2[$i];
|
||||
}
|
||||
$index3 = implode(".", $index3);
|
||||
|
||||
if ($index2[0] == 1) {
|
||||
$radio_mac = $clientTable["iso.3.6.1.4.1.14823.2.3.3.1.2.4.1.2.".$index3];
|
||||
$radio_mac = str_replace(" ", ":", trim(str_replace("Hex-STRING: ", "", $radio_mac)));
|
||||
$macs[] = array (
|
||||
"mac" => strtolower(str_replace(" ", ":", trim(str_replace("Hex-STRING: ", "", $value)))),
|
||||
"ssid" => trim(str_replace("\"", "", str_replace("STRING: ", "", $ssid[$radio_mac]))),
|
||||
// "radio" => "IAP",
|
||||
"signal" => intval(trim(str_replace("INTEGER: ", "", $clientTable["iso.3.6.1.4.1.14823.2.3.3.1.2.4.1.7.".$index3]))),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
print(json_encode($macs, JSON_PRETTY_PRINT)."\n");
|
||||
|
||||
} catch (Exception $err) {
|
||||
print("Ah, fuck: $err\n");
|
||||
}
|
100
wifi-mqtt.py
Executable file
100
wifi-mqtt.py
Executable file
|
@ -0,0 +1,100 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import json
|
||||
import os
|
||||
import os.path as path
|
||||
import paho.mqtt.client as mqtt
|
||||
import re
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
|
||||
MQTT_HOST = 'mqtt.bitlair.nl'
|
||||
AP_DIR = path.join(path.dirname(__file__), 'access_points.d')
|
||||
|
||||
|
||||
def read_ap(filepath):
|
||||
regexp_mac = re.compile('^(:?[0-9a-f]{2}:){5}[0-9a-f]{2}$')
|
||||
associations = json.loads(subprocess.check_output([ filepath ]).decode('utf8'))
|
||||
assert type(associations) is list, 'The value returned by the AP driver is not a list'
|
||||
for assoc in associations:
|
||||
assert type(assoc['mac']) is str
|
||||
assert regexp_mac.match(assoc['mac']), 'Invalid MAC: %s' % assoc['mac']
|
||||
assert type(assoc['ssid']) is str and len(assoc['ssid']) > 1, 'Invalid SSID: %s' % assoc['ssid']
|
||||
if 'signal' in assoc:
|
||||
assert type(assoc['signal']) is int
|
||||
return associations
|
||||
|
||||
class Activity(object):
|
||||
|
||||
def __init__(self, driver_directory):
|
||||
self.associations = {}
|
||||
if driver_directory == "":
|
||||
return
|
||||
for ap_driver in os.listdir(driver_directory):
|
||||
filepath = path.join(driver_directory, ap_driver)
|
||||
if os.access(filepath, os.X_OK):
|
||||
self.associations.update({ assoc['mac']: assoc for assoc in read_ap(filepath) })
|
||||
|
||||
def ssids(self):
|
||||
return { assoc['ssid'] for assoc in self.associations.values() }
|
||||
|
||||
def macs(self):
|
||||
return self.associations.keys()
|
||||
|
||||
def diff(self, prev_activity):
|
||||
macs_joined = self.macs() - prev_activity.macs()
|
||||
macs_parted = prev_activity.macs() - self.macs()
|
||||
return {
|
||||
'joined': [ self.associations[mac] for mac in macs_joined ],
|
||||
'parted': [ prev_activity.associations[mac] for mac in macs_parted ],
|
||||
}
|
||||
|
||||
|
||||
def hook_print(activity, prev_activity, diff):
|
||||
print('')
|
||||
print('total online: %s' % len(activity.associations))
|
||||
if len(diff['joined']) > 0:
|
||||
print('joined: %s' % ', '.join([ '%s on %s' % (assoc['mac'], assoc['ssid']) for assoc in diff['joined'] ]))
|
||||
if len(diff['parted']) > 0:
|
||||
print('parted: %s' % ', '.join([ '%s on %s' % (assoc['mac'], assoc['ssid']) for assoc in diff['parted'] ]))
|
||||
|
||||
def hook_mqtt(activity, prev_activity, diff):
|
||||
normalize_ssid = lambda s: s.lower().replace(' ', '-')
|
||||
mqttc.publish('bitlair/wifi/all/online', len(activity.associations), retain=True)
|
||||
for ssid in activity.ssids() | prev_activity.ssids():
|
||||
online_count = sum(assoc['ssid'] == ssid for assoc in activity.associations.values())
|
||||
mqttc.publish('bitlair/wifi/%s/online' % normalize_ssid(ssid), str(online_count), retain=True)
|
||||
for assoc in diff['joined']:
|
||||
signal = assoc['signal'] if 'signal' in assoc else '-'
|
||||
payload = 'join %s %s' % (assoc['mac'], signal)
|
||||
mqttc.publish('bitlair/wifi/%s' % normalize_ssid(assoc['ssid']), payload)
|
||||
for assoc in diff['parted']:
|
||||
mqttc.publish('bitlair/wifi/%s' % normalize_ssid(assoc['ssid']), 'part %s' % assoc['mac'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mqttc = mqtt.Client()
|
||||
mqttc.connect(MQTT_HOST)
|
||||
mqttc.loop_start()
|
||||
|
||||
prev_activity = Activity('')
|
||||
while True:
|
||||
try:
|
||||
activity = Activity(AP_DIR)
|
||||
except Exception as err:
|
||||
print(err)
|
||||
time.sleep(1)
|
||||
continue
|
||||
|
||||
diff = activity.diff(prev_activity)
|
||||
if len(diff['joined']) > 0 or len(diff['parted']) > 0:
|
||||
hooks = [
|
||||
# hook_print,
|
||||
hook_mqtt,
|
||||
]
|
||||
for hook in hooks:
|
||||
hook(activity, prev_activity, diff)
|
||||
|
||||
prev_activity = activity
|
||||
time.sleep(30)
|
Loading…
Add table
Add a link
Reference in a new issue