File: //usr/lib/python2.7/site-packages/salt/modules/bluez_bluetooth.py
# -*- coding: utf-8 -*-
'''
Support for Bluetooth (using BlueZ in Linux).
The following packages are required packages for this module:
bluez >= 5.7
bluez-libs >= 5.7
bluez-utils >= 5.7
pybluez >= 0.18
'''
from __future__ import absolute_import, print_function, unicode_literals
# Import 3rd-party libs
# pylint: disable=import-error
from salt.ext.six.moves import shlex_quote as _cmd_quote
# pylint: enable=import-error
# Import salt libs
import salt.utils.validate.net
from salt.exceptions import CommandExecutionError
HAS_PYBLUEZ = False
try:
import bluetooth # pylint: disable=import-error
HAS_PYBLUEZ = True
except ImportError:
pass
__func_alias__ = {
'address_': 'address'
}
# Define the module's virtual name
__virtualname__ = 'bluetooth'
def __virtual__():
'''
Only load the module if bluetooth is installed
'''
if HAS_PYBLUEZ:
return __virtualname__
return (False, 'The bluetooth execution module cannot be loaded: bluetooth not installed.')
def version():
'''
Return Bluez version from bluetoothd -v
CLI Example:
.. code-block:: bash
salt '*' bluetoothd.version
'''
cmd = 'bluetoothctl -v'
out = __salt__['cmd.run'](cmd).splitlines()
bluez_version = out[0]
pybluez_version = '<= 0.18 (Unknown, but installed)'
try:
pybluez_version = bluetooth.__version__
except Exception as exc: # pylint: disable=broad-except
pass
return {'Bluez': bluez_version, 'PyBluez': pybluez_version}
def address_():
'''
Get the many addresses of the Bluetooth adapter
CLI Example:
.. code-block:: bash
salt '*' bluetooth.address
'''
ret = {}
cmd = 'hciconfig'
out = __salt__['cmd.run'](cmd).splitlines()
dev = ''
for line in out:
if line.startswith('hci'):
comps = line.split(':')
dev = comps[0]
ret[dev] = {
'device': dev,
'path': '/sys/class/bluetooth/{0}'.format(dev),
}
if 'BD Address' in line:
comps = line.split()
ret[dev]['address'] = comps[2]
if 'DOWN' in line:
ret[dev]['power'] = 'off'
if 'UP RUNNING' in line:
ret[dev]['power'] = 'on'
return ret
def power(dev, mode):
'''
Power a bluetooth device on or off
CLI Examples:
.. code-block:: bash
salt '*' bluetooth.power hci0 on
salt '*' bluetooth.power hci0 off
'''
if dev not in address_():
raise CommandExecutionError('Invalid dev passed to bluetooth.power')
if mode == 'on' or mode is True:
state = 'up'
mode = 'on'
else:
state = 'down'
mode = 'off'
cmd = 'hciconfig {0} {1}'.format(dev, state)
__salt__['cmd.run'](cmd).splitlines()
info = address_()
if info[dev]['power'] == mode:
return True
return False
def discoverable(dev):
'''
Enable this bluetooth device to be discoverable.
CLI Example:
.. code-block:: bash
salt '*' bluetooth.discoverable hci0
'''
if dev not in address_():
raise CommandExecutionError(
'Invalid dev passed to bluetooth.discoverable'
)
cmd = 'hciconfig {0} iscan'.format(dev)
__salt__['cmd.run'](cmd).splitlines()
cmd = 'hciconfig {0}'.format(dev)
out = __salt__['cmd.run'](cmd)
if 'UP RUNNING ISCAN' in out:
return True
return False
def noscan(dev):
'''
Turn off scanning modes on this device.
CLI Example:
.. code-block:: bash
salt '*' bluetooth.noscan hci0
'''
if dev not in address_():
raise CommandExecutionError('Invalid dev passed to bluetooth.noscan')
cmd = 'hciconfig {0} noscan'.format(dev)
__salt__['cmd.run'](cmd).splitlines()
cmd = 'hciconfig {0}'.format(dev)
out = __salt__['cmd.run'](cmd)
if 'SCAN' in out:
return False
return True
def scan():
'''
Scan for bluetooth devices in the area
CLI Example:
.. code-block:: bash
salt '*' bluetooth.scan
'''
ret = []
devices = bluetooth.discover_devices(lookup_names=True)
for device in devices:
ret.append({device[0]: device[1]})
return ret
def block(bdaddr):
'''
Block a specific bluetooth device by BD Address
CLI Example:
.. code-block:: bash
salt '*' bluetooth.block DE:AD:BE:EF:CA:FE
'''
if not salt.utils.validate.net.mac(bdaddr):
raise CommandExecutionError(
'Invalid BD address passed to bluetooth.block'
)
cmd = 'hciconfig {0} block'.format(bdaddr)
__salt__['cmd.run'](cmd).splitlines()
def unblock(bdaddr):
'''
Unblock a specific bluetooth device by BD Address
CLI Example:
.. code-block:: bash
salt '*' bluetooth.unblock DE:AD:BE:EF:CA:FE
'''
if not salt.utils.validate.net.mac(bdaddr):
raise CommandExecutionError(
'Invalid BD address passed to bluetooth.unblock'
)
cmd = 'hciconfig {0} unblock'.format(bdaddr)
__salt__['cmd.run'](cmd).splitlines()
def pair(address, key):
'''
Pair the bluetooth adapter with a device
CLI Example:
.. code-block:: bash
salt '*' bluetooth.pair DE:AD:BE:EF:CA:FE 1234
Where DE:AD:BE:EF:CA:FE is the address of the device to pair with, and 1234
is the passphrase.
TODO: This function is currently broken, as the bluez-simple-agent program
no longer ships with BlueZ >= 5.0. It needs to be refactored.
'''
if not salt.utils.validate.net.mac(address):
raise CommandExecutionError(
'Invalid BD address passed to bluetooth.pair'
)
try:
int(key)
except Exception: # pylint: disable=broad-except
raise CommandExecutionError(
'bluetooth.pair requires a numerical key to be used'
)
addy = address_()
cmd = 'echo {0} | bluez-simple-agent {1} {2}'.format(
_cmd_quote(addy['device']), _cmd_quote(address), _cmd_quote(key)
)
out = __salt__['cmd.run'](cmd, python_shell=True).splitlines()
return out
def unpair(address):
'''
Unpair the bluetooth adapter from a device
CLI Example:
.. code-block:: bash
salt '*' bluetooth.unpair DE:AD:BE:EF:CA:FE
Where DE:AD:BE:EF:CA:FE is the address of the device to unpair.
TODO: This function is currently broken, as the bluez-simple-agent program
no longer ships with BlueZ >= 5.0. It needs to be refactored.
'''
if not salt.utils.validate.net.mac(address):
raise CommandExecutionError(
'Invalid BD address passed to bluetooth.unpair'
)
cmd = 'bluez-test-device remove {0}'.format(address)
out = __salt__['cmd.run'](cmd).splitlines()
return out
def start():
'''
Start the bluetooth service.
CLI Example:
.. code-block:: bash
salt '*' bluetooth.start
'''
out = __salt__['service.start']('bluetooth')
return out
def stop():
'''
Stop the bluetooth service.
CLI Example:
.. code-block:: bash
salt '*' bluetooth.stop
'''
out = __salt__['service.stop']('bluetooth')
return out