Add the thing and a reader for the "Aruba Instant"

This commit is contained in:
polyfloyd 2017-03-11 12:09:38 +01:00
parent e586ce62ea
commit 8cd62b46ed
2 changed files with 174 additions and 0 deletions

View 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
View 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)