. * * @link https://www.librenms.org * * @copyright 2017 Tony Murray * @author Tony Murray */ namespace LibreNMS\Device; use LibreNMS\Config; use LibreNMS\OS; use LibreNMS\Util\StringHelpers; class WirelessSensor extends Sensor { protected static $name = 'Wireless Sensor'; protected static $table = 'wireless_sensors'; protected static $data_name = 'wireless-sensor'; protected static $translation_prefix = 'wireless'; private $access_point_ip; /** * Sensor constructor. Create a new sensor to be discovered. * * @param string $type Class of this sensor, must be a supported class * @param int $device_id the device_id of the device that owns this sensor * @param array|string $oids an array or single oid that contains the data for this sensor * @param string $subtype the type of sensor an additional identifier to separate out sensors of the same class, generally this is the os name * @param int|string $index the index of this sensor, must be stable, generally the index of the oid * @param string $description A user visible description of this sensor, may be truncated in some places (like graphs) * @param int|float $current The current value of this sensor, will seed the db and may be used to guess limits * @param int $multiplier a number to multiply the value(s) by * @param int $divisor a number to divide the value(s) by * @param string $aggregator an operation to combine multiple numbers. Supported: sum, avg * @param int $access_point_id The id of the AP in the access_points sensor this belongs to (generally used for controllers) * @param int|float $high_limit Alerting: Maximum value * @param int|float $low_limit Alerting: Minimum value * @param int|float $high_warn Alerting: High warning value * @param int|float $low_warn Alerting: Low warning value * @param int|float $entPhysicalIndex The entPhysicalIndex this sensor is associated, often a port * @param int|float $entPhysicalMeasured the table to look for the entPhysicalIndex, for example 'ports' (maybe unused) */ public function __construct( $type, $device_id, $oids, $subtype, $index, $description, $current = null, $multiplier = 1, $divisor = 1, $aggregator = 'sum', $access_point_id = null, $high_limit = null, $low_limit = null, $high_warn = null, $low_warn = null, $entPhysicalIndex = null, $entPhysicalMeasured = null ) { $this->access_point_ip = $access_point_id; parent::__construct( $type, $device_id, $oids, $subtype, $index, $description, $current, $multiplier, $divisor, $aggregator, $high_limit, $low_limit, $high_warn, $low_warn, $entPhysicalIndex, $entPhysicalMeasured ); } protected function toArray() { $sensor = parent::toArray(); $sensor['access_point_id'] = $this->access_point_ip; return $sensor; } public static function runDiscovery(OS $os) { $types = array_keys(self::getTypes()); $submodules = Config::get('discovery_submodules.wireless', $types); $types = array_intersect($types, $submodules); foreach ($types as $type) { static::discoverType($os, $type); } } /** * Return a list of valid types with metadata about each type * $class => array( * 'short' - short text for this class * 'long' - long text for this class * 'unit' - units used by this class 'dBm' for example * 'icon' - font awesome icon used by this class * ) * * @param bool $valid filter this list by valid types in the database * @param int $device_id when filtering, only return types valid for this device_id * @return array */ public static function getTypes($valid = false, $device_id = null) { // Add new types here translations/descriptions/units in lang//wireless.php // FIXME I'm really bad with icons, someone please help! static $types = [ 'ap-count' => [ 'icon' => 'wifi', ], 'clients' => [ 'icon' => 'tablet', ], 'quality' => [ 'icon' => 'feed', ], 'capacity' => [ 'icon' => 'feed', ], 'utilization' => [ 'icon' => 'percent', ], 'rate' => [ 'icon' => 'tachometer', ], 'ccq' => [ 'icon' => 'wifi', ], 'snr' => [ 'icon' => 'signal', ], 'sinr' => [ 'icon' => 'signal', ], 'rsrp' => [ 'icon' => 'signal', ], 'rsrq' => [ 'icon' => 'signal', ], 'ssr' => [ 'icon' => 'signal', ], 'mse' => [ 'icon' => 'signal', ], 'xpi' => [ 'icon' => 'signal', ], 'rssi' => [ 'icon' => 'signal', ], 'power' => [ 'icon' => 'bolt', ], 'noise-floor' => [ 'icon' => 'signal', ], 'errors' => [ 'icon' => 'exclamation-triangle', 'type' => 'counter', ], 'error-ratio' => [ 'icon' => 'exclamation-triangle', ], 'error-rate' => [ 'icon' => 'exclamation-triangle', ], 'frequency' => [ 'icon' => 'line-chart', ], 'distance' => [ 'icon' => 'space-shuttle', ], 'cell' => [ 'icon' => 'line-chart', ], 'channel' => [ 'icon' => 'line-chart', ], ]; if ($valid) { $sql = 'SELECT `sensor_class` FROM `wireless_sensors`'; $params = []; if (isset($device_id)) { $sql .= ' WHERE `device_id`=?'; $params[] = $device_id; } $sql .= ' GROUP BY `sensor_class`'; $sensors = dbFetchColumn($sql, $params); return array_intersect_key($types, array_flip($sensors)); } return $types; } protected static function getDiscoveryInterface($type) { return StringHelpers::toClass($type, 'LibreNMS\\Interfaces\\Discovery\\Sensors\\Wireless') . 'Discovery'; } protected static function getDiscoveryMethod($type) { return 'discoverWireless' . StringHelpers::toClass($type, null); } protected static function getPollingInterface($type) { return StringHelpers::toClass($type, 'LibreNMS\\Interfaces\\Polling\\Sensors\\Wireless') . 'Polling'; } protected static function getPollingMethod($type) { return 'pollWireless' . StringHelpers::toClass($type, null); } /** * Convert a WiFi channel to a Frequency in MHz * * @param int $channel * @return int */ public static function channelToFrequency($channel): int { $channels = [ 1 => 2412, 2 => 2417, 3 => 2422, 4 => 2427, 5 => 2432, 6 => 2437, 7 => 2442, 8 => 2447, 9 => 2452, 10 => 2457, 11 => 2462, 12 => 2467, 13 => 2472, 14 => 2484, 34 => 5170, 36 => 5180, 38 => 5190, 40 => 5200, 42 => 5210, 44 => 5220, 46 => 5230, 48 => 5240, 52 => 5260, 56 => 5280, 60 => 5300, 64 => 5320, 100 => 5500, 104 => 5520, 108 => 5540, 112 => 5560, 116 => 5580, 120 => 5600, 124 => 5620, 128 => 5640, 132 => 5660, 136 => 5680, 140 => 5700, 149 => 5745, 153 => 5765, 157 => 5785, 161 => 5805, 165 => 5825, ]; return $channels[$channel] ?? 0; } }