Skip to content

Commit

Permalink
Merge pull request kivy#488 from kivy/linux_wifi_interfaces
Browse files Browse the repository at this point in the history
Add support for interfaces in Linux WiFi
  • Loading branch information
KeyWeeUsr authored Dec 24, 2018
2 parents 6768c2b + e5dba2e commit dd09864
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 19 deletions.
43 changes: 34 additions & 9 deletions plyer/facades/wifi.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,33 @@ class Wifi(object):

def is_enabled(self):
'''
Returns `True`if the Wifi is enables else `False`.
Return enabled status of WiFi hardware.
'''
return self._is_enabled()

def start_scanning(self):
def is_connected(self, interface=None):
'''
Return connection state of WiFi interface.
.. versionadded:: 1.3.3
'''
return self._is_connected(interface=interface)

@property
def interfaces(self):
'''
List all available WiFi interfaces.
.. versionadded:: 1.3.3
'''

raise NotImplementedError()

def start_scanning(self, interface=None):
'''
Turn on scanning.
'''
return self._start_scanning()
return self._start_scanning(interface=interface)

def get_network_info(self, name):
'''
Expand All @@ -111,17 +129,21 @@ def get_available_wifi(self):
'''
return self._get_available_wifi()

def connect(self, network, parameters):
def connect(self, network, parameters, interface=None):
'''
Method to connect to some network.
'''
self._connect(network=network, parameters=parameters)
self._connect(
network=network,
parameters=parameters,
interface=interface
)

def disconnect(self):
def disconnect(self, interface=None):
'''
To disconnect from some network.
'''
self._disconnect()
self._disconnect(interface=interface)

def enable(self):
'''
Expand All @@ -140,7 +162,10 @@ def disable(self):
def _is_enabled(self):
raise NotImplementedError()

def _start_scanning(self):
def _is_connected(self, interface=None):
raise NotImplementedError()

def _start_scanning(self, interface=None):
raise NotImplementedError()

def _get_network_info(self, **kwargs):
Expand All @@ -152,7 +177,7 @@ def _get_available_wifi(self):
def _connect(self, **kwargs):
raise NotImplementedError()

def _disconnect(self):
def _disconnect(self, interface=None):
raise NotImplementedError()

def _enable(self):
Expand Down
116 changes: 106 additions & 10 deletions plyer/platforms/linux/wifi.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,97 @@


class LinuxWifi(Wifi):
names = {}
'''
.. versionadded:: 1.2.5
'''

def __init__(self, *args, **kwargs):
'''
.. versionadded:: 1.3.3
'''

super(LinuxWifi, self).__init__(*args, **kwargs)
self.names = {}

@property
def interfaces(self):
'''
.. versionadded:: 1.3.3
'''

proc = Popen([
'nmcli', '--terse',
'--fields', 'DEVICE,TYPE',
'device'
], stdout=PIPE)
lines = proc.communicate()[0].decode('utf-8').splitlines()

interfaces = []
for line in lines:
device, dtype = line.split(':')
if dtype != 'wifi':
continue
interfaces.append(device)

return interfaces

def _is_enabled(self):
'''
Returns `True` if wifi is enabled else `False`.
.. versionadded:: 1.2.5
.. versionchanged:: 1.3.2
nmcli output is properly decoded to unicode
'''
enbl = Popen(["nmcli", "radio", "wifi"], stdout=PIPE, stderr=PIPE)
if enbl.communicate()[0].split()[0].decode('utf-8') == "enabled":
return True
return False

def _start_scanning(self):
def _is_connected(self, interface=None):
'''
.. versionadded:: 1.3.3
'''

if not interface:
interface = self.interfaces[0]

proc = Popen([
'nmcli', '--terse',
'--fields', 'DEVICE,TYPE,STATE',
'device'
], stdout=PIPE)
lines = proc.communicate()[0].decode('utf-8').splitlines()

connected = False
for line in lines:
device, dtype, state = line.split(':')
if dtype != 'wifi':
continue

if device != interface:
continue

if state == 'connected':
connected = True

return connected

def _start_scanning(self, interface=None):
'''
Returns all the network information.
.. versionadded:: 1.2.5
.. versionchanged:: 1.3.0
scan only if wifi is enabled
'''

if not interface:
interface = self.interfaces[0]

import wifi
if self._is_enabled():
list_ = list(wifi.Cell.all('wlan0'))
list_ = list(wifi.Cell.all(interface))
for i in range(len(list_)):
self.names[list_[i].ssid] = list_[i]
else:
Expand All @@ -43,6 +116,8 @@ def _get_network_info(self, name):
'''
Starts scanning for available Wi-Fi networks and returns the available,
devices.
.. versionadded:: 1.2.5
'''
ret_list = {}
ret_list['ssid'] = self.names[name].ssid
Expand All @@ -63,16 +138,25 @@ def _get_network_info(self, name):
def _get_available_wifi(self):
'''
Returns the name of available networks.
.. versionadded:: 1.2.5
.. versionchanged:: 1.3.3
return a proper list of elements instead of dict_keys
'''
return self.names.keys()
return list(self.names.keys())

def _connect(self, network, parameters):
def _connect(self, network, parameters, interface=None):
'''
Expects 2 parameters:
- name/ssid of the network.
- parameters:
- password: dict type
- parameters: dict type
- password: string or None
.. versionadded:: 1.2.5
'''
if not interface:
interface = self.interfaces[0]

import wifi
result = None
try:
Expand All @@ -81,32 +165,44 @@ def _connect(self, network, parameters):
password = parameters['password']
cell = self.names[network]
result = wifi.Scheme.for_cell(
'wlan0', network, cell, password
interface, network, cell, password
)
return result

def _disconnect(self):
def _disconnect(self, interface=None):
'''
Disconnect all the networks managed by Network manager.
.. versionadded:: 1.2.5
'''
if not interface:
interface = self.interfaces[0]

if self._nmcli_version() >= (1, 2, 6):
call(['nmcli', 'dev', 'disconnect', 'wlan0'])
call(['nmcli', 'dev', 'disconnect', interface])
else:
call(['nmcli', 'nm', 'enable', 'false'])

def _enable(self):
'''
Wifi interface power state is set to "ON".
.. versionadded:: 1.3.2
'''
return call(['nmcli', 'radio', 'wifi', 'on'])

def _disable(self):
'''
Wifi interface power state is set to "OFF".
.. versionadded:: 1.3.2
'''
return call(['nmcli', 'radio', 'wifi', 'off'])

def _nmcli_version(self):
'''
.. versionadded:: 1.3.2
'''
version = Popen(['nmcli', '-v'], stdout=PIPE)
version = version.communicate()[0].decode('utf-8')
while version and not version[0].isdigit():
Expand Down

0 comments on commit dd09864

Please sign in to comment.